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) => self.generate_unary_func("LENGTH", f),
2524 Expression::Trim(f) => self.generate_trim(f),
2525 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2526 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2527 Expression::Replace(f) => self.generate_replace(f),
2528 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2529 Expression::Left(f) => self.generate_left_right("LEFT", f),
2530 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2531 Expression::Repeat(f) => self.generate_repeat(f),
2532 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2533 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2534 Expression::Split(f) => self.generate_split(f),
2535 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2536 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2537 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2538 Expression::Overlay(f) => self.generate_overlay(f),
2539
2540 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2542 Expression::Round(f) => self.generate_round(f),
2543 Expression::Floor(f) => self.generate_floor(f),
2544 Expression::Ceil(f) => self.generate_ceil(f),
2545 Expression::Power(f) => self.generate_power(f),
2546 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2547 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2548 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2549 Expression::Log(f) => self.generate_log(f),
2550 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2551 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2552 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2553 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2554
2555 Expression::CurrentDate(_) => {
2557 self.write_keyword("CURRENT_DATE");
2558 Ok(())
2559 }
2560 Expression::CurrentTime(f) => self.generate_current_time(f),
2561 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2562 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2563 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2564 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2565 Expression::DateDiff(f) => self.generate_datediff(f),
2566 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2567 Expression::Extract(f) => self.generate_extract(f),
2568 Expression::ToDate(f) => self.generate_to_date(f),
2569 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2570
2571 Expression::Coalesce(f) => {
2573 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2575 self.generate_vararg_func(func_name, &f.expressions)
2576 }
2577 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2578 Expression::IfFunc(f) => self.generate_if_func(f),
2579 Expression::IfNull(f) => self.generate_ifnull(f),
2580 Expression::Nvl(f) => self.generate_nvl(f),
2581 Expression::Nvl2(f) => self.generate_nvl2(f),
2582
2583 Expression::TryCast(cast) => self.generate_try_cast(cast),
2585 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2586
2587 Expression::Count(f) => self.generate_count(f),
2589 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2590 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2591 Expression::Min(f) => self.generate_agg_func("MIN", f),
2592 Expression::Max(f) => self.generate_agg_func("MAX", f),
2593 Expression::GroupConcat(f) => self.generate_group_concat(f),
2594 Expression::StringAgg(f) => self.generate_string_agg(f),
2595 Expression::ListAgg(f) => self.generate_listagg(f),
2596 Expression::ArrayAgg(f) => {
2597 let override_name = f
2600 .name
2601 .as_ref()
2602 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2603 .map(|n| n.to_ascii_uppercase());
2604 match override_name {
2605 Some(name) => self.generate_agg_func(&name, f),
2606 None => self.generate_agg_func("ARRAY_AGG", f),
2607 }
2608 }
2609 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2610 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2611 Expression::SumIf(f) => self.generate_sum_if(f),
2612 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2613 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2614 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2615 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2616 Expression::VarPop(f) => {
2617 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2618 "VARIANCE_POP"
2619 } else {
2620 "VAR_POP"
2621 };
2622 self.generate_agg_func(name, f)
2623 }
2624 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2625 Expression::Skewness(f) => {
2626 let name = match self.config.dialect {
2627 Some(DialectType::Snowflake) => "SKEW",
2628 _ => "SKEWNESS",
2629 };
2630 self.generate_agg_func(name, f)
2631 }
2632 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2633 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2634 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2635 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2636 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2637 Expression::ApproxDistinct(f) => {
2638 match self.config.dialect {
2639 Some(DialectType::Hive)
2640 | Some(DialectType::Spark)
2641 | Some(DialectType::Databricks)
2642 | Some(DialectType::BigQuery) => {
2643 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2645 }
2646 Some(DialectType::Redshift) => {
2647 self.write_keyword("APPROXIMATE COUNT");
2649 self.write("(");
2650 self.write_keyword("DISTINCT");
2651 self.write(" ");
2652 self.generate_expression(&f.this)?;
2653 self.write(")");
2654 Ok(())
2655 }
2656 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2657 }
2658 }
2659 Expression::ApproxCountDistinct(f) => {
2660 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2661 }
2662 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2663 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2664 Expression::LogicalAnd(f) => {
2665 let name = match self.config.dialect {
2666 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2667 Some(DialectType::Spark)
2668 | Some(DialectType::Databricks)
2669 | Some(DialectType::PostgreSQL)
2670 | Some(DialectType::DuckDB)
2671 | Some(DialectType::Redshift) => "BOOL_AND",
2672 Some(DialectType::Oracle)
2673 | Some(DialectType::SQLite)
2674 | Some(DialectType::MySQL) => "MIN",
2675 _ => "BOOL_AND",
2676 };
2677 self.generate_agg_func(name, f)
2678 }
2679 Expression::LogicalOr(f) => {
2680 let name = match self.config.dialect {
2681 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2682 Some(DialectType::Spark)
2683 | Some(DialectType::Databricks)
2684 | Some(DialectType::PostgreSQL)
2685 | Some(DialectType::DuckDB)
2686 | Some(DialectType::Redshift) => "BOOL_OR",
2687 Some(DialectType::Oracle)
2688 | Some(DialectType::SQLite)
2689 | Some(DialectType::MySQL) => "MAX",
2690 _ => "BOOL_OR",
2691 };
2692 self.generate_agg_func(name, f)
2693 }
2694
2695 Expression::RowNumber(_) => {
2697 if self.config.dialect == Some(DialectType::ClickHouse) {
2698 self.write("row_number");
2699 } else {
2700 self.write_keyword("ROW_NUMBER");
2701 }
2702 self.write("()");
2703 Ok(())
2704 }
2705 Expression::Rank(r) => {
2706 self.write_keyword("RANK");
2707 self.write("(");
2708 if !r.args.is_empty() {
2710 for (i, arg) in r.args.iter().enumerate() {
2711 if i > 0 {
2712 self.write(", ");
2713 }
2714 self.generate_expression(arg)?;
2715 }
2716 } else if let Some(order_by) = &r.order_by {
2717 self.write_keyword(" ORDER BY ");
2719 for (i, ob) in order_by.iter().enumerate() {
2720 if i > 0 {
2721 self.write(", ");
2722 }
2723 self.generate_ordered(ob)?;
2724 }
2725 }
2726 self.write(")");
2727 Ok(())
2728 }
2729 Expression::DenseRank(dr) => {
2730 self.write_keyword("DENSE_RANK");
2731 self.write("(");
2732 for (i, arg) in dr.args.iter().enumerate() {
2734 if i > 0 {
2735 self.write(", ");
2736 }
2737 self.generate_expression(arg)?;
2738 }
2739 self.write(")");
2740 Ok(())
2741 }
2742 Expression::NTile(f) => self.generate_ntile(f),
2743 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2744 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2745 Expression::FirstValue(f) => {
2746 self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f)
2747 }
2748 Expression::LastValue(f) => {
2749 self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f)
2750 }
2751 Expression::NthValue(f) => self.generate_nth_value(f),
2752 Expression::PercentRank(pr) => {
2753 self.write_keyword("PERCENT_RANK");
2754 self.write("(");
2755 if !pr.args.is_empty() {
2757 for (i, arg) in pr.args.iter().enumerate() {
2758 if i > 0 {
2759 self.write(", ");
2760 }
2761 self.generate_expression(arg)?;
2762 }
2763 } else if let Some(order_by) = &pr.order_by {
2764 self.write_keyword(" ORDER BY ");
2766 for (i, ob) in order_by.iter().enumerate() {
2767 if i > 0 {
2768 self.write(", ");
2769 }
2770 self.generate_ordered(ob)?;
2771 }
2772 }
2773 self.write(")");
2774 Ok(())
2775 }
2776 Expression::CumeDist(cd) => {
2777 self.write_keyword("CUME_DIST");
2778 self.write("(");
2779 if !cd.args.is_empty() {
2781 for (i, arg) in cd.args.iter().enumerate() {
2782 if i > 0 {
2783 self.write(", ");
2784 }
2785 self.generate_expression(arg)?;
2786 }
2787 } else if let Some(order_by) = &cd.order_by {
2788 self.write_keyword(" ORDER BY ");
2790 for (i, ob) in order_by.iter().enumerate() {
2791 if i > 0 {
2792 self.write(", ");
2793 }
2794 self.generate_ordered(ob)?;
2795 }
2796 }
2797 self.write(")");
2798 Ok(())
2799 }
2800 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2801 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2802
2803 Expression::Contains(f) => {
2805 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2806 }
2807 Expression::StartsWith(f) => {
2808 let name = match self.config.dialect {
2809 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2810 _ => "STARTS_WITH",
2811 };
2812 self.generate_binary_func(name, &f.this, &f.expression)
2813 }
2814 Expression::EndsWith(f) => {
2815 let name = match self.config.dialect {
2816 Some(DialectType::Snowflake) => "ENDSWITH",
2817 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2818 Some(DialectType::ClickHouse) => "endsWith",
2819 _ => "ENDS_WITH",
2820 };
2821 self.generate_binary_func(name, &f.this, &f.expression)
2822 }
2823 Expression::Position(f) => self.generate_position(f),
2824 Expression::Initcap(f) => match self.config.dialect {
2825 Some(DialectType::Presto)
2826 | Some(DialectType::Trino)
2827 | Some(DialectType::Athena) => {
2828 self.write_keyword("REGEXP_REPLACE");
2829 self.write("(");
2830 self.generate_expression(&f.this)?;
2831 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2832 Ok(())
2833 }
2834 _ => self.generate_simple_func("INITCAP", &f.this),
2835 },
2836 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2837 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2838 Expression::CharFunc(f) => self.generate_char_func(f),
2839 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2840 Expression::Levenshtein(f) => {
2841 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2842 }
2843
2844 Expression::ModFunc(f) => self.generate_mod_func(f),
2846 Expression::Random(_) => {
2847 self.write_keyword("RANDOM");
2848 self.write("()");
2849 Ok(())
2850 }
2851 Expression::Rand(f) => self.generate_rand(f),
2852 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2853 Expression::Pi(_) => {
2854 self.write_keyword("PI");
2855 self.write("()");
2856 Ok(())
2857 }
2858 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2859 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2860 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2861 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2862 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2863 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2864 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2865 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2866 Expression::Atan2(f) => {
2867 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2868 self.generate_binary_func(name, &f.this, &f.expression)
2869 }
2870
2871 Expression::Decode(f) => self.generate_decode(f),
2873
2874 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2876 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2877 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2878 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2879 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2880 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2881 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2882 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2883 Expression::DayOfWeek(f) => {
2884 let name = match self.config.dialect {
2885 Some(DialectType::Presto)
2886 | Some(DialectType::Trino)
2887 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2888 Some(DialectType::DuckDB) => "ISODOW",
2889 _ => "DAYOFWEEK",
2890 };
2891 self.generate_simple_func(name, &f.this)
2892 }
2893 Expression::DayOfMonth(f) => {
2894 let name = match self.config.dialect {
2895 Some(DialectType::Presto)
2896 | Some(DialectType::Trino)
2897 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2898 _ => "DAYOFMONTH",
2899 };
2900 self.generate_simple_func(name, &f.this)
2901 }
2902 Expression::DayOfYear(f) => {
2903 let name = match self.config.dialect {
2904 Some(DialectType::Presto)
2905 | Some(DialectType::Trino)
2906 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2907 _ => "DAYOFYEAR",
2908 };
2909 self.generate_simple_func(name, &f.this)
2910 }
2911 Expression::WeekOfYear(f) => {
2912 let name = match self.config.dialect {
2914 Some(DialectType::Hive)
2915 | Some(DialectType::DuckDB)
2916 | Some(DialectType::Spark)
2917 | Some(DialectType::Databricks)
2918 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2919 _ => "WEEK_OF_YEAR",
2920 };
2921 self.generate_simple_func(name, &f.this)
2922 }
2923 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2924 Expression::AddMonths(f) => {
2925 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2926 }
2927 Expression::MonthsBetween(f) => {
2928 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2929 }
2930 Expression::LastDay(f) => self.generate_last_day(f),
2931 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2932 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2933 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2934 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2935 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2936 Expression::MakeDate(f) => self.generate_make_date(f),
2937 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2938 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2939
2940 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2942 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2943 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2944 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2945 Expression::ArrayContains(f) => {
2946 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2947 }
2948 Expression::ArrayPosition(f) => {
2949 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2950 }
2951 Expression::ArrayAppend(f) => {
2952 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2953 }
2954 Expression::ArrayPrepend(f) => {
2955 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2956 }
2957 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2958 Expression::ArraySort(f) => self.generate_array_sort(f),
2959 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2960 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2961 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2962 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2963 Expression::Unnest(f) => self.generate_unnest(f),
2964 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2965 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2966 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2967 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2968 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2969 Expression::ArrayCompact(f) => {
2970 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2971 self.write("LIST_FILTER(");
2973 self.generate_expression(&f.this)?;
2974 self.write(", _u -> NOT _u IS NULL)");
2975 Ok(())
2976 } else {
2977 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2978 }
2979 }
2980 Expression::ArrayIntersect(f) => {
2981 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2982 self.generate_vararg_func(func_name, &f.expressions)
2983 }
2984 Expression::ArrayUnion(f) => {
2985 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2986 }
2987 Expression::ArrayExcept(f) => {
2988 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2989 }
2990 Expression::ArrayRemove(f) => {
2991 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2992 }
2993 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2994 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2995 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2996
2997 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2999 Expression::StructExtract(f) => self.generate_struct_extract(f),
3000 Expression::NamedStruct(f) => self.generate_named_struct(f),
3001
3002 Expression::MapFunc(f) => self.generate_map_constructor(f),
3004 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
3005 Expression::MapFromArrays(f) => {
3006 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
3007 }
3008 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
3009 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
3010 Expression::MapContainsKey(f) => {
3011 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
3012 }
3013 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
3014 Expression::ElementAt(f) => {
3015 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
3016 }
3017 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
3018 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
3019
3020 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
3022 Expression::JsonExtractScalar(f) => {
3023 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
3024 }
3025 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
3026 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
3027 Expression::JsonObject(f) => self.generate_json_object(f),
3028 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
3029 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
3030 Expression::JsonArrayLength(f) => {
3031 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
3032 }
3033 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
3034 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
3035 Expression::ParseJson(f) => {
3036 let name = match self.config.dialect {
3037 Some(DialectType::Presto)
3038 | Some(DialectType::Trino)
3039 | Some(DialectType::Athena) => "JSON_PARSE",
3040 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
3041 self.write_keyword("CAST");
3043 self.write("(");
3044 self.generate_expression(&f.this)?;
3045 self.write_keyword(" AS ");
3046 self.write_keyword("JSON");
3047 self.write(")");
3048 return Ok(());
3049 }
3050 Some(DialectType::Hive)
3051 | Some(DialectType::Spark)
3052 | Some(DialectType::MySQL)
3053 | Some(DialectType::SingleStore)
3054 | Some(DialectType::TiDB)
3055 | Some(DialectType::TSQL) => {
3056 self.generate_expression(&f.this)?;
3058 return Ok(());
3059 }
3060 Some(DialectType::DuckDB) => "JSON",
3061 _ => "PARSE_JSON",
3062 };
3063 self.generate_simple_func(name, &f.this)
3064 }
3065 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3066 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3067 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3068 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3069 Expression::JsonMergePatch(f) => {
3070 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3071 }
3072 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3073 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3074
3075 Expression::Convert(f) => self.generate_convert(f),
3077 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3078
3079 Expression::Lambda(f) => self.generate_lambda(f),
3081 Expression::Parameter(f) => self.generate_parameter(f),
3082 Expression::Placeholder(f) => self.generate_placeholder(f),
3083 Expression::NamedArgument(f) => self.generate_named_argument(f),
3084 Expression::TableArgument(f) => self.generate_table_argument(f),
3085 Expression::SqlComment(f) => self.generate_sql_comment(f),
3086
3087 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3089 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3090 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3091 Expression::SimilarTo(f) => self.generate_similar_to(f),
3092 Expression::Any(f) => self.generate_quantified("ANY", f),
3093 Expression::All(f) => self.generate_quantified("ALL", f),
3094 Expression::Overlaps(f) => self.generate_overlaps(f),
3095
3096 Expression::BitwiseLeftShift(op) => {
3098 if matches!(
3099 self.config.dialect,
3100 Some(DialectType::Presto) | Some(DialectType::Trino)
3101 ) {
3102 self.write_keyword("BITWISE_LEFT_SHIFT");
3103 self.write("(");
3104 self.generate_expression(&op.left)?;
3105 self.write(", ");
3106 self.generate_expression(&op.right)?;
3107 self.write(")");
3108 Ok(())
3109 } else if matches!(
3110 self.config.dialect,
3111 Some(DialectType::Spark) | Some(DialectType::Databricks)
3112 ) {
3113 self.write_keyword("SHIFTLEFT");
3114 self.write("(");
3115 self.generate_expression(&op.left)?;
3116 self.write(", ");
3117 self.generate_expression(&op.right)?;
3118 self.write(")");
3119 Ok(())
3120 } else {
3121 self.generate_binary_op(op, "<<")
3122 }
3123 }
3124 Expression::BitwiseRightShift(op) => {
3125 if matches!(
3126 self.config.dialect,
3127 Some(DialectType::Presto) | Some(DialectType::Trino)
3128 ) {
3129 self.write_keyword("BITWISE_RIGHT_SHIFT");
3130 self.write("(");
3131 self.generate_expression(&op.left)?;
3132 self.write(", ");
3133 self.generate_expression(&op.right)?;
3134 self.write(")");
3135 Ok(())
3136 } else if matches!(
3137 self.config.dialect,
3138 Some(DialectType::Spark) | Some(DialectType::Databricks)
3139 ) {
3140 self.write_keyword("SHIFTRIGHT");
3141 self.write("(");
3142 self.generate_expression(&op.left)?;
3143 self.write(", ");
3144 self.generate_expression(&op.right)?;
3145 self.write(")");
3146 Ok(())
3147 } else {
3148 self.generate_binary_op(op, ">>")
3149 }
3150 }
3151 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3152 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3153 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3154
3155 Expression::Subscript(s) => self.generate_subscript(s),
3157 Expression::Dot(d) => self.generate_dot_access(d),
3158 Expression::MethodCall(m) => self.generate_method_call(m),
3159 Expression::ArraySlice(s) => self.generate_array_slice(s),
3160
3161 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3162 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3163 Expression::Add(op) => self.generate_binary_op(op, "+"),
3164 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3165 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3166 Expression::Div(op) => self.generate_binary_op(op, "/"),
3167 Expression::IntDiv(f) => {
3168 use crate::dialects::DialectType;
3169 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3170 self.generate_expression(&f.this)?;
3172 self.write(" // ");
3173 self.generate_expression(&f.expression)?;
3174 Ok(())
3175 } else if matches!(
3176 self.config.dialect,
3177 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3178 ) {
3179 self.generate_expression(&f.this)?;
3181 self.write(" ");
3182 self.write_keyword("DIV");
3183 self.write(" ");
3184 self.generate_expression(&f.expression)?;
3185 Ok(())
3186 } else {
3187 self.write_keyword("DIV");
3189 self.write("(");
3190 self.generate_expression(&f.this)?;
3191 self.write(", ");
3192 self.generate_expression(&f.expression)?;
3193 self.write(")");
3194 Ok(())
3195 }
3196 }
3197 Expression::Mod(op) => {
3198 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3199 self.generate_binary_op(op, "MOD")
3200 } else {
3201 self.generate_binary_op(op, "%")
3202 }
3203 }
3204 Expression::Eq(op) => self.generate_binary_op(op, "="),
3205 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3206 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3207 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3208 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3209 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3210 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3211 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3212 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3213 Expression::Concat(op) => {
3214 if self.config.dialect == Some(DialectType::Solr) {
3216 self.generate_binary_op(op, "OR")
3217 } else if self.config.dialect == Some(DialectType::MySQL) {
3218 self.generate_mysql_concat_from_concat(op)
3219 } else {
3220 self.generate_binary_op(op, "||")
3221 }
3222 }
3223 Expression::BitwiseAnd(op) => {
3224 if matches!(
3226 self.config.dialect,
3227 Some(DialectType::Presto) | Some(DialectType::Trino)
3228 ) {
3229 self.write_keyword("BITWISE_AND");
3230 self.write("(");
3231 self.generate_expression(&op.left)?;
3232 self.write(", ");
3233 self.generate_expression(&op.right)?;
3234 self.write(")");
3235 Ok(())
3236 } else {
3237 self.generate_binary_op(op, "&")
3238 }
3239 }
3240 Expression::BitwiseOr(op) => {
3241 if matches!(
3243 self.config.dialect,
3244 Some(DialectType::Presto) | Some(DialectType::Trino)
3245 ) {
3246 self.write_keyword("BITWISE_OR");
3247 self.write("(");
3248 self.generate_expression(&op.left)?;
3249 self.write(", ");
3250 self.generate_expression(&op.right)?;
3251 self.write(")");
3252 Ok(())
3253 } else {
3254 self.generate_binary_op(op, "|")
3255 }
3256 }
3257 Expression::BitwiseXor(op) => {
3258 if matches!(
3260 self.config.dialect,
3261 Some(DialectType::Presto) | Some(DialectType::Trino)
3262 ) {
3263 self.write_keyword("BITWISE_XOR");
3264 self.write("(");
3265 self.generate_expression(&op.left)?;
3266 self.write(", ");
3267 self.generate_expression(&op.right)?;
3268 self.write(")");
3269 Ok(())
3270 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3271 self.generate_binary_op(op, "#")
3272 } else {
3273 self.generate_binary_op(op, "^")
3274 }
3275 }
3276 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3277 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3278 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3279 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3280 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3281 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3282 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3283 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3284 Expression::JSONBContains(f) => {
3285 self.generate_expression(&f.this)?;
3287 self.write_space();
3288 self.write(f.original_name.as_deref().unwrap_or("?"));
3289 self.write_space();
3290 self.generate_expression(&f.expression)
3291 }
3292 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3293 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3294 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3295 Expression::Not(op) => match &op.this {
3296 Expression::Like(like) => self.generate_like_op_negated(like, "LIKE"),
3297 Expression::ILike(like) => self.generate_like_op_negated(like, "ILIKE"),
3298 _ => self.generate_unary_op(op, "NOT"),
3299 },
3300 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3301 Expression::BitwiseNot(op) => {
3302 if matches!(
3304 self.config.dialect,
3305 Some(DialectType::Presto) | Some(DialectType::Trino)
3306 ) {
3307 self.write_keyword("BITWISE_NOT");
3308 self.write("(");
3309 self.generate_expression(&op.this)?;
3310 self.write(")");
3311 Ok(())
3312 } else {
3313 self.generate_unary_op(op, "~")
3314 }
3315 }
3316 Expression::In(in_expr) => self.generate_in(in_expr),
3317 Expression::Between(between) => self.generate_between(between),
3318 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3319 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3320 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3321 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3322 Expression::Is(is_expr) => self.generate_is(is_expr),
3323 Expression::Exists(exists) => self.generate_exists(exists),
3324 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3325 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3326 Expression::Paren(paren) => {
3327 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3329
3330 if !skip_parens {
3331 self.write("(");
3332 if self.config.pretty {
3333 self.write_newline();
3334 self.indent_level += 1;
3335 self.write_indent();
3336 }
3337 }
3338 self.generate_expression(&paren.this)?;
3339 if !skip_parens {
3340 if self.config.pretty {
3341 self.write_newline();
3342 self.indent_level -= 1;
3343 self.write_indent();
3344 }
3345 self.write(")");
3346 }
3347 for comment in &paren.trailing_comments {
3349 self.write(" ");
3350 self.write_formatted_comment(comment);
3351 }
3352 Ok(())
3353 }
3354 Expression::Array(arr) => self.generate_array(arr),
3355 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3356 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3357 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3358 Expression::DataType(dt) => self.generate_data_type(dt),
3359 Expression::Raw(raw) => {
3360 self.write(&raw.sql);
3361 Ok(())
3362 }
3363 Expression::CreateTask(task) => self.generate_create_task(task),
3364 Expression::TryCatch(try_catch) => self.generate_try_catch(try_catch),
3365 Expression::Command(cmd) => {
3366 self.write(&cmd.this);
3367 if matches!(self.config.dialect, Some(DialectType::ClickHouse))
3368 && cmd
3369 .this
3370 .trim_start()
3371 .get(..7)
3372 .is_some_and(|prefix| prefix.eq_ignore_ascii_case("EXPLAIN"))
3373 {
3374 for _ in 0..Self::missing_closing_parens_outside_quotes(&cmd.this) {
3375 self.write(")");
3376 }
3377 }
3378 Ok(())
3379 }
3380 Expression::Kill(kill) => {
3381 self.write_keyword("KILL");
3382 if let Some(kind) = &kill.kind {
3383 self.write_space();
3384 self.write_keyword(kind);
3385 }
3386 self.write_space();
3387 self.generate_expression(&kill.this)?;
3388 Ok(())
3389 }
3390 Expression::Prepare(prepare) => self.generate_prepare(prepare),
3391 Expression::Execute(exec) => {
3392 self.write_keyword("EXECUTE");
3393 self.write_space();
3394 self.generate_expression(&exec.this)?;
3395 if exec.prepared {
3396 if !exec.arguments.is_empty() {
3397 self.write("(");
3398 for (i, argument) in exec.arguments.iter().enumerate() {
3399 if i > 0 {
3400 self.write(", ");
3401 }
3402 self.generate_expression(argument)?;
3403 }
3404 self.write(")");
3405 }
3406 return Ok(());
3407 }
3408 for (i, param) in exec.parameters.iter().enumerate() {
3409 if i == 0 {
3410 self.write_space();
3411 } else {
3412 self.write(", ");
3413 }
3414 self.write(¶m.name);
3415 if !param.positional {
3417 self.write(" = ");
3418 self.generate_expression(¶m.value)?;
3419 }
3420 if param.output {
3421 self.write_space();
3422 self.write_keyword("OUTPUT");
3423 }
3424 }
3425 if let Some(ref suffix) = exec.suffix {
3426 self.write_space();
3427 self.write(suffix);
3428 }
3429 Ok(())
3430 }
3431 Expression::Annotated(annotated) => {
3432 self.generate_expression(&annotated.this)?;
3433 for comment in &annotated.trailing_comments {
3434 self.write(" ");
3435 self.write_formatted_comment(comment);
3436 }
3437 Ok(())
3438 }
3439
3440 Expression::CreateTable(ct) => self.generate_create_table(ct),
3442 Expression::DropTable(dt) => self.generate_drop_table(dt),
3443 Expression::Undrop(u) => self.generate_undrop(u),
3444 Expression::AlterTable(at) => self.generate_alter_table(at),
3445 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3446 Expression::DropIndex(di) => self.generate_drop_index(di),
3447 Expression::CreateView(cv) => self.generate_create_view(cv),
3448 Expression::DropView(dv) => self.generate_drop_view(dv),
3449 Expression::AlterView(av) => self.generate_alter_view(av),
3450 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3451 Expression::Truncate(tr) => self.generate_truncate(tr),
3452 Expression::Use(u) => self.generate_use(u),
3453 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3455 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3456 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3457 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3458 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3459 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3460 Expression::DropFunction(df) => self.generate_drop_function(df),
3461 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3462 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3463 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3464 Expression::CreateSynonym(cs) => {
3465 self.write_keyword("CREATE SYNONYM");
3466 self.write_space();
3467 self.generate_table(&cs.name)?;
3468 self.write_space();
3469 self.write_keyword("FOR");
3470 self.write_space();
3471 self.generate_table(&cs.target)?;
3472 Ok(())
3473 }
3474 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3475 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3476 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3477 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3478 Expression::CreateType(ct) => self.generate_create_type(ct),
3479 Expression::DropType(dt) => self.generate_drop_type(dt),
3480 Expression::Describe(d) => self.generate_describe(d),
3481 Expression::Show(s) => self.generate_show(s),
3482
3483 Expression::Cache(c) => self.generate_cache(c),
3485 Expression::Uncache(u) => self.generate_uncache(u),
3486 Expression::LoadData(l) => self.generate_load_data(l),
3487 Expression::Pragma(p) => self.generate_pragma(p),
3488 Expression::Grant(g) => self.generate_grant(g),
3489 Expression::Revoke(r) => self.generate_revoke(r),
3490 Expression::Comment(c) => self.generate_comment(c),
3491 Expression::SetStatement(s) => self.generate_set_statement(s),
3492
3493 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3495 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3496
3497 Expression::Values(values) => self.generate_values(values),
3499
3500 Expression::AIAgg(e) => self.generate_ai_agg(e),
3502 Expression::AIClassify(e) => self.generate_ai_classify(e),
3503 Expression::AddPartition(e) => self.generate_add_partition(e),
3504 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3505 Expression::Aliases(e) => self.generate_aliases(e),
3506 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3507 Expression::AlterColumn(e) => self.generate_alter_column(e),
3508 Expression::AlterSession(e) => self.generate_alter_session(e),
3509 Expression::AlterSet(e) => self.generate_alter_set(e),
3510 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3511 Expression::Analyze(e) => self.generate_analyze(e),
3512 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3513 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3514 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3515 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3516 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3517 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3518 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3519 Expression::Anonymous(e) => self.generate_anonymous(e),
3520 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3521 Expression::Apply(e) => self.generate_apply(e),
3522 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3523 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3524 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3525 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3526 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3527 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3528 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3529 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3530 Expression::ArgMax(e) => self.generate_arg_max(e),
3531 Expression::ArgMin(e) => self.generate_arg_min(e),
3532 Expression::ArrayAll(e) => self.generate_array_all(e),
3533 Expression::ArrayAny(e) => self.generate_array_any(e),
3534 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3535 Expression::ArraySum(e) => self.generate_array_sum(e),
3536 Expression::AtIndex(e) => self.generate_at_index(e),
3537 Expression::Attach(e) => self.generate_attach(e),
3538 Expression::AttachOption(e) => self.generate_attach_option(e),
3539 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3540 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3541 Expression::BackupProperty(e) => self.generate_backup_property(e),
3542 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3543 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3544 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3545 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3546 Expression::Booland(e) => self.generate_booland(e),
3547 Expression::Boolor(e) => self.generate_boolor(e),
3548 Expression::BuildProperty(e) => self.generate_build_property(e),
3549 Expression::ByteString(e) => self.generate_byte_string(e),
3550 Expression::CaseSpecificColumnConstraint(e) => {
3551 self.generate_case_specific_column_constraint(e)
3552 }
3553 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3554 Expression::Changes(e) => self.generate_changes(e),
3555 Expression::CharacterSetColumnConstraint(e) => {
3556 self.generate_character_set_column_constraint(e)
3557 }
3558 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3559 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3560 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3561 Expression::CheckJson(e) => self.generate_check_json(e),
3562 Expression::CheckXml(e) => self.generate_check_xml(e),
3563 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3564 Expression::Clone(e) => self.generate_clone(e),
3565 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3566 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3567 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3568 Expression::CollateProperty(e) => self.generate_collate_property(e),
3569 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3570 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3571 Expression::ColumnPosition(e) => self.generate_column_position(e),
3572 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3573 Expression::Columns(e) => self.generate_columns(e),
3574 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3575 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3576 Expression::Commit(e) => self.generate_commit(e),
3577 Expression::Comprehension(e) => self.generate_comprehension(e),
3578 Expression::Compress(e) => self.generate_compress(e),
3579 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3580 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3581 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3582 Expression::Constraint(e) => self.generate_constraint(e),
3583 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3584 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3585 Expression::Copy(e) => self.generate_copy(e),
3586 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3587 Expression::Corr(e) => self.generate_corr(e),
3588 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3589 Expression::CovarPop(e) => self.generate_covar_pop(e),
3590 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3591 Expression::Credentials(e) => self.generate_credentials(e),
3592 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3593 Expression::Cte(e) => self.generate_cte(e),
3594 Expression::Cube(e) => self.generate_cube(e),
3595 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3596 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3597 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3598 Expression::CurrentUser(e) => self.generate_current_user(e),
3599 Expression::DPipe(e) => self.generate_d_pipe(e),
3600 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3601 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3602 Expression::Date(e) => self.generate_date_func(e),
3603 Expression::DateBin(e) => self.generate_date_bin(e),
3604 Expression::DateFormatColumnConstraint(e) => {
3605 self.generate_date_format_column_constraint(e)
3606 }
3607 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3608 Expression::Datetime(e) => self.generate_datetime(e),
3609 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3610 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3611 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3612 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3613 Expression::Dayname(e) => self.generate_dayname(e),
3614 Expression::Declare(e) => self.generate_declare(e),
3615 Expression::DeclareItem(e) => self.generate_declare_item(e),
3616 Expression::DecodeCase(e) => self.generate_decode_case(e),
3617 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3618 Expression::DecompressString(e) => self.generate_decompress_string(e),
3619 Expression::Decrypt(e) => self.generate_decrypt(e),
3620 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3621 Expression::DefaultColumnConstraint(e) => {
3622 self.write_keyword("DEFAULT");
3623 self.write_space();
3624 self.generate_expression(&e.this)?;
3625 if let Some(ref col) = e.for_column {
3626 self.write_space();
3627 self.write_keyword("FOR");
3628 self.write_space();
3629 self.generate_identifier(col)?;
3630 }
3631 Ok(())
3632 }
3633 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3634 Expression::Detach(e) => self.generate_detach(e),
3635 Expression::DictProperty(e) => self.generate_dict_property(e),
3636 Expression::DictRange(e) => self.generate_dict_range(e),
3637 Expression::Directory(e) => self.generate_directory(e),
3638 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3639 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3640 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3641 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3642 Expression::DotProduct(e) => self.generate_dot_product(e),
3643 Expression::DropPartition(e) => self.generate_drop_partition(e),
3644 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3645 Expression::Elt(e) => self.generate_elt(e),
3646 Expression::Encode(e) => self.generate_encode(e),
3647 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3648 Expression::Encrypt(e) => self.generate_encrypt(e),
3649 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3650 Expression::EngineProperty(e) => self.generate_engine_property(e),
3651 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3652 Expression::EphemeralColumnConstraint(e) => {
3653 self.generate_ephemeral_column_constraint(e)
3654 }
3655 Expression::EqualNull(e) => self.generate_equal_null(e),
3656 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3657 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3658 Expression::Export(e) => self.generate_export(e),
3659 Expression::ExternalProperty(e) => self.generate_external_property(e),
3660 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3661 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3662 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3663 Expression::Fetch(e) => self.generate_fetch(e),
3664 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3665 Expression::Filter(e) => self.generate_filter(e),
3666 Expression::Float64(e) => self.generate_float64(e),
3667 Expression::ForIn(e) => self.generate_for_in(e),
3668 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3669 Expression::Format(e) => self.generate_format(e),
3670 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3671 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3672 Expression::From(e) => self.generate_from(e),
3673 Expression::FromBase(e) => self.generate_from_base(e),
3674 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3675 Expression::GapFill(e) => self.generate_gap_fill(e),
3676 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3677 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3678 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3679 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3680 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3681 self.generate_generated_as_identity_column_constraint(e)
3682 }
3683 Expression::GeneratedAsRowColumnConstraint(e) => {
3684 self.generate_generated_as_row_column_constraint(e)
3685 }
3686 Expression::Get(e) => self.generate_get(e),
3687 Expression::GetExtract(e) => self.generate_get_extract(e),
3688 Expression::Getbit(e) => self.generate_getbit(e),
3689 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3690 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3691 Expression::Group(e) => self.generate_group(e),
3692 Expression::GroupBy(e) => self.generate_group_by(e),
3693 Expression::Grouping(e) => self.generate_grouping(e),
3694 Expression::GroupingId(e) => self.generate_grouping_id(e),
3695 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3696 Expression::HashAgg(e) => self.generate_hash_agg(e),
3697 Expression::Having(e) => self.generate_having(e),
3698 Expression::HavingMax(e) => self.generate_having_max(e),
3699 Expression::Heredoc(e) => self.generate_heredoc(e),
3700 Expression::HexEncode(e) => self.generate_hex_encode(e),
3701 Expression::Hll(e) => self.generate_hll(e),
3702 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3703 Expression::IncludeProperty(e) => self.generate_include_property(e),
3704 Expression::Index(e) => self.generate_index(e),
3705 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3706 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3707 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3708 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3709 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3710 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3711 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3712 Expression::Install(e) => self.generate_install(e),
3713 Expression::IntervalOp(e) => self.generate_interval_op(e),
3714 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3715 Expression::IntoClause(e) => self.generate_into_clause(e),
3716 Expression::Introducer(e) => self.generate_introducer(e),
3717 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3718 Expression::JSON(e) => self.generate_json(e),
3719 Expression::JSONArray(e) => self.generate_json_array(e),
3720 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3721 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3722 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3723 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3724 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3725 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3726 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3727 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3728 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3729 Expression::JSONExists(e) => self.generate_json_exists(e),
3730 Expression::JSONCast(e) => self.generate_json_cast(e),
3731 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3732 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3733 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3734 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3735 Expression::JSONFormat(e) => self.generate_json_format(e),
3736 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3737 Expression::JSONKeys(e) => self.generate_json_keys(e),
3738 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3739 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3740 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3741 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3742 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3743 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3744 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3745 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3746 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3747 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3748 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3749 Expression::JSONRemove(e) => self.generate_json_remove(e),
3750 Expression::JSONSchema(e) => self.generate_json_schema(e),
3751 Expression::JSONSet(e) => self.generate_json_set(e),
3752 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3753 Expression::JSONTable(e) => self.generate_json_table(e),
3754 Expression::JSONType(e) => self.generate_json_type(e),
3755 Expression::JSONValue(e) => self.generate_json_value(e),
3756 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3757 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3758 Expression::JoinHint(e) => self.generate_join_hint(e),
3759 Expression::JournalProperty(e) => self.generate_journal_property(e),
3760 Expression::LanguageProperty(e) => self.generate_language_property(e),
3761 Expression::Lateral(e) => self.generate_lateral(e),
3762 Expression::LikeProperty(e) => self.generate_like_property(e),
3763 Expression::Limit(e) => self.generate_limit(e),
3764 Expression::LimitOptions(e) => self.generate_limit_options(e),
3765 Expression::List(e) => self.generate_list(e),
3766 Expression::ToMap(e) => self.generate_tomap(e),
3767 Expression::Localtime(e) => self.generate_localtime(e),
3768 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3769 Expression::LocationProperty(e) => self.generate_location_property(e),
3770 Expression::Lock(e) => self.generate_lock(e),
3771 Expression::LockProperty(e) => self.generate_lock_property(e),
3772 Expression::LockingProperty(e) => self.generate_locking_property(e),
3773 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3774 Expression::LogProperty(e) => self.generate_log_property(e),
3775 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3776 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3777 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3778 Expression::MakeInterval(e) => self.generate_make_interval(e),
3779 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3780 Expression::Map(e) => self.generate_map(e),
3781 Expression::MapCat(e) => self.generate_map_cat(e),
3782 Expression::MapDelete(e) => self.generate_map_delete(e),
3783 Expression::MapInsert(e) => self.generate_map_insert(e),
3784 Expression::MapPick(e) => self.generate_map_pick(e),
3785 Expression::MaskingPolicyColumnConstraint(e) => {
3786 self.generate_masking_policy_column_constraint(e)
3787 }
3788 Expression::MatchAgainst(e) => self.generate_match_against(e),
3789 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3790 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3791 Expression::Merge(e) => self.generate_merge(e),
3792 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3793 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3794 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3795 Expression::Minhash(e) => self.generate_minhash(e),
3796 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3797 Expression::Monthname(e) => self.generate_monthname(e),
3798 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3799 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3800 Expression::Normal(e) => self.generate_normal(e),
3801 Expression::Normalize(e) => self.generate_normalize(e),
3802 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3803 Expression::Nullif(e) => self.generate_nullif(e),
3804 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3805 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3806 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3807 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3808 Expression::Offset(e) => self.generate_offset(e),
3809 Expression::Qualify(e) => self.generate_qualify(e),
3810 Expression::OnCluster(e) => self.generate_on_cluster(e),
3811 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3812 Expression::OnCondition(e) => self.generate_on_condition(e),
3813 Expression::OnConflict(e) => self.generate_on_conflict(e),
3814 Expression::OnProperty(e) => self.generate_on_property(e),
3815 Expression::Opclass(e) => self.generate_opclass(e),
3816 Expression::OpenJSON(e) => self.generate_open_json(e),
3817 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3818 Expression::Operator(e) => self.generate_operator(e),
3819 Expression::OrderBy(e) => self.generate_order_by(e),
3820 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3821 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3822 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3823 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3824 Expression::ParseIp(e) => self.generate_parse_ip(e),
3825 Expression::ParseJSON(e) => self.generate_parse_json(e),
3826 Expression::ParseTime(e) => self.generate_parse_time(e),
3827 Expression::ParseUrl(e) => self.generate_parse_url(e),
3828 Expression::Partition(e) => self.generate_partition_expr(e),
3829 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3830 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3831 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3832 Expression::PartitionByRangePropertyDynamic(e) => {
3833 self.generate_partition_by_range_property_dynamic(e)
3834 }
3835 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3836 Expression::PartitionList(e) => self.generate_partition_list(e),
3837 Expression::PartitionRange(e) => self.generate_partition_range(e),
3838 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3839 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3840 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3841 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3842 Expression::PeriodForSystemTimeConstraint(e) => {
3843 self.generate_period_for_system_time_constraint(e)
3844 }
3845 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3846 Expression::PivotAny(e) => self.generate_pivot_any(e),
3847 Expression::Predict(e) => self.generate_predict(e),
3848 Expression::PreviousDay(e) => self.generate_previous_day(e),
3849 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3850 Expression::PrimaryKeyColumnConstraint(e) => {
3851 self.generate_primary_key_column_constraint(e)
3852 }
3853 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3854 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3855 Expression::OptionsProperty(e) => self.generate_options_property(e),
3856 Expression::Properties(e) => self.generate_properties(e),
3857 Expression::Property(e) => self.generate_property(e),
3858 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3859 Expression::Put(e) => self.generate_put(e),
3860 Expression::Quantile(e) => self.generate_quantile(e),
3861 Expression::QueryBand(e) => self.generate_query_band(e),
3862 Expression::QueryOption(e) => self.generate_query_option(e),
3863 Expression::QueryTransform(e) => self.generate_query_transform(e),
3864 Expression::Randn(e) => self.generate_randn(e),
3865 Expression::Randstr(e) => self.generate_randstr(e),
3866 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3867 Expression::RangeN(e) => self.generate_range_n(e),
3868 Expression::ReadCSV(e) => self.generate_read_csv(e),
3869 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3870 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3871 Expression::Reduce(e) => self.generate_reduce(e),
3872 Expression::Reference(e) => self.generate_reference(e),
3873 Expression::Refresh(e) => self.generate_refresh(e),
3874 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3875 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3876 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3877 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3878 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3879 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3880 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3881 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3882 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3883 Expression::RegrCount(e) => self.generate_regr_count(e),
3884 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3885 Expression::RegrR2(e) => self.generate_regr_r2(e),
3886 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3887 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3888 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3889 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3890 Expression::RegrValx(e) => self.generate_regr_valx(e),
3891 Expression::RegrValy(e) => self.generate_regr_valy(e),
3892 Expression::RemoteWithConnectionModelProperty(e) => {
3893 self.generate_remote_with_connection_model_property(e)
3894 }
3895 Expression::RenameColumn(e) => self.generate_rename_column(e),
3896 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3897 Expression::Returning(e) => self.generate_returning(e),
3898 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3899 Expression::Rollback(e) => self.generate_rollback(e),
3900 Expression::Rollup(e) => self.generate_rollup(e),
3901 Expression::RowFormatDelimitedProperty(e) => {
3902 self.generate_row_format_delimited_property(e)
3903 }
3904 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3905 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3906 Expression::SHA2(e) => self.generate_sha2(e),
3907 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3908 Expression::SafeAdd(e) => self.generate_safe_add(e),
3909 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3910 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3911 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3912 Expression::SampleProperty(e) => self.generate_sample_property(e),
3913 Expression::Schema(e) => self.generate_schema(e),
3914 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3915 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3916 Expression::Search(e) => self.generate_search(e),
3917 Expression::SearchIp(e) => self.generate_search_ip(e),
3918 Expression::SecurityProperty(e) => self.generate_security_property(e),
3919 Expression::SemanticView(e) => self.generate_semantic_view(e),
3920 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3921 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3922 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3923 Expression::Set(e) => self.generate_set(e),
3924 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3925 Expression::SetItem(e) => self.generate_set_item(e),
3926 Expression::SetOperation(e) => self.generate_set_operation(e),
3927 Expression::SetProperty(e) => self.generate_set_property(e),
3928 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3929 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3930 Expression::Slice(e) => self.generate_slice(e),
3931 Expression::SortArray(e) => self.generate_sort_array(e),
3932 Expression::SortBy(e) => self.generate_sort_by(e),
3933 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3934 Expression::SplitPart(e) => self.generate_split_part(e),
3935 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3936 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3937 Expression::StDistance(e) => self.generate_st_distance(e),
3938 Expression::StPoint(e) => self.generate_st_point(e),
3939 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3940 Expression::StandardHash(e) => self.generate_standard_hash(e),
3941 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3942 Expression::StrPosition(e) => self.generate_str_position(e),
3943 Expression::StrToDate(e) => self.generate_str_to_date(e),
3944 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3945 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3946 Expression::StrToMap(e) => self.generate_str_to_map(e),
3947 Expression::StrToTime(e) => self.generate_str_to_time(e),
3948 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3949 Expression::StringToArray(e) => self.generate_string_to_array(e),
3950 Expression::Struct(e) => self.generate_struct(e),
3951 Expression::Stuff(e) => self.generate_stuff(e),
3952 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3953 Expression::Summarize(e) => self.generate_summarize(e),
3954 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3955 Expression::TableAlias(e) => self.generate_table_alias(e),
3956 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3957 Expression::RowsFrom(e) => self.generate_rows_from(e),
3958 Expression::TableSample(e) => self.generate_table_sample(e),
3959 Expression::Tag(e) => self.generate_tag(e),
3960 Expression::Tags(e) => self.generate_tags(e),
3961 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3962 Expression::Time(e) => self.generate_time_func(e),
3963 Expression::TimeAdd(e) => self.generate_time_add(e),
3964 Expression::TimeDiff(e) => self.generate_time_diff(e),
3965 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3966 Expression::TimeSlice(e) => self.generate_time_slice(e),
3967 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3968 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3969 Expression::TimeSub(e) => self.generate_time_sub(e),
3970 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3971 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3972 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3973 Expression::TimeUnit(e) => self.generate_time_unit(e),
3974 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3975 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3976 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3977 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3978 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3979 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3980 Expression::ToBinary(e) => self.generate_to_binary(e),
3981 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3982 Expression::ToChar(e) => self.generate_to_char(e),
3983 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3984 Expression::ToDouble(e) => self.generate_to_double(e),
3985 Expression::ToFile(e) => self.generate_to_file(e),
3986 Expression::ToNumber(e) => self.generate_to_number(e),
3987 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3988 Expression::Transaction(e) => self.generate_transaction(e),
3989 Expression::Transform(e) => self.generate_transform(e),
3990 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3991 Expression::TransientProperty(e) => self.generate_transient_property(e),
3992 Expression::Translate(e) => self.generate_translate(e),
3993 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3994 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3995 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3996 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3997 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3998 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3999 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
4000 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
4001 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
4002 Expression::Unhex(e) => self.generate_unhex(e),
4003 Expression::UnicodeString(e) => self.generate_unicode_string(e),
4004 Expression::Uniform(e) => self.generate_uniform(e),
4005 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
4006 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
4007 Expression::RollupProperty(e) => self.generate_rollup_property(e),
4008 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
4009 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
4010 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
4011 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
4012 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
4013 Expression::UtcTime(e) => self.generate_utc_time(e),
4014 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
4015 Expression::Uuid(e) => self.generate_uuid(e),
4016 Expression::Var(v) => {
4017 if matches!(self.config.dialect, Some(DialectType::MySQL))
4018 && v.this.len() > 2
4019 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
4020 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
4021 {
4022 return self.generate_identifier(&Identifier {
4023 name: v.this.clone(),
4024 quoted: true,
4025 trailing_comments: Vec::new(),
4026 span: None,
4027 });
4028 }
4029 self.write(&v.this);
4030 Ok(())
4031 }
4032 Expression::Variadic(e) => {
4033 self.write_keyword("VARIADIC");
4034 self.write_space();
4035 self.generate_expression(&e.this)?;
4036 Ok(())
4037 }
4038 Expression::VarMap(e) => self.generate_var_map(e),
4039 Expression::VectorSearch(e) => self.generate_vector_search(e),
4040 Expression::Version(e) => self.generate_version(e),
4041 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
4042 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
4043 Expression::WatermarkColumnConstraint(e) => {
4044 self.generate_watermark_column_constraint(e)
4045 }
4046 Expression::Week(e) => self.generate_week(e),
4047 Expression::When(e) => self.generate_when(e),
4048 Expression::Whens(e) => self.generate_whens(e),
4049 Expression::Where(e) => self.generate_where(e),
4050 Expression::WidthBucket(e) => self.generate_width_bucket(e),
4051 Expression::Window(e) => self.generate_window(e),
4052 Expression::WindowSpec(e) => self.generate_window_spec(e),
4053 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
4054 Expression::WithFill(e) => self.generate_with_fill(e),
4055 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
4056 Expression::WithOperator(e) => self.generate_with_operator(e),
4057 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
4058 Expression::WithSchemaBindingProperty(e) => {
4059 self.generate_with_schema_binding_property(e)
4060 }
4061 Expression::WithSystemVersioningProperty(e) => {
4062 self.generate_with_system_versioning_property(e)
4063 }
4064 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
4065 Expression::XMLElement(e) => self.generate_xml_element(e),
4066 Expression::XMLGet(e) => self.generate_xml_get(e),
4067 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
4068 Expression::XMLTable(e) => self.generate_xml_table(e),
4069 Expression::Xor(e) => self.generate_xor(e),
4070 Expression::Zipf(e) => self.generate_zipf(e),
4071 _ => self.write_unsupported_comment("unsupported expression"),
4072 }
4073 }
4074
4075 fn should_handle_tsql_distinct_null_ordering(&self, select: &Select) -> bool {
4076 matches!(
4077 self.config.dialect,
4078 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4079 ) && !self.config.null_ordering_supported
4080 && select.distinct
4081 && select.order_by.as_ref().is_some_and(|order_by| {
4082 order_by
4083 .expressions
4084 .iter()
4085 .any(Self::ordered_requires_tsql_null_ordering_emulation)
4086 })
4087 }
4088
4089 fn ordered_requires_tsql_null_ordering_emulation(ordered: &Ordered) -> bool {
4090 let Some(nulls_first) = ordered.nulls_first else {
4091 return false;
4092 };
4093
4094 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
4095 let target_default_nulls_first = !ordered.desc;
4096
4097 nulls_first != target_default_nulls_first && !random_ordering
4098 }
4099
4100 fn projection_output_identifier(expression: &Expression) -> Option<Identifier> {
4101 match expression {
4102 Expression::Alias(alias) if !alias.alias.name.is_empty() => Some(alias.alias.clone()),
4103 Expression::Column(column) => Some(column.name.clone()),
4104 Expression::Identifier(identifier) => Some(identifier.clone()),
4105 _ => None,
4106 }
4107 }
4108
4109 fn identifier_names_match(left: &Identifier, right: &Identifier) -> bool {
4110 if left.quoted || right.quoted {
4111 left.name == right.name
4112 } else {
4113 left.name.eq_ignore_ascii_case(&right.name)
4114 }
4115 }
4116
4117 fn expression_matches_identifier(expression: &Expression, identifier: &Identifier) -> bool {
4118 match expression {
4119 Expression::Column(column) if column.table.is_none() => {
4120 Self::identifier_names_match(&column.name, identifier)
4121 }
4122 Expression::Identifier(other) => Self::identifier_names_match(other, identifier),
4123 _ => false,
4124 }
4125 }
4126
4127 fn column_expression(identifier: Identifier) -> Expression {
4128 Expression::Column(Box::new(Column {
4129 name: identifier,
4130 table: None,
4131 join_mark: false,
4132 trailing_comments: Vec::new(),
4133 span: None,
4134 inferred_type: None,
4135 }))
4136 }
4137
4138 fn positional_ordering_index(expression: &Expression) -> Option<usize> {
4139 match expression {
4140 Expression::Literal(lit) => match lit.as_ref() {
4141 Literal::Number(n) => {
4142 let value = n.parse::<usize>().ok()?;
4143 value.checked_sub(1)
4144 }
4145 _ => None,
4146 },
4147 _ => None,
4148 }
4149 }
4150
4151 fn projection_sort_expression(expression: &Expression) -> Option<Expression> {
4152 let expression = match expression {
4153 Expression::Alias(alias) => &alias.this,
4154 other => other,
4155 };
4156
4157 match expression {
4158 Expression::Star(_)
4159 | Expression::Literal(_)
4160 | Expression::Null(_)
4161 | Expression::Boolean(_) => None,
4162 _ => Some(expression.clone()),
4163 }
4164 }
4165
4166 fn resolve_positional_order_projection(
4167 projections: &[Expression],
4168 index: usize,
4169 ) -> Option<Expression> {
4170 Self::projection_sort_expression(projections.get(index)?)
4171 }
4172
4173 fn is_direct_grouping_expression(expression: &Expression) -> bool {
4174 match expression {
4175 Expression::Paren(paren) => Self::is_direct_grouping_expression(&paren.this),
4176 Expression::Grouping(_) | Expression::GroupingId(_) => true,
4177 Expression::Function(function) => {
4178 function.name.eq_ignore_ascii_case("GROUPING")
4179 || function.name.eq_ignore_ascii_case("GROUPING_ID")
4180 }
4181 _ => false,
4182 }
4183 }
4184
4185 fn group_by_has_multiple_grouping_levels(group_by: &GroupBy) -> bool {
4186 group_by
4187 .expressions
4188 .iter()
4189 .any(|expression| match expression {
4190 Expression::Cube(_) | Expression::Rollup(_) => true,
4191 Expression::GroupingSets(grouping_sets) => grouping_sets.expressions.len() > 1,
4192 Expression::Function(function)
4193 if function.name.eq_ignore_ascii_case("CUBE")
4194 || function.name.eq_ignore_ascii_case("ROLLUP") =>
4195 {
4196 !function.args.is_empty()
4197 }
4198 Expression::Function(function)
4199 if function.name.eq_ignore_ascii_case("GROUPING SETS") =>
4200 {
4201 function.args.len() > 1
4202 || function.args.first().is_some_and(|expression| {
4203 matches!(expression, Expression::Cube(_) | Expression::Rollup(_))
4204 || matches!(expression,
4205 Expression::Function(nested)
4206 if nested.name.eq_ignore_ascii_case("CUBE")
4207 || nested.name.eq_ignore_ascii_case("ROLLUP")
4208 )
4209 })
4210 }
4211 _ => false,
4212 })
4213 }
4214
4215 fn set_output_identifier_at(expression: &Expression, index: usize) -> Option<Identifier> {
4216 match expression {
4217 Expression::Select(select) => {
4218 Self::projection_output_identifier(select.expressions.get(index)?)
4219 }
4220 Expression::Union(union) => Self::set_output_identifier_at(&union.left, index),
4221 Expression::Intersect(intersect) => {
4222 Self::set_output_identifier_at(&intersect.left, index)
4223 }
4224 Expression::Except(except) => Self::set_output_identifier_at(&except.left, index),
4225 Expression::Subquery(subquery) => subquery
4226 .column_aliases
4227 .get(index)
4228 .cloned()
4229 .or_else(|| Self::set_output_identifier_at(&subquery.this, index)),
4230 _ => None,
4231 }
4232 }
4233
4234 fn resolve_single_subquery_star_projection(
4235 select: &Select,
4236 index: usize,
4237 ) -> Option<Expression> {
4238 if select.expressions.len() != 1
4239 || !matches!(select.expressions.first(), Some(Expression::Star(_)))
4240 {
4241 return None;
4242 }
4243
4244 let from = select.from.as_ref()?;
4245 if from.expressions.len() != 1 {
4246 return None;
4247 }
4248
4249 let Expression::Subquery(subquery) = from.expressions.first()? else {
4250 return None;
4251 };
4252
4253 subquery
4254 .column_aliases
4255 .get(index)
4256 .cloned()
4257 .or_else(|| Self::set_output_identifier_at(&subquery.this, index))
4258 .map(Self::column_expression)
4259 }
4260
4261 fn sole_tsql_ordering_source_qualifier(select: &Select) -> Option<Identifier> {
4262 if !select.joins.is_empty() {
4263 return None;
4264 }
4265
4266 let from = select.from.as_ref()?;
4267 if from.expressions.len() != 1 {
4268 return None;
4269 }
4270
4271 match from.expressions.first()? {
4272 Expression::Table(table) => {
4273 Some(table.alias.clone().unwrap_or_else(|| table.name.clone()))
4274 }
4275 Expression::Subquery(subquery) => subquery.alias.clone(),
4276 _ => None,
4277 }
4278 }
4279
4280 fn resolve_duplicate_tsql_ordering_column(
4281 select: &Select,
4282 expression: &Expression,
4283 ) -> Option<Expression> {
4284 let Expression::Column(order_column) = expression else {
4285 return None;
4286 };
4287 if order_column.table.is_some() {
4288 return None;
4289 }
4290
4291 let matching_projections: Vec<_> = select
4292 .expressions
4293 .iter()
4294 .filter(|projection| {
4295 Self::projection_output_identifier(projection).is_some_and(|identifier| {
4296 Self::identifier_names_match(&identifier, &order_column.name)
4297 })
4298 })
4299 .filter_map(Self::projection_sort_expression)
4300 .collect();
4301
4302 if matching_projections.len() < 2
4303 || matching_projections[1..]
4304 .iter()
4305 .any(|projection| projection != &matching_projections[0])
4306 {
4307 return None;
4308 }
4309
4310 let Expression::Column(projected_column) = &matching_projections[0] else {
4311 return None;
4312 };
4313 if !Self::identifier_names_match(&projected_column.name, &order_column.name) {
4314 return None;
4315 }
4316
4317 let qualifier = projected_column
4318 .table
4319 .clone()
4320 .or_else(|| Self::sole_tsql_ordering_source_qualifier(select))?;
4321 let mut resolved = order_column.as_ref().clone();
4322 resolved.table = Some(qualifier);
4323 Some(Expression::Column(Box::new(resolved)))
4324 }
4325
4326 fn resolve_tsql_null_ordering_for_select(&self, select: &Select) -> Option<Select> {
4327 if !matches!(
4328 self.config.dialect,
4329 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4330 ) || self.config.null_ordering_supported
4331 {
4332 return None;
4333 }
4334
4335 let order_by = select.order_by.as_ref()?;
4336 let grouping_order_is_constant = matches!(self.config.dialect, Some(DialectType::Fabric))
4337 && select
4338 .group_by
4339 .as_ref()
4340 .is_some_and(|group_by| !Self::group_by_has_multiple_grouping_levels(group_by));
4341 let mut resolved_expressions = Vec::with_capacity(order_by.expressions.len());
4342 let mut changed = false;
4343
4344 for mut ordered in order_by.expressions.iter().cloned() {
4345 if Self::ordered_requires_tsql_null_ordering_emulation(&ordered) {
4346 if let Some(index) = Self::positional_ordering_index(&ordered.this) {
4347 if let Some(resolved) =
4348 Self::resolve_positional_order_projection(&select.expressions, index)
4349 .or_else(|| {
4350 Self::resolve_single_subquery_star_projection(select, index)
4351 })
4352 {
4353 if resolved != ordered.this {
4354 ordered.this = resolved;
4355 changed = true;
4356 }
4357 }
4358 }
4359
4360 if let Some(resolved) =
4361 Self::resolve_duplicate_tsql_ordering_column(select, &ordered.this)
4362 {
4363 ordered.this = resolved;
4364 changed = true;
4365 }
4366 }
4367
4368 if grouping_order_is_constant && Self::is_direct_grouping_expression(&ordered.this) {
4372 changed = true;
4373 continue;
4374 }
4375
4376 resolved_expressions.push(ordered);
4377 }
4378
4379 if changed {
4380 let mut resolved_select = select.clone();
4381 resolved_select.order_by = if resolved_expressions.is_empty() {
4382 None
4383 } else {
4384 Some(OrderBy {
4385 expressions: resolved_expressions,
4386 siblings: order_by.siblings,
4387 comments: order_by.comments.clone(),
4388 })
4389 };
4390 Some(resolved_select)
4391 } else {
4392 None
4393 }
4394 }
4395
4396 fn resolve_distinct_order_projection(
4397 projections: &[Expression],
4398 order_expression: &Expression,
4399 ) -> Option<Expression> {
4400 for projection in projections {
4401 if let Expression::Alias(alias) = projection {
4402 if Self::expression_matches_identifier(order_expression, &alias.alias)
4403 || &alias.this == order_expression
4404 {
4405 return Some(alias.this.clone());
4406 }
4407 } else if projection == order_expression {
4408 return Some(projection.clone());
4409 } else if let Some(identifier) = Self::projection_output_identifier(projection) {
4410 if Self::expression_matches_identifier(order_expression, &identifier) {
4411 return Some(projection.clone());
4412 }
4413 }
4414 }
4415
4416 None
4417 }
4418
4419 fn fresh_polyglot_alias(base: &str, index: usize, used_names: &mut Vec<String>) -> String {
4420 let mut suffix = 0;
4421 loop {
4422 let candidate = if suffix == 0 {
4423 format!("{base}_{index}")
4424 } else {
4425 format!("{base}_{index}_{suffix}")
4426 };
4427
4428 if !used_names
4429 .iter()
4430 .any(|name| name.eq_ignore_ascii_case(&candidate))
4431 {
4432 used_names.push(candidate.clone());
4433 return candidate;
4434 }
4435
4436 suffix += 1;
4437 }
4438 }
4439
4440 fn tsql_null_ordering_case(expression: Expression) -> Expression {
4441 Expression::Case(Box::new(Case {
4442 operand: None,
4443 whens: vec![(
4444 Expression::IsNull(Box::new(IsNull {
4445 this: expression,
4446 not: false,
4447 postfix_form: false,
4448 })),
4449 Expression::number(1),
4450 )],
4451 else_: Some(Expression::number(0)),
4452 comments: Vec::new(),
4453 inferred_type: None,
4454 }))
4455 }
4456
4457 fn try_build_tsql_distinct_null_ordering_wrapper(&self, select: &Select) -> Option<Select> {
4458 let order_by = select.order_by.as_ref()?;
4459
4460 if order_by.siblings
4461 || select.distinct_on.is_some()
4462 || select.distribute_by.is_some()
4463 || select.cluster_by.is_some()
4464 || select.sort_by.is_some()
4465 || select.limit.is_some()
4466 || select.offset.is_some()
4467 || select.limit_by.is_some()
4468 || select.fetch.is_some()
4469 || select.top.is_some()
4470 || select.settings.is_some()
4471 || select.format.is_some()
4472 || select.kind.is_some()
4473 || select.hint.is_some()
4474 || select.into.is_some()
4475 || !select.locks.is_empty()
4476 || !select.for_xml.is_empty()
4477 || !select.for_json.is_empty()
4478 || !select.operation_modifiers.is_empty()
4479 || select.option.is_some()
4480 || select.exclude.is_some()
4481 {
4482 return None;
4483 }
4484
4485 let projection_identifiers: Vec<_> = select
4486 .expressions
4487 .iter()
4488 .map(Self::projection_output_identifier)
4489 .collect::<Option<_>>()?;
4490 let mut used_names: Vec<_> = projection_identifiers
4491 .iter()
4492 .map(|identifier| identifier.name.clone())
4493 .collect();
4494
4495 let mut inner = select.clone();
4496 inner.order_by = None;
4497
4498 let outer_with = inner.with.take();
4499 let outer_leading_comments = std::mem::take(&mut inner.leading_comments);
4500 let outer_post_select_comments = std::mem::take(&mut inner.post_select_comments);
4501
4502 let mut outer_order_expressions = Vec::with_capacity(order_by.expressions.len() * 2);
4503 for (index, ordered) in order_by.expressions.iter().enumerate() {
4504 if ordered.with_fill.is_some() {
4505 return None;
4506 }
4507
4508 let sort_expression =
4509 Self::resolve_distinct_order_projection(&select.expressions, &ordered.this)?;
4510
4511 if Self::ordered_requires_tsql_null_ordering_emulation(ordered) {
4512 let null_alias =
4513 Self::fresh_polyglot_alias("_polyglot_order_null", index, &mut used_names);
4514 inner.expressions.push(
4515 Self::tsql_null_ordering_case(sort_expression.clone())
4516 .alias(null_alias.clone()),
4517 );
4518 outer_order_expressions.push(Ordered {
4519 this: Expression::column(null_alias),
4520 desc: ordered.nulls_first == Some(true),
4521 nulls_first: None,
4522 explicit_asc: false,
4523 with_fill: None,
4524 });
4525 }
4526
4527 let key_alias =
4528 Self::fresh_polyglot_alias("_polyglot_order_key", index, &mut used_names);
4529 inner
4530 .expressions
4531 .push(sort_expression.alias(key_alias.clone()));
4532 outer_order_expressions.push(Ordered {
4533 this: Expression::column(key_alias),
4534 desc: ordered.desc,
4535 nulls_first: None,
4536 explicit_asc: ordered.explicit_asc,
4537 with_fill: None,
4538 });
4539 }
4540
4541 let subquery = Subquery {
4542 this: Expression::Select(Box::new(inner)),
4543 alias: Some(Identifier::new("_polyglot_distinct_order")),
4544 column_aliases: Vec::new(),
4545 alias_explicit_as: true,
4546 alias_keyword: None,
4547 order_by: None,
4548 limit: None,
4549 offset: None,
4550 distribute_by: None,
4551 sort_by: None,
4552 cluster_by: None,
4553 lateral: false,
4554 modifiers_inside: false,
4555 trailing_comments: Vec::new(),
4556 inferred_type: None,
4557 };
4558
4559 let mut outer = Select::new();
4560 outer.with = outer_with;
4561 outer.leading_comments = outer_leading_comments;
4562 outer.post_select_comments = outer_post_select_comments;
4563 outer.expressions = projection_identifiers
4564 .into_iter()
4565 .map(Self::column_expression)
4566 .collect();
4567 outer.from = Some(From {
4568 expressions: vec![Expression::Subquery(Box::new(subquery))],
4569 });
4570 outer.order_by = Some(OrderBy {
4571 expressions: outer_order_expressions,
4572 siblings: false,
4573 comments: order_by.comments.clone(),
4574 });
4575
4576 Some(outer)
4577 }
4578
4579 fn generate_select(&mut self, select: &Select) -> Result<()> {
4580 use crate::dialects::DialectType;
4581
4582 if let Some(resolved_select) = self.resolve_tsql_null_ordering_for_select(select) {
4583 return self.generate_select(&resolved_select);
4584 }
4585
4586 if self.should_handle_tsql_distinct_null_ordering(select) {
4587 if let Some(wrapped_select) = self.try_build_tsql_distinct_null_ordering_wrapper(select)
4588 {
4589 return self.generate_select(&wrapped_select);
4590 }
4591
4592 self.unsupported(
4593 "SELECT DISTINCT with emulated NULL ordering is not supported for TSQL/Fabric",
4594 )?;
4595 }
4596
4597 if let Some(exclude) = &select.exclude {
4601 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4602 let mut inner_select = select.clone();
4604 inner_select.exclude = None;
4605 let inner_expr = Expression::Select(Box::new(inner_select));
4606
4607 let subquery = crate::expressions::Subquery {
4609 this: inner_expr,
4610 alias: None,
4611 column_aliases: Vec::new(),
4612 alias_explicit_as: false,
4613 alias_keyword: None,
4614 order_by: None,
4615 limit: None,
4616 offset: None,
4617 distribute_by: None,
4618 sort_by: None,
4619 cluster_by: None,
4620 lateral: false,
4621 modifiers_inside: false,
4622 trailing_comments: Vec::new(),
4623 inferred_type: None,
4624 };
4625
4626 let star = Expression::Star(crate::expressions::Star {
4628 table: None,
4629 except: Some(
4630 exclude
4631 .iter()
4632 .map(|e| match e {
4633 Expression::Column(col) => col.name.clone(),
4634 Expression::Identifier(id) => id.clone(),
4635 _ => crate::expressions::Identifier::new("unknown".to_string()),
4636 })
4637 .collect(),
4638 ),
4639 replace: None,
4640 rename: None,
4641 trailing_comments: Vec::new(),
4642 span: None,
4643 });
4644
4645 let outer_select = Select {
4646 expressions: vec![star],
4647 from: Some(crate::expressions::From {
4648 expressions: vec![Expression::Subquery(Box::new(subquery))],
4649 }),
4650 ..Select::new()
4651 };
4652
4653 return self.generate_select(&outer_select);
4654 }
4655 }
4656
4657 for comment in &select.leading_comments {
4659 self.write_formatted_comment(comment);
4660 self.write(" ");
4661 }
4662
4663 if let Some(with) = &select.with {
4665 self.generate_with(with)?;
4666 if self.config.pretty {
4667 self.write_newline();
4668 self.write_indent();
4669 } else {
4670 self.write_space();
4671 }
4672 }
4673
4674 for comment in &select.post_select_comments {
4677 self.write_formatted_comment(comment);
4678 self.write(" ");
4679 }
4680
4681 self.write_keyword("SELECT");
4682
4683 if let Some(hint) = &select.hint {
4685 self.generate_hint(hint)?;
4686 }
4687
4688 let use_top_from_limit = matches!(
4692 self.config.dialect,
4693 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4694 ) && select.top.is_none()
4695 && select
4696 .limit
4697 .as_ref()
4698 .is_some_and(|limit| !Self::is_noop_limit_expr(&limit.this))
4699 && select.offset.is_none(); let is_top_dialect = matches!(
4704 self.config.dialect,
4705 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4706 );
4707 let keep_top_verbatim = !is_top_dialect
4708 && select.limit.is_none()
4709 && select
4710 .top
4711 .as_ref()
4712 .map_or(false, |top| top.percent || top.with_ties);
4713
4714 if select.distinct && (is_top_dialect || select.top.is_some()) {
4715 self.write_space();
4716 self.write_keyword("DISTINCT");
4717 }
4718
4719 if is_top_dialect || keep_top_verbatim {
4720 if let Some(top) = &select.top {
4721 self.write_space();
4722 self.write_keyword("TOP");
4723 if top.parenthesized {
4724 if matches!(&top.this, Expression::Subquery(_) | Expression::Paren(_)) {
4725 self.write_space();
4726 self.generate_expression(&top.this)?;
4727 } else {
4728 self.write(" (");
4729 self.generate_expression(&top.this)?;
4730 self.write(")");
4731 }
4732 } else {
4733 self.write_space();
4734 self.generate_expression(&top.this)?;
4735 }
4736 if top.percent {
4737 self.write_space();
4738 self.write_keyword("PERCENT");
4739 }
4740 if top.with_ties {
4741 self.write_space();
4742 self.write_keyword("WITH TIES");
4743 }
4744 } else if use_top_from_limit {
4745 if let Some(limit) = &select.limit {
4747 self.write_space();
4748 self.write_keyword("TOP");
4749 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4751 if is_simple_literal {
4752 self.write_space();
4753 self.generate_expression(&limit.this)?;
4754 } else {
4755 self.write(" (");
4756 self.generate_expression(&limit.this)?;
4757 self.write(")");
4758 }
4759 }
4760 }
4761 }
4762
4763 if select.distinct && !is_top_dialect && select.top.is_none() {
4764 self.write_space();
4765 self.write_keyword("DISTINCT");
4766 }
4767
4768 if let Some(distinct_on) = &select.distinct_on {
4770 self.write_space();
4771 self.write_keyword("ON");
4772 self.write(" (");
4773 for (i, expr) in distinct_on.iter().enumerate() {
4774 if i > 0 {
4775 self.write(", ");
4776 }
4777 self.generate_expression(expr)?;
4778 }
4779 self.write(")");
4780 }
4781
4782 for modifier in &select.operation_modifiers {
4784 self.write_space();
4785 self.write_keyword(modifier);
4786 }
4787
4788 if let Some(kind) = &select.kind {
4790 self.write_space();
4791 self.write_keyword("AS");
4792 self.write_space();
4793 self.write_keyword(kind);
4794 }
4795
4796 if !select.expressions.is_empty() {
4798 if self.config.pretty {
4799 self.write_newline();
4800 self.indent_level += 1;
4801 } else {
4802 self.write_space();
4803 }
4804 }
4805
4806 for (i, expr) in select.expressions.iter().enumerate() {
4807 if i > 0 {
4808 self.write(",");
4809 if self.config.pretty {
4810 self.write_newline();
4811 } else {
4812 self.write_space();
4813 }
4814 }
4815 if self.config.pretty {
4816 self.write_indent();
4817 }
4818 self.generate_expression(expr)?;
4819 }
4820
4821 if self.config.pretty && !select.expressions.is_empty() {
4822 self.indent_level -= 1;
4823 }
4824
4825 if let Some(exclude) = &select.exclude {
4830 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4831 self.write_space();
4832 self.write_keyword("EXCLUDE");
4833 self.write(" (");
4834 for (i, col) in exclude.iter().enumerate() {
4835 if i > 0 {
4836 self.write(", ");
4837 }
4838 self.generate_expression(col)?;
4839 }
4840 self.write(")");
4841 }
4842 }
4843
4844 if let Some(into) = &select.into {
4847 if self.config.pretty {
4848 self.write_newline();
4849 self.write_indent();
4850 } else {
4851 self.write_space();
4852 }
4853 if into.bulk_collect {
4854 self.write_keyword("BULK COLLECT INTO");
4855 } else {
4856 self.write_keyword("INTO");
4857 }
4858 if into.temporary {
4859 self.write_space();
4860 self.write_keyword("TEMPORARY");
4861 }
4862 if into.unlogged {
4863 self.write_space();
4864 self.write_keyword("UNLOGGED");
4865 }
4866 self.write_space();
4867 if !into.expressions.is_empty() {
4869 for (i, expr) in into.expressions.iter().enumerate() {
4870 if i > 0 {
4871 self.write(", ");
4872 }
4873 self.generate_expression(expr)?;
4874 }
4875 } else {
4876 self.generate_expression(&into.this)?;
4877 }
4878 }
4879
4880 if let Some(from) = &select.from {
4882 if self.config.pretty {
4883 self.write_newline();
4884 self.write_indent();
4885 } else {
4886 self.write_space();
4887 }
4888 self.write_keyword("FROM");
4889 self.write_space();
4890
4891 let has_tablesample = from
4896 .expressions
4897 .iter()
4898 .any(|e| matches!(e, Expression::TableSample(_)));
4899 let is_cross_join_dialect = matches!(
4900 self.config.dialect,
4901 Some(DialectType::BigQuery)
4902 | Some(DialectType::Hive)
4903 | Some(DialectType::Spark)
4904 | Some(DialectType::Databricks)
4905 | Some(DialectType::SQLite)
4906 | Some(DialectType::ClickHouse)
4907 );
4908 let source_is_same_as_target = self.config.source_dialect.is_some()
4911 && self.config.source_dialect == self.config.dialect;
4912 let source_is_cross_join_dialect = matches!(
4913 self.config.source_dialect,
4914 Some(DialectType::BigQuery)
4915 | Some(DialectType::Hive)
4916 | Some(DialectType::Spark)
4917 | Some(DialectType::Databricks)
4918 | Some(DialectType::SQLite)
4919 | Some(DialectType::ClickHouse)
4920 );
4921 let use_cross_join = !has_tablesample
4922 && is_cross_join_dialect
4923 && (source_is_same_as_target
4924 || source_is_cross_join_dialect
4925 || self.config.source_dialect.is_none());
4926
4927 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4929
4930 for (i, expr) in from.expressions.iter().enumerate() {
4931 if i > 0 {
4932 if use_cross_join {
4933 self.write(" CROSS JOIN ");
4934 } else {
4935 self.write(", ");
4936 }
4937 }
4938 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4939 self.write("(");
4940 self.generate_expression(expr)?;
4941 self.write(")");
4942 } else {
4943 self.generate_expression(expr)?;
4944 }
4945 let leading = Self::extract_table_leading_comments(expr);
4948 for comment in &leading {
4949 self.write_space();
4950 self.write_formatted_comment(comment);
4951 }
4952 }
4953 }
4954
4955 if self.config.pretty {
4959 self.generate_joins_with_nesting(&select.joins)?;
4960 } else {
4961 for join in &select.joins {
4962 self.generate_join(join)?;
4963 }
4964 for join in select.joins.iter().rev() {
4966 if join.deferred_condition {
4967 self.generate_join_condition(join)?;
4968 }
4969 }
4970 }
4971
4972 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4974 self.generate_lateral_view(lateral_view, lv_idx)?;
4975 }
4976
4977 if let Some(prewhere) = &select.prewhere {
4979 self.write_clause_condition("PREWHERE", prewhere)?;
4980 }
4981
4982 if let Some(where_clause) = &select.where_clause {
4984 self.write_clause_condition("WHERE", &where_clause.this)?;
4985 }
4986
4987 if let Some(connect) = &select.connect {
4989 self.generate_connect(connect)?;
4990 }
4991
4992 if let Some(group_by) = &select.group_by {
4994 if self.config.pretty {
4995 for comment in &group_by.comments {
4997 self.write_newline();
4998 self.write_indent();
4999 self.write_formatted_comment(comment);
5000 }
5001 self.write_newline();
5002 self.write_indent();
5003 } else {
5004 self.write_space();
5005 for comment in &group_by.comments {
5007 self.write_formatted_comment(comment);
5008 self.write_space();
5009 }
5010 }
5011 let clickhouse_bare_modifiers =
5012 matches!(self.config.dialect, Some(DialectType::ClickHouse))
5013 && group_by.all.is_none()
5014 && (group_by.totals || !group_by.expressions.is_empty())
5015 && group_by.expressions.iter().all(|expr| match expr {
5016 Expression::Cube(c) => c.expressions.is_empty(),
5017 Expression::Rollup(r) => r.expressions.is_empty(),
5018 _ => false,
5019 });
5020
5021 if clickhouse_bare_modifiers {
5022 let trailing_cube = group_by
5023 .expressions
5024 .iter()
5025 .any(|expr| matches!(expr, Expression::Cube(c) if c.expressions.is_empty()));
5026 let trailing_rollup = group_by
5027 .expressions
5028 .iter()
5029 .any(|expr| matches!(expr, Expression::Rollup(r) if r.expressions.is_empty()));
5030
5031 if trailing_cube {
5032 self.write_keyword("WITH CUBE");
5033 } else if trailing_rollup {
5034 self.write_keyword("WITH ROLLUP");
5035 }
5036
5037 if group_by.totals {
5038 if trailing_cube || trailing_rollup {
5039 self.write_space();
5040 }
5041 self.write_keyword("WITH TOTALS");
5042 }
5043 } else {
5044 self.write_keyword("GROUP BY");
5045 match group_by.all {
5047 Some(true) => {
5048 self.write_space();
5049 self.write_keyword("ALL");
5050 }
5051 Some(false) => {
5052 self.write_space();
5053 self.write_keyword("DISTINCT");
5054 }
5055 None => {}
5056 }
5057 if !group_by.expressions.is_empty() {
5058 let mut trailing_cube = false;
5061 let mut trailing_rollup = false;
5062 let mut plain_expressions: Vec<&Expression> = Vec::new();
5063 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
5064 let mut cube_expressions: Vec<&Expression> = Vec::new();
5065 let mut rollup_expressions: Vec<&Expression> = Vec::new();
5066
5067 for expr in &group_by.expressions {
5068 match expr {
5069 Expression::Cube(c) if c.expressions.is_empty() => {
5070 trailing_cube = true;
5071 }
5072 Expression::Rollup(r) if r.expressions.is_empty() => {
5073 trailing_rollup = true;
5074 }
5075 Expression::Function(f) if f.name == "CUBE" => {
5076 cube_expressions.push(expr);
5077 }
5078 Expression::Function(f) if f.name == "ROLLUP" => {
5079 rollup_expressions.push(expr);
5080 }
5081 Expression::Function(f) if f.name == "GROUPING SETS" => {
5082 grouping_sets_expressions.push(expr);
5083 }
5084 _ => {
5085 plain_expressions.push(expr);
5086 }
5087 }
5088 }
5089
5090 let mut regular_expressions: Vec<&Expression> = Vec::new();
5092 regular_expressions.extend(plain_expressions);
5093 regular_expressions.extend(grouping_sets_expressions);
5094 regular_expressions.extend(cube_expressions);
5095 regular_expressions.extend(rollup_expressions);
5096
5097 if self.config.pretty {
5098 self.write_newline();
5099 self.indent_level += 1;
5100 self.write_indent();
5101 } else {
5102 self.write_space();
5103 }
5104
5105 for (i, expr) in regular_expressions.iter().enumerate() {
5106 if i > 0 {
5107 if self.config.pretty {
5108 self.write(",");
5109 self.write_newline();
5110 self.write_indent();
5111 } else {
5112 self.write(", ");
5113 }
5114 }
5115 self.generate_expression(expr)?;
5116 }
5117
5118 if self.config.pretty {
5119 self.indent_level -= 1;
5120 }
5121
5122 if trailing_cube {
5124 self.write_space();
5125 self.write_keyword("WITH CUBE");
5126 } else if trailing_rollup {
5127 self.write_space();
5128 self.write_keyword("WITH ROLLUP");
5129 }
5130 }
5131
5132 if group_by.totals {
5134 self.write_space();
5135 self.write_keyword("WITH TOTALS");
5136 }
5137 }
5138 }
5139
5140 if let Some(having) = &select.having {
5142 if self.config.pretty {
5143 for comment in &having.comments {
5145 self.write_newline();
5146 self.write_indent();
5147 self.write_formatted_comment(comment);
5148 }
5149 } else {
5150 for comment in &having.comments {
5151 self.write_space();
5152 self.write_formatted_comment(comment);
5153 }
5154 }
5155 self.write_clause_condition("HAVING", &having.this)?;
5156 }
5157
5158 if select.qualify_after_window {
5160 if let Some(windows) = &select.windows {
5162 self.write_window_clause(windows)?;
5163 }
5164 if let Some(qualify) = &select.qualify {
5165 self.write_clause_condition("QUALIFY", &qualify.this)?;
5166 }
5167 } else {
5168 if let Some(qualify) = &select.qualify {
5170 self.write_clause_condition("QUALIFY", &qualify.this)?;
5171 }
5172 if let Some(windows) = &select.windows {
5173 self.write_window_clause(windows)?;
5174 }
5175 }
5176
5177 if let Some(distribute_by) = &select.distribute_by {
5179 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
5180 }
5181
5182 if let Some(cluster_by) = &select.cluster_by {
5184 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
5185 }
5186
5187 if let Some(sort_by) = &select.sort_by {
5189 self.write_order_clause("SORT BY", &sort_by.expressions)?;
5190 }
5191
5192 if let Some(order_by) = &select.order_by {
5194 if self.config.pretty {
5195 for comment in &order_by.comments {
5197 self.write_newline();
5198 self.write_indent();
5199 self.write_formatted_comment(comment);
5200 }
5201 } else {
5202 for comment in &order_by.comments {
5203 self.write_space();
5204 self.write_formatted_comment(comment);
5205 }
5206 }
5207 let keyword = if order_by.siblings {
5208 "ORDER SIBLINGS BY"
5209 } else {
5210 "ORDER BY"
5211 };
5212 self.write_order_clause(keyword, &order_by.expressions)?;
5213 }
5214
5215 if select.order_by.is_none()
5217 && select.fetch.is_some()
5218 && matches!(
5219 self.config.dialect,
5220 Some(DialectType::TSQL) | Some(DialectType::Fabric)
5221 )
5222 {
5223 if self.config.pretty {
5224 self.write_newline();
5225 self.write_indent();
5226 } else {
5227 self.write_space();
5228 }
5229 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
5230 }
5231
5232 let is_presto_like = matches!(
5237 self.config.dialect,
5238 Some(DialectType::Presto) | Some(DialectType::Trino)
5239 );
5240
5241 if is_presto_like && select.offset.is_some() {
5242 if let Some(offset) = &select.offset {
5244 if self.config.pretty {
5245 self.write_newline();
5246 self.write_indent();
5247 } else {
5248 self.write_space();
5249 }
5250 self.write_keyword("OFFSET");
5251 self.write_space();
5252 self.write_limit_expr(&offset.this)?;
5253 if offset.rows == Some(true) {
5254 self.write_space();
5255 self.write_keyword("ROWS");
5256 }
5257 }
5258 if let Some(limit) = &select.limit {
5259 if self.config.pretty {
5260 self.write_newline();
5261 self.write_indent();
5262 } else {
5263 self.write_space();
5264 }
5265 self.write_keyword("LIMIT");
5266 self.write_space();
5267 self.write_limit_expr(&limit.this)?;
5268 if limit.percent {
5269 self.write_space();
5270 self.write_keyword("PERCENT");
5271 }
5272 for comment in &limit.comments {
5274 self.write(" ");
5275 self.write_formatted_comment(comment);
5276 }
5277 }
5278 } else {
5279 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
5281 !fetch.percent
5282 && !fetch.with_ties
5283 && fetch.count.is_some()
5284 && matches!(
5285 self.config.dialect,
5286 Some(DialectType::Spark)
5287 | Some(DialectType::Hive)
5288 | Some(DialectType::DuckDB)
5289 | Some(DialectType::SQLite)
5290 | Some(DialectType::MySQL)
5291 | Some(DialectType::BigQuery)
5292 | Some(DialectType::Databricks)
5293 | Some(DialectType::StarRocks)
5294 | Some(DialectType::Doris)
5295 | Some(DialectType::Athena)
5296 | Some(DialectType::ClickHouse)
5297 | Some(DialectType::Redshift)
5298 )
5299 });
5300
5301 if let Some(limit) = &select.limit {
5303 if !matches!(
5305 self.config.dialect,
5306 Some(DialectType::TSQL) | Some(DialectType::Fabric)
5307 ) {
5308 if self.config.pretty {
5309 self.write_newline();
5310 self.write_indent();
5311 } else {
5312 self.write_space();
5313 }
5314 self.write_keyword("LIMIT");
5315 self.write_space();
5316 self.write_limit_expr(&limit.this)?;
5317 if limit.percent {
5318 self.write_space();
5319 self.write_keyword("PERCENT");
5320 }
5321 for comment in &limit.comments {
5323 self.write(" ");
5324 self.write_formatted_comment(comment);
5325 }
5326 }
5327 }
5328
5329 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
5331 if let Some(top) = &select.top {
5332 if !top.percent && !top.with_ties {
5333 if self.config.pretty {
5334 self.write_newline();
5335 self.write_indent();
5336 } else {
5337 self.write_space();
5338 }
5339 self.write_keyword("LIMIT");
5340 self.write_space();
5341 self.generate_expression(&top.this)?;
5342 }
5343 }
5344 }
5345
5346 if fetch_as_limit && select.offset.is_some() {
5349 if let Some(fetch) = &select.fetch {
5350 if self.config.pretty {
5351 self.write_newline();
5352 self.write_indent();
5353 } else {
5354 self.write_space();
5355 }
5356 self.write_keyword("LIMIT");
5357 self.write_space();
5358 self.generate_expression(fetch.count.as_ref().unwrap())?;
5359 }
5360 }
5361
5362 if let Some(offset) = &select.offset {
5366 if self.config.pretty {
5367 self.write_newline();
5368 self.write_indent();
5369 } else {
5370 self.write_space();
5371 }
5372 if matches!(
5373 self.config.dialect,
5374 Some(DialectType::TSQL) | Some(DialectType::Fabric)
5375 ) {
5376 self.write_keyword("OFFSET");
5378 self.write_space();
5379 self.write_limit_expr(&offset.this)?;
5380 self.write_space();
5381 self.write_keyword("ROWS");
5382 if let Some(limit) = &select.limit {
5386 if !Self::is_noop_limit_expr(&limit.this) {
5387 self.write_space();
5388 self.write_keyword("FETCH NEXT");
5389 self.write_space();
5390 self.write_limit_expr(&limit.this)?;
5391 self.write_space();
5392 self.write_keyword("ROWS ONLY");
5393 }
5394 }
5395 } else {
5396 self.write_keyword("OFFSET");
5397 self.write_space();
5398 self.write_limit_expr(&offset.this)?;
5399 if offset.rows == Some(true) {
5401 self.write_space();
5402 self.write_keyword("ROWS");
5403 }
5404 }
5405 }
5406 }
5407
5408 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5410 if let Some(limit_by) = &select.limit_by {
5411 if !limit_by.is_empty() {
5412 self.write_space();
5413 self.write_keyword("BY");
5414 self.write_space();
5415 for (i, expr) in limit_by.iter().enumerate() {
5416 if i > 0 {
5417 self.write(", ");
5418 }
5419 self.generate_expression(expr)?;
5420 }
5421 }
5422 }
5423 }
5424
5425 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5427 if let Some(settings) = &select.settings {
5428 if self.config.pretty {
5429 self.write_newline();
5430 self.write_indent();
5431 } else {
5432 self.write_space();
5433 }
5434 self.write_keyword("SETTINGS");
5435 self.write_space();
5436 for (i, expr) in settings.iter().enumerate() {
5437 if i > 0 {
5438 self.write(", ");
5439 }
5440 self.generate_expression(expr)?;
5441 }
5442 }
5443
5444 if let Some(format_expr) = &select.format {
5445 if self.config.pretty {
5446 self.write_newline();
5447 self.write_indent();
5448 } else {
5449 self.write_space();
5450 }
5451 self.write_keyword("FORMAT");
5452 self.write_space();
5453 self.generate_expression(format_expr)?;
5454 }
5455 }
5456
5457 if let Some(fetch) = &select.fetch {
5459 let fetch_already_as_limit = select.offset.is_some()
5461 && !fetch.percent
5462 && !fetch.with_ties
5463 && fetch.count.is_some()
5464 && matches!(
5465 self.config.dialect,
5466 Some(DialectType::Spark)
5467 | Some(DialectType::Hive)
5468 | Some(DialectType::DuckDB)
5469 | Some(DialectType::SQLite)
5470 | Some(DialectType::MySQL)
5471 | Some(DialectType::BigQuery)
5472 | Some(DialectType::Databricks)
5473 | Some(DialectType::StarRocks)
5474 | Some(DialectType::Doris)
5475 | Some(DialectType::Athena)
5476 | Some(DialectType::ClickHouse)
5477 | Some(DialectType::Redshift)
5478 );
5479
5480 if fetch_already_as_limit {
5481 } else {
5483 if self.config.pretty {
5484 self.write_newline();
5485 self.write_indent();
5486 } else {
5487 self.write_space();
5488 }
5489
5490 let use_limit = !fetch.percent
5492 && !fetch.with_ties
5493 && fetch.count.is_some()
5494 && matches!(
5495 self.config.dialect,
5496 Some(DialectType::Spark)
5497 | Some(DialectType::Hive)
5498 | Some(DialectType::DuckDB)
5499 | Some(DialectType::SQLite)
5500 | Some(DialectType::MySQL)
5501 | Some(DialectType::BigQuery)
5502 | Some(DialectType::Databricks)
5503 | Some(DialectType::StarRocks)
5504 | Some(DialectType::Doris)
5505 | Some(DialectType::Athena)
5506 | Some(DialectType::ClickHouse)
5507 | Some(DialectType::Redshift)
5508 );
5509
5510 if use_limit {
5511 self.write_keyword("LIMIT");
5512 self.write_space();
5513 self.generate_expression(fetch.count.as_ref().unwrap())?;
5514 } else {
5515 self.write_keyword("FETCH");
5516 self.write_space();
5517 self.write_keyword(&fetch.direction);
5518 if let Some(ref count) = fetch.count {
5519 self.write_space();
5520 self.generate_expression(count)?;
5521 }
5522 if fetch.percent {
5523 self.write_space();
5524 self.write_keyword("PERCENT");
5525 }
5526 if fetch.rows {
5527 self.write_space();
5528 self.write_keyword("ROWS");
5529 }
5530 if fetch.with_ties {
5531 self.write_space();
5532 self.write_keyword("WITH TIES");
5533 } else {
5534 self.write_space();
5535 self.write_keyword("ONLY");
5536 }
5537 }
5538 } }
5540
5541 if let Some(sample) = &select.sample {
5543 use crate::dialects::DialectType;
5544 if self.config.pretty {
5545 self.write_newline();
5546 } else {
5547 self.write_space();
5548 }
5549
5550 if sample.is_using_sample {
5551 self.write_keyword("USING SAMPLE");
5553 self.generate_sample_body(sample)?;
5554 } else {
5555 self.write_keyword("TABLESAMPLE");
5556
5557 let snowflake_bernoulli =
5559 matches!(self.config.dialect, Some(DialectType::Snowflake))
5560 && !sample.explicit_method;
5561 if snowflake_bernoulli {
5562 self.write_space();
5563 self.write_keyword("BERNOULLI");
5564 }
5565
5566 if matches!(sample.method, SampleMethod::Bucket) {
5568 self.write_space();
5569 self.write("(");
5570 self.write_keyword("BUCKET");
5571 self.write_space();
5572 if let Some(ref num) = sample.bucket_numerator {
5573 self.generate_expression(num)?;
5574 }
5575 self.write_space();
5576 self.write_keyword("OUT OF");
5577 self.write_space();
5578 if let Some(ref denom) = sample.bucket_denominator {
5579 self.generate_expression(denom)?;
5580 }
5581 if let Some(ref field) = sample.bucket_field {
5582 self.write_space();
5583 self.write_keyword("ON");
5584 self.write_space();
5585 self.generate_expression(field)?;
5586 }
5587 self.write(")");
5588 } else if sample.unit_after_size {
5589 if sample.explicit_method && sample.method_before_size {
5591 self.write_space();
5592 match sample.method {
5593 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5594 SampleMethod::System => self.write_keyword("SYSTEM"),
5595 SampleMethod::Block => self.write_keyword("BLOCK"),
5596 SampleMethod::Row => self.write_keyword("ROW"),
5597 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5598 _ => {}
5599 }
5600 }
5601 self.write(" (");
5602 self.generate_expression(&sample.size)?;
5603 self.write_space();
5604 match sample.method {
5605 SampleMethod::Percent => self.write_keyword("PERCENT"),
5606 SampleMethod::Row => self.write_keyword("ROWS"),
5607 SampleMethod::Reservoir => self.write_keyword("ROWS"),
5608 _ => {
5609 self.write_keyword("PERCENT");
5610 }
5611 }
5612 self.write(")");
5613 } else {
5614 self.write_space();
5616 match sample.method {
5617 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5618 SampleMethod::System => self.write_keyword("SYSTEM"),
5619 SampleMethod::Block => self.write_keyword("BLOCK"),
5620 SampleMethod::Row => self.write_keyword("ROW"),
5621 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
5622 SampleMethod::Bucket => {}
5623 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5624 }
5625 self.write(" (");
5626 self.generate_expression(&sample.size)?;
5627 if matches!(sample.method, SampleMethod::Percent) {
5628 self.write_space();
5629 self.write_keyword("PERCENT");
5630 }
5631 self.write(")");
5632 }
5633 }
5634
5635 if let Some(seed) = &sample.seed {
5636 self.write_space();
5637 let use_seed = sample.use_seed_keyword
5639 && !matches!(
5640 self.config.dialect,
5641 Some(crate::dialects::DialectType::Databricks)
5642 | Some(crate::dialects::DialectType::Spark)
5643 );
5644 if use_seed {
5645 self.write_keyword("SEED");
5646 } else {
5647 self.write_keyword("REPEATABLE");
5648 }
5649 self.write(" (");
5650 self.generate_expression(seed)?;
5651 self.write(")");
5652 }
5653 }
5654
5655 if self.config.locking_reads_supported {
5658 for lock in &select.locks {
5659 if self.config.pretty {
5660 self.write_newline();
5661 self.write_indent();
5662 } else {
5663 self.write_space();
5664 }
5665 self.generate_lock(lock)?;
5666 }
5667 }
5668
5669 if !select.for_xml.is_empty() {
5671 if self.config.pretty {
5672 self.write_newline();
5673 self.write_indent();
5674 } else {
5675 self.write_space();
5676 }
5677 self.write_keyword("FOR XML");
5678 for (i, opt) in select.for_xml.iter().enumerate() {
5679 if self.config.pretty {
5680 if i > 0 {
5681 self.write(",");
5682 }
5683 self.write_newline();
5684 self.write_indent();
5685 self.write(" "); } else {
5687 if i > 0 {
5688 self.write(",");
5689 }
5690 self.write_space();
5691 }
5692 self.generate_for_xml_option(opt)?;
5693 }
5694 }
5695
5696 if !select.for_json.is_empty()
5698 && matches!(
5699 self.config.dialect,
5700 None | Some(DialectType::TSQL) | Some(DialectType::Fabric)
5701 )
5702 {
5703 if self.config.pretty {
5704 self.write_newline();
5705 self.write_indent();
5706 } else {
5707 self.write_space();
5708 }
5709 self.write_keyword("FOR JSON");
5710 for (i, opt) in select.for_json.iter().enumerate() {
5711 if self.config.pretty {
5712 if i > 0 {
5713 self.write(",");
5714 }
5715 self.write_newline();
5716 self.write_indent();
5717 self.write(" "); } else {
5719 if i > 0 {
5720 self.write(",");
5721 }
5722 self.write_space();
5723 }
5724 self.generate_for_xml_option(opt)?;
5725 }
5726 }
5727
5728 if let Some(ref option) = select.option {
5730 if matches!(
5731 self.config.dialect,
5732 Some(crate::dialects::DialectType::TSQL)
5733 | Some(crate::dialects::DialectType::Fabric)
5734 ) {
5735 self.write_space();
5736 self.write(option);
5737 }
5738 }
5739
5740 Ok(())
5741 }
5742
5743 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5745 match opt {
5746 Expression::QueryOption(qo) => {
5747 if let Expression::Var(var) = &*qo.this {
5749 self.write(&var.this);
5750 } else {
5751 self.generate_expression(&qo.this)?;
5752 }
5753 if let Some(expr) = &qo.expression {
5755 self.write("(");
5756 self.generate_expression(expr)?;
5757 self.write(")");
5758 }
5759 }
5760 _ => {
5761 self.generate_expression(opt)?;
5762 }
5763 }
5764 Ok(())
5765 }
5766
5767 fn generate_with(&mut self, with: &With) -> Result<()> {
5768 use crate::dialects::DialectType;
5769
5770 for comment in &with.leading_comments {
5772 self.write_formatted_comment(comment);
5773 self.write(" ");
5774 }
5775 self.write_keyword("WITH");
5776 if with.recursive && self.config.cte_recursive_keyword_required {
5777 self.write_space();
5778 self.write_keyword("RECURSIVE");
5779 }
5780 self.write_space();
5781
5782 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5784
5785 for (i, cte) in with.ctes.iter().enumerate() {
5786 if i > 0 {
5787 self.write(",");
5788 if self.config.pretty {
5789 self.write_space();
5790 } else {
5791 self.write(" ");
5792 }
5793 }
5794 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5795 self.generate_expression(&cte.this)?;
5796 self.write_space();
5797 self.write_keyword("AS");
5798 self.write_space();
5799 self.generate_identifier(&cte.alias)?;
5800 continue;
5801 }
5802 self.generate_identifier(&cte.alias)?;
5803 for comment in &cte.comments {
5805 self.write_space();
5806 self.write_formatted_comment(comment);
5807 }
5808 if !cte.columns.is_empty() && !skip_cte_columns {
5809 self.write("(");
5810 for (j, col) in cte.columns.iter().enumerate() {
5811 if j > 0 {
5812 self.write(", ");
5813 }
5814 self.generate_identifier(col)?;
5815 }
5816 self.write(")");
5817 }
5818 if !cte.key_expressions.is_empty() {
5820 self.write_space();
5821 self.write_keyword("USING KEY");
5822 self.write(" (");
5823 for (i, key) in cte.key_expressions.iter().enumerate() {
5824 if i > 0 {
5825 self.write(", ");
5826 }
5827 self.generate_identifier(key)?;
5828 }
5829 self.write(")");
5830 }
5831 self.write_space();
5832 self.write_keyword("AS");
5833 if let Some(materialized) = cte.materialized {
5835 self.write_space();
5836 if materialized {
5837 self.write_keyword("MATERIALIZED");
5838 } else {
5839 self.write_keyword("NOT MATERIALIZED");
5840 }
5841 }
5842 self.write(" (");
5843 if self.config.pretty {
5844 self.write_newline();
5845 self.indent_level += 1;
5846 self.write_indent();
5847 }
5848 let wrap_values_in_select = matches!(
5851 self.config.dialect,
5852 Some(DialectType::Spark) | Some(DialectType::Databricks)
5853 ) && matches!(&cte.this, Expression::Values(_));
5854
5855 if wrap_values_in_select {
5856 self.write_keyword("SELECT");
5857 self.write(" * ");
5858 self.write_keyword("FROM");
5859 self.write_space();
5860 }
5861 self.generate_expression(&cte.this)?;
5862 if self.config.pretty {
5863 self.write_newline();
5864 self.indent_level -= 1;
5865 self.write_indent();
5866 }
5867 self.write(")");
5868 }
5869
5870 if let Some(search) = &with.search {
5872 self.write_space();
5873 self.generate_expression(search)?;
5874 }
5875
5876 Ok(())
5877 }
5878
5879 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5883 let mut i = 0;
5884 while i < joins.len() {
5885 if joins[i].deferred_condition {
5886 let parent_group = joins[i].nesting_group;
5887
5888 self.generate_join_without_condition(&joins[i])?;
5891
5892 let child_start = i + 1;
5894 let mut child_end = child_start;
5895 while child_end < joins.len()
5896 && !joins[child_end].deferred_condition
5897 && joins[child_end].nesting_group == parent_group
5898 {
5899 child_end += 1;
5900 }
5901
5902 if child_start < child_end {
5904 self.indent_level += 1;
5905 for j in child_start..child_end {
5906 self.generate_join(&joins[j])?;
5907 }
5908 self.indent_level -= 1;
5909 }
5910
5911 self.generate_join_condition(&joins[i])?;
5913
5914 i = child_end;
5915 } else {
5916 self.generate_join(&joins[i])?;
5918 i += 1;
5919 }
5920 }
5921 Ok(())
5922 }
5923
5924 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5927 let mut join_copy = join.clone();
5930 join_copy.on = None;
5931 join_copy.using = Vec::new();
5932 join_copy.deferred_condition = false;
5933 self.generate_join(&join_copy)
5934 }
5935
5936 fn generate_join(&mut self, join: &Join) -> Result<()> {
5937 if join.kind == JoinKind::Implicit {
5939 self.write(",");
5940 if self.config.pretty {
5941 self.write_newline();
5942 self.write_indent();
5943 } else {
5944 self.write_space();
5945 }
5946 self.generate_expression(&join.this)?;
5947 return Ok(());
5948 }
5949
5950 if self.config.pretty {
5951 self.write_newline();
5952 self.write_indent();
5953 } else {
5954 self.write_space();
5955 }
5956
5957 let hint_str = if self.config.join_hints {
5960 join.join_hint
5961 .as_ref()
5962 .map(|h| format!(" {}", h))
5963 .unwrap_or_default()
5964 } else {
5965 String::new()
5966 };
5967
5968 let clickhouse_join_keyword =
5969 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5970 if let Some(hint) = &join.join_hint {
5971 let mut global = false;
5972 let mut strictness: Option<&'static str> = None;
5973 for part in hint.split_whitespace() {
5974 if part.eq_ignore_ascii_case("GLOBAL") {
5975 global = true;
5976 } else if part.eq_ignore_ascii_case("ALL") {
5977 strictness = Some("ALL");
5978 } else if part.eq_ignore_ascii_case("ANY") {
5979 strictness = Some("ANY");
5980 } else if part.eq_ignore_ascii_case("ASOF") {
5981 strictness = Some("ASOF");
5982 } else if part.eq_ignore_ascii_case("SEMI") {
5983 strictness = Some("SEMI");
5984 } else if part.eq_ignore_ascii_case("ANTI") {
5985 strictness = Some("ANTI");
5986 }
5987 }
5988
5989 if global || strictness.is_some() {
5990 let join_type = match join.kind {
5991 JoinKind::Left => {
5992 if join.use_outer_keyword {
5993 "LEFT OUTER"
5994 } else if join.use_inner_keyword {
5995 "LEFT INNER"
5996 } else {
5997 "LEFT"
5998 }
5999 }
6000 JoinKind::Right => {
6001 if join.use_outer_keyword {
6002 "RIGHT OUTER"
6003 } else if join.use_inner_keyword {
6004 "RIGHT INNER"
6005 } else {
6006 "RIGHT"
6007 }
6008 }
6009 JoinKind::Full => {
6010 if join.use_outer_keyword {
6011 "FULL OUTER"
6012 } else {
6013 "FULL"
6014 }
6015 }
6016 JoinKind::Inner => {
6017 if join.use_inner_keyword {
6018 "INNER"
6019 } else {
6020 ""
6021 }
6022 }
6023 _ => "",
6024 };
6025
6026 let mut parts = Vec::new();
6027 if global {
6028 parts.push("GLOBAL");
6029 }
6030 if !join_type.is_empty() {
6031 parts.push(join_type);
6032 }
6033 if let Some(strict) = strictness {
6034 parts.push(strict);
6035 }
6036 parts.push("JOIN");
6037 Some(parts.join(" "))
6038 } else {
6039 None
6040 }
6041 } else {
6042 None
6043 }
6044 } else {
6045 None
6046 };
6047
6048 if !join.comments.is_empty() {
6052 if self.config.pretty {
6053 let trimmed = self.output.trim_end().len();
6058 self.output.truncate(trimmed);
6059 for comment in &join.comments {
6060 self.write_newline();
6061 self.write_indent();
6062 self.write_formatted_comment(comment);
6063 }
6064 self.write_newline();
6065 self.write_indent();
6066 } else {
6067 for comment in &join.comments {
6068 self.write_formatted_comment(comment);
6069 self.write_space();
6070 }
6071 }
6072 }
6073
6074 let directed_str = if join.directed { " DIRECTED" } else { "" };
6075
6076 if let Some(keyword) = clickhouse_join_keyword {
6077 self.write_keyword(&keyword);
6078 } else {
6079 match join.kind {
6080 JoinKind::Inner => {
6081 if join.use_inner_keyword {
6082 if hint_str.is_empty() && directed_str.is_empty() {
6083 self.write_keyword("INNER JOIN");
6084 } else {
6085 self.write_keyword("INNER");
6086 if !hint_str.is_empty() {
6087 self.write_keyword(&hint_str);
6088 }
6089 if !directed_str.is_empty() {
6090 self.write_keyword(directed_str);
6091 }
6092 self.write_keyword(" JOIN");
6093 }
6094 } else {
6095 if !hint_str.is_empty() {
6096 self.write_keyword(hint_str.trim());
6097 self.write_keyword(" ");
6098 }
6099 if !directed_str.is_empty() {
6100 self.write_keyword("DIRECTED ");
6101 }
6102 self.write_keyword("JOIN");
6103 }
6104 }
6105 JoinKind::Left => {
6106 if join.use_outer_keyword {
6107 if hint_str.is_empty() && directed_str.is_empty() {
6108 self.write_keyword("LEFT OUTER JOIN");
6109 } else {
6110 self.write_keyword("LEFT OUTER");
6111 if !hint_str.is_empty() {
6112 self.write_keyword(&hint_str);
6113 }
6114 if !directed_str.is_empty() {
6115 self.write_keyword(directed_str);
6116 }
6117 self.write_keyword(" JOIN");
6118 }
6119 } else if join.use_inner_keyword {
6120 if hint_str.is_empty() && directed_str.is_empty() {
6121 self.write_keyword("LEFT INNER JOIN");
6122 } else {
6123 self.write_keyword("LEFT INNER");
6124 if !hint_str.is_empty() {
6125 self.write_keyword(&hint_str);
6126 }
6127 if !directed_str.is_empty() {
6128 self.write_keyword(directed_str);
6129 }
6130 self.write_keyword(" JOIN");
6131 }
6132 } else {
6133 if hint_str.is_empty() && directed_str.is_empty() {
6134 self.write_keyword("LEFT JOIN");
6135 } else {
6136 self.write_keyword("LEFT");
6137 if !hint_str.is_empty() {
6138 self.write_keyword(&hint_str);
6139 }
6140 if !directed_str.is_empty() {
6141 self.write_keyword(directed_str);
6142 }
6143 self.write_keyword(" JOIN");
6144 }
6145 }
6146 }
6147 JoinKind::Right => {
6148 if join.use_outer_keyword {
6149 if hint_str.is_empty() && directed_str.is_empty() {
6150 self.write_keyword("RIGHT OUTER JOIN");
6151 } else {
6152 self.write_keyword("RIGHT OUTER");
6153 if !hint_str.is_empty() {
6154 self.write_keyword(&hint_str);
6155 }
6156 if !directed_str.is_empty() {
6157 self.write_keyword(directed_str);
6158 }
6159 self.write_keyword(" JOIN");
6160 }
6161 } else if join.use_inner_keyword {
6162 if hint_str.is_empty() && directed_str.is_empty() {
6163 self.write_keyword("RIGHT INNER JOIN");
6164 } else {
6165 self.write_keyword("RIGHT INNER");
6166 if !hint_str.is_empty() {
6167 self.write_keyword(&hint_str);
6168 }
6169 if !directed_str.is_empty() {
6170 self.write_keyword(directed_str);
6171 }
6172 self.write_keyword(" JOIN");
6173 }
6174 } else {
6175 if hint_str.is_empty() && directed_str.is_empty() {
6176 self.write_keyword("RIGHT JOIN");
6177 } else {
6178 self.write_keyword("RIGHT");
6179 if !hint_str.is_empty() {
6180 self.write_keyword(&hint_str);
6181 }
6182 if !directed_str.is_empty() {
6183 self.write_keyword(directed_str);
6184 }
6185 self.write_keyword(" JOIN");
6186 }
6187 }
6188 }
6189 JoinKind::Full => {
6190 if join.use_outer_keyword {
6191 if hint_str.is_empty() && directed_str.is_empty() {
6192 self.write_keyword("FULL OUTER JOIN");
6193 } else {
6194 self.write_keyword("FULL OUTER");
6195 if !hint_str.is_empty() {
6196 self.write_keyword(&hint_str);
6197 }
6198 if !directed_str.is_empty() {
6199 self.write_keyword(directed_str);
6200 }
6201 self.write_keyword(" JOIN");
6202 }
6203 } else {
6204 if hint_str.is_empty() && directed_str.is_empty() {
6205 self.write_keyword("FULL JOIN");
6206 } else {
6207 self.write_keyword("FULL");
6208 if !hint_str.is_empty() {
6209 self.write_keyword(&hint_str);
6210 }
6211 if !directed_str.is_empty() {
6212 self.write_keyword(directed_str);
6213 }
6214 self.write_keyword(" JOIN");
6215 }
6216 }
6217 }
6218 JoinKind::Outer => {
6219 if directed_str.is_empty() {
6220 self.write_keyword("OUTER JOIN");
6221 } else {
6222 self.write_keyword("OUTER");
6223 self.write_keyword(directed_str);
6224 self.write_keyword(" JOIN");
6225 }
6226 }
6227 JoinKind::Cross => {
6228 if directed_str.is_empty() {
6229 self.write_keyword("CROSS JOIN");
6230 } else {
6231 self.write_keyword("CROSS");
6232 self.write_keyword(directed_str);
6233 self.write_keyword(" JOIN");
6234 }
6235 }
6236 JoinKind::Natural => {
6237 if join.use_inner_keyword {
6238 if directed_str.is_empty() {
6239 self.write_keyword("NATURAL INNER JOIN");
6240 } else {
6241 self.write_keyword("NATURAL INNER");
6242 self.write_keyword(directed_str);
6243 self.write_keyword(" JOIN");
6244 }
6245 } else {
6246 if directed_str.is_empty() {
6247 self.write_keyword("NATURAL JOIN");
6248 } else {
6249 self.write_keyword("NATURAL");
6250 self.write_keyword(directed_str);
6251 self.write_keyword(" JOIN");
6252 }
6253 }
6254 }
6255 JoinKind::NaturalLeft => {
6256 if join.use_outer_keyword {
6257 if directed_str.is_empty() {
6258 self.write_keyword("NATURAL LEFT OUTER JOIN");
6259 } else {
6260 self.write_keyword("NATURAL LEFT OUTER");
6261 self.write_keyword(directed_str);
6262 self.write_keyword(" JOIN");
6263 }
6264 } else {
6265 if directed_str.is_empty() {
6266 self.write_keyword("NATURAL LEFT JOIN");
6267 } else {
6268 self.write_keyword("NATURAL LEFT");
6269 self.write_keyword(directed_str);
6270 self.write_keyword(" JOIN");
6271 }
6272 }
6273 }
6274 JoinKind::NaturalRight => {
6275 if join.use_outer_keyword {
6276 if directed_str.is_empty() {
6277 self.write_keyword("NATURAL RIGHT OUTER JOIN");
6278 } else {
6279 self.write_keyword("NATURAL RIGHT OUTER");
6280 self.write_keyword(directed_str);
6281 self.write_keyword(" JOIN");
6282 }
6283 } else {
6284 if directed_str.is_empty() {
6285 self.write_keyword("NATURAL RIGHT JOIN");
6286 } else {
6287 self.write_keyword("NATURAL RIGHT");
6288 self.write_keyword(directed_str);
6289 self.write_keyword(" JOIN");
6290 }
6291 }
6292 }
6293 JoinKind::NaturalFull => {
6294 if join.use_outer_keyword {
6295 if directed_str.is_empty() {
6296 self.write_keyword("NATURAL FULL OUTER JOIN");
6297 } else {
6298 self.write_keyword("NATURAL FULL OUTER");
6299 self.write_keyword(directed_str);
6300 self.write_keyword(" JOIN");
6301 }
6302 } else {
6303 if directed_str.is_empty() {
6304 self.write_keyword("NATURAL FULL JOIN");
6305 } else {
6306 self.write_keyword("NATURAL FULL");
6307 self.write_keyword(directed_str);
6308 self.write_keyword(" JOIN");
6309 }
6310 }
6311 }
6312 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
6313 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
6314 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
6315 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
6316 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
6317 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
6318 JoinKind::CrossApply => {
6319 if matches!(
6321 self.config.dialect,
6322 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
6323 ) {
6324 self.write_keyword("CROSS APPLY");
6325 } else {
6326 self.write_keyword("INNER JOIN LATERAL");
6327 }
6328 }
6329 JoinKind::OuterApply => {
6330 if matches!(
6332 self.config.dialect,
6333 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
6334 ) {
6335 self.write_keyword("OUTER APPLY");
6336 } else {
6337 self.write_keyword("LEFT JOIN LATERAL");
6338 }
6339 }
6340 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
6341 JoinKind::AsOfLeft => {
6342 if join.use_outer_keyword {
6343 self.write_keyword("ASOF LEFT OUTER JOIN");
6344 } else {
6345 self.write_keyword("ASOF LEFT JOIN");
6346 }
6347 }
6348 JoinKind::AsOfRight => {
6349 if join.use_outer_keyword {
6350 self.write_keyword("ASOF RIGHT OUTER JOIN");
6351 } else {
6352 self.write_keyword("ASOF RIGHT JOIN");
6353 }
6354 }
6355 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
6356 JoinKind::LeftLateral => {
6357 if join.use_outer_keyword {
6358 self.write_keyword("LEFT OUTER LATERAL JOIN");
6359 } else {
6360 self.write_keyword("LEFT LATERAL JOIN");
6361 }
6362 }
6363 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
6364 JoinKind::Implicit => {
6365 use crate::dialects::DialectType;
6369 let is_cj_dialect = matches!(
6370 self.config.dialect,
6371 Some(DialectType::BigQuery)
6372 | Some(DialectType::Hive)
6373 | Some(DialectType::Spark)
6374 | Some(DialectType::Databricks)
6375 );
6376 let source_is_same = self.config.source_dialect.is_some()
6377 && self.config.source_dialect == self.config.dialect;
6378 let source_is_cj = matches!(
6379 self.config.source_dialect,
6380 Some(DialectType::BigQuery)
6381 | Some(DialectType::Hive)
6382 | Some(DialectType::Spark)
6383 | Some(DialectType::Databricks)
6384 );
6385 if is_cj_dialect
6386 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
6387 {
6388 self.write_keyword("CROSS JOIN");
6389 } else {
6390 self.output.truncate(self.output.trim_end().len());
6394 self.write(",");
6395 }
6396 }
6397 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
6398 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
6399 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
6400 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
6401 }
6402 }
6403
6404 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
6406 match &join.this {
6407 Expression::Tuple(t) if t.expressions.is_empty() => {}
6408 Expression::Tuple(t) => {
6409 self.write_space();
6410 for (i, item) in t.expressions.iter().enumerate() {
6411 if i > 0 {
6412 self.write(", ");
6413 }
6414 self.generate_expression(item)?;
6415 }
6416 }
6417 other => {
6418 self.write_space();
6419 self.generate_expression(other)?;
6420 }
6421 }
6422 } else {
6423 self.write_space();
6424 self.generate_expression(&join.this)?;
6425 }
6426
6427 if !join.deferred_condition {
6429 if let Some(match_cond) = &join.match_condition {
6431 self.write_space();
6432 self.write_keyword("MATCH_CONDITION");
6433 self.write(" (");
6434 self.generate_expression(match_cond)?;
6435 self.write(")");
6436 }
6437
6438 if let Some(on) = &join.on {
6439 if self.config.pretty {
6440 self.write_newline();
6441 self.indent_level += 1;
6442 self.write_indent();
6443 self.write_keyword("ON");
6444 self.write_space();
6445 self.generate_join_on_condition(on)?;
6446 self.indent_level -= 1;
6447 } else {
6448 self.write_space();
6449 self.write_keyword("ON");
6450 self.write_space();
6451 self.generate_expression(on)?;
6452 }
6453 }
6454
6455 if !join.using.is_empty() {
6456 if self.config.pretty {
6457 self.write_newline();
6458 self.indent_level += 1;
6459 self.write_indent();
6460 self.write_keyword("USING");
6461 self.write(" (");
6462 for (i, col) in join.using.iter().enumerate() {
6463 if i > 0 {
6464 self.write(", ");
6465 }
6466 self.generate_identifier(col)?;
6467 }
6468 self.write(")");
6469 self.indent_level -= 1;
6470 } else {
6471 self.write_space();
6472 self.write_keyword("USING");
6473 self.write(" (");
6474 for (i, col) in join.using.iter().enumerate() {
6475 if i > 0 {
6476 self.write(", ");
6477 }
6478 self.generate_identifier(col)?;
6479 }
6480 self.write(")");
6481 }
6482 }
6483 }
6484
6485 for pivot in &join.pivots {
6487 self.write_space();
6488 self.generate_expression(pivot)?;
6489 }
6490
6491 Ok(())
6492 }
6493
6494 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
6496 if let Some(match_cond) = &join.match_condition {
6498 self.write_space();
6499 self.write_keyword("MATCH_CONDITION");
6500 self.write(" (");
6501 self.generate_expression(match_cond)?;
6502 self.write(")");
6503 }
6504
6505 if let Some(on) = &join.on {
6506 if self.config.pretty {
6507 self.write_newline();
6508 self.indent_level += 1;
6509 self.write_indent();
6510 self.write_keyword("ON");
6511 self.write_space();
6512 self.generate_join_on_condition(on)?;
6514 self.indent_level -= 1;
6515 } else {
6516 self.write_space();
6517 self.write_keyword("ON");
6518 self.write_space();
6519 self.generate_expression(on)?;
6520 }
6521 }
6522
6523 if !join.using.is_empty() {
6524 if self.config.pretty {
6525 self.write_newline();
6526 self.indent_level += 1;
6527 self.write_indent();
6528 self.write_keyword("USING");
6529 self.write(" (");
6530 for (i, col) in join.using.iter().enumerate() {
6531 if i > 0 {
6532 self.write(", ");
6533 }
6534 self.generate_identifier(col)?;
6535 }
6536 self.write(")");
6537 self.indent_level -= 1;
6538 } else {
6539 self.write_space();
6540 self.write_keyword("USING");
6541 self.write(" (");
6542 for (i, col) in join.using.iter().enumerate() {
6543 if i > 0 {
6544 self.write(", ");
6545 }
6546 self.generate_identifier(col)?;
6547 }
6548 self.write(")");
6549 }
6550 }
6551
6552 for pivot in &join.pivots {
6554 self.write_space();
6555 self.generate_expression(pivot)?;
6556 }
6557
6558 Ok(())
6559 }
6560
6561 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
6563 if let Expression::And(and_op) = expr {
6564 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
6565 self.generate_expression(conditions[0])?;
6566 for condition in conditions.iter().skip(1) {
6567 self.write_newline();
6568 self.write_indent();
6569 self.write_keyword("AND");
6570 self.write_space();
6571 self.generate_expression(condition)?;
6572 }
6573 return Ok(());
6574 }
6575 }
6576
6577 self.generate_expression(expr)
6578 }
6579
6580 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
6581 self.write("(");
6583 self.generate_expression(&jt.left)?;
6584
6585 for join in &jt.joins {
6587 self.generate_join(join)?;
6588 }
6589
6590 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
6592 self.generate_lateral_view(lv, lv_idx)?;
6593 }
6594
6595 self.write(")");
6596
6597 if let Some(alias) = &jt.alias {
6599 self.write_space();
6600 self.write_keyword("AS");
6601 self.write_space();
6602 self.generate_identifier(alias)?;
6603 }
6604
6605 Ok(())
6606 }
6607
6608 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
6609 use crate::dialects::DialectType;
6610
6611 if self.config.pretty {
6612 self.write_newline();
6613 self.write_indent();
6614 } else {
6615 self.write_space();
6616 }
6617
6618 let use_lateral_join = matches!(
6621 self.config.dialect,
6622 Some(DialectType::PostgreSQL)
6623 | Some(DialectType::DuckDB)
6624 | Some(DialectType::Snowflake)
6625 | Some(DialectType::TSQL)
6626 | Some(DialectType::Presto)
6627 | Some(DialectType::Trino)
6628 | Some(DialectType::Athena)
6629 );
6630
6631 let use_unnest = matches!(
6633 self.config.dialect,
6634 Some(DialectType::DuckDB)
6635 | Some(DialectType::Presto)
6636 | Some(DialectType::Trino)
6637 | Some(DialectType::Athena)
6638 );
6639
6640 let (is_posexplode, is_inline, func_args) = match &lv.this {
6642 Expression::Explode(uf) => {
6643 (false, false, vec![uf.this.clone()])
6645 }
6646 Expression::Unnest(uf) => {
6647 let mut args = vec![uf.this.clone()];
6648 args.extend(uf.expressions.clone());
6649 (false, false, args)
6650 }
6651 Expression::Function(func) => {
6652 if func.name.eq_ignore_ascii_case("POSEXPLODE")
6653 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
6654 {
6655 (true, false, func.args.clone())
6656 } else if func.name.eq_ignore_ascii_case("INLINE") {
6657 (false, true, func.args.clone())
6658 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6659 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6660 {
6661 (false, false, func.args.clone())
6662 } else {
6663 (false, false, vec![])
6664 }
6665 }
6666 _ => (false, false, vec![]),
6667 };
6668
6669 if use_lateral_join {
6670 if lv.outer {
6672 self.write_keyword("LEFT JOIN LATERAL");
6673 } else {
6674 self.write_keyword("CROSS JOIN");
6675 }
6676 self.write_space();
6677
6678 if use_unnest && !func_args.is_empty() {
6679 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6682 func_args
6684 .iter()
6685 .map(|a| {
6686 if let Expression::Function(ref f) = a {
6687 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6688 return Expression::ArrayFunc(Box::new(
6689 crate::expressions::ArrayConstructor {
6690 expressions: f.args.clone(),
6691 bracket_notation: true,
6692 use_list_keyword: false,
6693 },
6694 ));
6695 }
6696 }
6697 a.clone()
6698 })
6699 .collect::<Vec<_>>()
6700 } else if matches!(
6701 self.config.dialect,
6702 Some(DialectType::Presto)
6703 | Some(DialectType::Trino)
6704 | Some(DialectType::Athena)
6705 ) {
6706 func_args
6708 .iter()
6709 .map(|a| {
6710 if let Expression::Function(ref f) = a {
6711 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6712 return Expression::ArrayFunc(Box::new(
6713 crate::expressions::ArrayConstructor {
6714 expressions: f.args.clone(),
6715 bracket_notation: true,
6716 use_list_keyword: false,
6717 },
6718 ));
6719 }
6720 }
6721 a.clone()
6722 })
6723 .collect::<Vec<_>>()
6724 } else {
6725 func_args
6726 };
6727
6728 if is_posexplode {
6730 self.write_keyword("LATERAL");
6731 self.write(" (");
6732 self.write_keyword("SELECT");
6733 self.write_space();
6734
6735 let pos_alias = if !lv.column_aliases.is_empty() {
6738 lv.column_aliases[0].clone()
6739 } else {
6740 Identifier::new("pos")
6741 };
6742 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6743 lv.column_aliases[1..].to_vec()
6744 } else {
6745 vec![Identifier::new("col")]
6746 };
6747
6748 self.generate_identifier(&pos_alias)?;
6750 self.write(" - 1");
6751 self.write_space();
6752 self.write_keyword("AS");
6753 self.write_space();
6754 self.generate_identifier(&pos_alias)?;
6755
6756 for data_col in &data_aliases {
6758 self.write(", ");
6759 self.generate_identifier(data_col)?;
6760 }
6761
6762 self.write_space();
6763 self.write_keyword("FROM");
6764 self.write_space();
6765 self.write_keyword("UNNEST");
6766 self.write("(");
6767 for (i, arg) in unnest_args.iter().enumerate() {
6768 if i > 0 {
6769 self.write(", ");
6770 }
6771 self.generate_expression(arg)?;
6772 }
6773 self.write(")");
6774 self.write_space();
6775 self.write_keyword("WITH ORDINALITY");
6776 self.write_space();
6777 self.write_keyword("AS");
6778 self.write_space();
6779
6780 let table_alias_ident = lv
6782 .table_alias
6783 .clone()
6784 .unwrap_or_else(|| Identifier::new("t"));
6785 self.generate_identifier(&table_alias_ident)?;
6786 self.write("(");
6787 for (i, data_col) in data_aliases.iter().enumerate() {
6788 if i > 0 {
6789 self.write(", ");
6790 }
6791 self.generate_identifier(data_col)?;
6792 }
6793 self.write(", ");
6794 self.generate_identifier(&pos_alias)?;
6795 self.write("))");
6796 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6797 self.write_keyword("LATERAL");
6799 self.write(" (");
6800 self.write_keyword("SELECT");
6801 self.write_space();
6802 self.write_keyword("UNNEST");
6803 self.write("(");
6804 for (i, arg) in unnest_args.iter().enumerate() {
6805 if i > 0 {
6806 self.write(", ");
6807 }
6808 self.generate_expression(arg)?;
6809 }
6810 self.write(", ");
6811 self.write_keyword("max_depth");
6812 self.write(" => 2))");
6813
6814 if let Some(alias) = &lv.table_alias {
6816 self.write_space();
6817 self.write_keyword("AS");
6818 self.write_space();
6819 self.generate_identifier(alias)?;
6820 if !lv.column_aliases.is_empty() {
6821 self.write("(");
6822 for (i, col) in lv.column_aliases.iter().enumerate() {
6823 if i > 0 {
6824 self.write(", ");
6825 }
6826 self.generate_identifier(col)?;
6827 }
6828 self.write(")");
6829 }
6830 } else if !lv.column_aliases.is_empty() {
6831 self.write_space();
6833 self.write_keyword("AS");
6834 self.write_space();
6835 self.write(&format!("_u_{}", lv_index));
6836 self.write("(");
6837 for (i, col) in lv.column_aliases.iter().enumerate() {
6838 if i > 0 {
6839 self.write(", ");
6840 }
6841 self.generate_identifier(col)?;
6842 }
6843 self.write(")");
6844 }
6845 } else {
6846 self.write_keyword("UNNEST");
6847 self.write("(");
6848 for (i, arg) in unnest_args.iter().enumerate() {
6849 if i > 0 {
6850 self.write(", ");
6851 }
6852 self.generate_expression(arg)?;
6853 }
6854 self.write(")");
6855
6856 if let Some(alias) = &lv.table_alias {
6858 self.write_space();
6859 self.write_keyword("AS");
6860 self.write_space();
6861 self.generate_identifier(alias)?;
6862 if !lv.column_aliases.is_empty() {
6863 self.write("(");
6864 for (i, col) in lv.column_aliases.iter().enumerate() {
6865 if i > 0 {
6866 self.write(", ");
6867 }
6868 self.generate_identifier(col)?;
6869 }
6870 self.write(")");
6871 }
6872 } else if !lv.column_aliases.is_empty() {
6873 self.write_space();
6874 self.write_keyword("AS");
6875 self.write(" t(");
6876 for (i, col) in lv.column_aliases.iter().enumerate() {
6877 if i > 0 {
6878 self.write(", ");
6879 }
6880 self.generate_identifier(col)?;
6881 }
6882 self.write(")");
6883 }
6884 }
6885 } else {
6886 if !lv.outer {
6888 self.write_keyword("LATERAL");
6889 self.write_space();
6890 }
6891 self.generate_expression(&lv.this)?;
6892
6893 if let Some(alias) = &lv.table_alias {
6895 self.write_space();
6896 self.write_keyword("AS");
6897 self.write_space();
6898 self.generate_identifier(alias)?;
6899 if !lv.column_aliases.is_empty() {
6900 self.write("(");
6901 for (i, col) in lv.column_aliases.iter().enumerate() {
6902 if i > 0 {
6903 self.write(", ");
6904 }
6905 self.generate_identifier(col)?;
6906 }
6907 self.write(")");
6908 }
6909 } else if !lv.column_aliases.is_empty() {
6910 self.write_space();
6911 self.write_keyword("AS");
6912 self.write(" t(");
6913 for (i, col) in lv.column_aliases.iter().enumerate() {
6914 if i > 0 {
6915 self.write(", ");
6916 }
6917 self.generate_identifier(col)?;
6918 }
6919 self.write(")");
6920 }
6921 }
6922
6923 if lv.outer {
6925 self.write_space();
6926 self.write_keyword("ON TRUE");
6927 }
6928 } else {
6929 self.write_keyword("LATERAL VIEW");
6931 if lv.outer {
6932 self.write_space();
6933 self.write_keyword("OUTER");
6934 }
6935 if self.config.pretty {
6936 self.write_newline();
6937 self.write_indent();
6938 } else {
6939 self.write_space();
6940 }
6941 self.generate_expression(&lv.this)?;
6942
6943 if let Some(alias) = &lv.table_alias {
6945 self.write_space();
6946 self.generate_identifier(alias)?;
6947 }
6948
6949 if !lv.column_aliases.is_empty() {
6951 self.write_space();
6952 self.write_keyword("AS");
6953 self.write_space();
6954 for (i, col) in lv.column_aliases.iter().enumerate() {
6955 if i > 0 {
6956 self.write(", ");
6957 }
6958 self.generate_identifier(col)?;
6959 }
6960 }
6961 }
6962
6963 Ok(())
6964 }
6965
6966 fn should_wrap_set_operation_modifiers(
6967 &self,
6968 order_by: &Option<OrderBy>,
6969 limit: &Option<Box<Expression>>,
6970 offset: &Option<Box<Expression>>,
6971 ) -> bool {
6972 let has_row_limit = limit.is_some() || offset.is_some();
6973 let has_emulated_null_ordering = order_by.as_ref().map_or(false, |order_by| {
6974 order_by
6975 .expressions
6976 .iter()
6977 .any(|ordered| ordered.nulls_first.is_some())
6978 });
6979
6980 (has_row_limit || has_emulated_null_ordering)
6981 && matches!(
6982 self.config.dialect,
6983 Some(DialectType::TSQL) | Some(DialectType::Fabric)
6984 )
6985 }
6986
6987 fn generate_tsql_wrapped_set_operation(
6988 &mut self,
6989 inner: Expression,
6990 with: Option<With>,
6991 order_by: Option<OrderBy>,
6992 limit: Option<Box<Expression>>,
6993 offset: Option<Box<Expression>>,
6994 ) -> Result<()> {
6995 let subquery = Subquery {
6996 this: inner,
6997 alias: Some(Identifier::new("_l_0".to_string())),
6998 column_aliases: Vec::new(),
6999 alias_explicit_as: true,
7000 alias_keyword: None,
7001 order_by: None,
7002 limit: None,
7003 offset: None,
7004 lateral: false,
7005 modifiers_inside: false,
7006 trailing_comments: Vec::new(),
7007 distribute_by: None,
7008 sort_by: None,
7009 cluster_by: None,
7010 inferred_type: None,
7011 };
7012
7013 let mut outer_select = Select {
7014 expressions: vec![Expression::Star(Star {
7015 table: None,
7016 except: None,
7017 replace: None,
7018 rename: None,
7019 trailing_comments: Vec::new(),
7020 span: None,
7021 })],
7022 from: Some(From {
7023 expressions: vec![Expression::Subquery(Box::new(subquery))],
7024 }),
7025 with,
7026 order_by,
7027 limit: limit.map(|limit| Limit {
7028 this: *limit,
7029 percent: false,
7030 comments: Vec::new(),
7031 }),
7032 offset: offset.map(|offset| Offset {
7033 this: *offset,
7034 rows: Some(true),
7035 }),
7036 ..Select::new()
7037 };
7038
7039 if outer_select.offset.is_some() && outer_select.order_by.is_none() {
7040 outer_select.order_by = Some(Self::dummy_tsql_order_by());
7041 }
7042
7043 self.generate_select(&outer_select)
7044 }
7045
7046 pub(crate) fn dummy_tsql_order_by() -> OrderBy {
7047 let null_select = Expression::Select(Box::new(Select {
7048 expressions: vec![Expression::Null(Null)],
7049 ..Select::new()
7050 }));
7051
7052 OrderBy {
7053 expressions: vec![Ordered {
7054 this: Expression::Subquery(Box::new(Subquery {
7055 this: null_select,
7056 alias: None,
7057 column_aliases: Vec::new(),
7058 alias_explicit_as: false,
7059 alias_keyword: None,
7060 order_by: None,
7061 limit: None,
7062 offset: None,
7063 lateral: false,
7064 modifiers_inside: false,
7065 trailing_comments: Vec::new(),
7066 distribute_by: None,
7067 sort_by: None,
7068 cluster_by: None,
7069 inferred_type: None,
7070 })),
7071 desc: false,
7072 nulls_first: None,
7073 explicit_asc: false,
7074 with_fill: None,
7075 }],
7076 siblings: false,
7077 comments: Vec::new(),
7078 }
7079 }
7080
7081 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
7082 if self.should_wrap_set_operation_modifiers(
7083 &outermost.order_by,
7084 &outermost.limit,
7085 &outermost.offset,
7086 ) {
7087 let mut inner = outermost.clone();
7088 let with = inner.with.take();
7089 let order_by = inner.order_by.take();
7090 let limit = inner.limit.take();
7091 let offset = inner.offset.take();
7092
7093 return self.generate_tsql_wrapped_set_operation(
7094 Expression::Union(Box::new(inner)),
7095 with,
7096 order_by,
7097 limit,
7098 offset,
7099 );
7100 }
7101
7102 let mut chain: Vec<&Union> = vec![outermost];
7107 let mut leftmost: &Expression = &outermost.left;
7108 while let Expression::Union(inner) = leftmost {
7109 chain.push(inner);
7110 leftmost = &inner.left;
7111 }
7112 if let Some(with) = &outermost.with {
7117 self.generate_with(with)?;
7118 self.write_space();
7119 }
7120
7121 self.generate_expression(leftmost)?;
7123
7124 for union in chain.iter().rev() {
7126 self.generate_union_step(union)?;
7127 }
7128 Ok(())
7129 }
7130
7131 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
7133 if self.config.pretty {
7134 self.write_newline();
7135 self.write_indent();
7136 } else {
7137 self.write_space();
7138 }
7139
7140 if let Some(side) = &union.side {
7142 self.write_keyword(side);
7143 self.write_space();
7144 }
7145 if let Some(kind) = &union.kind {
7146 self.write_keyword(kind);
7147 self.write_space();
7148 }
7149
7150 self.write_keyword("UNION");
7151 if union.all {
7152 self.write_space();
7153 self.write_keyword("ALL");
7154 } else if union.distinct {
7155 self.write_space();
7156 self.write_keyword("DISTINCT");
7157 }
7158
7159 if union.corresponding || union.by_name {
7162 self.write_space();
7163 self.write_keyword("BY NAME");
7164 }
7165 if !union.on_columns.is_empty() {
7166 self.write_space();
7167 self.write_keyword("ON");
7168 self.write(" (");
7169 for (i, col) in union.on_columns.iter().enumerate() {
7170 if i > 0 {
7171 self.write(", ");
7172 }
7173 self.generate_expression(col)?;
7174 }
7175 self.write(")");
7176 }
7177
7178 if self.config.pretty {
7179 self.write_newline();
7180 self.write_indent();
7181 } else {
7182 self.write_space();
7183 }
7184 self.generate_expression(&union.right)?;
7185 if let Some(order_by) = &union.order_by {
7187 if self.config.pretty {
7188 self.write_newline();
7189 } else {
7190 self.write_space();
7191 }
7192 self.write_keyword("ORDER BY");
7193 self.write_space();
7194 for (i, ordered) in order_by.expressions.iter().enumerate() {
7195 if i > 0 {
7196 self.write(", ");
7197 }
7198 self.generate_ordered(ordered)?;
7199 }
7200 }
7201 if let Some(limit) = &union.limit {
7202 if self.config.pretty {
7203 self.write_newline();
7204 } else {
7205 self.write_space();
7206 }
7207 self.write_keyword("LIMIT");
7208 self.write_space();
7209 self.generate_expression(limit)?;
7210 }
7211 if let Some(offset) = &union.offset {
7212 if self.config.pretty {
7213 self.write_newline();
7214 } else {
7215 self.write_space();
7216 }
7217 self.write_keyword("OFFSET");
7218 self.write_space();
7219 self.generate_expression(offset)?;
7220 }
7221 if let Some(distribute_by) = &union.distribute_by {
7223 self.write_space();
7224 self.write_keyword("DISTRIBUTE BY");
7225 self.write_space();
7226 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7227 if i > 0 {
7228 self.write(", ");
7229 }
7230 self.generate_expression(expr)?;
7231 }
7232 }
7233 if let Some(sort_by) = &union.sort_by {
7235 self.write_space();
7236 self.write_keyword("SORT BY");
7237 self.write_space();
7238 for (i, ord) in sort_by.expressions.iter().enumerate() {
7239 if i > 0 {
7240 self.write(", ");
7241 }
7242 self.generate_ordered(ord)?;
7243 }
7244 }
7245 if let Some(cluster_by) = &union.cluster_by {
7247 self.write_space();
7248 self.write_keyword("CLUSTER BY");
7249 self.write_space();
7250 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7251 if i > 0 {
7252 self.write(", ");
7253 }
7254 self.generate_ordered(ord)?;
7255 }
7256 }
7257 Ok(())
7258 }
7259
7260 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
7261 if self.should_wrap_set_operation_modifiers(
7262 &outermost.order_by,
7263 &outermost.limit,
7264 &outermost.offset,
7265 ) {
7266 let mut inner = outermost.clone();
7267 let with = inner.with.take();
7268 let order_by = inner.order_by.take();
7269 let limit = inner.limit.take();
7270 let offset = inner.offset.take();
7271
7272 return self.generate_tsql_wrapped_set_operation(
7273 Expression::Intersect(Box::new(inner)),
7274 with,
7275 order_by,
7276 limit,
7277 offset,
7278 );
7279 }
7280
7281 let mut chain: Vec<&Intersect> = vec![outermost];
7283 let mut leftmost: &Expression = &outermost.left;
7284 while let Expression::Intersect(inner) = leftmost {
7285 chain.push(inner);
7286 leftmost = &inner.left;
7287 }
7288
7289 if let Some(with) = &outermost.with {
7290 self.generate_with(with)?;
7291 self.write_space();
7292 }
7293
7294 self.generate_expression(leftmost)?;
7295
7296 for intersect in chain.iter().rev() {
7297 self.generate_intersect_step(intersect)?;
7298 }
7299 Ok(())
7300 }
7301
7302 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
7304 if self.config.pretty {
7305 self.write_newline();
7306 self.write_indent();
7307 } else {
7308 self.write_space();
7309 }
7310
7311 if let Some(side) = &intersect.side {
7313 self.write_keyword(side);
7314 self.write_space();
7315 }
7316 if let Some(kind) = &intersect.kind {
7317 self.write_keyword(kind);
7318 self.write_space();
7319 }
7320
7321 self.write_keyword("INTERSECT");
7322 if intersect.all {
7323 if !self.config.except_intersect_support_all_clause {
7324 self.unsupported("INTERSECT ALL is not supported")?;
7325 }
7326 self.write_space();
7327 self.write_keyword("ALL");
7328 } else if intersect.distinct {
7329 self.write_space();
7330 self.write_keyword("DISTINCT");
7331 }
7332
7333 if intersect.corresponding || intersect.by_name {
7336 self.write_space();
7337 self.write_keyword("BY NAME");
7338 }
7339 if !intersect.on_columns.is_empty() {
7340 self.write_space();
7341 self.write_keyword("ON");
7342 self.write(" (");
7343 for (i, col) in intersect.on_columns.iter().enumerate() {
7344 if i > 0 {
7345 self.write(", ");
7346 }
7347 self.generate_expression(col)?;
7348 }
7349 self.write(")");
7350 }
7351
7352 if self.config.pretty {
7353 self.write_newline();
7354 self.write_indent();
7355 } else {
7356 self.write_space();
7357 }
7358 self.generate_expression(&intersect.right)?;
7359 if let Some(order_by) = &intersect.order_by {
7361 if self.config.pretty {
7362 self.write_newline();
7363 } else {
7364 self.write_space();
7365 }
7366 self.write_keyword("ORDER BY");
7367 self.write_space();
7368 for (i, ordered) in order_by.expressions.iter().enumerate() {
7369 if i > 0 {
7370 self.write(", ");
7371 }
7372 self.generate_ordered(ordered)?;
7373 }
7374 }
7375 if let Some(limit) = &intersect.limit {
7376 if self.config.pretty {
7377 self.write_newline();
7378 } else {
7379 self.write_space();
7380 }
7381 self.write_keyword("LIMIT");
7382 self.write_space();
7383 self.generate_expression(limit)?;
7384 }
7385 if let Some(offset) = &intersect.offset {
7386 if self.config.pretty {
7387 self.write_newline();
7388 } else {
7389 self.write_space();
7390 }
7391 self.write_keyword("OFFSET");
7392 self.write_space();
7393 self.generate_expression(offset)?;
7394 }
7395 if let Some(distribute_by) = &intersect.distribute_by {
7397 self.write_space();
7398 self.write_keyword("DISTRIBUTE BY");
7399 self.write_space();
7400 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7401 if i > 0 {
7402 self.write(", ");
7403 }
7404 self.generate_expression(expr)?;
7405 }
7406 }
7407 if let Some(sort_by) = &intersect.sort_by {
7409 self.write_space();
7410 self.write_keyword("SORT BY");
7411 self.write_space();
7412 for (i, ord) in sort_by.expressions.iter().enumerate() {
7413 if i > 0 {
7414 self.write(", ");
7415 }
7416 self.generate_ordered(ord)?;
7417 }
7418 }
7419 if let Some(cluster_by) = &intersect.cluster_by {
7421 self.write_space();
7422 self.write_keyword("CLUSTER BY");
7423 self.write_space();
7424 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7425 if i > 0 {
7426 self.write(", ");
7427 }
7428 self.generate_ordered(ord)?;
7429 }
7430 }
7431 Ok(())
7432 }
7433
7434 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
7435 if self.should_wrap_set_operation_modifiers(
7436 &outermost.order_by,
7437 &outermost.limit,
7438 &outermost.offset,
7439 ) {
7440 let mut inner = outermost.clone();
7441 let with = inner.with.take();
7442 let order_by = inner.order_by.take();
7443 let limit = inner.limit.take();
7444 let offset = inner.offset.take();
7445
7446 return self.generate_tsql_wrapped_set_operation(
7447 Expression::Except(Box::new(inner)),
7448 with,
7449 order_by,
7450 limit,
7451 offset,
7452 );
7453 }
7454
7455 let mut chain: Vec<&Except> = vec![outermost];
7457 let mut leftmost: &Expression = &outermost.left;
7458 while let Expression::Except(inner) = leftmost {
7459 chain.push(inner);
7460 leftmost = &inner.left;
7461 }
7462
7463 if let Some(with) = &outermost.with {
7464 self.generate_with(with)?;
7465 self.write_space();
7466 }
7467
7468 self.generate_expression(leftmost)?;
7469
7470 for except in chain.iter().rev() {
7471 self.generate_except_step(except)?;
7472 }
7473 Ok(())
7474 }
7475
7476 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
7478 use crate::dialects::DialectType;
7479
7480 if self.config.pretty {
7481 self.write_newline();
7482 self.write_indent();
7483 } else {
7484 self.write_space();
7485 }
7486
7487 if let Some(side) = &except.side {
7489 self.write_keyword(side);
7490 self.write_space();
7491 }
7492 if let Some(kind) = &except.kind {
7493 self.write_keyword(kind);
7494 self.write_space();
7495 }
7496
7497 match self.config.dialect {
7499 Some(DialectType::Oracle) if !except.all => {
7500 self.write_keyword("MINUS");
7501 }
7502 Some(DialectType::ClickHouse) => {
7503 self.write_keyword("EXCEPT");
7504 let preserve_all = self.config.source_dialect.is_none()
7505 || matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
7506 if except.all && preserve_all {
7507 self.write_space();
7508 self.write_keyword("ALL");
7509 }
7510 if except.distinct {
7511 self.write_space();
7512 self.write_keyword("DISTINCT");
7513 }
7514 }
7515 Some(DialectType::BigQuery) => {
7516 self.write_keyword("EXCEPT");
7518 if except.all {
7519 self.write_space();
7520 self.write_keyword("ALL");
7521 } else {
7522 self.write_space();
7523 self.write_keyword("DISTINCT");
7524 }
7525 }
7526 _ => {
7527 self.write_keyword("EXCEPT");
7528 if except.all {
7529 if !self.config.except_intersect_support_all_clause {
7530 self.unsupported("EXCEPT ALL is not supported")?;
7531 }
7532 self.write_space();
7533 self.write_keyword("ALL");
7534 } else if except.distinct {
7535 self.write_space();
7536 self.write_keyword("DISTINCT");
7537 }
7538 }
7539 }
7540
7541 if except.corresponding || except.by_name {
7544 self.write_space();
7545 self.write_keyword("BY NAME");
7546 }
7547 if !except.on_columns.is_empty() {
7548 self.write_space();
7549 self.write_keyword("ON");
7550 self.write(" (");
7551 for (i, col) in except.on_columns.iter().enumerate() {
7552 if i > 0 {
7553 self.write(", ");
7554 }
7555 self.generate_expression(col)?;
7556 }
7557 self.write(")");
7558 }
7559
7560 if self.config.pretty {
7561 self.write_newline();
7562 self.write_indent();
7563 } else {
7564 self.write_space();
7565 }
7566 self.generate_expression(&except.right)?;
7567 if let Some(order_by) = &except.order_by {
7569 if self.config.pretty {
7570 self.write_newline();
7571 } else {
7572 self.write_space();
7573 }
7574 self.write_keyword("ORDER BY");
7575 self.write_space();
7576 for (i, ordered) in order_by.expressions.iter().enumerate() {
7577 if i > 0 {
7578 self.write(", ");
7579 }
7580 self.generate_ordered(ordered)?;
7581 }
7582 }
7583 if let Some(limit) = &except.limit {
7584 if self.config.pretty {
7585 self.write_newline();
7586 } else {
7587 self.write_space();
7588 }
7589 self.write_keyword("LIMIT");
7590 self.write_space();
7591 self.generate_expression(limit)?;
7592 }
7593 if let Some(offset) = &except.offset {
7594 if self.config.pretty {
7595 self.write_newline();
7596 } else {
7597 self.write_space();
7598 }
7599 self.write_keyword("OFFSET");
7600 self.write_space();
7601 self.generate_expression(offset)?;
7602 }
7603 if let Some(distribute_by) = &except.distribute_by {
7605 self.write_space();
7606 self.write_keyword("DISTRIBUTE BY");
7607 self.write_space();
7608 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7609 if i > 0 {
7610 self.write(", ");
7611 }
7612 self.generate_expression(expr)?;
7613 }
7614 }
7615 if let Some(sort_by) = &except.sort_by {
7617 self.write_space();
7618 self.write_keyword("SORT BY");
7619 self.write_space();
7620 for (i, ord) in sort_by.expressions.iter().enumerate() {
7621 if i > 0 {
7622 self.write(", ");
7623 }
7624 self.generate_ordered(ord)?;
7625 }
7626 }
7627 if let Some(cluster_by) = &except.cluster_by {
7629 self.write_space();
7630 self.write_keyword("CLUSTER BY");
7631 self.write_space();
7632 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7633 if i > 0 {
7634 self.write(", ");
7635 }
7636 self.generate_ordered(ord)?;
7637 }
7638 }
7639 Ok(())
7640 }
7641
7642 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
7643 let prepend_query_cte = if insert.with.is_none() {
7645 use crate::dialects::DialectType;
7646 let should_prepend = matches!(
7647 self.config.dialect,
7648 Some(DialectType::TSQL)
7649 | Some(DialectType::Fabric)
7650 | Some(DialectType::Spark)
7651 | Some(DialectType::Databricks)
7652 | Some(DialectType::Hive)
7653 );
7654 if should_prepend {
7655 if let Some(Expression::Select(select)) = &insert.query {
7656 select.with.clone()
7657 } else {
7658 None
7659 }
7660 } else {
7661 None
7662 }
7663 } else {
7664 None
7665 };
7666
7667 if let Some(with) = &insert.with {
7669 self.generate_with(with)?;
7670 self.write_space();
7671 } else if let Some(with) = &prepend_query_cte {
7672 self.generate_with(with)?;
7673 self.write_space();
7674 }
7675
7676 for comment in &insert.leading_comments {
7678 self.write_formatted_comment(comment);
7679 self.write(" ");
7680 }
7681
7682 if let Some(dir) = &insert.directory {
7684 self.write_keyword("INSERT OVERWRITE");
7685 if dir.local {
7686 self.write_space();
7687 self.write_keyword("LOCAL");
7688 }
7689 self.write_space();
7690 self.write_keyword("DIRECTORY");
7691 self.write_space();
7692 self.write("'");
7693 self.write(&dir.path);
7694 self.write("'");
7695
7696 if let Some(row_format) = &dir.row_format {
7698 self.write_space();
7699 self.write_keyword("ROW FORMAT");
7700 if row_format.delimited {
7701 self.write_space();
7702 self.write_keyword("DELIMITED");
7703 }
7704 if let Some(val) = &row_format.fields_terminated_by {
7705 self.write_space();
7706 self.write_keyword("FIELDS TERMINATED BY");
7707 self.write_space();
7708 self.generate_string_literal(val)?;
7709 }
7710 if let Some(val) = &row_format.collection_items_terminated_by {
7711 self.write_space();
7712 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
7713 self.write_space();
7714 self.write("'");
7715 self.write(val);
7716 self.write("'");
7717 }
7718 if let Some(val) = &row_format.map_keys_terminated_by {
7719 self.write_space();
7720 self.write_keyword("MAP KEYS TERMINATED BY");
7721 self.write_space();
7722 self.write("'");
7723 self.write(val);
7724 self.write("'");
7725 }
7726 if let Some(val) = &row_format.lines_terminated_by {
7727 self.write_space();
7728 self.write_keyword("LINES TERMINATED BY");
7729 self.write_space();
7730 self.write("'");
7731 self.write(val);
7732 self.write("'");
7733 }
7734 if let Some(val) = &row_format.null_defined_as {
7735 self.write_space();
7736 self.write_keyword("NULL DEFINED AS");
7737 self.write_space();
7738 self.write("'");
7739 self.write(val);
7740 self.write("'");
7741 }
7742 }
7743
7744 if let Some(format) = &dir.stored_as {
7746 self.write_space();
7747 self.write_keyword("STORED AS");
7748 self.write_space();
7749 self.write_keyword(format);
7750 }
7751
7752 if let Some(query) = &insert.query {
7754 self.write_space();
7755 self.generate_expression(query)?;
7756 }
7757
7758 return Ok(());
7759 }
7760
7761 if insert.is_replace {
7762 self.write_keyword("REPLACE INTO");
7764 } else if insert.overwrite {
7765 self.write_keyword("INSERT");
7767 if let Some(ref hint) = insert.hint {
7769 self.generate_hint(hint)?;
7770 }
7771 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
7772 } else if let Some(ref action) = insert.conflict_action {
7773 self.write_keyword("INSERT OR");
7775 self.write_space();
7776 self.write_keyword(action);
7777 self.write_space();
7778 self.write_keyword("INTO");
7779 } else if insert.ignore {
7780 self.write_keyword("INSERT IGNORE INTO");
7782 } else {
7783 self.write_keyword("INSERT");
7784 if let Some(ref hint) = insert.hint {
7786 self.generate_hint(hint)?;
7787 }
7788 self.write_space();
7789 self.write_keyword("INTO");
7790 }
7791 if let Some(ref func) = insert.function_target {
7793 self.write_space();
7794 self.write_keyword("FUNCTION");
7795 self.write_space();
7796 self.generate_expression(func)?;
7797 } else {
7798 self.write_space();
7799 self.generate_table(&insert.table)?;
7800 }
7801
7802 if let Some(ref alias) = insert.alias {
7804 self.write_space();
7805 if insert.alias_explicit_as {
7806 self.write_keyword("AS");
7807 self.write_space();
7808 }
7809 self.generate_identifier(alias)?;
7810 }
7811
7812 if insert.if_exists {
7814 self.write_space();
7815 self.write_keyword("IF EXISTS");
7816 }
7817
7818 if let Some(ref replace_where) = insert.replace_where {
7820 if self.config.pretty {
7821 self.write_newline();
7822 self.write_indent();
7823 } else {
7824 self.write_space();
7825 }
7826 self.write_keyword("REPLACE WHERE");
7827 self.write_space();
7828 self.generate_expression(replace_where)?;
7829 }
7830
7831 if !insert.partition.is_empty() {
7833 self.write_space();
7834 self.write_keyword("PARTITION");
7835 self.write("(");
7836 for (i, (col, val)) in insert.partition.iter().enumerate() {
7837 if i > 0 {
7838 self.write(", ");
7839 }
7840 self.generate_identifier(col)?;
7841 if let Some(v) = val {
7842 self.write(" = ");
7843 self.generate_expression(v)?;
7844 }
7845 }
7846 self.write(")");
7847 }
7848
7849 if let Some(ref partition_by) = insert.partition_by {
7851 self.write_space();
7852 self.write_keyword("PARTITION BY");
7853 self.write_space();
7854 self.generate_expression(partition_by)?;
7855 }
7856
7857 if !insert.settings.is_empty() {
7859 self.write_space();
7860 self.write_keyword("SETTINGS");
7861 self.write_space();
7862 for (i, setting) in insert.settings.iter().enumerate() {
7863 if i > 0 {
7864 self.write(", ");
7865 }
7866 self.generate_expression(setting)?;
7867 }
7868 }
7869
7870 if !insert.columns.is_empty() {
7871 if insert.alias.is_some() && insert.alias_explicit_as {
7872 self.write("(");
7874 } else {
7875 self.write(" (");
7877 }
7878 for (i, col) in insert.columns.iter().enumerate() {
7879 if i > 0 {
7880 self.write(", ");
7881 }
7882 self.generate_identifier(col)?;
7883 }
7884 self.write(")");
7885 }
7886
7887 if let Some(ref output) = insert.output {
7889 self.generate_output_clause(output)?;
7890 }
7891
7892 if insert.by_name {
7894 self.write_space();
7895 self.write_keyword("BY NAME");
7896 }
7897
7898 if insert.default_values {
7899 self.write_space();
7900 self.write_keyword("DEFAULT VALUES");
7901 } else if let Some(query) = &insert.query {
7902 if self.config.pretty {
7903 self.write_newline();
7904 } else {
7905 self.write_space();
7906 }
7907 if prepend_query_cte.is_some() {
7909 if let Expression::Select(select) = query {
7910 let mut select_no_with = select.clone();
7911 select_no_with.with = None;
7912 self.generate_select(&select_no_with)?;
7913 } else {
7914 self.generate_expression(query)?;
7915 }
7916 } else {
7917 self.generate_expression(query)?;
7918 }
7919 } else if !insert.values.is_empty() {
7920 if self.config.pretty {
7921 self.write_newline();
7923 self.write_keyword("VALUES");
7924 self.write_newline();
7925 self.indent_level += 1;
7926 for (i, row) in insert.values.iter().enumerate() {
7927 if i > 0 {
7928 self.write(",");
7929 self.write_newline();
7930 }
7931 self.write_indent();
7932 self.write("(");
7933 for (j, val) in row.iter().enumerate() {
7934 if j > 0 {
7935 self.write(", ");
7936 }
7937 self.generate_expression(val)?;
7938 }
7939 self.write(")");
7940 }
7941 self.indent_level -= 1;
7942 } else {
7943 self.write_space();
7945 self.write_keyword("VALUES");
7946 for (i, row) in insert.values.iter().enumerate() {
7947 if i > 0 {
7948 self.write(",");
7949 }
7950 self.write(" (");
7951 for (j, val) in row.iter().enumerate() {
7952 if j > 0 {
7953 self.write(", ");
7954 }
7955 self.generate_expression(val)?;
7956 }
7957 self.write(")");
7958 }
7959 }
7960 }
7961
7962 if let Some(ref source) = insert.source {
7964 self.write_space();
7965 self.write_keyword("TABLE");
7966 self.write_space();
7967 self.generate_expression(source)?;
7968 }
7969
7970 if let Some(alias) = &insert.source_alias {
7972 self.write_space();
7973 self.write_keyword("AS");
7974 self.write_space();
7975 self.generate_identifier(alias)?;
7976 }
7977
7978 if let Some(on_conflict) = &insert.on_conflict {
7980 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7981 self.write_space();
7982 self.generate_expression(on_conflict)?;
7983 }
7984 }
7985
7986 if !insert.returning.is_empty() {
7988 self.write_space();
7989 self.write_keyword("RETURNING");
7990 self.write_space();
7991 for (i, expr) in insert.returning.iter().enumerate() {
7992 if i > 0 {
7993 self.write(", ");
7994 }
7995 self.generate_expression(expr)?;
7996 }
7997 }
7998
7999 Ok(())
8000 }
8001
8002 fn generate_update(&mut self, update: &Update) -> Result<()> {
8003 for comment in &update.leading_comments {
8005 self.write_formatted_comment(comment);
8006 self.write(" ");
8007 }
8008
8009 if let Some(ref with) = update.with {
8011 self.generate_with(with)?;
8012 self.write_space();
8013 }
8014
8015 self.write_keyword("UPDATE");
8016 if let Some(hint) = &update.hint {
8017 self.generate_hint(hint)?;
8018 }
8019 self.write_space();
8020 self.generate_table(&update.table)?;
8021
8022 let mysql_like_update_from = matches!(
8023 self.config.dialect,
8024 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
8025 ) && update.from_clause.is_some();
8026
8027 let mut set_pairs = update.set.clone();
8028
8029 let mut pre_set_joins = update.table_joins.clone();
8031 if mysql_like_update_from {
8032 let target_name = update
8033 .table
8034 .alias
8035 .as_ref()
8036 .map(|a| a.name.clone())
8037 .unwrap_or_else(|| update.table.name.name.clone());
8038
8039 for (col, _) in &mut set_pairs {
8040 if !col.name.contains('.') {
8041 col.name = format!("{}.{}", target_name, col.name);
8042 }
8043 }
8044
8045 if let Some(from_clause) = &update.from_clause {
8046 for table_expr in &from_clause.expressions {
8047 pre_set_joins.push(crate::expressions::Join {
8048 this: table_expr.clone(),
8049 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
8050 value: true,
8051 })),
8052 using: Vec::new(),
8053 kind: crate::expressions::JoinKind::Inner,
8054 use_inner_keyword: false,
8055 use_outer_keyword: false,
8056 deferred_condition: false,
8057 join_hint: None,
8058 match_condition: None,
8059 pivots: Vec::new(),
8060 comments: Vec::new(),
8061 nesting_group: 0,
8062 directed: false,
8063 });
8064 }
8065 }
8066 for join in &update.from_joins {
8067 let mut join = join.clone();
8068 if join.on.is_none() && join.using.is_empty() {
8069 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
8070 value: true,
8071 }));
8072 }
8073 pre_set_joins.push(join);
8074 }
8075 }
8076
8077 for extra_table in &update.extra_tables {
8079 self.write(", ");
8080 self.generate_table(extra_table)?;
8081 }
8082
8083 for join in &pre_set_joins {
8085 self.generate_join(join)?;
8087 }
8088
8089 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
8091 if teradata_from_before_set && !mysql_like_update_from {
8092 if let Some(ref from_clause) = update.from_clause {
8093 self.write_space();
8094 self.write_keyword("FROM");
8095 self.write_space();
8096 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
8097 if i > 0 {
8098 self.write(", ");
8099 }
8100 self.generate_expression(table_expr)?;
8101 }
8102 }
8103 for join in &update.from_joins {
8104 self.generate_join(join)?;
8105 }
8106 }
8107
8108 self.write_space();
8109 self.write_keyword("SET");
8110 self.write_space();
8111
8112 for (i, (col, val)) in set_pairs.iter().enumerate() {
8113 if i > 0 {
8114 self.write(", ");
8115 }
8116 self.generate_identifier(col)?;
8117 self.write(" = ");
8118 self.generate_expression(val)?;
8119 }
8120
8121 if let Some(ref output) = update.output {
8123 self.generate_output_clause(output)?;
8124 }
8125
8126 if !mysql_like_update_from && !teradata_from_before_set {
8128 if let Some(ref from_clause) = update.from_clause {
8129 self.write_space();
8130 self.write_keyword("FROM");
8131 self.write_space();
8132 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
8134 if i > 0 {
8135 self.write(", ");
8136 }
8137 self.generate_expression(table_expr)?;
8138 }
8139 }
8140 }
8141
8142 if !mysql_like_update_from && !teradata_from_before_set {
8143 for join in &update.from_joins {
8145 self.generate_join(join)?;
8146 }
8147 }
8148
8149 if let Some(where_clause) = &update.where_clause {
8150 self.write_space();
8151 self.write_keyword("WHERE");
8152 self.write_space();
8153 self.generate_expression(&where_clause.this)?;
8154 }
8155
8156 if !update.returning.is_empty() {
8158 self.write_space();
8159 self.write_keyword("RETURNING");
8160 self.write_space();
8161 for (i, expr) in update.returning.iter().enumerate() {
8162 if i > 0 {
8163 self.write(", ");
8164 }
8165 self.generate_expression(expr)?;
8166 }
8167 }
8168
8169 if let Some(ref order_by) = update.order_by {
8171 self.write_space();
8172 self.generate_order_by(order_by)?;
8173 }
8174
8175 if let Some(ref limit) = update.limit {
8177 self.write_space();
8178 self.write_keyword("LIMIT");
8179 self.write_space();
8180 self.generate_expression(limit)?;
8181 }
8182
8183 Ok(())
8184 }
8185
8186 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
8187 if let Some(with) = &delete.with {
8189 self.generate_with(with)?;
8190 self.write_space();
8191 }
8192
8193 for comment in &delete.leading_comments {
8195 self.write_formatted_comment(comment);
8196 self.write(" ");
8197 }
8198
8199 if !delete.tables.is_empty() && !delete.tables_from_using {
8201 self.write_keyword("DELETE");
8203 if let Some(hint) = &delete.hint {
8204 self.generate_hint(hint)?;
8205 }
8206 self.write_space();
8207 for (i, tbl) in delete.tables.iter().enumerate() {
8208 if i > 0 {
8209 self.write(", ");
8210 }
8211 self.generate_table(tbl)?;
8212 }
8213 if let Some(ref output) = delete.output {
8215 self.generate_output_clause(output)?;
8216 }
8217 self.write_space();
8218 self.write_keyword("FROM");
8219 self.write_space();
8220 self.generate_table(&delete.table)?;
8221 } else if !delete.tables.is_empty() && delete.tables_from_using {
8222 self.write_keyword("DELETE");
8224 if let Some(hint) = &delete.hint {
8225 self.generate_hint(hint)?;
8226 }
8227 self.write_space();
8228 self.write_keyword("FROM");
8229 self.write_space();
8230 for (i, tbl) in delete.tables.iter().enumerate() {
8231 if i > 0 {
8232 self.write(", ");
8233 }
8234 self.generate_table(tbl)?;
8235 }
8236 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
8237 self.write_keyword("DELETE");
8239 if let Some(hint) = &delete.hint {
8240 self.generate_hint(hint)?;
8241 }
8242 self.write_space();
8243 self.generate_table(&delete.table)?;
8244 } else {
8245 self.write_keyword("DELETE");
8246 if let Some(hint) = &delete.hint {
8247 self.generate_hint(hint)?;
8248 }
8249 self.write_space();
8250 self.write_keyword("FROM");
8251 self.write_space();
8252 self.generate_table(&delete.table)?;
8253 }
8254
8255 if let Some(ref on_cluster) = delete.on_cluster {
8257 self.write_space();
8258 self.generate_on_cluster(on_cluster)?;
8259 }
8260
8261 if let Some(ref idx) = delete.force_index {
8263 self.write_space();
8264 self.write_keyword("FORCE INDEX");
8265 self.write(" (");
8266 self.write(idx);
8267 self.write(")");
8268 }
8269
8270 if let Some(ref alias) = delete.alias {
8272 self.write_space();
8273 if delete.alias_explicit_as
8274 || matches!(self.config.dialect, Some(DialectType::BigQuery))
8275 {
8276 self.write_keyword("AS");
8277 self.write_space();
8278 }
8279 self.generate_identifier(alias)?;
8280 }
8281
8282 if !delete.tables_from_using {
8284 for join in &delete.joins {
8285 self.generate_join(join)?;
8286 }
8287 }
8288
8289 if !delete.using.is_empty() {
8291 self.write_space();
8292 self.write_keyword("USING");
8293 for (i, table) in delete.using.iter().enumerate() {
8294 if i > 0 {
8295 self.write(",");
8296 }
8297 self.write_space();
8298 if !table.hints.is_empty() && table.name.is_empty() {
8300 self.generate_expression(&table.hints[0])?;
8302 if let Some(ref alias) = table.alias {
8303 self.write_space();
8304 if table.alias_explicit_as {
8305 self.write_keyword("AS");
8306 self.write_space();
8307 }
8308 self.generate_identifier(alias)?;
8309 if !table.column_aliases.is_empty() {
8310 self.write("(");
8311 for (j, col_alias) in table.column_aliases.iter().enumerate() {
8312 if j > 0 {
8313 self.write(", ");
8314 }
8315 self.generate_identifier(col_alias)?;
8316 }
8317 self.write(")");
8318 }
8319 }
8320 } else {
8321 self.generate_table(table)?;
8322 }
8323 }
8324 }
8325
8326 if delete.tables_from_using {
8328 for join in &delete.joins {
8329 self.generate_join(join)?;
8330 }
8331 }
8332
8333 let output_already_emitted =
8335 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
8336 if !output_already_emitted {
8337 if let Some(ref output) = delete.output {
8338 self.generate_output_clause(output)?;
8339 }
8340 }
8341
8342 if let Some(where_clause) = &delete.where_clause {
8343 self.write_space();
8344 self.write_keyword("WHERE");
8345 self.write_space();
8346 self.generate_expression(&where_clause.this)?;
8347 }
8348
8349 if let Some(ref order_by) = delete.order_by {
8351 self.write_space();
8352 self.generate_order_by(order_by)?;
8353 }
8354
8355 if let Some(ref limit) = delete.limit {
8357 self.write_space();
8358 self.write_keyword("LIMIT");
8359 self.write_space();
8360 self.generate_expression(limit)?;
8361 }
8362
8363 if !delete.returning.is_empty() {
8365 self.write_space();
8366 self.write_keyword("RETURNING");
8367 self.write_space();
8368 for (i, expr) in delete.returning.iter().enumerate() {
8369 if i > 0 {
8370 self.write(", ");
8371 }
8372 self.generate_expression(expr)?;
8373 }
8374 }
8375
8376 Ok(())
8377 }
8378
8379 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
8382 let saved_athena_hive_context = self.athena_hive_context;
8386 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
8387 if matches!(
8388 self.config.dialect,
8389 Some(crate::dialects::DialectType::Athena)
8390 ) {
8391 let is_external = ct
8395 .table_modifier
8396 .as_ref()
8397 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
8398 .unwrap_or(false);
8399 let has_as_select = ct.as_select.is_some();
8400 self.athena_hive_context = is_external || !has_as_select;
8401 }
8402
8403 if matches!(
8405 self.config.dialect,
8406 Some(crate::dialects::DialectType::TSQL)
8407 ) {
8408 if let Some(ref query) = ct.as_select {
8409 if let Some(with_cte) = &ct.with_cte {
8411 self.generate_with(with_cte)?;
8412 self.write_space();
8413 }
8414
8415 self.write_keyword("SELECT");
8417 self.write(" * ");
8418 self.write_keyword("INTO");
8419 self.write_space();
8420
8421 if ct.temporary {
8423 self.write("#");
8424 }
8425 self.generate_table(&ct.name)?;
8426
8427 self.write_space();
8428 self.write_keyword("FROM");
8429 self.write(" (");
8430 let aliased_query = Self::add_column_aliases_to_query(query.clone());
8432 self.generate_expression(&aliased_query)?;
8433 self.write(") ");
8434 self.write_keyword("AS");
8435 self.write(" temp");
8436 return Ok(());
8437 }
8438 }
8439
8440 if let Some(with_cte) = &ct.with_cte {
8442 self.generate_with(with_cte)?;
8443 self.write_space();
8444 }
8445
8446 for comment in &ct.leading_comments {
8448 self.write_formatted_comment(comment);
8449 self.write(" ");
8450 }
8451 self.write_keyword("CREATE");
8452
8453 if ct.or_replace {
8454 self.write_space();
8455 self.write_keyword("OR REPLACE");
8456 }
8457
8458 if ct.temporary {
8459 self.write_space();
8460 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
8462 self.write_keyword("GLOBAL TEMPORARY");
8463 } else {
8464 self.write_keyword("TEMPORARY");
8465 }
8466 }
8467
8468 let is_dictionary = ct
8470 .table_modifier
8471 .as_ref()
8472 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
8473 .unwrap_or(false);
8474 if let Some(ref modifier) = ct.table_modifier {
8475 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
8477 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
8478 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
8480 || modifier.eq_ignore_ascii_case("SET")
8481 || modifier.eq_ignore_ascii_case("MULTISET")
8482 || modifier.to_ascii_uppercase().contains("VOLATILE")
8483 || modifier.to_ascii_uppercase().starts_with("SET ")
8484 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
8485 let skip_teradata =
8486 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
8487 if !skip_transient && !skip_teradata {
8488 self.write_space();
8489 self.write_keyword(modifier);
8490 }
8491 }
8492
8493 if !is_dictionary {
8494 self.write_space();
8495 self.write_keyword("TABLE");
8496 }
8497
8498 if ct.if_not_exists {
8499 self.write_space();
8500 self.write_keyword("IF NOT EXISTS");
8501 }
8502
8503 self.write_space();
8504 self.generate_table(&ct.name)?;
8505
8506 if let Some(ref uuid) = ct.uuid {
8508 self.write_space();
8509 self.write_keyword("UUID");
8510 self.write(" '");
8511 self.write(uuid);
8512 self.write("'");
8513 }
8514
8515 if let Some(ref on_cluster) = ct.on_cluster {
8517 self.write_space();
8518 self.generate_on_cluster(on_cluster)?;
8519 }
8520
8521 if matches!(
8523 self.config.dialect,
8524 Some(crate::dialects::DialectType::Teradata)
8525 ) && !ct.teradata_post_name_options.is_empty()
8526 {
8527 for opt in &ct.teradata_post_name_options {
8528 self.write(", ");
8529 self.write(opt);
8530 }
8531 }
8532
8533 if ct.copy_grants {
8535 self.write_space();
8536 self.write_keyword("COPY GRANTS");
8537 }
8538
8539 if let Some(ref using_template) = ct.using_template {
8541 self.write_space();
8542 self.write_keyword("USING TEMPLATE");
8543 self.write_space();
8544 self.generate_expression(using_template)?;
8545 return Ok(());
8546 }
8547
8548 if is_clickhouse {
8552 if let Some(ref clone_source) = ct.clone_source {
8553 if ct.columns.is_empty() && ct.constraints.is_empty() {
8554 self.write_space();
8555 self.write_keyword("AS");
8556 self.write_space();
8557 self.generate_table(clone_source)?;
8558 }
8559 }
8560 }
8561
8562 if !is_clickhouse {
8564 if let Some(ref clone_source) = ct.clone_source {
8565 self.write_space();
8566 if ct.is_copy && self.config.supports_table_copy {
8567 self.write_keyword("COPY");
8569 } else if ct.shallow_clone {
8570 self.write_keyword("SHALLOW CLONE");
8571 } else if ct.deep_clone {
8572 self.write_keyword("DEEP CLONE");
8573 } else {
8574 self.write_keyword("CLONE");
8575 }
8576 self.write_space();
8577 self.generate_table(clone_source)?;
8578 if let Some(ref at_clause) = ct.clone_at_clause {
8580 self.write_space();
8581 self.generate_expression(at_clause)?;
8582 }
8583 return Ok(());
8584 }
8585 }
8586
8587 if let Some(ref partition_of) = ct.partition_of {
8591 self.write_space();
8592
8593 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
8595 self.write_keyword("PARTITION OF");
8597 self.write_space();
8598 self.generate_expression(&pop.this)?;
8599
8600 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8602 self.write(" (");
8603 let mut first = true;
8604 for col in &ct.columns {
8605 if !first {
8606 self.write(", ");
8607 }
8608 first = false;
8609 self.generate_column_def(col)?;
8610 }
8611 for constraint in &ct.constraints {
8612 if !first {
8613 self.write(", ");
8614 }
8615 first = false;
8616 self.generate_table_constraint(constraint)?;
8617 }
8618 self.write(")");
8619 }
8620
8621 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
8623 self.write_space();
8624 self.write_keyword("FOR VALUES");
8625 self.write_space();
8626 self.generate_expression(&pop.expression)?;
8627 } else {
8628 self.write_space();
8629 self.write_keyword("DEFAULT");
8630 }
8631 } else {
8632 self.generate_expression(partition_of)?;
8634
8635 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8637 self.write(" (");
8638 let mut first = true;
8639 for col in &ct.columns {
8640 if !first {
8641 self.write(", ");
8642 }
8643 first = false;
8644 self.generate_column_def(col)?;
8645 }
8646 for constraint in &ct.constraints {
8647 if !first {
8648 self.write(", ");
8649 }
8650 first = false;
8651 self.generate_table_constraint(constraint)?;
8652 }
8653 self.write(")");
8654 }
8655 }
8656
8657 for prop in &ct.properties {
8659 self.write_space();
8660 self.generate_expression(prop)?;
8661 }
8662
8663 return Ok(());
8664 }
8665
8666 self.sqlite_inline_pk_columns.clear();
8669 if matches!(
8670 self.config.dialect,
8671 Some(crate::dialects::DialectType::SQLite)
8672 ) {
8673 for constraint in &ct.constraints {
8674 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8675 if columns.len() == 1 && name.is_none() {
8677 let pk_col_name = columns[0].name.to_ascii_lowercase();
8678 if ct
8680 .columns
8681 .iter()
8682 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
8683 {
8684 self.sqlite_inline_pk_columns.insert(pk_col_name);
8685 }
8686 }
8687 }
8688 }
8689 }
8690
8691 if !ct.columns.is_empty() {
8693 if self.config.pretty {
8694 self.write(" (");
8696 self.write_newline();
8697 self.indent_level += 1;
8698 for (i, col) in ct.columns.iter().enumerate() {
8699 if i > 0 {
8700 self.write(",");
8701 self.write_newline();
8702 }
8703 self.write_indent();
8704 self.generate_column_def(col)?;
8705 }
8706 for constraint in &ct.constraints {
8708 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8710 if columns.len() == 1
8711 && name.is_none()
8712 && self
8713 .sqlite_inline_pk_columns
8714 .contains(&columns[0].name.to_ascii_lowercase())
8715 {
8716 continue;
8717 }
8718 }
8719 self.write(",");
8720 self.write_newline();
8721 self.write_indent();
8722 self.generate_table_constraint(constraint)?;
8723 }
8724 self.indent_level -= 1;
8725 self.write_newline();
8726 self.write(")");
8727 } else {
8728 self.write(" (");
8729 for (i, col) in ct.columns.iter().enumerate() {
8730 if i > 0 {
8731 self.write(", ");
8732 }
8733 self.generate_column_def(col)?;
8734 }
8735 let mut first_constraint = true;
8737 for constraint in &ct.constraints {
8738 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8740 if columns.len() == 1
8741 && name.is_none()
8742 && self
8743 .sqlite_inline_pk_columns
8744 .contains(&columns[0].name.to_ascii_lowercase())
8745 {
8746 continue;
8747 }
8748 }
8749 if first_constraint {
8750 self.write(", ");
8751 first_constraint = false;
8752 } else {
8753 self.write(", ");
8754 }
8755 self.generate_table_constraint(constraint)?;
8756 }
8757 self.write(")");
8758 }
8759 } else if !ct.constraints.is_empty() {
8760 let has_like_only = ct
8762 .constraints
8763 .iter()
8764 .all(|c| matches!(c, TableConstraint::Like { .. }));
8765 let has_tags_only = ct
8766 .constraints
8767 .iter()
8768 .all(|c| matches!(c, TableConstraint::Tags(_)));
8769 let is_pg_like = matches!(
8773 self.config.dialect,
8774 Some(crate::dialects::DialectType::PostgreSQL)
8775 | Some(crate::dialects::DialectType::CockroachDB)
8776 | Some(crate::dialects::DialectType::Materialize)
8777 | Some(crate::dialects::DialectType::RisingWave)
8778 | Some(crate::dialects::DialectType::Redshift)
8779 | Some(crate::dialects::DialectType::Presto)
8780 | Some(crate::dialects::DialectType::Trino)
8781 | Some(crate::dialects::DialectType::Athena)
8782 );
8783 let use_parens = if has_like_only {
8784 is_pg_like
8785 } else {
8786 !has_tags_only
8787 };
8788 if self.config.pretty && use_parens {
8789 self.write(" (");
8790 self.write_newline();
8791 self.indent_level += 1;
8792 for (i, constraint) in ct.constraints.iter().enumerate() {
8793 if i > 0 {
8794 self.write(",");
8795 self.write_newline();
8796 }
8797 self.write_indent();
8798 self.generate_table_constraint(constraint)?;
8799 }
8800 self.indent_level -= 1;
8801 self.write_newline();
8802 self.write(")");
8803 } else {
8804 if use_parens {
8805 self.write(" (");
8806 } else {
8807 self.write_space();
8808 }
8809 for (i, constraint) in ct.constraints.iter().enumerate() {
8810 if i > 0 {
8811 self.write(", ");
8812 }
8813 self.generate_table_constraint(constraint)?;
8814 }
8815 if use_parens {
8816 self.write(")");
8817 }
8818 }
8819 }
8820
8821 if is_clickhouse && (!ct.columns.is_empty() || !ct.constraints.is_empty()) {
8822 if let Some(ref clone_source) = ct.clone_source {
8823 self.write_space();
8824 self.write_keyword("AS");
8825 self.write_space();
8826 self.generate_table(clone_source)?;
8827 }
8828 }
8829
8830 if let Some(ref on_prop) = ct.on_property {
8832 self.write(" ");
8833 self.write_keyword("ON");
8834 self.write(" ");
8835 self.generate_expression(&on_prop.this)?;
8836 }
8837
8838 if !ct.with_partition_columns.is_empty() {
8840 if self.config.pretty {
8841 self.write_newline();
8842 } else {
8843 self.write_space();
8844 }
8845 self.write_keyword("WITH PARTITION COLUMNS");
8846 self.write(" (");
8847 if self.config.pretty {
8848 self.write_newline();
8849 self.indent_level += 1;
8850 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8851 if i > 0 {
8852 self.write(",");
8853 self.write_newline();
8854 }
8855 self.write_indent();
8856 self.generate_column_def(col)?;
8857 }
8858 self.indent_level -= 1;
8859 self.write_newline();
8860 } else {
8861 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8862 if i > 0 {
8863 self.write(", ");
8864 }
8865 self.generate_column_def(col)?;
8866 }
8867 }
8868 self.write(")");
8869 }
8870
8871 if let Some(ref conn) = ct.with_connection {
8873 if self.config.pretty {
8874 self.write_newline();
8875 } else {
8876 self.write_space();
8877 }
8878 self.write_keyword("WITH CONNECTION");
8879 self.write_space();
8880 self.generate_table(conn)?;
8881 }
8882
8883 if !is_clickhouse {
8886 for prop in &ct.properties {
8887 if let Expression::SchemaCommentProperty(_) = prop {
8888 if self.config.pretty {
8889 self.write_newline();
8890 } else {
8891 self.write_space();
8892 }
8893 self.generate_expression(prop)?;
8894 }
8895 }
8896 }
8897
8898 if !ct.with_properties.is_empty() {
8900 let is_snowflake_special_table = matches!(
8902 self.config.dialect,
8903 Some(crate::dialects::DialectType::Snowflake)
8904 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8905 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8906 if is_snowflake_special_table {
8907 for (key, value) in &ct.with_properties {
8908 self.write_space();
8909 self.write(key);
8910 self.write("=");
8911 self.write(value);
8912 }
8913 } else if self.config.pretty {
8914 self.write_newline();
8915 self.write_keyword("WITH");
8916 self.write(" (");
8917 self.write_newline();
8918 self.indent_level += 1;
8919 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8920 if i > 0 {
8921 self.write(",");
8922 self.write_newline();
8923 }
8924 self.write_indent();
8925 self.write(key);
8926 self.write("=");
8927 self.write(value);
8928 }
8929 self.indent_level -= 1;
8930 self.write_newline();
8931 self.write(")");
8932 } else {
8933 self.write_space();
8934 self.write_keyword("WITH");
8935 self.write(" (");
8936 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8937 if i > 0 {
8938 self.write(", ");
8939 }
8940 self.write(key);
8941 self.write("=");
8942 self.write(value);
8943 }
8944 self.write(")");
8945 }
8946 }
8947
8948 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8949 if is_clickhouse && ct.as_select.is_some() {
8950 let mut pre = Vec::new();
8951 let mut post = Vec::new();
8952 for prop in &ct.properties {
8953 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8954 post.push(prop);
8955 } else {
8956 pre.push(prop);
8957 }
8958 }
8959 (pre, post)
8960 } else {
8961 (ct.properties.iter().collect(), Vec::new())
8962 };
8963
8964 for prop in pre_as_properties {
8966 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8968 continue;
8969 }
8970 if self.config.pretty {
8971 self.write_newline();
8972 } else {
8973 self.write_space();
8974 }
8975 if let Expression::Properties(props) = prop {
8979 let is_hive_dialect = matches!(
8980 self.config.dialect,
8981 Some(crate::dialects::DialectType::Hive)
8982 | Some(crate::dialects::DialectType::Spark)
8983 | Some(crate::dialects::DialectType::Databricks)
8984 | Some(crate::dialects::DialectType::Athena)
8985 );
8986 let is_doris_starrocks = matches!(
8987 self.config.dialect,
8988 Some(crate::dialects::DialectType::Doris)
8989 | Some(crate::dialects::DialectType::StarRocks)
8990 );
8991 if is_hive_dialect {
8992 self.generate_tblproperties_clause(&props.expressions)?;
8993 } else if is_doris_starrocks {
8994 self.generate_properties_clause(&props.expressions)?;
8995 } else {
8996 self.generate_options_clause(&props.expressions)?;
8997 }
8998 } else {
8999 self.generate_expression(prop)?;
9000 }
9001 }
9002
9003 for prop in &ct.post_table_properties {
9005 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
9006 self.write(" WITH(");
9007 self.generate_system_versioning_content(svp)?;
9008 self.write(")");
9009 } else if let Expression::Properties(props) = prop {
9010 let is_doris_starrocks = matches!(
9012 self.config.dialect,
9013 Some(crate::dialects::DialectType::Doris)
9014 | Some(crate::dialects::DialectType::StarRocks)
9015 );
9016 self.write_space();
9017 if is_doris_starrocks {
9018 self.generate_properties_clause(&props.expressions)?;
9019 } else {
9020 self.generate_options_clause(&props.expressions)?;
9021 }
9022 } else {
9023 self.write_space();
9024 self.generate_expression(prop)?;
9025 }
9026 }
9027
9028 if let Some(ref rollup) = ct.rollup {
9031 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
9032 self.write_space();
9033 self.generate_rollup_property(rollup)?;
9034 }
9035 }
9036
9037 let is_mysql_compatible = matches!(
9041 self.config.dialect,
9042 Some(DialectType::MySQL)
9043 | Some(DialectType::SingleStore)
9044 | Some(DialectType::Doris)
9045 | Some(DialectType::StarRocks)
9046 | None
9047 );
9048 let is_hive_compatible = matches!(
9049 self.config.dialect,
9050 Some(DialectType::Hive)
9051 | Some(DialectType::Spark)
9052 | Some(DialectType::Databricks)
9053 | Some(DialectType::Athena)
9054 );
9055 let mysql_pretty_options =
9056 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
9057 for (key, value) in &ct.mysql_table_options {
9058 let should_output = if is_mysql_compatible {
9060 true
9061 } else if is_hive_compatible && key == "COMMENT" {
9062 true } else {
9064 false
9065 };
9066 if should_output {
9067 if mysql_pretty_options {
9068 self.write_newline();
9069 self.write_indent();
9070 } else {
9071 self.write_space();
9072 }
9073 self.write_keyword(key);
9074 if key == "COMMENT" && !self.config.schema_comment_with_eq {
9076 self.write_space();
9077 } else {
9078 self.write("=");
9079 }
9080 self.write(value);
9081 }
9082 }
9083
9084 if ct.temporary
9086 && matches!(
9087 self.config.dialect,
9088 Some(DialectType::Spark) | Some(DialectType::Databricks)
9089 )
9090 && ct.as_select.is_none()
9091 {
9092 self.write_space();
9093 self.write_keyword("USING PARQUET");
9094 }
9095
9096 if !ct.inherits.is_empty() {
9098 self.write_space();
9099 self.write_keyword("INHERITS");
9100 self.write(" (");
9101 for (i, parent) in ct.inherits.iter().enumerate() {
9102 if i > 0 {
9103 self.write(", ");
9104 }
9105 self.generate_table(parent)?;
9106 }
9107 self.write(")");
9108 }
9109
9110 if let Some(ref query) = ct.as_select {
9112 self.write_space();
9113 self.write_keyword("AS");
9114 self.write_space();
9115 let source_is_clickhouse =
9116 matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
9117 let wrap_as_select =
9118 ct.as_select_parenthesized && !(is_clickhouse && source_is_clickhouse);
9119 if wrap_as_select {
9120 self.write("(");
9121 }
9122 self.generate_expression(query)?;
9123 if wrap_as_select {
9124 self.write(")");
9125 }
9126
9127 if let Some(with_data) = ct.with_data {
9129 self.write_space();
9130 self.write_keyword("WITH");
9131 if !with_data {
9132 self.write_space();
9133 self.write_keyword("NO");
9134 }
9135 self.write_space();
9136 self.write_keyword("DATA");
9137 }
9138
9139 if let Some(with_statistics) = ct.with_statistics {
9141 self.write_space();
9142 self.write_keyword("AND");
9143 if !with_statistics {
9144 self.write_space();
9145 self.write_keyword("NO");
9146 }
9147 self.write_space();
9148 self.write_keyword("STATISTICS");
9149 }
9150
9151 for index in &ct.teradata_indexes {
9153 self.write_space();
9154 match index.kind {
9155 TeradataIndexKind::NoPrimary => {
9156 self.write_keyword("NO PRIMARY INDEX");
9157 }
9158 TeradataIndexKind::Primary => {
9159 self.write_keyword("PRIMARY INDEX");
9160 }
9161 TeradataIndexKind::PrimaryAmp => {
9162 self.write_keyword("PRIMARY AMP INDEX");
9163 }
9164 TeradataIndexKind::Unique => {
9165 self.write_keyword("UNIQUE INDEX");
9166 }
9167 TeradataIndexKind::UniquePrimary => {
9168 self.write_keyword("UNIQUE PRIMARY INDEX");
9169 }
9170 TeradataIndexKind::Secondary => {
9171 self.write_keyword("INDEX");
9172 }
9173 }
9174 if let Some(ref name) = index.name {
9176 self.write_space();
9177 self.write(name);
9178 }
9179 if !index.columns.is_empty() {
9181 self.write(" (");
9182 for (i, col) in index.columns.iter().enumerate() {
9183 if i > 0 {
9184 self.write(", ");
9185 }
9186 self.write(col);
9187 }
9188 self.write(")");
9189 }
9190 }
9191
9192 if let Some(ref on_commit) = ct.on_commit {
9194 self.write_space();
9195 self.write_keyword("ON COMMIT");
9196 self.write_space();
9197 match on_commit {
9198 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
9199 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
9200 }
9201 }
9202
9203 if !post_as_properties.is_empty() {
9204 for prop in post_as_properties {
9205 self.write_space();
9206 self.generate_expression(prop)?;
9207 }
9208 }
9209
9210 self.athena_hive_context = saved_athena_hive_context;
9212 return Ok(());
9213 }
9214
9215 if let Some(ref on_commit) = ct.on_commit {
9217 self.write_space();
9218 self.write_keyword("ON COMMIT");
9219 self.write_space();
9220 match on_commit {
9221 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
9222 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
9223 }
9224 }
9225
9226 self.athena_hive_context = saved_athena_hive_context;
9228
9229 Ok(())
9230 }
9231
9232 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
9235 self.generate_identifier(&col.name)?;
9237 if !matches!(col.data_type, DataType::Unknown) {
9239 self.write_space();
9240 self.generate_data_type(&col.data_type)?;
9241 }
9242 for constraint in &col.constraints {
9244 if let ColumnConstraint::Path(path_expr) = constraint {
9245 self.write_space();
9246 self.write_keyword("PATH");
9247 self.write_space();
9248 self.generate_expression(path_expr)?;
9249 }
9250 }
9251 Ok(())
9252 }
9253
9254 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
9255 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
9257 && col
9258 .constraints
9259 .iter()
9260 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
9261 let omit_computed_type = !self.config.computed_column_with_type
9263 && col
9264 .constraints
9265 .iter()
9266 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
9267
9268 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
9271
9272 let has_no_type = col.no_type
9275 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
9276 && col.constraints.is_empty());
9277
9278 self.generate_identifier(&col.name)?;
9279
9280 let serial_expansion = if matches!(
9282 self.config.dialect,
9283 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
9284 ) {
9285 if let DataType::Custom { ref name } = col.data_type {
9286 if name.eq_ignore_ascii_case("SERIAL") {
9287 Some("INT")
9288 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
9289 Some("BIGINT")
9290 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
9291 Some("SMALLINT")
9292 } else {
9293 None
9294 }
9295 } else {
9296 None
9297 }
9298 } else {
9299 None
9300 };
9301
9302 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
9303 {
9304 self.write_space();
9305 let saved_nullable_depth = self.clickhouse_nullable_depth;
9308 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
9309 self.clickhouse_nullable_depth = -1;
9310 }
9311 if let Some(int_type) = serial_expansion {
9312 self.write_keyword(int_type);
9314 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
9315 let unsigned_type = match &col.data_type {
9317 DataType::Int { .. } => Some("UINTEGER"),
9318 DataType::BigInt { .. } => Some("UBIGINT"),
9319 DataType::SmallInt { .. } => Some("USMALLINT"),
9320 DataType::TinyInt { .. } => Some("UTINYINT"),
9321 _ => None,
9322 };
9323 if let Some(utype) = unsigned_type {
9324 self.write_keyword(utype);
9325 } else {
9326 self.generate_data_type(&col.data_type)?;
9327 }
9328 } else {
9329 self.generate_data_type(&col.data_type)?;
9330 }
9331 self.clickhouse_nullable_depth = saved_nullable_depth;
9332 }
9333
9334 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
9337 self.write_space();
9338 self.write_keyword("UNSIGNED");
9339 }
9340 if col.zerofill {
9341 self.write_space();
9342 self.write_keyword("ZEROFILL");
9343 }
9344
9345 if let Some(ref charset) = col.character_set {
9349 self.write_space();
9350 self.write_keyword("CHARACTER SET");
9351 self.write_space();
9352 self.write(charset);
9353 }
9354
9355 if col.uppercase {
9356 self.write_space();
9357 self.write_keyword("UPPERCASE");
9358 }
9359
9360 if let Some(casespecific) = col.casespecific {
9361 self.write_space();
9362 if casespecific {
9363 self.write_keyword("CASESPECIFIC");
9364 } else {
9365 self.write_keyword("NOT CASESPECIFIC");
9366 }
9367 }
9368
9369 if let Some(ref format) = col.format {
9370 self.write_space();
9371 self.write_keyword("FORMAT");
9372 self.write(" '");
9373 self.write(format);
9374 self.write("'");
9375 }
9376
9377 if let Some(ref title) = col.title {
9378 self.write_space();
9379 self.write_keyword("TITLE");
9380 self.write(" '");
9381 self.write(title);
9382 self.write("'");
9383 }
9384
9385 if let Some(length) = col.inline_length {
9386 self.write_space();
9387 self.write_keyword("INLINE LENGTH");
9388 self.write(" ");
9389 self.write(&length.to_string());
9390 }
9391
9392 if let Some(ref compress) = col.compress {
9393 self.write_space();
9394 self.write_keyword("COMPRESS");
9395 if !compress.is_empty() {
9396 if compress.len() == 1 {
9398 if let Expression::Literal(lit) = &compress[0] {
9399 if let Literal::String(_) = lit.as_ref() {
9400 self.write_space();
9401 self.generate_expression(&compress[0])?;
9402 }
9403 } else {
9404 self.write(" (");
9405 self.generate_expression(&compress[0])?;
9406 self.write(")");
9407 }
9408 } else {
9409 self.write(" (");
9410 for (i, val) in compress.iter().enumerate() {
9411 if i > 0 {
9412 self.write(", ");
9413 }
9414 self.generate_expression(val)?;
9415 }
9416 self.write(")");
9417 }
9418 }
9419 }
9420
9421 if !col.constraint_order.is_empty() {
9424 let mut references_idx = 0;
9427 let mut check_idx = 0;
9428 let mut generated_idx = 0;
9429 let mut collate_idx = 0;
9430 let mut comment_idx = 0;
9431 let defer_not_null_after_identity = false;
9434 let mut pending_not_null_after_identity = false;
9435
9436 for constraint_type in &col.constraint_order {
9437 match constraint_type {
9438 ConstraintType::PrimaryKey => {
9439 if col.primary_key
9441 && !matches!(self.config.dialect, Some(DialectType::Materialize))
9442 {
9443 if let Some(ref cname) = col.primary_key_constraint_name {
9444 self.write_space();
9445 self.write_keyword("CONSTRAINT");
9446 self.write_space();
9447 self.write(cname);
9448 }
9449 self.write_space();
9450 self.write_keyword("PRIMARY KEY");
9451 if let Some(ref order) = col.primary_key_order {
9452 self.write_space();
9453 match order {
9454 SortOrder::Asc => self.write_keyword("ASC"),
9455 SortOrder::Desc => self.write_keyword("DESC"),
9456 }
9457 }
9458 }
9459 }
9460 ConstraintType::Unique => {
9461 if col.unique {
9462 if let Some(ref cname) = col.unique_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("UNIQUE");
9470 if col.unique_nulls_not_distinct {
9472 self.write(" NULLS NOT DISTINCT");
9473 }
9474 }
9475 }
9476 ConstraintType::NotNull => {
9477 if col.nullable == Some(false) {
9478 if defer_not_null_after_identity {
9479 pending_not_null_after_identity = true;
9480 continue;
9481 }
9482 if let Some(ref cname) = col.not_null_constraint_name {
9483 self.write_space();
9484 self.write_keyword("CONSTRAINT");
9485 self.write_space();
9486 self.write(cname);
9487 }
9488 self.write_space();
9489 self.write_keyword("NOT NULL");
9490 }
9491 }
9492 ConstraintType::Null => {
9493 if col.nullable == Some(true) {
9494 self.write_space();
9495 self.write_keyword("NULL");
9496 }
9497 }
9498 ConstraintType::Default => {
9499 if let Some(ref default) = col.default {
9500 self.write_space();
9501 self.write_keyword("DEFAULT");
9502 self.write_space();
9503 self.generate_expression(default)?;
9504 }
9505 }
9506 ConstraintType::AutoIncrement => {
9507 if col.auto_increment {
9508 if matches!(
9510 self.config.dialect,
9511 Some(crate::dialects::DialectType::DuckDB)
9512 ) {
9513 } else if matches!(
9515 self.config.dialect,
9516 Some(crate::dialects::DialectType::Materialize)
9517 ) {
9518 if !matches!(col.nullable, Some(false)) {
9520 self.write_space();
9521 self.write_keyword("NOT NULL");
9522 }
9523 } else if matches!(
9524 self.config.dialect,
9525 Some(crate::dialects::DialectType::PostgreSQL)
9526 ) {
9527 self.write_space();
9529 self.generate_auto_increment_keyword(col)?;
9530 } else if matches!(
9531 self.config.dialect,
9532 Some(crate::dialects::DialectType::SQLite)
9533 ) && !col.primary_key
9534 && self
9535 .sqlite_inline_pk_columns
9536 .contains(&col.name.name.to_ascii_lowercase())
9537 {
9538 } else {
9541 self.write_space();
9542 self.generate_auto_increment_keyword(col)?;
9543 if pending_not_null_after_identity {
9544 self.write_space();
9545 self.write_keyword("NOT NULL");
9546 pending_not_null_after_identity = false;
9547 }
9548 }
9549 } }
9551 ConstraintType::References => {
9552 while references_idx < col.constraints.len() {
9554 if let ColumnConstraint::References(fk_ref) =
9555 &col.constraints[references_idx]
9556 {
9557 if let Some(ref name) = fk_ref.constraint_name {
9559 self.write_space();
9560 self.write_keyword("CONSTRAINT");
9561 self.write_space();
9562 self.write(name);
9563 }
9564 self.write_space();
9565 if fk_ref.has_foreign_key_keywords {
9566 self.write_keyword("FOREIGN KEY");
9567 self.write_space();
9568 }
9569 self.write_keyword("REFERENCES");
9570 self.write_space();
9571 self.generate_table(&fk_ref.table)?;
9572 if !fk_ref.columns.is_empty() {
9573 self.write(" (");
9574 for (i, c) in fk_ref.columns.iter().enumerate() {
9575 if i > 0 {
9576 self.write(", ");
9577 }
9578 self.generate_identifier(c)?;
9579 }
9580 self.write(")");
9581 }
9582 self.generate_referential_actions(fk_ref)?;
9583 references_idx += 1;
9584 break;
9585 }
9586 references_idx += 1;
9587 }
9588 }
9589 ConstraintType::Check => {
9590 while check_idx < col.constraints.len() {
9592 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
9593 if check_idx == 0 {
9595 if let Some(ref cname) = col.check_constraint_name {
9596 self.write_space();
9597 self.write_keyword("CONSTRAINT");
9598 self.write_space();
9599 self.write(cname);
9600 }
9601 }
9602 self.write_space();
9603 self.write_keyword("CHECK");
9604 self.write(" (");
9605 self.generate_expression(expr)?;
9606 self.write(")");
9607 check_idx += 1;
9608 break;
9609 }
9610 check_idx += 1;
9611 }
9612 }
9613 ConstraintType::GeneratedAsIdentity => {
9614 while generated_idx < col.constraints.len() {
9616 if let ColumnConstraint::GeneratedAsIdentity(gen) =
9617 &col.constraints[generated_idx]
9618 {
9619 self.write_space();
9620 if matches!(
9622 self.config.dialect,
9623 Some(crate::dialects::DialectType::Redshift)
9624 ) {
9625 self.write_keyword("IDENTITY");
9626 self.write("(");
9627 if let Some(ref start) = gen.start {
9628 self.generate_expression(start)?;
9629 } else {
9630 self.write("0");
9631 }
9632 self.write(", ");
9633 if let Some(ref incr) = gen.increment {
9634 self.generate_expression(incr)?;
9635 } else {
9636 self.write("1");
9637 }
9638 self.write(")");
9639 } else {
9640 self.write_keyword("GENERATED");
9641 if gen.always {
9642 self.write_space();
9643 self.write_keyword("ALWAYS");
9644 } else {
9645 self.write_space();
9646 self.write_keyword("BY DEFAULT");
9647 if gen.on_null {
9648 self.write_space();
9649 self.write_keyword("ON NULL");
9650 }
9651 }
9652 self.write_space();
9653 self.write_keyword("AS IDENTITY");
9654
9655 let has_options = gen.start.is_some()
9656 || gen.increment.is_some()
9657 || gen.minvalue.is_some()
9658 || gen.maxvalue.is_some()
9659 || gen.cycle.is_some();
9660 if has_options {
9661 self.write(" (");
9662 let mut first = true;
9663 if let Some(ref start) = gen.start {
9664 if !first {
9665 self.write(" ");
9666 }
9667 first = false;
9668 self.write_keyword("START WITH");
9669 self.write_space();
9670 self.generate_expression(start)?;
9671 }
9672 if let Some(ref incr) = gen.increment {
9673 if !first {
9674 self.write(" ");
9675 }
9676 first = false;
9677 self.write_keyword("INCREMENT BY");
9678 self.write_space();
9679 self.generate_expression(incr)?;
9680 }
9681 if let Some(ref minv) = gen.minvalue {
9682 if !first {
9683 self.write(" ");
9684 }
9685 first = false;
9686 self.write_keyword("MINVALUE");
9687 self.write_space();
9688 self.generate_expression(minv)?;
9689 }
9690 if let Some(ref maxv) = gen.maxvalue {
9691 if !first {
9692 self.write(" ");
9693 }
9694 first = false;
9695 self.write_keyword("MAXVALUE");
9696 self.write_space();
9697 self.generate_expression(maxv)?;
9698 }
9699 if let Some(cycle) = gen.cycle {
9700 if !first {
9701 self.write(" ");
9702 }
9703 if cycle {
9704 self.write_keyword("CYCLE");
9705 } else {
9706 self.write_keyword("NO CYCLE");
9707 }
9708 }
9709 self.write(")");
9710 }
9711 }
9712 generated_idx += 1;
9713 break;
9714 }
9715 generated_idx += 1;
9716 }
9717 }
9718 ConstraintType::Collate => {
9719 while collate_idx < col.constraints.len() {
9721 if let ColumnConstraint::Collate(collation) =
9722 &col.constraints[collate_idx]
9723 {
9724 self.write_space();
9725 self.write_keyword("COLLATE");
9726 self.write_space();
9727 self.generate_identifier(collation)?;
9728 collate_idx += 1;
9729 break;
9730 }
9731 collate_idx += 1;
9732 }
9733 }
9734 ConstraintType::Comment => {
9735 while comment_idx < col.constraints.len() {
9737 if let ColumnConstraint::Comment(comment) =
9738 &col.constraints[comment_idx]
9739 {
9740 self.write_space();
9741 self.write_keyword("COMMENT");
9742 self.write_space();
9743 self.generate_string_literal(comment)?;
9744 comment_idx += 1;
9745 break;
9746 }
9747 comment_idx += 1;
9748 }
9749 }
9750 ConstraintType::Tags => {
9751 for constraint in &col.constraints {
9753 if let ColumnConstraint::Tags(tags) = constraint {
9754 self.write_space();
9755 self.write_keyword("TAG");
9756 self.write(" (");
9757 for (i, expr) in tags.expressions.iter().enumerate() {
9758 if i > 0 {
9759 self.write(", ");
9760 }
9761 self.generate_expression(expr)?;
9762 }
9763 self.write(")");
9764 break;
9765 }
9766 }
9767 }
9768 ConstraintType::ComputedColumn => {
9769 for constraint in &col.constraints {
9771 if let ColumnConstraint::ComputedColumn(cc) = constraint {
9772 self.write_space();
9773 self.generate_computed_column_inline(cc)?;
9774 break;
9775 }
9776 }
9777 }
9778 ConstraintType::GeneratedAsRow => {
9779 for constraint in &col.constraints {
9781 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
9782 self.write_space();
9783 self.generate_generated_as_row_inline(gar)?;
9784 break;
9785 }
9786 }
9787 }
9788 ConstraintType::OnUpdate => {
9789 if let Some(ref expr) = col.on_update {
9790 self.write_space();
9791 self.write_keyword("ON UPDATE");
9792 self.write_space();
9793 self.generate_expression(expr)?;
9794 }
9795 }
9796 ConstraintType::Encode => {
9797 if let Some(ref encoding) = col.encoding {
9798 self.write_space();
9799 self.write_keyword("ENCODE");
9800 self.write_space();
9801 self.write(encoding);
9802 }
9803 }
9804 ConstraintType::Path => {
9805 for constraint in &col.constraints {
9807 if let ColumnConstraint::Path(path_expr) = constraint {
9808 self.write_space();
9809 self.write_keyword("PATH");
9810 self.write_space();
9811 self.generate_expression(path_expr)?;
9812 break;
9813 }
9814 }
9815 }
9816 }
9817 }
9818 if pending_not_null_after_identity {
9819 self.write_space();
9820 self.write_keyword("NOT NULL");
9821 }
9822 } else {
9823 if col.primary_key {
9825 self.write_space();
9826 self.write_keyword("PRIMARY KEY");
9827 if let Some(ref order) = col.primary_key_order {
9828 self.write_space();
9829 match order {
9830 SortOrder::Asc => self.write_keyword("ASC"),
9831 SortOrder::Desc => self.write_keyword("DESC"),
9832 }
9833 }
9834 }
9835
9836 if col.unique {
9837 self.write_space();
9838 self.write_keyword("UNIQUE");
9839 if col.unique_nulls_not_distinct {
9841 self.write(" NULLS NOT DISTINCT");
9842 }
9843 }
9844
9845 match col.nullable {
9846 Some(false) => {
9847 self.write_space();
9848 self.write_keyword("NOT NULL");
9849 }
9850 Some(true) => {
9851 self.write_space();
9852 self.write_keyword("NULL");
9853 }
9854 None => {}
9855 }
9856
9857 if let Some(ref default) = col.default {
9858 self.write_space();
9859 self.write_keyword("DEFAULT");
9860 self.write_space();
9861 self.generate_expression(default)?;
9862 }
9863
9864 if col.auto_increment {
9865 self.write_space();
9866 self.generate_auto_increment_keyword(col)?;
9867 }
9868
9869 for constraint in &col.constraints {
9871 match constraint {
9872 ColumnConstraint::References(fk_ref) => {
9873 self.write_space();
9874 if fk_ref.has_foreign_key_keywords {
9875 self.write_keyword("FOREIGN KEY");
9876 self.write_space();
9877 }
9878 self.write_keyword("REFERENCES");
9879 self.write_space();
9880 self.generate_table(&fk_ref.table)?;
9881 if !fk_ref.columns.is_empty() {
9882 self.write(" (");
9883 for (i, c) in fk_ref.columns.iter().enumerate() {
9884 if i > 0 {
9885 self.write(", ");
9886 }
9887 self.generate_identifier(c)?;
9888 }
9889 self.write(")");
9890 }
9891 self.generate_referential_actions(fk_ref)?;
9892 }
9893 ColumnConstraint::Check(expr) => {
9894 self.write_space();
9895 self.write_keyword("CHECK");
9896 self.write(" (");
9897 self.generate_expression(expr)?;
9898 self.write(")");
9899 }
9900 ColumnConstraint::GeneratedAsIdentity(gen) => {
9901 self.write_space();
9902 if matches!(
9904 self.config.dialect,
9905 Some(crate::dialects::DialectType::Redshift)
9906 ) {
9907 self.write_keyword("IDENTITY");
9908 self.write("(");
9909 if let Some(ref start) = gen.start {
9910 self.generate_expression(start)?;
9911 } else {
9912 self.write("0");
9913 }
9914 self.write(", ");
9915 if let Some(ref incr) = gen.increment {
9916 self.generate_expression(incr)?;
9917 } else {
9918 self.write("1");
9919 }
9920 self.write(")");
9921 } else {
9922 self.write_keyword("GENERATED");
9923 if gen.always {
9924 self.write_space();
9925 self.write_keyword("ALWAYS");
9926 } else {
9927 self.write_space();
9928 self.write_keyword("BY DEFAULT");
9929 if gen.on_null {
9930 self.write_space();
9931 self.write_keyword("ON NULL");
9932 }
9933 }
9934 self.write_space();
9935 self.write_keyword("AS IDENTITY");
9936
9937 let has_options = gen.start.is_some()
9938 || gen.increment.is_some()
9939 || gen.minvalue.is_some()
9940 || gen.maxvalue.is_some()
9941 || gen.cycle.is_some();
9942 if has_options {
9943 self.write(" (");
9944 let mut first = true;
9945 if let Some(ref start) = gen.start {
9946 if !first {
9947 self.write(" ");
9948 }
9949 first = false;
9950 self.write_keyword("START WITH");
9951 self.write_space();
9952 self.generate_expression(start)?;
9953 }
9954 if let Some(ref incr) = gen.increment {
9955 if !first {
9956 self.write(" ");
9957 }
9958 first = false;
9959 self.write_keyword("INCREMENT BY");
9960 self.write_space();
9961 self.generate_expression(incr)?;
9962 }
9963 if let Some(ref minv) = gen.minvalue {
9964 if !first {
9965 self.write(" ");
9966 }
9967 first = false;
9968 self.write_keyword("MINVALUE");
9969 self.write_space();
9970 self.generate_expression(minv)?;
9971 }
9972 if let Some(ref maxv) = gen.maxvalue {
9973 if !first {
9974 self.write(" ");
9975 }
9976 first = false;
9977 self.write_keyword("MAXVALUE");
9978 self.write_space();
9979 self.generate_expression(maxv)?;
9980 }
9981 if let Some(cycle) = gen.cycle {
9982 if !first {
9983 self.write(" ");
9984 }
9985 if cycle {
9986 self.write_keyword("CYCLE");
9987 } else {
9988 self.write_keyword("NO CYCLE");
9989 }
9990 }
9991 self.write(")");
9992 }
9993 }
9994 }
9995 ColumnConstraint::Collate(collation) => {
9996 self.write_space();
9997 self.write_keyword("COLLATE");
9998 self.write_space();
9999 self.generate_identifier(collation)?;
10000 }
10001 ColumnConstraint::Comment(comment) => {
10002 self.write_space();
10003 self.write_keyword("COMMENT");
10004 self.write_space();
10005 self.generate_string_literal(comment)?;
10006 }
10007 ColumnConstraint::Path(path_expr) => {
10008 self.write_space();
10009 self.write_keyword("PATH");
10010 self.write_space();
10011 self.generate_expression(path_expr)?;
10012 }
10013 _ => {} }
10015 }
10016
10017 if let Some(ref encoding) = col.encoding {
10019 self.write_space();
10020 self.write_keyword("ENCODE");
10021 self.write_space();
10022 self.write(encoding);
10023 }
10024 }
10025
10026 if let Some(ref codec) = col.codec {
10028 self.write_space();
10029 self.write_keyword("CODEC");
10030 self.write("(");
10031 self.write(codec);
10032 self.write(")");
10033 }
10034
10035 if let Some(visible) = col.visible {
10036 self.write_space();
10037 if visible {
10038 self.write_keyword("VISIBLE");
10039 } else {
10040 self.write_keyword("INVISIBLE");
10041 }
10042 }
10043
10044 if let Some(ref ephemeral) = col.ephemeral {
10046 self.write_space();
10047 self.write_keyword("EPHEMERAL");
10048 if let Some(ref expr) = ephemeral {
10049 self.write_space();
10050 self.generate_expression(expr)?;
10051 }
10052 }
10053
10054 if let Some(ref mat_expr) = col.materialized_expr {
10056 self.write_space();
10057 self.write_keyword("MATERIALIZED");
10058 self.write_space();
10059 self.generate_expression(mat_expr)?;
10060 }
10061
10062 if let Some(ref alias_expr) = col.alias_expr {
10064 self.write_space();
10065 self.write_keyword("ALIAS");
10066 self.write_space();
10067 self.generate_expression(alias_expr)?;
10068 }
10069
10070 if let Some(ref ttl_expr) = col.ttl_expr {
10072 self.write_space();
10073 self.write_keyword("TTL");
10074 self.write_space();
10075 self.generate_expression(ttl_expr)?;
10076 }
10077
10078 if col.not_for_replication
10080 && matches!(
10081 self.config.dialect,
10082 Some(crate::dialects::DialectType::TSQL)
10083 | Some(crate::dialects::DialectType::Fabric)
10084 )
10085 {
10086 self.write_space();
10087 self.write_keyword("NOT FOR REPLICATION");
10088 }
10089
10090 if !col.options.is_empty() {
10092 self.write_space();
10093 self.generate_options_clause(&col.options)?;
10094 }
10095
10096 if !col.primary_key
10099 && self
10100 .sqlite_inline_pk_columns
10101 .contains(&col.name.name.to_ascii_lowercase())
10102 {
10103 self.write_space();
10104 self.write_keyword("PRIMARY KEY");
10105 if matches!(self.config.dialect, Some(DialectType::SQLite)) && col.auto_increment {
10106 self.write_space();
10107 self.generate_auto_increment_keyword(col)?;
10108 }
10109 }
10110
10111 if serial_expansion.is_some() {
10114 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
10115 self.write_space();
10116 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
10117 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
10118 self.write_space();
10119 self.write_keyword("NOT NULL");
10120 }
10121 }
10122
10123 Ok(())
10124 }
10125
10126 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
10127 match constraint {
10128 TableConstraint::PrimaryKey {
10129 name,
10130 columns,
10131 include_columns,
10132 modifiers,
10133 has_constraint_keyword,
10134 } => {
10135 if let Some(ref n) = name {
10136 if *has_constraint_keyword {
10137 self.write_keyword("CONSTRAINT");
10138 self.write_space();
10139 self.generate_identifier(n)?;
10140 self.write_space();
10141 }
10142 }
10143 self.write_keyword("PRIMARY KEY");
10144 if let Some(ref clustered) = modifiers.clustered {
10146 self.write_space();
10147 self.write_keyword(clustered);
10148 }
10149 if let Some(ref n) = name {
10151 if !*has_constraint_keyword {
10152 self.write_space();
10153 self.generate_identifier(n)?;
10154 }
10155 }
10156 self.write(" (");
10157 for (i, col) in columns.iter().enumerate() {
10158 if i > 0 {
10159 self.write(", ");
10160 }
10161 self.generate_identifier(col)?;
10162 }
10163 self.write(")");
10164 if !include_columns.is_empty() {
10165 self.write_space();
10166 self.write_keyword("INCLUDE");
10167 self.write(" (");
10168 for (i, col) in include_columns.iter().enumerate() {
10169 if i > 0 {
10170 self.write(", ");
10171 }
10172 self.generate_identifier(col)?;
10173 }
10174 self.write(")");
10175 }
10176 self.generate_constraint_modifiers(modifiers);
10177 }
10178 TableConstraint::Unique {
10179 name,
10180 columns,
10181 columns_parenthesized,
10182 modifiers,
10183 has_constraint_keyword,
10184 nulls_not_distinct,
10185 } => {
10186 if let Some(ref n) = name {
10187 if *has_constraint_keyword {
10188 self.write_keyword("CONSTRAINT");
10189 self.write_space();
10190 self.generate_identifier(n)?;
10191 self.write_space();
10192 }
10193 }
10194 self.write_keyword("UNIQUE");
10195 if let Some(ref clustered) = modifiers.clustered {
10197 self.write_space();
10198 self.write_keyword(clustered);
10199 }
10200 if *nulls_not_distinct {
10202 self.write(" NULLS NOT DISTINCT");
10203 }
10204 if let Some(ref n) = name {
10206 if !*has_constraint_keyword {
10207 self.write_space();
10208 self.generate_identifier(n)?;
10209 }
10210 }
10211 if *columns_parenthesized {
10212 self.write(" (");
10213 for (i, col) in columns.iter().enumerate() {
10214 if i > 0 {
10215 self.write(", ");
10216 }
10217 self.generate_identifier(col)?;
10218 }
10219 self.write(")");
10220 } else {
10221 for col in columns.iter() {
10223 self.write_space();
10224 self.generate_identifier(col)?;
10225 }
10226 }
10227 self.generate_constraint_modifiers(modifiers);
10228 }
10229 TableConstraint::ForeignKey {
10230 name,
10231 columns,
10232 references,
10233 on_delete,
10234 on_update,
10235 modifiers,
10236 } => {
10237 if let Some(ref n) = name {
10238 self.write_keyword("CONSTRAINT");
10239 self.write_space();
10240 self.generate_identifier(n)?;
10241 self.write_space();
10242 }
10243 self.write_keyword("FOREIGN KEY");
10244 self.write(" (");
10245 for (i, col) in columns.iter().enumerate() {
10246 if i > 0 {
10247 self.write(", ");
10248 }
10249 self.generate_identifier(col)?;
10250 }
10251 self.write(")");
10252 if let Some(ref refs) = references {
10253 self.write(" ");
10254 self.write_keyword("REFERENCES");
10255 self.write_space();
10256 self.generate_table(&refs.table)?;
10257 if !refs.columns.is_empty() {
10258 if self.config.pretty {
10259 self.write(" (");
10260 self.write_newline();
10261 self.indent_level += 1;
10262 for (i, col) in refs.columns.iter().enumerate() {
10263 if i > 0 {
10264 self.write(",");
10265 self.write_newline();
10266 }
10267 self.write_indent();
10268 self.generate_identifier(col)?;
10269 }
10270 self.indent_level -= 1;
10271 self.write_newline();
10272 self.write_indent();
10273 self.write(")");
10274 } else {
10275 self.write(" (");
10276 for (i, col) in refs.columns.iter().enumerate() {
10277 if i > 0 {
10278 self.write(", ");
10279 }
10280 self.generate_identifier(col)?;
10281 }
10282 self.write(")");
10283 }
10284 }
10285 self.generate_referential_actions(refs)?;
10286 } else {
10287 if let Some(ref action) = on_delete {
10289 self.write_space();
10290 self.write_keyword("ON DELETE");
10291 self.write_space();
10292 self.generate_referential_action(action);
10293 }
10294 if let Some(ref action) = on_update {
10295 self.write_space();
10296 self.write_keyword("ON UPDATE");
10297 self.write_space();
10298 self.generate_referential_action(action);
10299 }
10300 }
10301 self.generate_constraint_modifiers(modifiers);
10302 }
10303 TableConstraint::Check {
10304 name,
10305 expression,
10306 modifiers,
10307 } => {
10308 if let Some(ref n) = name {
10309 self.write_keyword("CONSTRAINT");
10310 self.write_space();
10311 self.generate_identifier(n)?;
10312 self.write_space();
10313 }
10314 self.write_keyword("CHECK");
10315 self.write(" (");
10316 self.generate_expression(expression)?;
10317 self.write(")");
10318 self.generate_constraint_modifiers(modifiers);
10319 }
10320 TableConstraint::Assume { name, expression } => {
10321 if let Some(ref n) = name {
10322 self.write_keyword("CONSTRAINT");
10323 self.write_space();
10324 self.generate_identifier(n)?;
10325 self.write_space();
10326 }
10327 self.write_keyword("ASSUME");
10328 self.write(" (");
10329 self.generate_expression(expression)?;
10330 self.write(")");
10331 }
10332 TableConstraint::Default {
10333 name,
10334 expression,
10335 column,
10336 } => {
10337 if let Some(ref n) = name {
10338 self.write_keyword("CONSTRAINT");
10339 self.write_space();
10340 self.generate_identifier(n)?;
10341 self.write_space();
10342 }
10343 self.write_keyword("DEFAULT");
10344 self.write_space();
10345 self.generate_expression(expression)?;
10346 self.write_space();
10347 self.write_keyword("FOR");
10348 self.write_space();
10349 self.generate_identifier(column)?;
10350 }
10351 TableConstraint::Index {
10352 name,
10353 columns,
10354 kind,
10355 modifiers,
10356 use_key_keyword,
10357 expression,
10358 index_type,
10359 granularity,
10360 } => {
10361 if expression.is_some() {
10363 self.write_keyword("INDEX");
10364 if let Some(ref n) = name {
10365 self.write_space();
10366 self.generate_identifier(n)?;
10367 }
10368 if let Some(ref expr) = expression {
10369 self.write_space();
10370 self.generate_expression(expr)?;
10371 }
10372 if let Some(ref idx_type) = index_type {
10373 self.write_space();
10374 self.write_keyword("TYPE");
10375 self.write_space();
10376 self.generate_expression(idx_type)?;
10377 }
10378 if let Some(ref gran) = granularity {
10379 self.write_space();
10380 self.write_keyword("GRANULARITY");
10381 self.write_space();
10382 self.generate_expression(gran)?;
10383 }
10384 } else {
10385 use crate::dialects::DialectType;
10389 let index_keyword = if *use_key_keyword
10390 && !matches!(self.config.dialect, Some(DialectType::MySQL))
10391 {
10392 "KEY"
10393 } else {
10394 "INDEX"
10395 };
10396
10397 if let Some(ref k) = kind {
10399 self.write_keyword(k);
10400 if k != "UNIQUE" {
10402 self.write_space();
10403 self.write_keyword(index_keyword);
10404 }
10405 } else {
10406 self.write_keyword(index_keyword);
10407 }
10408
10409 if modifiers.using_before_columns && name.is_none() {
10411 if let Some(ref using) = modifiers.using {
10412 self.write_space();
10413 self.write_keyword("USING");
10414 self.write_space();
10415 self.write_keyword(using);
10416 }
10417 }
10418
10419 if let Some(ref n) = name {
10421 self.write_space();
10422 self.generate_identifier(n)?;
10423 }
10424
10425 if modifiers.using_before_columns && name.is_some() {
10427 if let Some(ref using) = modifiers.using {
10428 self.write_space();
10429 self.write_keyword("USING");
10430 self.write_space();
10431 self.write_keyword(using);
10432 }
10433 }
10434
10435 self.write(" (");
10437 for (i, col) in columns.iter().enumerate() {
10438 if i > 0 {
10439 self.write(", ");
10440 }
10441 self.generate_identifier(col)?;
10442 }
10443 self.write(")");
10444
10445 if !modifiers.using_before_columns {
10447 if let Some(ref using) = modifiers.using {
10448 self.write_space();
10449 self.write_keyword("USING");
10450 self.write_space();
10451 self.write_keyword(using);
10452 }
10453 }
10454
10455 self.generate_constraint_modifiers_without_using(modifiers);
10457 }
10458 }
10459 TableConstraint::Projection { name, expression } => {
10460 self.write_keyword("PROJECTION");
10462 self.write_space();
10463 self.generate_identifier(name)?;
10464 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
10465 if let Expression::Raw(raw) = expression {
10466 if raw
10467 .sql
10468 .trim_start()
10469 .to_ascii_uppercase()
10470 .starts_with("INDEX ")
10471 {
10472 self.write_space();
10473 self.write(raw.sql.trim());
10474 return Ok(());
10475 }
10476 }
10477 }
10478 self.write(" (");
10479 self.generate_expression(expression)?;
10480 self.write(")");
10481 }
10482 TableConstraint::Like { source, options } => {
10483 self.write_keyword("LIKE");
10484 self.write_space();
10485 self.generate_table(source)?;
10486 for (action, prop) in options {
10487 self.write_space();
10488 match action {
10489 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
10490 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
10491 }
10492 self.write_space();
10493 self.write_keyword(prop);
10494 }
10495 }
10496 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
10497 self.write_keyword("PERIOD FOR SYSTEM_TIME");
10498 self.write(" (");
10499 self.generate_identifier(start_col)?;
10500 self.write(", ");
10501 self.generate_identifier(end_col)?;
10502 self.write(")");
10503 }
10504 TableConstraint::Exclude {
10505 name,
10506 using,
10507 elements,
10508 include_columns,
10509 where_clause,
10510 with_params,
10511 using_index_tablespace,
10512 modifiers: _,
10513 } => {
10514 if let Some(ref n) = name {
10515 self.write_keyword("CONSTRAINT");
10516 self.write_space();
10517 self.generate_identifier(n)?;
10518 self.write_space();
10519 }
10520 self.write_keyword("EXCLUDE");
10521 if let Some(ref method) = using {
10522 self.write_space();
10523 self.write_keyword("USING");
10524 self.write_space();
10525 self.write(method);
10526 self.write("(");
10527 } else {
10528 self.write(" (");
10529 }
10530 for (i, elem) in elements.iter().enumerate() {
10531 if i > 0 {
10532 self.write(", ");
10533 }
10534 self.write(&elem.expression);
10535 self.write_space();
10536 self.write_keyword("WITH");
10537 self.write_space();
10538 self.write(&elem.operator);
10539 }
10540 self.write(")");
10541 if !include_columns.is_empty() {
10542 self.write_space();
10543 self.write_keyword("INCLUDE");
10544 self.write(" (");
10545 for (i, col) in include_columns.iter().enumerate() {
10546 if i > 0 {
10547 self.write(", ");
10548 }
10549 self.generate_identifier(col)?;
10550 }
10551 self.write(")");
10552 }
10553 if !with_params.is_empty() {
10554 self.write_space();
10555 self.write_keyword("WITH");
10556 self.write(" (");
10557 for (i, (key, val)) in with_params.iter().enumerate() {
10558 if i > 0 {
10559 self.write(", ");
10560 }
10561 self.write(key);
10562 self.write("=");
10563 self.write(val);
10564 }
10565 self.write(")");
10566 }
10567 if let Some(ref tablespace) = using_index_tablespace {
10568 self.write_space();
10569 self.write_keyword("USING INDEX TABLESPACE");
10570 self.write_space();
10571 self.write(tablespace);
10572 }
10573 if let Some(ref where_expr) = where_clause {
10574 self.write_space();
10575 self.write_keyword("WHERE");
10576 self.write(" (");
10577 self.generate_expression(where_expr)?;
10578 self.write(")");
10579 }
10580 }
10581 TableConstraint::Tags(tags) => {
10582 self.write_keyword("TAG");
10583 self.write(" (");
10584 for (i, expr) in tags.expressions.iter().enumerate() {
10585 if i > 0 {
10586 self.write(", ");
10587 }
10588 self.generate_expression(expr)?;
10589 }
10590 self.write(")");
10591 }
10592 TableConstraint::InitiallyDeferred { deferred } => {
10593 self.write_keyword("INITIALLY");
10594 self.write_space();
10595 if *deferred {
10596 self.write_keyword("DEFERRED");
10597 } else {
10598 self.write_keyword("IMMEDIATE");
10599 }
10600 }
10601 }
10602 Ok(())
10603 }
10604
10605 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10606 if let Some(using) = &modifiers.using {
10608 self.write_space();
10609 self.write_keyword("USING");
10610 self.write_space();
10611 self.write_keyword(using);
10612 }
10613 if let Some(enforced) = modifiers.enforced {
10615 self.write_space();
10616 if enforced {
10617 self.write_keyword("ENFORCED");
10618 } else {
10619 self.write_keyword("NOT ENFORCED");
10620 }
10621 }
10622 if let Some(deferrable) = modifiers.deferrable {
10624 self.write_space();
10625 if deferrable {
10626 self.write_keyword("DEFERRABLE");
10627 } else {
10628 self.write_keyword("NOT DEFERRABLE");
10629 }
10630 }
10631 if let Some(initially_deferred) = modifiers.initially_deferred {
10633 self.write_space();
10634 if initially_deferred {
10635 self.write_keyword("INITIALLY DEFERRED");
10636 } else {
10637 self.write_keyword("INITIALLY IMMEDIATE");
10638 }
10639 }
10640 if modifiers.norely {
10642 self.write_space();
10643 self.write_keyword("NORELY");
10644 }
10645 if modifiers.rely {
10647 self.write_space();
10648 self.write_keyword("RELY");
10649 }
10650 if modifiers.not_valid {
10652 self.write_space();
10653 self.write_keyword("NOT VALID");
10654 }
10655 if let Some(on_conflict) = &modifiers.on_conflict {
10657 self.write_space();
10658 self.write_keyword("ON CONFLICT");
10659 self.write_space();
10660 self.write_keyword(on_conflict);
10661 }
10662 if !modifiers.with_options.is_empty() {
10664 self.write_space();
10665 self.write_keyword("WITH");
10666 self.write(" (");
10667 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
10668 if i > 0 {
10669 self.write(", ");
10670 }
10671 self.write(key);
10672 self.write("=");
10673 self.write(value);
10674 }
10675 self.write(")");
10676 }
10677 if let Some(ref fg) = modifiers.on_filegroup {
10679 self.write_space();
10680 self.write_keyword("ON");
10681 self.write_space();
10682 let _ = self.generate_identifier(fg);
10683 }
10684 }
10685
10686 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
10688 if let Some(enforced) = modifiers.enforced {
10690 self.write_space();
10691 if enforced {
10692 self.write_keyword("ENFORCED");
10693 } else {
10694 self.write_keyword("NOT ENFORCED");
10695 }
10696 }
10697 if let Some(deferrable) = modifiers.deferrable {
10699 self.write_space();
10700 if deferrable {
10701 self.write_keyword("DEFERRABLE");
10702 } else {
10703 self.write_keyword("NOT DEFERRABLE");
10704 }
10705 }
10706 if let Some(initially_deferred) = modifiers.initially_deferred {
10708 self.write_space();
10709 if initially_deferred {
10710 self.write_keyword("INITIALLY DEFERRED");
10711 } else {
10712 self.write_keyword("INITIALLY IMMEDIATE");
10713 }
10714 }
10715 if modifiers.norely {
10717 self.write_space();
10718 self.write_keyword("NORELY");
10719 }
10720 if modifiers.rely {
10722 self.write_space();
10723 self.write_keyword("RELY");
10724 }
10725 if modifiers.not_valid {
10727 self.write_space();
10728 self.write_keyword("NOT VALID");
10729 }
10730 if let Some(on_conflict) = &modifiers.on_conflict {
10732 self.write_space();
10733 self.write_keyword("ON CONFLICT");
10734 self.write_space();
10735 self.write_keyword(on_conflict);
10736 }
10737 self.generate_index_specific_modifiers(modifiers);
10739 }
10740
10741 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10743 if let Some(ref comment) = modifiers.comment {
10744 self.write_space();
10745 self.write_keyword("COMMENT");
10746 self.write(" '");
10747 self.write(comment);
10748 self.write("'");
10749 }
10750 if let Some(visible) = modifiers.visible {
10751 self.write_space();
10752 if visible {
10753 self.write_keyword("VISIBLE");
10754 } else {
10755 self.write_keyword("INVISIBLE");
10756 }
10757 }
10758 if let Some(ref attr) = modifiers.engine_attribute {
10759 self.write_space();
10760 self.write_keyword("ENGINE_ATTRIBUTE");
10761 self.write(" = '");
10762 self.write(attr);
10763 self.write("'");
10764 }
10765 if let Some(ref parser) = modifiers.with_parser {
10766 self.write_space();
10767 self.write_keyword("WITH PARSER");
10768 self.write_space();
10769 self.write(parser);
10770 }
10771 }
10772
10773 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
10774 if !fk_ref.match_after_actions {
10776 if let Some(ref match_type) = fk_ref.match_type {
10777 self.write_space();
10778 self.write_keyword("MATCH");
10779 self.write_space();
10780 match match_type {
10781 MatchType::Full => self.write_keyword("FULL"),
10782 MatchType::Partial => self.write_keyword("PARTIAL"),
10783 MatchType::Simple => self.write_keyword("SIMPLE"),
10784 }
10785 }
10786 }
10787
10788 if fk_ref.on_update_first {
10790 if let Some(ref action) = fk_ref.on_update {
10791 self.write_space();
10792 self.write_keyword("ON UPDATE");
10793 self.write_space();
10794 self.generate_referential_action(action);
10795 }
10796 if let Some(ref action) = fk_ref.on_delete {
10797 self.write_space();
10798 self.write_keyword("ON DELETE");
10799 self.write_space();
10800 self.generate_referential_action(action);
10801 }
10802 } else {
10803 if let Some(ref action) = fk_ref.on_delete {
10804 self.write_space();
10805 self.write_keyword("ON DELETE");
10806 self.write_space();
10807 self.generate_referential_action(action);
10808 }
10809 if let Some(ref action) = fk_ref.on_update {
10810 self.write_space();
10811 self.write_keyword("ON UPDATE");
10812 self.write_space();
10813 self.generate_referential_action(action);
10814 }
10815 }
10816
10817 if fk_ref.match_after_actions {
10819 if let Some(ref match_type) = fk_ref.match_type {
10820 self.write_space();
10821 self.write_keyword("MATCH");
10822 self.write_space();
10823 match match_type {
10824 MatchType::Full => self.write_keyword("FULL"),
10825 MatchType::Partial => self.write_keyword("PARTIAL"),
10826 MatchType::Simple => self.write_keyword("SIMPLE"),
10827 }
10828 }
10829 }
10830
10831 if let Some(deferrable) = fk_ref.deferrable {
10833 self.write_space();
10834 if deferrable {
10835 self.write_keyword("DEFERRABLE");
10836 } else {
10837 self.write_keyword("NOT DEFERRABLE");
10838 }
10839 }
10840
10841 Ok(())
10842 }
10843
10844 fn generate_referential_action(&mut self, action: &ReferentialAction) {
10845 match action {
10846 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
10847 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
10848 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
10849 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
10850 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
10851 }
10852 }
10853
10854 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
10855 if let Some(ref object_id_args) = dt.object_id_args {
10857 if matches!(
10858 self.config.dialect,
10859 Some(crate::dialects::DialectType::TSQL)
10860 | Some(crate::dialects::DialectType::Fabric)
10861 ) {
10862 self.write_keyword("IF NOT OBJECT_ID");
10863 self.write("(");
10864 self.write(object_id_args);
10865 self.write(")");
10866 self.write_space();
10867 self.write_keyword("IS NULL BEGIN DROP TABLE");
10868 self.write_space();
10869 for (i, table) in dt.names.iter().enumerate() {
10870 if i > 0 {
10871 self.write(", ");
10872 }
10873 self.generate_table(table)?;
10874 }
10875 self.write("; ");
10876 self.write_keyword("END");
10877 return Ok(());
10878 }
10879 }
10880
10881 let saved_athena_hive_context = self.athena_hive_context;
10883 if matches!(
10884 self.config.dialect,
10885 Some(crate::dialects::DialectType::Athena)
10886 ) {
10887 self.athena_hive_context = true;
10888 }
10889
10890 for comment in &dt.leading_comments {
10892 self.write_formatted_comment(comment);
10893 self.write_space();
10894 }
10895 if dt.iceberg {
10896 self.write_keyword("DROP ICEBERG TABLE");
10897 } else {
10898 self.write_keyword("DROP TABLE");
10899 }
10900
10901 if dt.if_exists {
10902 self.write_space();
10903 self.write_keyword("IF EXISTS");
10904 }
10905
10906 self.write_space();
10907 for (i, table) in dt.names.iter().enumerate() {
10908 if i > 0 {
10909 self.write(", ");
10910 }
10911 self.generate_table(table)?;
10912 }
10913
10914 if dt.cascade_constraints {
10915 self.write_space();
10916 self.write_keyword("CASCADE CONSTRAINTS");
10917 } else if dt.cascade {
10918 self.write_space();
10919 self.write_keyword("CASCADE");
10920 }
10921
10922 if dt.restrict {
10923 self.write_space();
10924 self.write_keyword("RESTRICT");
10925 }
10926
10927 if dt.purge {
10928 self.write_space();
10929 self.write_keyword("PURGE");
10930 }
10931
10932 if dt.sync {
10933 self.write_space();
10934 self.write_keyword("SYNC");
10935 }
10936
10937 self.athena_hive_context = saved_athena_hive_context;
10939
10940 Ok(())
10941 }
10942
10943 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10944 self.write_keyword("UNDROP");
10945 self.write_space();
10946 self.write_keyword(&u.kind);
10947 if u.if_exists {
10948 self.write_space();
10949 self.write_keyword("IF EXISTS");
10950 }
10951 self.write_space();
10952 self.generate_table(&u.name)?;
10953 if let Some(rename_to) = &u.rename_to {
10954 self.write_space();
10955 self.write_keyword("RENAME TO");
10956 self.write_space();
10957 self.generate_table(rename_to)?;
10958 }
10959 Ok(())
10960 }
10961
10962 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
10963 let saved_athena_hive_context = self.athena_hive_context;
10965 if matches!(
10966 self.config.dialect,
10967 Some(crate::dialects::DialectType::Athena)
10968 ) {
10969 self.athena_hive_context = true;
10970 }
10971
10972 self.write_keyword("ALTER");
10973 if let Some(ref modifier) = at.table_modifier {
10975 if !matches!(
10976 self.config.dialect,
10977 Some(crate::dialects::DialectType::DuckDB)
10978 ) {
10979 self.write_space();
10980 self.write_keyword(modifier);
10981 }
10982 }
10983 self.write(" ");
10984 self.write_keyword("TABLE");
10985 if at.if_exists {
10986 self.write_space();
10987 self.write_keyword("IF EXISTS");
10988 }
10989 self.write_space();
10990 self.generate_table(&at.name)?;
10991
10992 if let Some(ref on_cluster) = at.on_cluster {
10994 self.write_space();
10995 self.generate_on_cluster(on_cluster)?;
10996 }
10997
10998 if let Some(ref partition) = at.partition {
11000 self.write_space();
11001 self.write_keyword("PARTITION");
11002 self.write("(");
11003 for (i, (key, value)) in partition.iter().enumerate() {
11004 if i > 0 {
11005 self.write(", ");
11006 }
11007 self.generate_identifier(key)?;
11008 self.write(" = ");
11009 self.generate_expression(value)?;
11010 }
11011 self.write(")");
11012 }
11013
11014 if let Some(ref with_check) = at.with_check {
11016 self.write_space();
11017 self.write_keyword(with_check);
11018 }
11019
11020 if self.config.pretty {
11021 self.write_newline();
11023 self.indent_level += 1;
11024 for (i, action) in at.actions.iter().enumerate() {
11025 let is_continuation = i > 0
11027 && matches!(
11028 (&at.actions[i - 1], action),
11029 (
11030 AlterTableAction::AddColumn { .. },
11031 AlterTableAction::AddColumn { .. }
11032 ) | (
11033 AlterTableAction::AddConstraint(_),
11034 AlterTableAction::AddConstraint(_)
11035 )
11036 );
11037 if i > 0 {
11038 self.write(",");
11039 self.write_newline();
11040 }
11041 self.write_indent();
11042 self.generate_alter_action_with_continuation(action, is_continuation)?;
11043 }
11044 self.indent_level -= 1;
11045 } else {
11046 for (i, action) in at.actions.iter().enumerate() {
11047 let is_continuation = i > 0
11049 && matches!(
11050 (&at.actions[i - 1], action),
11051 (
11052 AlterTableAction::AddColumn { .. },
11053 AlterTableAction::AddColumn { .. }
11054 ) | (
11055 AlterTableAction::AddConstraint(_),
11056 AlterTableAction::AddConstraint(_)
11057 )
11058 );
11059 if i > 0 {
11060 self.write(",");
11061 }
11062 self.write_space();
11063 self.generate_alter_action_with_continuation(action, is_continuation)?;
11064 }
11065 }
11066
11067 if let Some(ref algorithm) = at.algorithm {
11069 self.write(", ");
11070 self.write_keyword("ALGORITHM");
11071 self.write("=");
11072 self.write_keyword(algorithm);
11073 }
11074 if let Some(ref lock) = at.lock {
11075 self.write(", ");
11076 self.write_keyword("LOCK");
11077 self.write("=");
11078 self.write_keyword(lock);
11079 }
11080
11081 self.athena_hive_context = saved_athena_hive_context;
11083
11084 Ok(())
11085 }
11086
11087 fn generate_alter_action_with_continuation(
11088 &mut self,
11089 action: &AlterTableAction,
11090 is_continuation: bool,
11091 ) -> Result<()> {
11092 match action {
11093 AlterTableAction::AddColumn {
11094 column,
11095 if_not_exists,
11096 position,
11097 } => {
11098 use crate::dialects::DialectType;
11099 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
11103 let is_tsql_like = matches!(
11104 self.config.dialect,
11105 Some(DialectType::TSQL) | Some(DialectType::Fabric)
11106 );
11107 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
11109
11110 if is_continuation && (is_snowflake || is_tsql_like) {
11111 } else if is_snowflake {
11113 self.write_keyword("ADD");
11114 self.write_space();
11115 } else if is_athena {
11116 self.write_keyword("ADD COLUMNS");
11118 self.write(" (");
11119 } else if self.config.alter_table_include_column_keyword {
11120 self.write_keyword("ADD COLUMN");
11121 self.write_space();
11122 } else {
11123 self.write_keyword("ADD");
11125 self.write_space();
11126 }
11127
11128 if *if_not_exists {
11129 self.write_keyword("IF NOT EXISTS");
11130 self.write_space();
11131 }
11132 self.generate_column_def(column)?;
11133
11134 if is_athena {
11136 self.write(")");
11137 }
11138
11139 if let Some(pos) = position {
11141 self.write_space();
11142 match pos {
11143 ColumnPosition::First => self.write_keyword("FIRST"),
11144 ColumnPosition::After(col_name) => {
11145 self.write_keyword("AFTER");
11146 self.write_space();
11147 self.generate_identifier(col_name)?;
11148 }
11149 }
11150 }
11151 }
11152 AlterTableAction::DropColumn {
11153 name,
11154 if_exists,
11155 cascade,
11156 } => {
11157 self.write_keyword("DROP COLUMN");
11158 if *if_exists {
11159 self.write_space();
11160 self.write_keyword("IF EXISTS");
11161 }
11162 self.write_space();
11163 self.generate_identifier(name)?;
11164 if *cascade {
11165 self.write_space();
11166 self.write_keyword("CASCADE");
11167 }
11168 }
11169 AlterTableAction::DropColumns { names } => {
11170 self.write_keyword("DROP COLUMNS");
11171 self.write(" (");
11172 for (i, name) in names.iter().enumerate() {
11173 if i > 0 {
11174 self.write(", ");
11175 }
11176 self.generate_identifier(name)?;
11177 }
11178 self.write(")");
11179 }
11180 AlterTableAction::RenameColumn {
11181 old_name,
11182 new_name,
11183 if_exists,
11184 } => {
11185 self.write_keyword("RENAME COLUMN");
11186 if *if_exists {
11187 self.write_space();
11188 self.write_keyword("IF EXISTS");
11189 }
11190 self.write_space();
11191 self.generate_identifier(old_name)?;
11192 self.write_space();
11193 self.write_keyword("TO");
11194 self.write_space();
11195 self.generate_identifier(new_name)?;
11196 }
11197 AlterTableAction::AlterColumn {
11198 name,
11199 action,
11200 use_modify_keyword,
11201 } => {
11202 use crate::dialects::DialectType;
11203 let use_modify = *use_modify_keyword
11206 || (matches!(self.config.dialect, Some(DialectType::MySQL))
11207 && matches!(action, AlterColumnAction::SetDataType { .. }));
11208 if use_modify {
11209 self.write_keyword("MODIFY COLUMN");
11210 self.write_space();
11211 self.generate_identifier(name)?;
11212 if let AlterColumnAction::SetDataType {
11214 data_type,
11215 using: _,
11216 collate,
11217 } = action
11218 {
11219 self.write_space();
11220 self.generate_data_type(data_type)?;
11221 if let Some(collate_name) = collate {
11223 self.write_space();
11224 self.write_keyword("COLLATE");
11225 self.write_space();
11226 self.write(&format!("'{}'", collate_name));
11228 }
11229 } else {
11230 self.write_space();
11231 self.generate_alter_column_action(action)?;
11232 }
11233 } else if matches!(self.config.dialect, Some(DialectType::Hive))
11234 && matches!(action, AlterColumnAction::SetDataType { .. })
11235 {
11236 self.write_keyword("CHANGE COLUMN");
11238 self.write_space();
11239 self.generate_identifier(name)?;
11240 self.write_space();
11241 self.generate_identifier(name)?;
11242 if let AlterColumnAction::SetDataType { data_type, .. } = action {
11243 self.write_space();
11244 self.generate_data_type(data_type)?;
11245 }
11246 } else {
11247 self.write_keyword("ALTER COLUMN");
11248 self.write_space();
11249 self.generate_identifier(name)?;
11250 self.write_space();
11251 self.generate_alter_column_action(action)?;
11252 }
11253 }
11254 AlterTableAction::RenameTable(new_name) => {
11255 let mysql_like = matches!(
11257 self.config.dialect,
11258 Some(DialectType::MySQL)
11259 | Some(DialectType::Doris)
11260 | Some(DialectType::StarRocks)
11261 | Some(DialectType::SingleStore)
11262 );
11263 if mysql_like {
11264 self.write_keyword("RENAME");
11265 } else {
11266 self.write_keyword("RENAME TO");
11267 }
11268 self.write_space();
11269 let rename_table_with_db = !matches!(
11271 self.config.dialect,
11272 Some(DialectType::Doris)
11273 | Some(DialectType::DuckDB)
11274 | Some(DialectType::BigQuery)
11275 | Some(DialectType::PostgreSQL)
11276 );
11277 if !rename_table_with_db {
11278 let mut stripped = new_name.clone();
11279 stripped.schema = None;
11280 stripped.catalog = None;
11281 self.generate_table(&stripped)?;
11282 } else {
11283 self.generate_table(new_name)?;
11284 }
11285 }
11286 AlterTableAction::AddConstraint(constraint) => {
11287 if !is_continuation {
11290 self.write_keyword("ADD");
11291 self.write_space();
11292 }
11293 self.generate_table_constraint(constraint)?;
11294 }
11295 AlterTableAction::DropConstraint { name, if_exists } => {
11296 self.write_keyword("DROP CONSTRAINT");
11297 if *if_exists {
11298 self.write_space();
11299 self.write_keyword("IF EXISTS");
11300 }
11301 self.write_space();
11302 self.generate_identifier(name)?;
11303 }
11304 AlterTableAction::DropForeignKey { name } => {
11305 self.write_keyword("DROP FOREIGN KEY");
11306 self.write_space();
11307 self.generate_identifier(name)?;
11308 }
11309 AlterTableAction::DropPartition {
11310 partitions,
11311 if_exists,
11312 } => {
11313 self.write_keyword("DROP");
11314 if *if_exists {
11315 self.write_space();
11316 self.write_keyword("IF EXISTS");
11317 }
11318 for (i, partition) in partitions.iter().enumerate() {
11319 if i > 0 {
11320 self.write(",");
11321 }
11322 self.write_space();
11323 self.write_keyword("PARTITION");
11324 if partition.len() == 1 && partition[0].0.name == "__expr__" {
11326 self.write_space();
11328 self.generate_expression(&partition[0].1)?;
11329 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
11330 self.write_space();
11332 self.write_keyword("ALL");
11333 } else if partition.len() == 1 && partition[0].0.name == "ID" {
11334 self.write_space();
11336 self.write_keyword("ID");
11337 self.write_space();
11338 self.generate_expression(&partition[0].1)?;
11339 } else {
11340 self.write("(");
11342 for (j, (key, value)) in partition.iter().enumerate() {
11343 if j > 0 {
11344 self.write(", ");
11345 }
11346 self.generate_identifier(key)?;
11347 self.write(" = ");
11348 self.generate_expression(value)?;
11349 }
11350 self.write(")");
11351 }
11352 }
11353 }
11354 AlterTableAction::Delete { where_clause } => {
11355 self.write_keyword("DELETE");
11356 self.write_space();
11357 self.write_keyword("WHERE");
11358 self.write_space();
11359 self.generate_expression(where_clause)?;
11360 }
11361 AlterTableAction::SwapWith(target) => {
11362 self.write_keyword("SWAP WITH");
11363 self.write_space();
11364 self.generate_table(target)?;
11365 }
11366 AlterTableAction::SetProperty { properties } => {
11367 use crate::dialects::DialectType;
11368 self.write_keyword("SET");
11369 let is_trino_presto = matches!(
11371 self.config.dialect,
11372 Some(DialectType::Trino) | Some(DialectType::Presto)
11373 );
11374 if is_trino_presto {
11375 self.write_space();
11376 self.write_keyword("PROPERTIES");
11377 }
11378 let eq = if is_trino_presto { " = " } else { "=" };
11379 for (i, (key, value)) in properties.iter().enumerate() {
11380 if i > 0 {
11381 self.write(",");
11382 }
11383 self.write_space();
11384 if key.contains(' ') {
11386 self.generate_string_literal(key)?;
11387 } else {
11388 self.write(key);
11389 }
11390 self.write(eq);
11391 self.generate_expression(value)?;
11392 }
11393 }
11394 AlterTableAction::UnsetProperty { properties } => {
11395 self.write_keyword("UNSET");
11396 for (i, name) in properties.iter().enumerate() {
11397 if i > 0 {
11398 self.write(",");
11399 }
11400 self.write_space();
11401 self.write(name);
11402 }
11403 }
11404 AlterTableAction::ClusterBy { expressions } => {
11405 self.write_keyword("CLUSTER BY");
11406 self.write(" (");
11407 for (i, expr) in expressions.iter().enumerate() {
11408 if i > 0 {
11409 self.write(", ");
11410 }
11411 self.generate_expression(expr)?;
11412 }
11413 self.write(")");
11414 }
11415 AlterTableAction::SetTag { expressions } => {
11416 self.write_keyword("SET TAG");
11417 for (i, (key, value)) in expressions.iter().enumerate() {
11418 if i > 0 {
11419 self.write(",");
11420 }
11421 self.write_space();
11422 self.write(key);
11423 self.write(" = ");
11424 self.generate_expression(value)?;
11425 }
11426 }
11427 AlterTableAction::UnsetTag { names } => {
11428 self.write_keyword("UNSET TAG");
11429 for (i, name) in names.iter().enumerate() {
11430 if i > 0 {
11431 self.write(",");
11432 }
11433 self.write_space();
11434 self.write(name);
11435 }
11436 }
11437 AlterTableAction::SetOptions { expressions } => {
11438 self.write_keyword("SET");
11439 self.write(" (");
11440 for (i, expr) in expressions.iter().enumerate() {
11441 if i > 0 {
11442 self.write(", ");
11443 }
11444 self.generate_expression(expr)?;
11445 }
11446 self.write(")");
11447 }
11448 AlterTableAction::AlterIndex { name, visible } => {
11449 self.write_keyword("ALTER INDEX");
11450 self.write_space();
11451 self.generate_identifier(name)?;
11452 self.write_space();
11453 if *visible {
11454 self.write_keyword("VISIBLE");
11455 } else {
11456 self.write_keyword("INVISIBLE");
11457 }
11458 }
11459 AlterTableAction::SetAttribute { attribute } => {
11460 self.write_keyword("SET");
11461 self.write_space();
11462 self.write_keyword(attribute);
11463 }
11464 AlterTableAction::SetStageFileFormat { options } => {
11465 self.write_keyword("SET");
11466 self.write_space();
11467 self.write_keyword("STAGE_FILE_FORMAT");
11468 self.write(" = (");
11469 if let Some(opts) = options {
11470 self.generate_space_separated_properties(opts)?;
11471 }
11472 self.write(")");
11473 }
11474 AlterTableAction::SetStageCopyOptions { options } => {
11475 self.write_keyword("SET");
11476 self.write_space();
11477 self.write_keyword("STAGE_COPY_OPTIONS");
11478 self.write(" = (");
11479 if let Some(opts) = options {
11480 self.generate_space_separated_properties(opts)?;
11481 }
11482 self.write(")");
11483 }
11484 AlterTableAction::AddColumns { columns, cascade } => {
11485 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
11488 if is_oracle {
11489 self.write_keyword("ADD");
11490 } else {
11491 self.write_keyword("ADD COLUMNS");
11492 }
11493 self.write(" (");
11494 for (i, col) in columns.iter().enumerate() {
11495 if i > 0 {
11496 self.write(", ");
11497 }
11498 self.generate_column_def(col)?;
11499 }
11500 self.write(")");
11501 if *cascade {
11502 self.write_space();
11503 self.write_keyword("CASCADE");
11504 }
11505 }
11506 AlterTableAction::ChangeColumn {
11507 old_name,
11508 new_name,
11509 data_type,
11510 comment,
11511 cascade,
11512 } => {
11513 use crate::dialects::DialectType;
11514 let is_spark = matches!(
11515 self.config.dialect,
11516 Some(DialectType::Spark) | Some(DialectType::Databricks)
11517 );
11518 let is_rename = old_name.name != new_name.name;
11519
11520 if is_spark {
11521 if is_rename {
11522 self.write_keyword("RENAME COLUMN");
11524 self.write_space();
11525 self.generate_identifier(old_name)?;
11526 self.write_space();
11527 self.write_keyword("TO");
11528 self.write_space();
11529 self.generate_identifier(new_name)?;
11530 } else if comment.is_some() {
11531 self.write_keyword("ALTER COLUMN");
11533 self.write_space();
11534 self.generate_identifier(old_name)?;
11535 self.write_space();
11536 self.write_keyword("COMMENT");
11537 self.write_space();
11538 self.write("'");
11539 self.write(comment.as_ref().unwrap());
11540 self.write("'");
11541 } else if data_type.is_some() {
11542 self.write_keyword("ALTER COLUMN");
11544 self.write_space();
11545 self.generate_identifier(old_name)?;
11546 self.write_space();
11547 self.write_keyword("TYPE");
11548 self.write_space();
11549 self.generate_data_type(data_type.as_ref().unwrap())?;
11550 } else {
11551 self.write_keyword("CHANGE COLUMN");
11553 self.write_space();
11554 self.generate_identifier(old_name)?;
11555 self.write_space();
11556 self.generate_identifier(new_name)?;
11557 }
11558 } else {
11559 if data_type.is_some() {
11561 self.write_keyword("CHANGE COLUMN");
11562 } else {
11563 self.write_keyword("CHANGE");
11564 }
11565 self.write_space();
11566 self.generate_identifier(old_name)?;
11567 self.write_space();
11568 self.generate_identifier(new_name)?;
11569 if let Some(ref dt) = data_type {
11570 self.write_space();
11571 self.generate_data_type(dt)?;
11572 }
11573 if let Some(ref c) = comment {
11574 self.write_space();
11575 self.write_keyword("COMMENT");
11576 self.write_space();
11577 self.write("'");
11578 self.write(c);
11579 self.write("'");
11580 }
11581 if *cascade {
11582 self.write_space();
11583 self.write_keyword("CASCADE");
11584 }
11585 }
11586 }
11587 AlterTableAction::AddPartition {
11588 partition,
11589 if_not_exists,
11590 location,
11591 } => {
11592 self.write_keyword("ADD");
11593 self.write_space();
11594 if *if_not_exists {
11595 self.write_keyword("IF NOT EXISTS");
11596 self.write_space();
11597 }
11598 self.generate_expression(partition)?;
11599 if let Some(ref loc) = location {
11600 self.write_space();
11601 self.write_keyword("LOCATION");
11602 self.write_space();
11603 self.generate_expression(loc)?;
11604 }
11605 }
11606 AlterTableAction::AlterSortKey {
11607 this,
11608 expressions,
11609 compound,
11610 } => {
11611 self.write_keyword("ALTER");
11613 if *compound {
11614 self.write_space();
11615 self.write_keyword("COMPOUND");
11616 }
11617 self.write_space();
11618 self.write_keyword("SORTKEY");
11619 self.write_space();
11620 if let Some(style) = this {
11621 self.write_keyword(style);
11622 } else if !expressions.is_empty() {
11623 self.write("(");
11624 for (i, expr) in expressions.iter().enumerate() {
11625 if i > 0 {
11626 self.write(", ");
11627 }
11628 self.generate_expression(expr)?;
11629 }
11630 self.write(")");
11631 }
11632 }
11633 AlterTableAction::AlterDistStyle { style, distkey } => {
11634 self.write_keyword("ALTER");
11636 self.write_space();
11637 self.write_keyword("DISTSTYLE");
11638 self.write_space();
11639 self.write_keyword(style);
11640 if let Some(col) = distkey {
11641 self.write_space();
11642 self.write_keyword("DISTKEY");
11643 self.write_space();
11644 self.generate_identifier(col)?;
11645 }
11646 }
11647 AlterTableAction::SetTableProperties { properties } => {
11648 self.write_keyword("SET TABLE PROPERTIES");
11650 self.write(" (");
11651 for (i, (key, value)) in properties.iter().enumerate() {
11652 if i > 0 {
11653 self.write(", ");
11654 }
11655 self.generate_expression(key)?;
11656 self.write(" = ");
11657 self.generate_expression(value)?;
11658 }
11659 self.write(")");
11660 }
11661 AlterTableAction::SetLocation { location } => {
11662 self.write_keyword("SET LOCATION");
11664 self.write_space();
11665 self.write("'");
11666 self.write(location);
11667 self.write("'");
11668 }
11669 AlterTableAction::SetFileFormat { format } => {
11670 self.write_keyword("SET FILE FORMAT");
11672 self.write_space();
11673 self.write_keyword(format);
11674 }
11675 AlterTableAction::ReplacePartition { partition, source } => {
11676 self.write_keyword("REPLACE PARTITION");
11678 self.write_space();
11679 self.generate_expression(partition)?;
11680 if let Some(src) = source {
11681 self.write_space();
11682 self.write_keyword("FROM");
11683 self.write_space();
11684 self.generate_expression(src)?;
11685 }
11686 }
11687 AlterTableAction::Raw { sql } => {
11688 self.write(sql);
11689 }
11690 }
11691 Ok(())
11692 }
11693
11694 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
11695 match action {
11696 AlterColumnAction::SetDataType {
11697 data_type,
11698 using,
11699 collate,
11700 } => {
11701 use crate::dialects::DialectType;
11702 let is_no_prefix = matches!(
11707 self.config.dialect,
11708 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
11709 );
11710 let is_type_only = matches!(
11711 self.config.dialect,
11712 Some(DialectType::Redshift)
11713 | Some(DialectType::Spark)
11714 | Some(DialectType::Databricks)
11715 );
11716 if is_type_only {
11717 self.write_keyword("TYPE");
11718 self.write_space();
11719 } else if !is_no_prefix {
11720 self.write_keyword("SET DATA TYPE");
11721 self.write_space();
11722 }
11723 self.generate_data_type(data_type)?;
11724 if let Some(ref collation) = collate {
11725 self.write_space();
11726 self.write_keyword("COLLATE");
11727 self.write_space();
11728 self.write(collation);
11729 }
11730 if let Some(ref using_expr) = using {
11731 self.write_space();
11732 self.write_keyword("USING");
11733 self.write_space();
11734 self.generate_expression(using_expr)?;
11735 }
11736 }
11737 AlterColumnAction::SetDefault(expr) => {
11738 self.write_keyword("SET DEFAULT");
11739 self.write_space();
11740 self.generate_expression(expr)?;
11741 }
11742 AlterColumnAction::DropDefault => {
11743 self.write_keyword("DROP DEFAULT");
11744 }
11745 AlterColumnAction::SetNotNull => {
11746 self.write_keyword("SET NOT NULL");
11747 }
11748 AlterColumnAction::DropNotNull => {
11749 self.write_keyword("DROP NOT NULL");
11750 }
11751 AlterColumnAction::Comment(comment) => {
11752 self.write_keyword("COMMENT");
11753 self.write_space();
11754 self.generate_string_literal(comment)?;
11755 }
11756 AlterColumnAction::SetVisible => {
11757 self.write_keyword("SET VISIBLE");
11758 }
11759 AlterColumnAction::SetInvisible => {
11760 self.write_keyword("SET INVISIBLE");
11761 }
11762 }
11763 Ok(())
11764 }
11765
11766 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
11767 self.write_keyword("CREATE");
11768
11769 if ci.unique {
11770 self.write_space();
11771 self.write_keyword("UNIQUE");
11772 }
11773
11774 if let Some(ref clustered) = ci.clustered {
11776 self.write_space();
11777 self.write_keyword(clustered);
11778 }
11779
11780 self.write_space();
11781 self.write_keyword("INDEX");
11782
11783 if ci.concurrently {
11785 self.write_space();
11786 self.write_keyword("CONCURRENTLY");
11787 }
11788
11789 if ci.if_not_exists {
11790 self.write_space();
11791 self.write_keyword("IF NOT EXISTS");
11792 }
11793
11794 if !ci.name.name.is_empty() {
11796 self.write_space();
11797 self.generate_identifier(&ci.name)?;
11798 }
11799 self.write_space();
11800 self.write_keyword("ON");
11801 if matches!(self.config.dialect, Some(DialectType::Hive)) {
11803 self.write_space();
11804 self.write_keyword("TABLE");
11805 }
11806 self.write_space();
11807 self.generate_table(&ci.table)?;
11808
11809 if !ci.columns.is_empty() || ci.using.is_some() {
11812 let space_before_paren = false;
11813
11814 if let Some(ref using) = ci.using {
11815 self.write_space();
11816 self.write_keyword("USING");
11817 self.write_space();
11818 self.write(using);
11819 if space_before_paren {
11820 self.write(" (");
11821 } else {
11822 self.write("(");
11823 }
11824 } else {
11825 if space_before_paren {
11826 self.write(" (");
11827 } else {
11828 self.write("(");
11829 }
11830 }
11831 for (i, col) in ci.columns.iter().enumerate() {
11832 if i > 0 {
11833 self.write(", ");
11834 }
11835 self.generate_identifier(&col.column)?;
11836 if let Some(ref opclass) = col.opclass {
11837 self.write_space();
11838 self.write(opclass);
11839 }
11840 if col.desc {
11841 self.write_space();
11842 self.write_keyword("DESC");
11843 } else if col.asc {
11844 self.write_space();
11845 self.write_keyword("ASC");
11846 }
11847 if let Some(nulls_first) = col.nulls_first {
11848 self.write_space();
11849 self.write_keyword("NULLS");
11850 self.write_space();
11851 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
11852 }
11853 }
11854 self.write(")");
11855 }
11856
11857 if !ci.include_columns.is_empty() {
11859 self.write_space();
11860 self.write_keyword("INCLUDE");
11861 self.write(" (");
11862 for (i, col) in ci.include_columns.iter().enumerate() {
11863 if i > 0 {
11864 self.write(", ");
11865 }
11866 self.generate_identifier(col)?;
11867 }
11868 self.write(")");
11869 }
11870
11871 if !ci.with_options.is_empty() {
11873 self.write_space();
11874 self.write_keyword("WITH");
11875 self.write(" (");
11876 for (i, (key, value)) in ci.with_options.iter().enumerate() {
11877 if i > 0 {
11878 self.write(", ");
11879 }
11880 self.write(key);
11881 self.write("=");
11882 self.write(value);
11883 }
11884 self.write(")");
11885 }
11886
11887 if let Some(ref where_clause) = ci.where_clause {
11889 self.write_space();
11890 self.write_keyword("WHERE");
11891 self.write_space();
11892 self.generate_expression(where_clause)?;
11893 }
11894
11895 if let Some(ref on_fg) = ci.on_filegroup {
11897 self.write_space();
11898 self.write_keyword("ON");
11899 self.write_space();
11900 self.write(on_fg);
11901 }
11902
11903 Ok(())
11904 }
11905
11906 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
11907 self.write_keyword("DROP INDEX");
11908
11909 if di.concurrently {
11910 self.write_space();
11911 self.write_keyword("CONCURRENTLY");
11912 }
11913
11914 if di.if_exists {
11915 self.write_space();
11916 self.write_keyword("IF EXISTS");
11917 }
11918
11919 self.write_space();
11920 self.generate_table(&di.name)?;
11921
11922 if let Some(ref table) = di.table {
11923 self.write_space();
11924 self.write_keyword("ON");
11925 self.write_space();
11926 self.generate_table(table)?;
11927 }
11928
11929 Ok(())
11930 }
11931
11932 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
11933 self.write_keyword("CREATE");
11934
11935 if let Some(ref algorithm) = cv.algorithm {
11937 self.write_space();
11938 self.write_keyword("ALGORITHM");
11939 self.write("=");
11940 self.write_keyword(algorithm);
11941 }
11942
11943 if let Some(ref definer) = cv.definer {
11945 self.write_space();
11946 self.write_keyword("DEFINER");
11947 self.write("=");
11948 self.write(definer);
11949 }
11950
11951 if cv.security_sql_style && !cv.security_after_name {
11953 if let Some(ref security) = cv.security {
11954 self.write_space();
11955 self.write_keyword("SQL SECURITY");
11956 self.write_space();
11957 match security {
11958 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11959 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11960 FunctionSecurity::None => self.write_keyword("NONE"),
11961 }
11962 }
11963 }
11964
11965 if cv.or_alter {
11966 self.write_space();
11967 self.write_keyword("OR ALTER");
11968 } else if cv.or_replace {
11969 self.write_space();
11970 self.write_keyword("OR REPLACE");
11971 }
11972
11973 if cv.temporary {
11974 self.write_space();
11975 self.write_keyword("TEMPORARY");
11976 }
11977
11978 if cv.materialized {
11979 self.write_space();
11980 self.write_keyword("MATERIALIZED");
11981 }
11982
11983 if cv.secure {
11985 self.write_space();
11986 self.write_keyword("SECURE");
11987 }
11988
11989 self.write_space();
11990 self.write_keyword("VIEW");
11991
11992 if cv.if_not_exists {
11993 self.write_space();
11994 self.write_keyword("IF NOT EXISTS");
11995 }
11996
11997 self.write_space();
11998 self.generate_table(&cv.name)?;
11999
12000 if let Some(ref on_cluster) = cv.on_cluster {
12002 self.write_space();
12003 self.generate_on_cluster(on_cluster)?;
12004 }
12005
12006 if let Some(ref to_table) = cv.to_table {
12008 self.write_space();
12009 self.write_keyword("TO");
12010 self.write_space();
12011 self.generate_table(to_table)?;
12012 }
12013
12014 if !cv.materialized {
12017 if let Some(ref schema) = cv.schema {
12019 self.write(" (");
12020 for (i, expr) in schema.expressions.iter().enumerate() {
12021 if i > 0 {
12022 self.write(", ");
12023 }
12024 self.generate_expression(expr)?;
12025 }
12026 self.write(")");
12027 } else if !cv.columns.is_empty() {
12028 self.write(" (");
12029 for (i, col) in cv.columns.iter().enumerate() {
12030 if i > 0 {
12031 self.write(", ");
12032 }
12033 self.generate_identifier(&col.name)?;
12034 if !col.options.is_empty() {
12036 self.write_space();
12037 self.generate_options_clause(&col.options)?;
12038 }
12039 if let Some(ref comment) = col.comment {
12040 self.write_space();
12041 self.write_keyword("COMMENT");
12042 self.write_space();
12043 self.generate_string_literal(comment)?;
12044 }
12045 }
12046 self.write(")");
12047 }
12048
12049 if !cv.security_sql_style || cv.security_after_name {
12052 if let Some(ref security) = cv.security {
12053 self.write_space();
12054 if cv.security_sql_style {
12055 self.write_keyword("SQL SECURITY");
12056 } else {
12057 self.write_keyword("SECURITY");
12058 }
12059 self.write_space();
12060 match security {
12061 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12062 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12063 FunctionSecurity::None => self.write_keyword("NONE"),
12064 }
12065 }
12066 }
12067
12068 if cv.copy_grants {
12070 self.write_space();
12071 self.write_keyword("COPY GRANTS");
12072 }
12073 } else {
12074 if cv.copy_grants {
12076 self.write_space();
12077 self.write_keyword("COPY GRANTS");
12078 }
12079
12080 if let Some(ref schema) = cv.schema {
12082 self.write(" (");
12083 for (i, expr) in schema.expressions.iter().enumerate() {
12084 if i > 0 {
12085 self.write(", ");
12086 }
12087 self.generate_expression(expr)?;
12088 }
12089 self.write(")");
12090 } else if !cv.columns.is_empty() {
12091 self.write(" (");
12093 for (i, col) in cv.columns.iter().enumerate() {
12094 if i > 0 {
12095 self.write(", ");
12096 }
12097 self.generate_identifier(&col.name)?;
12098 if !col.options.is_empty() {
12100 self.write_space();
12101 self.generate_options_clause(&col.options)?;
12102 }
12103 if let Some(ref comment) = col.comment {
12104 self.write_space();
12105 self.write_keyword("COMMENT");
12106 self.write_space();
12107 self.generate_string_literal(comment)?;
12108 }
12109 }
12110 self.write(")");
12111 }
12112
12113 if let Some(ref unique_key) = cv.unique_key {
12115 self.write_space();
12116 self.write_keyword("KEY");
12117 self.write(" (");
12118 for (i, expr) in unique_key.expressions.iter().enumerate() {
12119 if i > 0 {
12120 self.write(", ");
12121 }
12122 self.generate_expression(expr)?;
12123 }
12124 self.write(")");
12125 }
12126 }
12127
12128 if let Some(ref row_access_policy) = cv.row_access_policy {
12129 self.write_space();
12130 self.write_keyword("WITH");
12131 self.write_space();
12132 self.write(row_access_policy);
12133 }
12134
12135 if let Some(ref comment) = cv.comment {
12137 self.write_space();
12138 self.write_keyword("COMMENT");
12139 self.write("=");
12140 self.generate_string_literal(comment)?;
12141 }
12142
12143 if !cv.tags.is_empty() {
12145 self.write_space();
12146 self.write_keyword("TAG");
12147 self.write(" (");
12148 for (i, (name, value)) in cv.tags.iter().enumerate() {
12149 if i > 0 {
12150 self.write(", ");
12151 }
12152 self.write(name);
12153 self.write("='");
12154 self.write(value);
12155 self.write("'");
12156 }
12157 self.write(")");
12158 }
12159
12160 if !cv.options.is_empty() {
12162 self.write_space();
12163 self.generate_options_clause(&cv.options)?;
12164 }
12165
12166 if let Some(ref build) = cv.build {
12168 self.write_space();
12169 self.write_keyword("BUILD");
12170 self.write_space();
12171 self.write_keyword(build);
12172 }
12173
12174 if let Some(ref refresh) = cv.refresh {
12176 self.write_space();
12177 self.generate_refresh_trigger_property(refresh)?;
12178 }
12179
12180 if let Some(auto_refresh) = cv.auto_refresh {
12182 self.write_space();
12183 self.write_keyword("AUTO REFRESH");
12184 self.write_space();
12185 if auto_refresh {
12186 self.write_keyword("YES");
12187 } else {
12188 self.write_keyword("NO");
12189 }
12190 }
12191
12192 for prop in &cv.table_properties {
12194 self.write_space();
12195 self.generate_expression(prop)?;
12196 }
12197
12198 if let Some(ref population) = cv.clickhouse_population {
12200 self.write_space();
12201 self.write_keyword(population);
12202 }
12203
12204 if !matches!(&cv.query, Expression::Null(_)) {
12206 self.write_space();
12207 self.write_keyword("AS");
12208 self.write_space();
12209
12210 if let Some(ref mode) = cv.locking_mode {
12212 self.write_keyword("LOCKING");
12213 self.write_space();
12214 self.write_keyword(mode);
12215 if let Some(ref access) = cv.locking_access {
12216 self.write_space();
12217 self.write_keyword("FOR");
12218 self.write_space();
12219 self.write_keyword(access);
12220 }
12221 self.write_space();
12222 }
12223
12224 if cv.query_parenthesized {
12225 self.write("(");
12226 }
12227 self.generate_expression(&cv.query)?;
12228 if cv.query_parenthesized {
12229 self.write(")");
12230 }
12231 }
12232
12233 if cv.no_schema_binding {
12235 self.write_space();
12236 self.write_keyword("WITH NO SCHEMA BINDING");
12237 }
12238
12239 Ok(())
12240 }
12241
12242 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
12243 self.write_keyword("DROP");
12244
12245 if dv.materialized {
12246 self.write_space();
12247 self.write_keyword("MATERIALIZED");
12248 }
12249
12250 self.write_space();
12251 self.write_keyword("VIEW");
12252
12253 if dv.if_exists {
12254 self.write_space();
12255 self.write_keyword("IF EXISTS");
12256 }
12257
12258 self.write_space();
12259 self.generate_table(&dv.name)?;
12260
12261 Ok(())
12262 }
12263
12264 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
12265 match tr.target {
12266 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
12267 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
12268 }
12269 if tr.if_exists {
12270 self.write_space();
12271 self.write_keyword("IF EXISTS");
12272 }
12273 self.write_space();
12274 self.generate_table(&tr.table)?;
12275
12276 if let Some(ref on_cluster) = tr.on_cluster {
12278 self.write_space();
12279 self.generate_on_cluster(on_cluster)?;
12280 }
12281
12282 if !tr.extra_tables.is_empty() {
12284 let skip_first = if let Some(first) = tr.extra_tables.first() {
12286 first.table.name == tr.table.name && first.star
12287 } else {
12288 false
12289 };
12290
12291 let strip_star = matches!(
12293 self.config.dialect,
12294 Some(crate::dialects::DialectType::PostgreSQL)
12295 | Some(crate::dialects::DialectType::Redshift)
12296 );
12297 if skip_first && !strip_star {
12298 self.write("*");
12299 }
12300
12301 for (i, entry) in tr.extra_tables.iter().enumerate() {
12303 if i == 0 && skip_first {
12304 continue; }
12306 self.write(", ");
12307 self.generate_table(&entry.table)?;
12308 if entry.star && !strip_star {
12309 self.write("*");
12310 }
12311 }
12312 }
12313
12314 if let Some(identity) = &tr.identity {
12316 self.write_space();
12317 match identity {
12318 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
12319 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
12320 }
12321 }
12322
12323 if tr.cascade {
12324 self.write_space();
12325 self.write_keyword("CASCADE");
12326 }
12327
12328 if tr.restrict {
12329 self.write_space();
12330 self.write_keyword("RESTRICT");
12331 }
12332
12333 if let Some(ref partition) = tr.partition {
12335 self.write_space();
12336 self.generate_expression(partition)?;
12337 }
12338
12339 Ok(())
12340 }
12341
12342 fn generate_use(&mut self, u: &Use) -> Result<()> {
12343 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
12345 self.write_keyword("DATABASE");
12346 self.write_space();
12347 self.generate_identifier(&u.this)?;
12348 return Ok(());
12349 }
12350
12351 self.write_keyword("USE");
12352
12353 if let Some(kind) = &u.kind {
12354 self.write_space();
12355 match kind {
12356 UseKind::Database => self.write_keyword("DATABASE"),
12357 UseKind::Schema => self.write_keyword("SCHEMA"),
12358 UseKind::Role => self.write_keyword("ROLE"),
12359 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
12360 UseKind::Catalog => self.write_keyword("CATALOG"),
12361 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
12362 }
12363 }
12364
12365 self.write_space();
12366 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
12369 self.write(&u.this.name);
12370 } else {
12371 self.generate_identifier(&u.this)?;
12372 }
12373 Ok(())
12374 }
12375
12376 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
12377 self.write_keyword("CACHE");
12378 if c.lazy {
12379 self.write_space();
12380 self.write_keyword("LAZY");
12381 }
12382 self.write_space();
12383 self.write_keyword("TABLE");
12384 self.write_space();
12385 self.generate_identifier(&c.table)?;
12386
12387 if !c.options.is_empty() {
12389 self.write_space();
12390 self.write_keyword("OPTIONS");
12391 self.write("(");
12392 for (i, (key, value)) in c.options.iter().enumerate() {
12393 if i > 0 {
12394 self.write(", ");
12395 }
12396 self.generate_expression(key)?;
12397 self.write(" = ");
12398 self.generate_expression(value)?;
12399 }
12400 self.write(")");
12401 }
12402
12403 if let Some(query) = &c.query {
12405 self.write_space();
12406 self.write_keyword("AS");
12407 self.write_space();
12408 self.generate_expression(query)?;
12409 }
12410
12411 Ok(())
12412 }
12413
12414 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
12415 self.write_keyword("UNCACHE TABLE");
12416 if u.if_exists {
12417 self.write_space();
12418 self.write_keyword("IF EXISTS");
12419 }
12420 self.write_space();
12421 self.generate_identifier(&u.table)?;
12422 Ok(())
12423 }
12424
12425 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
12426 self.write_keyword("LOAD DATA");
12427 if l.local {
12428 self.write_space();
12429 self.write_keyword("LOCAL");
12430 }
12431 self.write_space();
12432 self.write_keyword("INPATH");
12433 self.write_space();
12434 self.write("'");
12435 self.write(&l.inpath);
12436 self.write("'");
12437
12438 if l.overwrite {
12439 self.write_space();
12440 self.write_keyword("OVERWRITE");
12441 }
12442
12443 self.write_space();
12444 self.write_keyword("INTO TABLE");
12445 self.write_space();
12446 self.generate_expression(&l.table)?;
12447
12448 if !l.partition.is_empty() {
12450 self.write_space();
12451 self.write_keyword("PARTITION");
12452 self.write("(");
12453 for (i, (col, val)) in l.partition.iter().enumerate() {
12454 if i > 0 {
12455 self.write(", ");
12456 }
12457 self.generate_identifier(col)?;
12458 self.write(" = ");
12459 self.generate_expression(val)?;
12460 }
12461 self.write(")");
12462 }
12463
12464 if let Some(fmt) = &l.input_format {
12466 self.write_space();
12467 self.write_keyword("INPUTFORMAT");
12468 self.write_space();
12469 self.write("'");
12470 self.write(fmt);
12471 self.write("'");
12472 }
12473
12474 if let Some(serde) = &l.serde {
12476 self.write_space();
12477 self.write_keyword("SERDE");
12478 self.write_space();
12479 self.write("'");
12480 self.write(serde);
12481 self.write("'");
12482 }
12483
12484 Ok(())
12485 }
12486
12487 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
12488 self.write_keyword("PRAGMA");
12489 self.write_space();
12490
12491 if let Some(schema) = &p.schema {
12493 self.generate_identifier(schema)?;
12494 self.write(".");
12495 }
12496
12497 self.generate_identifier(&p.name)?;
12499
12500 if p.use_assignment_syntax {
12502 self.write(" = ");
12503 if let Some(value) = &p.value {
12504 self.generate_expression(value)?;
12505 } else if let Some(arg) = p.args.first() {
12506 self.generate_expression(arg)?;
12507 }
12508 } else if !p.args.is_empty() {
12509 self.write("(");
12510 for (i, arg) in p.args.iter().enumerate() {
12511 if i > 0 {
12512 self.write(", ");
12513 }
12514 self.generate_expression(arg)?;
12515 }
12516 self.write(")");
12517 }
12518
12519 Ok(())
12520 }
12521
12522 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
12523 self.write_keyword("GRANT");
12524 self.write_space();
12525
12526 for (i, privilege) in g.privileges.iter().enumerate() {
12528 if i > 0 {
12529 self.write(", ");
12530 }
12531 self.write_keyword(&privilege.name);
12532 if !privilege.columns.is_empty() {
12534 self.write("(");
12535 for (j, col) in privilege.columns.iter().enumerate() {
12536 if j > 0 {
12537 self.write(", ");
12538 }
12539 self.write(col);
12540 }
12541 self.write(")");
12542 }
12543 }
12544
12545 self.write_space();
12546 self.write_keyword("ON");
12547 self.write_space();
12548
12549 if let Some(kind) = &g.kind {
12551 self.write_keyword(kind);
12552 self.write_space();
12553 }
12554
12555 {
12557 use crate::dialects::DialectType;
12558 let should_upper = matches!(
12559 self.config.dialect,
12560 Some(DialectType::PostgreSQL)
12561 | Some(DialectType::CockroachDB)
12562 | Some(DialectType::Materialize)
12563 | Some(DialectType::RisingWave)
12564 ) && (g.kind.as_deref() == Some("FUNCTION")
12565 || g.kind.as_deref() == Some("PROCEDURE"));
12566 if should_upper {
12567 use crate::expressions::Identifier;
12568 let upper_id = Identifier {
12569 name: g.securable.name.to_ascii_uppercase(),
12570 quoted: g.securable.quoted,
12571 ..g.securable.clone()
12572 };
12573 self.generate_identifier(&upper_id)?;
12574 } else {
12575 self.generate_identifier(&g.securable)?;
12576 }
12577 }
12578
12579 if !g.function_params.is_empty() {
12581 self.write("(");
12582 for (i, param) in g.function_params.iter().enumerate() {
12583 if i > 0 {
12584 self.write(", ");
12585 }
12586 self.write(param);
12587 }
12588 self.write(")");
12589 }
12590
12591 self.write_space();
12592 self.write_keyword("TO");
12593 self.write_space();
12594
12595 for (i, principal) in g.principals.iter().enumerate() {
12597 if i > 0 {
12598 self.write(", ");
12599 }
12600 if principal.is_role {
12601 self.write_keyword("ROLE");
12602 self.write_space();
12603 } else if principal.is_group {
12604 self.write_keyword("GROUP");
12605 self.write_space();
12606 } else if principal.is_share {
12607 self.write_keyword("SHARE");
12608 self.write_space();
12609 }
12610 self.generate_identifier(&principal.name)?;
12611 }
12612
12613 if g.grant_option {
12615 self.write_space();
12616 self.write_keyword("WITH GRANT OPTION");
12617 }
12618
12619 if let Some(ref principal) = g.as_principal {
12621 self.write_space();
12622 self.write_keyword("AS");
12623 self.write_space();
12624 self.generate_identifier(principal)?;
12625 }
12626
12627 Ok(())
12628 }
12629
12630 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
12631 self.write_keyword("REVOKE");
12632 self.write_space();
12633
12634 if r.grant_option {
12636 self.write_keyword("GRANT OPTION FOR");
12637 self.write_space();
12638 }
12639
12640 for (i, privilege) in r.privileges.iter().enumerate() {
12642 if i > 0 {
12643 self.write(", ");
12644 }
12645 self.write_keyword(&privilege.name);
12646 if !privilege.columns.is_empty() {
12648 self.write("(");
12649 for (j, col) in privilege.columns.iter().enumerate() {
12650 if j > 0 {
12651 self.write(", ");
12652 }
12653 self.write(col);
12654 }
12655 self.write(")");
12656 }
12657 }
12658
12659 self.write_space();
12660 self.write_keyword("ON");
12661 self.write_space();
12662
12663 if let Some(kind) = &r.kind {
12665 self.write_keyword(kind);
12666 self.write_space();
12667 }
12668
12669 {
12671 use crate::dialects::DialectType;
12672 let should_upper = matches!(
12673 self.config.dialect,
12674 Some(DialectType::PostgreSQL)
12675 | Some(DialectType::CockroachDB)
12676 | Some(DialectType::Materialize)
12677 | Some(DialectType::RisingWave)
12678 ) && (r.kind.as_deref() == Some("FUNCTION")
12679 || r.kind.as_deref() == Some("PROCEDURE"));
12680 if should_upper {
12681 use crate::expressions::Identifier;
12682 let upper_id = Identifier {
12683 name: r.securable.name.to_ascii_uppercase(),
12684 quoted: r.securable.quoted,
12685 ..r.securable.clone()
12686 };
12687 self.generate_identifier(&upper_id)?;
12688 } else {
12689 self.generate_identifier(&r.securable)?;
12690 }
12691 }
12692
12693 if !r.function_params.is_empty() {
12695 self.write("(");
12696 for (i, param) in r.function_params.iter().enumerate() {
12697 if i > 0 {
12698 self.write(", ");
12699 }
12700 self.write(param);
12701 }
12702 self.write(")");
12703 }
12704
12705 self.write_space();
12706 self.write_keyword("FROM");
12707 self.write_space();
12708
12709 for (i, principal) in r.principals.iter().enumerate() {
12711 if i > 0 {
12712 self.write(", ");
12713 }
12714 if principal.is_role {
12715 self.write_keyword("ROLE");
12716 self.write_space();
12717 } else if principal.is_group {
12718 self.write_keyword("GROUP");
12719 self.write_space();
12720 } else if principal.is_share {
12721 self.write_keyword("SHARE");
12722 self.write_space();
12723 }
12724 self.generate_identifier(&principal.name)?;
12725 }
12726
12727 if r.cascade {
12729 self.write_space();
12730 self.write_keyword("CASCADE");
12731 } else if r.restrict {
12732 self.write_space();
12733 self.write_keyword("RESTRICT");
12734 }
12735
12736 Ok(())
12737 }
12738
12739 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
12740 self.write_keyword("COMMENT");
12741
12742 if c.exists {
12744 self.write_space();
12745 self.write_keyword("IF EXISTS");
12746 }
12747
12748 self.write_space();
12749 self.write_keyword("ON");
12750
12751 if c.materialized {
12753 self.write_space();
12754 self.write_keyword("MATERIALIZED");
12755 }
12756
12757 self.write_space();
12758 self.write_keyword(&c.kind);
12759 self.write_space();
12760
12761 self.generate_expression(&c.this)?;
12763
12764 self.write_space();
12765 self.write_keyword("IS");
12766 self.write_space();
12767
12768 self.generate_expression(&c.expression)?;
12770
12771 Ok(())
12772 }
12773
12774 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
12775 self.write_keyword("SET");
12776
12777 for (i, item) in s.items.iter().enumerate() {
12778 if i > 0 {
12779 self.write(",");
12780 }
12781 self.write_space();
12782
12783 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
12785 if let Some(ref kind) = item.kind {
12786 if has_variable_kind {
12790 if matches!(
12791 self.config.dialect,
12792 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
12793 ) {
12794 self.write_keyword("VARIABLE");
12795 self.write_space();
12796 }
12797 } else {
12798 self.write_keyword(kind);
12799 self.write_space();
12800 }
12801 }
12802
12803 let name_str = match &item.name {
12805 Expression::Identifier(id) => Some(id.name.as_str()),
12806 _ => None,
12807 };
12808
12809 let is_transaction = name_str == Some("TRANSACTION");
12810 let is_character_set = name_str == Some("CHARACTER SET");
12811 let is_names = name_str == Some("NAMES");
12812 let is_collate = name_str == Some("COLLATE");
12813 let is_identity_insert = name_str == Some("IDENTITY_INSERT");
12814 let is_value_only =
12815 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
12816
12817 if is_transaction {
12818 self.write_keyword("TRANSACTION");
12820 if let Expression::Identifier(id) = &item.value {
12821 if !id.name.is_empty() {
12822 self.write_space();
12823 self.write(&id.name);
12824 }
12825 }
12826 } else if is_character_set {
12827 self.write_keyword("CHARACTER SET");
12829 self.write_space();
12830 self.generate_set_value(&item.value)?;
12831 } else if is_names {
12832 self.write_keyword("NAMES");
12834 self.write_space();
12835 self.generate_set_value(&item.value)?;
12836 } else if is_collate {
12837 self.write_keyword("COLLATE");
12839 self.write_space();
12840 self.generate_set_value(&item.value)?;
12841 } else if is_identity_insert {
12842 self.write_keyword("IDENTITY_INSERT");
12844 self.write_space();
12845 self.generate_identity_insert_value(&item.value)?;
12846 } else if has_variable_kind {
12847 if let Some(ns) = name_str {
12850 self.write(ns);
12851 } else {
12852 self.generate_expression(&item.name)?;
12853 }
12854 self.write(" = ");
12855 self.generate_set_value(&item.value)?;
12856 } else if is_value_only {
12857 self.generate_expression(&item.name)?;
12859 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
12860 self.generate_expression(&item.name)?;
12862 self.write_space();
12863 self.generate_set_value(&item.value)?;
12864 } else {
12865 match &item.name {
12868 Expression::Identifier(id) => {
12869 self.write(&id.name);
12870 }
12871 _ => {
12872 self.generate_expression(&item.name)?;
12873 }
12874 }
12875 self.write(" = ");
12876 self.generate_set_value(&item.value)?;
12877 }
12878 }
12879
12880 Ok(())
12881 }
12882
12883 fn generate_identity_insert_value(&mut self, value: &Expression) -> Result<()> {
12884 if let Expression::Tuple(tuple) = value {
12885 if tuple.expressions.len() == 2 {
12886 self.generate_expression(&tuple.expressions[0])?;
12887 self.write_space();
12888 self.generate_set_value(&tuple.expressions[1])?;
12889 return Ok(());
12890 }
12891 }
12892
12893 self.generate_set_value(value)
12894 }
12895
12896 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
12899 if let Expression::Identifier(id) = value {
12900 match id.name.as_str() {
12901 "DEFAULT" | "ON" | "OFF" => {
12902 self.write_keyword(&id.name);
12903 return Ok(());
12904 }
12905 _ => {}
12906 }
12907 }
12908 self.generate_expression(value)
12909 }
12910
12911 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
12914 self.write_keyword("ALTER");
12915 if let Some(ref algorithm) = av.algorithm {
12917 self.write_space();
12918 self.write_keyword("ALGORITHM");
12919 self.write(" = ");
12920 self.write_keyword(algorithm);
12921 }
12922 if let Some(ref definer) = av.definer {
12923 self.write_space();
12924 self.write_keyword("DEFINER");
12925 self.write(" = ");
12926 self.write(definer);
12927 }
12928 if let Some(ref sql_security) = av.sql_security {
12929 self.write_space();
12930 self.write_keyword("SQL SECURITY");
12931 self.write(" = ");
12932 self.write_keyword(sql_security);
12933 }
12934 self.write_space();
12935 self.write_keyword("VIEW");
12936 self.write_space();
12937 self.generate_table(&av.name)?;
12938
12939 if !av.columns.is_empty() {
12941 self.write(" (");
12942 for (i, col) in av.columns.iter().enumerate() {
12943 if i > 0 {
12944 self.write(", ");
12945 }
12946 self.generate_identifier(&col.name)?;
12947 if let Some(ref comment) = col.comment {
12948 self.write_space();
12949 self.write_keyword("COMMENT");
12950 self.write(" ");
12951 self.generate_string_literal(comment)?;
12952 }
12953 }
12954 self.write(")");
12955 }
12956
12957 if let Some(ref opt) = av.with_option {
12959 self.write_space();
12960 self.write_keyword("WITH");
12961 self.write_space();
12962 self.write_keyword(opt);
12963 }
12964
12965 for action in &av.actions {
12966 self.write_space();
12967 match action {
12968 AlterViewAction::Rename(new_name) => {
12969 self.write_keyword("RENAME TO");
12970 self.write_space();
12971 self.generate_table(new_name)?;
12972 }
12973 AlterViewAction::OwnerTo(owner) => {
12974 self.write_keyword("OWNER TO");
12975 self.write_space();
12976 self.generate_identifier(owner)?;
12977 }
12978 AlterViewAction::SetSchema(schema) => {
12979 self.write_keyword("SET SCHEMA");
12980 self.write_space();
12981 self.generate_identifier(schema)?;
12982 }
12983 AlterViewAction::SetAuthorization(auth) => {
12984 self.write_keyword("SET AUTHORIZATION");
12985 self.write_space();
12986 self.write(auth);
12987 }
12988 AlterViewAction::AlterColumn { name, action } => {
12989 self.write_keyword("ALTER COLUMN");
12990 self.write_space();
12991 self.generate_identifier(name)?;
12992 self.write_space();
12993 self.generate_alter_column_action(action)?;
12994 }
12995 AlterViewAction::AsSelect(query) => {
12996 self.write_keyword("AS");
12997 self.write_space();
12998 self.generate_expression(query)?;
12999 }
13000 AlterViewAction::SetTblproperties(props) => {
13001 self.write_keyword("SET TBLPROPERTIES");
13002 self.write(" (");
13003 for (i, (key, value)) in props.iter().enumerate() {
13004 if i > 0 {
13005 self.write(", ");
13006 }
13007 self.generate_string_literal(key)?;
13008 self.write("=");
13009 self.generate_string_literal(value)?;
13010 }
13011 self.write(")");
13012 }
13013 AlterViewAction::UnsetTblproperties(keys) => {
13014 self.write_keyword("UNSET TBLPROPERTIES");
13015 self.write(" (");
13016 for (i, key) in keys.iter().enumerate() {
13017 if i > 0 {
13018 self.write(", ");
13019 }
13020 self.generate_string_literal(key)?;
13021 }
13022 self.write(")");
13023 }
13024 }
13025 }
13026
13027 Ok(())
13028 }
13029
13030 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
13031 self.write_keyword("ALTER INDEX");
13032 self.write_space();
13033 self.generate_identifier(&ai.name)?;
13034
13035 if let Some(table) = &ai.table {
13036 self.write_space();
13037 self.write_keyword("ON");
13038 self.write_space();
13039 self.generate_table(table)?;
13040 }
13041
13042 for action in &ai.actions {
13043 self.write_space();
13044 match action {
13045 AlterIndexAction::Rename(new_name) => {
13046 self.write_keyword("RENAME TO");
13047 self.write_space();
13048 self.generate_identifier(new_name)?;
13049 }
13050 AlterIndexAction::SetTablespace(tablespace) => {
13051 self.write_keyword("SET TABLESPACE");
13052 self.write_space();
13053 self.generate_identifier(tablespace)?;
13054 }
13055 AlterIndexAction::Visible(visible) => {
13056 if *visible {
13057 self.write_keyword("VISIBLE");
13058 } else {
13059 self.write_keyword("INVISIBLE");
13060 }
13061 }
13062 }
13063 }
13064
13065 Ok(())
13066 }
13067
13068 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
13069 for comment in &cs.leading_comments {
13071 self.write_formatted_comment(comment);
13072 self.write_space();
13073 }
13074
13075 let saved_athena_hive_context = self.athena_hive_context;
13077 if matches!(
13078 self.config.dialect,
13079 Some(crate::dialects::DialectType::Athena)
13080 ) {
13081 self.athena_hive_context = true;
13082 }
13083
13084 self.write_keyword("CREATE SCHEMA");
13085
13086 if cs.if_not_exists {
13087 self.write_space();
13088 self.write_keyword("IF NOT EXISTS");
13089 }
13090
13091 self.write_space();
13092 for (i, part) in cs.name.iter().enumerate() {
13093 if i > 0 {
13094 self.write(".");
13095 }
13096 self.generate_identifier(part)?;
13097 }
13098
13099 if let Some(ref clone_parts) = cs.clone_from {
13100 self.write_keyword(" CLONE ");
13101 for (i, part) in clone_parts.iter().enumerate() {
13102 if i > 0 {
13103 self.write(".");
13104 }
13105 self.generate_identifier(part)?;
13106 }
13107 }
13108
13109 if let Some(ref at_clause) = cs.at_clause {
13110 self.write_space();
13111 self.generate_expression(at_clause)?;
13112 }
13113
13114 if let Some(auth) = &cs.authorization {
13115 self.write_space();
13116 self.write_keyword("AUTHORIZATION");
13117 self.write_space();
13118 self.generate_identifier(auth)?;
13119 }
13120
13121 let with_properties: Vec<_> = cs
13124 .properties
13125 .iter()
13126 .filter(|p| matches!(p, Expression::Property(_)))
13127 .collect();
13128 let other_properties: Vec<_> = cs
13129 .properties
13130 .iter()
13131 .filter(|p| !matches!(p, Expression::Property(_)))
13132 .collect();
13133
13134 if !with_properties.is_empty() {
13136 self.write_space();
13137 self.write_keyword("WITH");
13138 self.write(" (");
13139 for (i, prop) in with_properties.iter().enumerate() {
13140 if i > 0 {
13141 self.write(", ");
13142 }
13143 self.generate_expression(prop)?;
13144 }
13145 self.write(")");
13146 }
13147
13148 for prop in other_properties {
13150 self.write_space();
13151 self.generate_expression(prop)?;
13152 }
13153
13154 self.athena_hive_context = saved_athena_hive_context;
13156
13157 Ok(())
13158 }
13159
13160 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
13161 self.write_keyword("DROP SCHEMA");
13162
13163 if ds.if_exists {
13164 self.write_space();
13165 self.write_keyword("IF EXISTS");
13166 }
13167
13168 self.write_space();
13169 self.generate_identifier(&ds.name)?;
13170
13171 if ds.cascade {
13172 self.write_space();
13173 self.write_keyword("CASCADE");
13174 }
13175
13176 Ok(())
13177 }
13178
13179 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
13180 self.write_keyword("DROP NAMESPACE");
13181
13182 if dn.if_exists {
13183 self.write_space();
13184 self.write_keyword("IF EXISTS");
13185 }
13186
13187 self.write_space();
13188 self.generate_identifier(&dn.name)?;
13189
13190 if dn.cascade {
13191 self.write_space();
13192 self.write_keyword("CASCADE");
13193 }
13194
13195 Ok(())
13196 }
13197
13198 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
13199 self.write_keyword("CREATE DATABASE");
13200
13201 if cd.if_not_exists {
13202 self.write_space();
13203 self.write_keyword("IF NOT EXISTS");
13204 }
13205
13206 self.write_space();
13207 self.generate_identifier(&cd.name)?;
13208
13209 if let Some(ref clone_src) = cd.clone_from {
13210 self.write_keyword(" CLONE ");
13211 self.generate_identifier(clone_src)?;
13212 }
13213
13214 if let Some(ref at_clause) = cd.at_clause {
13216 self.write_space();
13217 self.generate_expression(at_clause)?;
13218 }
13219
13220 for option in &cd.options {
13221 self.write_space();
13222 match option {
13223 DatabaseOption::CharacterSet(charset) => {
13224 self.write_keyword("CHARACTER SET");
13225 self.write(" = ");
13226 self.write(&format!("'{}'", charset));
13227 }
13228 DatabaseOption::Collate(collate) => {
13229 self.write_keyword("COLLATE");
13230 self.write(" = ");
13231 self.write(&format!("'{}'", collate));
13232 }
13233 DatabaseOption::Owner(owner) => {
13234 self.write_keyword("OWNER");
13235 self.write(" = ");
13236 self.generate_identifier(owner)?;
13237 }
13238 DatabaseOption::Template(template) => {
13239 self.write_keyword("TEMPLATE");
13240 self.write(" = ");
13241 self.generate_identifier(template)?;
13242 }
13243 DatabaseOption::Encoding(encoding) => {
13244 self.write_keyword("ENCODING");
13245 self.write(" = ");
13246 self.write(&format!("'{}'", encoding));
13247 }
13248 DatabaseOption::Location(location) => {
13249 self.write_keyword("LOCATION");
13250 self.write(" = ");
13251 self.write(&format!("'{}'", location));
13252 }
13253 }
13254 }
13255
13256 Ok(())
13257 }
13258
13259 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
13260 self.write_keyword("DROP DATABASE");
13261
13262 if dd.if_exists {
13263 self.write_space();
13264 self.write_keyword("IF EXISTS");
13265 }
13266
13267 self.write_space();
13268 self.generate_identifier(&dd.name)?;
13269
13270 if dd.sync {
13271 self.write_space();
13272 self.write_keyword("SYNC");
13273 }
13274
13275 Ok(())
13276 }
13277
13278 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
13279 self.write_keyword("CREATE");
13280
13281 if cf.or_alter {
13282 self.write_space();
13283 self.write_keyword("OR ALTER");
13284 } else if cf.or_replace {
13285 self.write_space();
13286 self.write_keyword("OR REPLACE");
13287 }
13288
13289 if cf.temporary {
13290 self.write_space();
13291 self.write_keyword("TEMPORARY");
13292 }
13293
13294 self.write_space();
13295 if cf.is_table_function {
13296 self.write_keyword("TABLE FUNCTION");
13297 } else {
13298 self.write_keyword("FUNCTION");
13299 }
13300
13301 if cf.if_not_exists {
13302 self.write_space();
13303 self.write_keyword("IF NOT EXISTS");
13304 }
13305
13306 self.write_space();
13307 self.generate_table(&cf.name)?;
13308 if cf.has_parens {
13309 let func_multiline = self.config.pretty
13310 && matches!(
13311 self.config.dialect,
13312 Some(crate::dialects::DialectType::TSQL)
13313 | Some(crate::dialects::DialectType::Fabric)
13314 )
13315 && !cf.parameters.is_empty();
13316 if func_multiline {
13317 self.write("(\n");
13318 self.indent_level += 2;
13319 self.write_indent();
13320 self.generate_function_parameters(&cf.parameters)?;
13321 self.write("\n");
13322 self.indent_level -= 2;
13323 self.write(")");
13324 } else {
13325 self.write("(");
13326 self.generate_function_parameters(&cf.parameters)?;
13327 self.write(")");
13328 }
13329 }
13330
13331 let use_multiline = self.config.pretty
13334 && matches!(
13335 self.config.dialect,
13336 Some(crate::dialects::DialectType::BigQuery)
13337 | Some(crate::dialects::DialectType::TSQL)
13338 | Some(crate::dialects::DialectType::Fabric)
13339 );
13340
13341 if cf.language_first {
13342 if let Some(lang) = &cf.language {
13344 if use_multiline {
13345 self.write_newline();
13346 } else {
13347 self.write_space();
13348 }
13349 self.write_keyword("LANGUAGE");
13350 self.write_space();
13351 self.write(lang);
13352 }
13353
13354 if let Some(sql_data) = &cf.sql_data_access {
13356 self.write_space();
13357 match sql_data {
13358 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13359 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13360 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13361 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13362 }
13363 }
13364
13365 if let Some(ref rtb) = cf.returns_table_body {
13366 if use_multiline {
13367 self.write_newline();
13368 } else {
13369 self.write_space();
13370 }
13371 self.write_keyword("RETURNS");
13372 self.write_space();
13373 self.write(rtb);
13374 } else if let Some(return_type) = &cf.return_type {
13375 if use_multiline {
13376 self.write_newline();
13377 } else {
13378 self.write_space();
13379 }
13380 self.write_keyword("RETURNS");
13381 self.write_space();
13382 self.generate_function_return_type(return_type)?;
13383 }
13384 } else {
13385 let is_duckdb = matches!(
13388 self.config.dialect,
13389 Some(crate::dialects::DialectType::DuckDB)
13390 );
13391 if let Some(ref rtb) = cf.returns_table_body {
13392 if !(is_duckdb && rtb.is_empty()) {
13393 if use_multiline {
13394 self.write_newline();
13395 } else {
13396 self.write_space();
13397 }
13398 self.write_keyword("RETURNS");
13399 self.write_space();
13400 self.write(rtb);
13401 }
13402 } else if let Some(return_type) = &cf.return_type {
13403 if !is_duckdb {
13405 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
13406 if use_multiline {
13407 self.write_newline();
13408 } else {
13409 self.write_space();
13410 }
13411 self.write_keyword("RETURNS");
13412 self.write_space();
13413 if is_table_return {
13414 self.write_keyword("TABLE");
13415 } else {
13416 self.generate_function_return_type(return_type)?;
13417 }
13418 }
13419 }
13420 }
13421
13422 if !cf.property_order.is_empty() {
13424 let is_bigquery = matches!(
13426 self.config.dialect,
13427 Some(crate::dialects::DialectType::BigQuery)
13428 );
13429 let is_postgres = matches!(
13430 self.config.dialect,
13431 Some(crate::dialects::DialectType::PostgreSQL)
13432 );
13433 let property_order = if is_bigquery {
13434 let mut reordered = Vec::new();
13436 let mut has_as = false;
13437 let mut has_options = false;
13438 for prop in &cf.property_order {
13439 match prop {
13440 FunctionPropertyKind::As => has_as = true,
13441 FunctionPropertyKind::Options => has_options = true,
13442 _ => {}
13443 }
13444 }
13445 if has_as && has_options {
13446 for prop in &cf.property_order {
13448 if *prop != FunctionPropertyKind::As
13449 && *prop != FunctionPropertyKind::Options
13450 {
13451 reordered.push(*prop);
13452 }
13453 }
13454 reordered.push(FunctionPropertyKind::Options);
13455 reordered.push(FunctionPropertyKind::As);
13456 reordered
13457 } else {
13458 cf.property_order.clone()
13459 }
13460 } else if is_postgres
13461 && cf.property_order.contains(&FunctionPropertyKind::As)
13462 && cf.property_order.contains(&FunctionPropertyKind::NullInput)
13463 {
13464 let mut reordered: Vec<_> = cf
13465 .property_order
13466 .iter()
13467 .copied()
13468 .filter(|prop| *prop != FunctionPropertyKind::As)
13469 .collect();
13470 reordered.push(FunctionPropertyKind::As);
13471 reordered
13472 } else {
13473 cf.property_order.clone()
13474 };
13475
13476 for prop in &property_order {
13477 match prop {
13478 FunctionPropertyKind::Set => {
13479 self.generate_function_set_options(cf)?;
13480 }
13481 FunctionPropertyKind::As => {
13482 self.generate_function_body(cf)?;
13483 }
13484 FunctionPropertyKind::Using => {
13485 self.generate_function_using_resources(cf)?;
13486 }
13487 FunctionPropertyKind::Language => {
13488 if !cf.language_first {
13489 if let Some(lang) = &cf.language {
13491 let use_multiline = self.config.pretty
13493 && matches!(
13494 self.config.dialect,
13495 Some(crate::dialects::DialectType::BigQuery)
13496 );
13497 if use_multiline {
13498 self.write_newline();
13499 } else {
13500 self.write_space();
13501 }
13502 self.write_keyword("LANGUAGE");
13503 self.write_space();
13504 self.write(lang);
13505 }
13506 }
13507 }
13508 FunctionPropertyKind::Determinism => {
13509 self.generate_function_determinism(cf)?;
13510 }
13511 FunctionPropertyKind::NullInput => {
13512 self.generate_function_null_input(cf)?;
13513 }
13514 FunctionPropertyKind::Security => {
13515 self.generate_function_security(cf)?;
13516 }
13517 FunctionPropertyKind::SqlDataAccess => {
13518 if !cf.language_first {
13519 self.generate_function_sql_data_access(cf)?;
13521 }
13522 }
13523 FunctionPropertyKind::Options => {
13524 if !cf.options.is_empty() {
13525 self.write_space();
13526 self.generate_options_clause(&cf.options)?;
13527 }
13528 }
13529 FunctionPropertyKind::Environment => {
13530 if !cf.environment.is_empty() {
13531 self.write_space();
13532 self.generate_environment_clause(&cf.environment)?;
13533 }
13534 }
13535 FunctionPropertyKind::Handler => {
13536 if let Some(ref h) = cf.handler {
13537 self.write_space();
13538 self.write_keyword("HANDLER");
13539 if cf.handler_uses_eq {
13540 self.write(" = ");
13541 } else {
13542 self.write_space();
13543 }
13544 self.write("'");
13545 self.write(h);
13546 self.write("'");
13547 }
13548 }
13549 FunctionPropertyKind::RuntimeVersion => {
13550 if let Some(ref runtime_version) = cf.runtime_version {
13551 self.write_space();
13552 self.write_keyword("RUNTIME_VERSION");
13553 self.write("='");
13554 self.write(runtime_version);
13555 self.write("'");
13556 }
13557 }
13558 FunctionPropertyKind::Packages => {
13559 if let Some(ref packages) = cf.packages {
13560 self.write_space();
13561 self.write_keyword("PACKAGES");
13562 self.write("=(");
13563 for (i, package) in packages.iter().enumerate() {
13564 if i > 0 {
13565 self.write(", ");
13566 }
13567 self.write("'");
13568 self.write(package);
13569 self.write("'");
13570 }
13571 self.write(")");
13572 }
13573 }
13574 FunctionPropertyKind::ParameterStyle => {
13575 if let Some(ref ps) = cf.parameter_style {
13576 self.write_space();
13577 self.write_keyword("PARAMETER STYLE");
13578 self.write_space();
13579 self.write_keyword(ps);
13580 }
13581 }
13582 }
13583 }
13584
13585 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
13587 {
13588 self.write_space();
13589 self.generate_options_clause(&cf.options)?;
13590 }
13591
13592 if !cf.environment.is_empty()
13594 && !cf
13595 .property_order
13596 .contains(&FunctionPropertyKind::Environment)
13597 {
13598 self.write_space();
13599 self.generate_environment_clause(&cf.environment)?;
13600 }
13601 } else {
13602 if matches!(
13605 self.config.dialect,
13606 Some(crate::dialects::DialectType::BigQuery)
13607 ) {
13608 self.generate_function_determinism(cf)?;
13609 }
13610
13611 let use_multiline = self.config.pretty
13613 && matches!(
13614 self.config.dialect,
13615 Some(crate::dialects::DialectType::BigQuery)
13616 );
13617
13618 if !cf.language_first {
13619 if let Some(lang) = &cf.language {
13620 if use_multiline {
13621 self.write_newline();
13622 } else {
13623 self.write_space();
13624 }
13625 self.write_keyword("LANGUAGE");
13626 self.write_space();
13627 self.write(lang);
13628 }
13629
13630 self.generate_function_sql_data_access(cf)?;
13632 }
13633
13634 if !matches!(
13636 self.config.dialect,
13637 Some(crate::dialects::DialectType::BigQuery)
13638 ) {
13639 self.generate_function_determinism(cf)?;
13640 }
13641
13642 self.generate_function_null_input(cf)?;
13643 self.generate_function_security(cf)?;
13644 self.generate_function_set_options(cf)?;
13645
13646 if !cf.options.is_empty() {
13648 self.write_space();
13649 self.generate_options_clause(&cf.options)?;
13650 }
13651
13652 if !cf.environment.is_empty() {
13654 self.write_space();
13655 self.generate_environment_clause(&cf.environment)?;
13656 }
13657
13658 if let Some(ref h) = cf.handler {
13659 self.write_space();
13660 self.write_keyword("HANDLER");
13661 if cf.handler_uses_eq {
13662 self.write(" = ");
13663 } else {
13664 self.write_space();
13665 }
13666 self.write("'");
13667 self.write(h);
13668 self.write("'");
13669 }
13670
13671 if let Some(ref runtime_version) = cf.runtime_version {
13672 self.write_space();
13673 self.write_keyword("RUNTIME_VERSION");
13674 self.write("='");
13675 self.write(runtime_version);
13676 self.write("'");
13677 }
13678
13679 if let Some(ref packages) = cf.packages {
13680 self.write_space();
13681 self.write_keyword("PACKAGES");
13682 self.write("=(");
13683 for (i, package) in packages.iter().enumerate() {
13684 if i > 0 {
13685 self.write(", ");
13686 }
13687 self.write("'");
13688 self.write(package);
13689 self.write("'");
13690 }
13691 self.write(")");
13692 }
13693
13694 self.generate_function_body(cf)?;
13695 self.generate_function_using_resources(cf)?;
13696 }
13697
13698 Ok(())
13699 }
13700
13701 fn generate_function_return_type(&mut self, return_type: &DataType) -> Result<()> {
13702 if matches!(
13703 self.config.dialect,
13704 Some(crate::dialects::DialectType::PostgreSQL)
13705 ) {
13706 if let DataType::Custom { name } = return_type {
13707 if name.eq_ignore_ascii_case("integer") {
13708 self.write_keyword("INT");
13709 return Ok(());
13710 }
13711 }
13712 }
13713
13714 self.generate_data_type(return_type)
13715 }
13716
13717 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
13719 for opt in &cf.set_options {
13720 self.write_space();
13721 self.write_keyword("SET");
13722 self.write_space();
13723 self.write(&opt.name);
13724 match &opt.value {
13725 FunctionSetValue::Value { value, use_to } => {
13726 if *use_to {
13727 self.write(" TO ");
13728 } else {
13729 self.write(" = ");
13730 }
13731 self.write(value);
13732 }
13733 FunctionSetValue::FromCurrent => {
13734 self.write_space();
13735 self.write_keyword("FROM CURRENT");
13736 }
13737 }
13738 }
13739 Ok(())
13740 }
13741
13742 fn generate_function_using_resources(&mut self, cf: &CreateFunction) -> Result<()> {
13743 if cf.using_resources.is_empty() {
13744 return Ok(());
13745 }
13746
13747 self.write_space();
13748 self.write_keyword("USING");
13749 for resource in &cf.using_resources {
13750 self.write_space();
13751 self.write_keyword(&resource.kind);
13752 self.write_space();
13753 self.generate_string_literal(&resource.uri)?;
13754 }
13755 Ok(())
13756 }
13757
13758 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
13760 if let Some(body) = &cf.body {
13761 self.write_space();
13763 let use_multiline = self.config.pretty
13765 && matches!(
13766 self.config.dialect,
13767 Some(crate::dialects::DialectType::BigQuery)
13768 );
13769 match body {
13770 FunctionBody::Block(block) => {
13771 self.write_keyword("AS");
13772 if matches!(
13773 self.config.dialect,
13774 Some(crate::dialects::DialectType::TSQL)
13775 ) {
13776 self.write(" BEGIN ");
13777 self.write(block);
13778 self.write(" END");
13779 } else if matches!(
13780 self.config.dialect,
13781 Some(crate::dialects::DialectType::PostgreSQL)
13782 ) {
13783 self.write(" $$");
13784 self.write(block);
13785 self.write("$$");
13786 } else {
13787 let escaped = self.escape_block_for_single_quote(block);
13789 if use_multiline {
13791 self.write_newline();
13792 } else {
13793 self.write(" ");
13794 }
13795 self.write("'");
13796 self.write(&escaped);
13797 self.write("'");
13798 }
13799 }
13800 FunctionBody::StringLiteral(s) => {
13801 self.write_keyword("AS");
13802 if use_multiline {
13804 self.write_newline();
13805 } else {
13806 self.write(" ");
13807 }
13808 self.write("'");
13809 self.write(s);
13810 self.write("'");
13811 }
13812 FunctionBody::Expression(expr) => {
13813 self.write_keyword("AS");
13814 self.write_space();
13815 self.generate_expression(expr)?;
13816 }
13817 FunctionBody::External(name) => {
13818 self.write_keyword("EXTERNAL NAME");
13819 self.write(" '");
13820 self.write(name);
13821 self.write("'");
13822 }
13823 FunctionBody::Return(expr) => {
13824 if matches!(
13825 self.config.dialect,
13826 Some(crate::dialects::DialectType::DuckDB)
13827 ) {
13828 self.write_keyword("AS");
13830 self.write_space();
13831 let is_table_return = cf.returns_table_body.is_some()
13833 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
13834 if is_table_return {
13835 self.write_keyword("TABLE");
13836 self.write_space();
13837 }
13838 self.generate_expression(expr)?;
13839 } else {
13840 if self.config.create_function_return_as {
13841 self.write_keyword("AS");
13842 if self.config.pretty
13844 && matches!(
13845 self.config.dialect,
13846 Some(crate::dialects::DialectType::TSQL)
13847 | Some(crate::dialects::DialectType::Fabric)
13848 )
13849 {
13850 self.write_newline();
13851 } else {
13852 self.write_space();
13853 }
13854 }
13855 self.write_keyword("RETURN");
13856 self.write_space();
13857 self.generate_expression(expr)?;
13858 }
13859 }
13860 FunctionBody::Statements(stmts) => {
13861 self.write_keyword("AS");
13862 self.write(" BEGIN ");
13863 for (i, stmt) in stmts.iter().enumerate() {
13864 if i > 0 {
13865 self.write(" ");
13866 }
13867 self.generate_expression(stmt)?;
13868 self.write(";");
13869 }
13870 self.write(" END");
13871 }
13872 FunctionBody::RawBlock(text) => {
13873 self.write_newline();
13874 self.write(text);
13875 }
13876 FunctionBody::DollarQuoted { content, tag } => {
13877 self.write_keyword("AS");
13878 self.write(" ");
13879 let supports_dollar_quoting = matches!(
13881 self.config.dialect,
13882 Some(crate::dialects::DialectType::PostgreSQL)
13883 | Some(crate::dialects::DialectType::Databricks)
13884 | Some(crate::dialects::DialectType::Redshift)
13885 | Some(crate::dialects::DialectType::DuckDB)
13886 );
13887 if supports_dollar_quoting {
13888 self.write("$");
13890 if let Some(t) = tag {
13891 self.write(t);
13892 }
13893 self.write("$");
13894 self.write(content);
13895 self.write("$");
13896 if let Some(t) = tag {
13897 self.write(t);
13898 }
13899 self.write("$");
13900 } else {
13901 let escaped = self.escape_block_for_single_quote(content);
13903 self.write("'");
13904 self.write(&escaped);
13905 self.write("'");
13906 }
13907 }
13908 }
13909 }
13910 Ok(())
13911 }
13912
13913 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
13915 if let Some(det) = cf.deterministic {
13916 self.write_space();
13917 if matches!(
13918 self.config.dialect,
13919 Some(crate::dialects::DialectType::BigQuery)
13920 ) {
13921 if det {
13923 self.write_keyword("DETERMINISTIC");
13924 } else {
13925 self.write_keyword("NOT DETERMINISTIC");
13926 }
13927 } else {
13928 if det {
13930 self.write_keyword("IMMUTABLE");
13931 } else {
13932 self.write_keyword("VOLATILE");
13933 }
13934 }
13935 }
13936 Ok(())
13937 }
13938
13939 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
13941 if let Some(returns_null) = cf.returns_null_on_null_input {
13942 self.write_space();
13943 if returns_null {
13944 if cf.strict {
13945 self.write_keyword("STRICT");
13946 } else {
13947 self.write_keyword("RETURNS NULL ON NULL INPUT");
13948 }
13949 } else {
13950 self.write_keyword("CALLED ON NULL INPUT");
13951 }
13952 }
13953 Ok(())
13954 }
13955
13956 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
13958 if let Some(security) = &cf.security {
13959 self.write_space();
13960 if matches!(
13962 self.config.dialect,
13963 Some(crate::dialects::DialectType::MySQL)
13964 ) {
13965 self.write_keyword("SQL SECURITY");
13966 } else {
13967 self.write_keyword("SECURITY");
13968 }
13969 self.write_space();
13970 match security {
13971 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13972 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13973 FunctionSecurity::None => self.write_keyword("NONE"),
13974 }
13975 }
13976 Ok(())
13977 }
13978
13979 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
13981 if let Some(sql_data) = &cf.sql_data_access {
13982 self.write_space();
13983 match sql_data {
13984 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13985 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13986 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13987 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13988 }
13989 }
13990 Ok(())
13991 }
13992
13993 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
13994 for (i, param) in params.iter().enumerate() {
13995 if i > 0 {
13996 self.write(", ");
13997 }
13998
13999 if let Some(mode) = ¶m.mode {
14000 if let Some(text) = ¶m.mode_text {
14001 self.write(text);
14002 } else {
14003 match mode {
14004 ParameterMode::In => self.write_keyword("IN"),
14005 ParameterMode::Out => self.write_keyword("OUT"),
14006 ParameterMode::InOut => self.write_keyword("INOUT"),
14007 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
14008 }
14009 }
14010 self.write_space();
14011 }
14012
14013 if let Some(name) = ¶m.name {
14014 self.generate_identifier(name)?;
14015 let skip_type =
14017 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
14018 if !skip_type {
14019 self.write_space();
14020 self.generate_data_type(¶m.data_type)?;
14021 }
14022 } else {
14023 self.generate_data_type(¶m.data_type)?;
14024 }
14025
14026 if let Some(default) = ¶m.default {
14027 if self.config.parameter_default_equals {
14028 self.write(" = ");
14029 } else {
14030 self.write(" DEFAULT ");
14031 }
14032 self.generate_expression(default)?;
14033 }
14034 }
14035
14036 Ok(())
14037 }
14038
14039 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
14040 self.write_keyword("DROP FUNCTION");
14041
14042 if df.if_exists {
14043 self.write_space();
14044 self.write_keyword("IF EXISTS");
14045 }
14046
14047 self.write_space();
14048 self.generate_table(&df.name)?;
14049
14050 if let Some(params) = &df.parameters {
14051 self.write(" (");
14052 for (i, dt) in params.iter().enumerate() {
14053 if i > 0 {
14054 self.write(", ");
14055 }
14056 self.generate_data_type(dt)?;
14057 }
14058 self.write(")");
14059 }
14060
14061 if df.cascade {
14062 self.write_space();
14063 self.write_keyword("CASCADE");
14064 }
14065
14066 Ok(())
14067 }
14068
14069 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
14070 self.write_keyword("CREATE");
14071
14072 if cp.or_alter {
14073 self.write_space();
14074 self.write_keyword("OR ALTER");
14075 } else if cp.or_replace {
14076 self.write_space();
14077 self.write_keyword("OR REPLACE");
14078 }
14079
14080 self.write_space();
14081 if cp.use_proc_keyword {
14082 self.write_keyword("PROC");
14083 } else {
14084 self.write_keyword("PROCEDURE");
14085 }
14086
14087 if cp.if_not_exists {
14088 self.write_space();
14089 self.write_keyword("IF NOT EXISTS");
14090 }
14091
14092 self.write_space();
14093 self.generate_table(&cp.name)?;
14094 if cp.has_parens {
14095 self.write("(");
14096 self.generate_function_parameters(&cp.parameters)?;
14097 self.write(")");
14098 } else if !cp.parameters.is_empty() {
14099 self.write_space();
14101 self.generate_function_parameters(&cp.parameters)?;
14102 }
14103
14104 if let Some(return_type) = &cp.return_type {
14106 self.write_space();
14107 self.write_keyword("RETURNS");
14108 self.write_space();
14109 self.generate_data_type(return_type)?;
14110 }
14111
14112 if let Some(execute_as) = &cp.execute_as {
14114 self.write_space();
14115 self.write_keyword("EXECUTE AS");
14116 self.write_space();
14117 self.write_keyword(execute_as);
14118 }
14119
14120 if let Some(lang) = &cp.language {
14121 self.write_space();
14122 self.write_keyword("LANGUAGE");
14123 self.write_space();
14124 self.write(lang);
14125 }
14126
14127 if let Some(security) = &cp.security {
14128 self.write_space();
14129 self.write_keyword("SECURITY");
14130 self.write_space();
14131 match security {
14132 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
14133 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
14134 FunctionSecurity::None => self.write_keyword("NONE"),
14135 }
14136 }
14137
14138 if !cp.with_options.is_empty() {
14140 self.write_space();
14141 self.write_keyword("WITH");
14142 self.write_space();
14143 for (i, opt) in cp.with_options.iter().enumerate() {
14144 if i > 0 {
14145 self.write(", ");
14146 }
14147 self.write(opt);
14148 }
14149 }
14150
14151 if let Some(body) = &cp.body {
14152 self.write_space();
14153 match body {
14154 FunctionBody::Block(block) => {
14155 self.write_keyword("AS");
14156 if matches!(
14157 self.config.dialect,
14158 Some(crate::dialects::DialectType::TSQL)
14159 ) {
14160 self.write(" BEGIN ");
14161 self.write(block);
14162 self.write(" END");
14163 } else if matches!(
14164 self.config.dialect,
14165 Some(crate::dialects::DialectType::PostgreSQL)
14166 ) {
14167 self.write(" $$");
14168 self.write(block);
14169 self.write("$$");
14170 } else {
14171 let escaped = self.escape_block_for_single_quote(block);
14173 self.write(" '");
14174 self.write(&escaped);
14175 self.write("'");
14176 }
14177 }
14178 FunctionBody::StringLiteral(s) => {
14179 self.write_keyword("AS");
14180 self.write(" '");
14181 self.write(s);
14182 self.write("'");
14183 }
14184 FunctionBody::Expression(expr) => {
14185 self.write_keyword("AS");
14186 self.write_space();
14187 self.generate_expression(expr)?;
14188 }
14189 FunctionBody::External(name) => {
14190 self.write_keyword("EXTERNAL NAME");
14191 self.write(" '");
14192 self.write(name);
14193 self.write("'");
14194 }
14195 FunctionBody::Return(expr) => {
14196 self.write_keyword("RETURN");
14197 self.write_space();
14198 self.generate_expression(expr)?;
14199 }
14200 FunctionBody::Statements(stmts) => {
14201 self.write_keyword("AS");
14202 self.write(" BEGIN ");
14203 for (i, stmt) in stmts.iter().enumerate() {
14204 if i > 0 {
14205 self.write(" ");
14206 }
14207 self.generate_expression(stmt)?;
14208 self.write(";");
14209 }
14210 self.write(" END");
14211 }
14212 FunctionBody::RawBlock(text) => {
14213 self.write_newline();
14214 self.write(text);
14215 }
14216 FunctionBody::DollarQuoted { content, tag } => {
14217 self.write_keyword("AS");
14218 self.write(" ");
14219 let supports_dollar_quoting = matches!(
14221 self.config.dialect,
14222 Some(crate::dialects::DialectType::PostgreSQL)
14223 | Some(crate::dialects::DialectType::Databricks)
14224 | Some(crate::dialects::DialectType::Redshift)
14225 | Some(crate::dialects::DialectType::DuckDB)
14226 );
14227 if supports_dollar_quoting {
14228 self.write("$");
14230 if let Some(t) = tag {
14231 self.write(t);
14232 }
14233 self.write("$");
14234 self.write(content);
14235 self.write("$");
14236 if let Some(t) = tag {
14237 self.write(t);
14238 }
14239 self.write("$");
14240 } else {
14241 let escaped = self.escape_block_for_single_quote(content);
14243 self.write("'");
14244 self.write(&escaped);
14245 self.write("'");
14246 }
14247 }
14248 }
14249 }
14250
14251 Ok(())
14252 }
14253
14254 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
14255 self.write_keyword("DROP PROCEDURE");
14256
14257 if dp.if_exists {
14258 self.write_space();
14259 self.write_keyword("IF EXISTS");
14260 }
14261
14262 self.write_space();
14263 self.generate_table(&dp.name)?;
14264
14265 if let Some(params) = &dp.parameters {
14266 self.write(" (");
14267 for (i, dt) in params.iter().enumerate() {
14268 if i > 0 {
14269 self.write(", ");
14270 }
14271 self.generate_data_type(dt)?;
14272 }
14273 self.write(")");
14274 }
14275
14276 if dp.cascade {
14277 self.write_space();
14278 self.write_keyword("CASCADE");
14279 }
14280
14281 Ok(())
14282 }
14283
14284 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
14285 self.write_keyword("CREATE");
14286
14287 if cs.or_replace {
14288 self.write_space();
14289 self.write_keyword("OR REPLACE");
14290 }
14291
14292 if cs.temporary {
14293 self.write_space();
14294 self.write_keyword("TEMPORARY");
14295 }
14296
14297 self.write_space();
14298 self.write_keyword("SEQUENCE");
14299
14300 if cs.if_not_exists {
14301 self.write_space();
14302 self.write_keyword("IF NOT EXISTS");
14303 }
14304
14305 self.write_space();
14306 self.generate_table(&cs.name)?;
14307
14308 if let Some(as_type) = &cs.as_type {
14310 self.write_space();
14311 self.write_keyword("AS");
14312 self.write_space();
14313 self.generate_data_type(as_type)?;
14314 }
14315
14316 if let Some(comment) = &cs.comment {
14318 self.write_space();
14319 self.write_keyword("COMMENT");
14320 self.write("=");
14321 self.generate_string_literal(comment)?;
14322 }
14323
14324 if !cs.property_order.is_empty() {
14326 for prop in &cs.property_order {
14327 match prop {
14328 SeqPropKind::Start => {
14329 if let Some(start) = cs.start {
14330 self.write_space();
14331 self.write_keyword("START WITH");
14332 self.write(&format!(" {}", start));
14333 }
14334 }
14335 SeqPropKind::Increment => {
14336 if let Some(inc) = cs.increment {
14337 self.write_space();
14338 self.write_keyword("INCREMENT BY");
14339 self.write(&format!(" {}", inc));
14340 }
14341 }
14342 SeqPropKind::Minvalue => {
14343 if let Some(min) = &cs.minvalue {
14344 self.write_space();
14345 match min {
14346 SequenceBound::Value(v) => {
14347 self.write_keyword("MINVALUE");
14348 self.write(&format!(" {}", v));
14349 }
14350 SequenceBound::None => {
14351 self.write_keyword("NO MINVALUE");
14352 }
14353 }
14354 }
14355 }
14356 SeqPropKind::Maxvalue => {
14357 if let Some(max) = &cs.maxvalue {
14358 self.write_space();
14359 match max {
14360 SequenceBound::Value(v) => {
14361 self.write_keyword("MAXVALUE");
14362 self.write(&format!(" {}", v));
14363 }
14364 SequenceBound::None => {
14365 self.write_keyword("NO MAXVALUE");
14366 }
14367 }
14368 }
14369 }
14370 SeqPropKind::Cache => {
14371 if let Some(cache) = cs.cache {
14372 self.write_space();
14373 self.write_keyword("CACHE");
14374 self.write(&format!(" {}", cache));
14375 }
14376 }
14377 SeqPropKind::NoCache => {
14378 self.write_space();
14379 self.write_keyword("NO CACHE");
14380 }
14381 SeqPropKind::NoCacheWord => {
14382 self.write_space();
14383 self.write_keyword("NOCACHE");
14384 }
14385 SeqPropKind::Cycle => {
14386 self.write_space();
14387 self.write_keyword("CYCLE");
14388 }
14389 SeqPropKind::NoCycle => {
14390 self.write_space();
14391 self.write_keyword("NO CYCLE");
14392 }
14393 SeqPropKind::NoCycleWord => {
14394 self.write_space();
14395 self.write_keyword("NOCYCLE");
14396 }
14397 SeqPropKind::OwnedBy => {
14398 if !cs.owned_by_none {
14400 if let Some(owned) = &cs.owned_by {
14401 self.write_space();
14402 self.write_keyword("OWNED BY");
14403 self.write_space();
14404 self.generate_table(owned)?;
14405 }
14406 }
14407 }
14408 SeqPropKind::Order => {
14409 self.write_space();
14410 self.write_keyword("ORDER");
14411 }
14412 SeqPropKind::NoOrder => {
14413 self.write_space();
14414 self.write_keyword("NOORDER");
14415 }
14416 SeqPropKind::Comment => {
14417 }
14419 SeqPropKind::Sharing => {
14420 if let Some(val) = &cs.sharing {
14421 self.write_space();
14422 self.write(&format!("SHARING={}", val));
14423 }
14424 }
14425 SeqPropKind::Keep => {
14426 self.write_space();
14427 self.write_keyword("KEEP");
14428 }
14429 SeqPropKind::NoKeep => {
14430 self.write_space();
14431 self.write_keyword("NOKEEP");
14432 }
14433 SeqPropKind::Scale => {
14434 self.write_space();
14435 self.write_keyword("SCALE");
14436 if let Some(modifier) = &cs.scale_modifier {
14437 if !modifier.is_empty() {
14438 self.write_space();
14439 self.write_keyword(modifier);
14440 }
14441 }
14442 }
14443 SeqPropKind::NoScale => {
14444 self.write_space();
14445 self.write_keyword("NOSCALE");
14446 }
14447 SeqPropKind::Shard => {
14448 self.write_space();
14449 self.write_keyword("SHARD");
14450 if let Some(modifier) = &cs.shard_modifier {
14451 if !modifier.is_empty() {
14452 self.write_space();
14453 self.write_keyword(modifier);
14454 }
14455 }
14456 }
14457 SeqPropKind::NoShard => {
14458 self.write_space();
14459 self.write_keyword("NOSHARD");
14460 }
14461 SeqPropKind::Session => {
14462 self.write_space();
14463 self.write_keyword("SESSION");
14464 }
14465 SeqPropKind::Global => {
14466 self.write_space();
14467 self.write_keyword("GLOBAL");
14468 }
14469 SeqPropKind::NoMinvalueWord => {
14470 self.write_space();
14471 self.write_keyword("NOMINVALUE");
14472 }
14473 SeqPropKind::NoMaxvalueWord => {
14474 self.write_space();
14475 self.write_keyword("NOMAXVALUE");
14476 }
14477 }
14478 }
14479 } else {
14480 if let Some(inc) = cs.increment {
14482 self.write_space();
14483 self.write_keyword("INCREMENT BY");
14484 self.write(&format!(" {}", inc));
14485 }
14486
14487 if let Some(min) = &cs.minvalue {
14488 self.write_space();
14489 match min {
14490 SequenceBound::Value(v) => {
14491 self.write_keyword("MINVALUE");
14492 self.write(&format!(" {}", v));
14493 }
14494 SequenceBound::None => {
14495 self.write_keyword("NO MINVALUE");
14496 }
14497 }
14498 }
14499
14500 if let Some(max) = &cs.maxvalue {
14501 self.write_space();
14502 match max {
14503 SequenceBound::Value(v) => {
14504 self.write_keyword("MAXVALUE");
14505 self.write(&format!(" {}", v));
14506 }
14507 SequenceBound::None => {
14508 self.write_keyword("NO MAXVALUE");
14509 }
14510 }
14511 }
14512
14513 if let Some(start) = cs.start {
14514 self.write_space();
14515 self.write_keyword("START WITH");
14516 self.write(&format!(" {}", start));
14517 }
14518
14519 if let Some(cache) = cs.cache {
14520 self.write_space();
14521 self.write_keyword("CACHE");
14522 self.write(&format!(" {}", cache));
14523 }
14524
14525 if cs.cycle {
14526 self.write_space();
14527 self.write_keyword("CYCLE");
14528 }
14529
14530 if let Some(owned) = &cs.owned_by {
14531 self.write_space();
14532 self.write_keyword("OWNED BY");
14533 self.write_space();
14534 self.generate_table(owned)?;
14535 }
14536 }
14537
14538 Ok(())
14539 }
14540
14541 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
14542 self.write_keyword("DROP SEQUENCE");
14543
14544 if ds.if_exists {
14545 self.write_space();
14546 self.write_keyword("IF EXISTS");
14547 }
14548
14549 self.write_space();
14550 self.generate_table(&ds.name)?;
14551
14552 if ds.cascade {
14553 self.write_space();
14554 self.write_keyword("CASCADE");
14555 }
14556
14557 Ok(())
14558 }
14559
14560 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
14561 self.write_keyword("ALTER SEQUENCE");
14562
14563 if als.if_exists {
14564 self.write_space();
14565 self.write_keyword("IF EXISTS");
14566 }
14567
14568 self.write_space();
14569 self.generate_table(&als.name)?;
14570
14571 if let Some(inc) = als.increment {
14572 self.write_space();
14573 self.write_keyword("INCREMENT BY");
14574 self.write(&format!(" {}", inc));
14575 }
14576
14577 if let Some(min) = &als.minvalue {
14578 self.write_space();
14579 match min {
14580 SequenceBound::Value(v) => {
14581 self.write_keyword("MINVALUE");
14582 self.write(&format!(" {}", v));
14583 }
14584 SequenceBound::None => {
14585 self.write_keyword("NO MINVALUE");
14586 }
14587 }
14588 }
14589
14590 if let Some(max) = &als.maxvalue {
14591 self.write_space();
14592 match max {
14593 SequenceBound::Value(v) => {
14594 self.write_keyword("MAXVALUE");
14595 self.write(&format!(" {}", v));
14596 }
14597 SequenceBound::None => {
14598 self.write_keyword("NO MAXVALUE");
14599 }
14600 }
14601 }
14602
14603 if let Some(start) = als.start {
14604 self.write_space();
14605 self.write_keyword("START WITH");
14606 self.write(&format!(" {}", start));
14607 }
14608
14609 if let Some(restart) = &als.restart {
14610 self.write_space();
14611 self.write_keyword("RESTART");
14612 if let Some(val) = restart {
14613 self.write_keyword(" WITH");
14614 self.write(&format!(" {}", val));
14615 }
14616 }
14617
14618 if let Some(cache) = als.cache {
14619 self.write_space();
14620 self.write_keyword("CACHE");
14621 self.write(&format!(" {}", cache));
14622 }
14623
14624 if let Some(cycle) = als.cycle {
14625 self.write_space();
14626 if cycle {
14627 self.write_keyword("CYCLE");
14628 } else {
14629 self.write_keyword("NO CYCLE");
14630 }
14631 }
14632
14633 if let Some(owned) = &als.owned_by {
14634 self.write_space();
14635 self.write_keyword("OWNED BY");
14636 self.write_space();
14637 if let Some(table) = owned {
14638 self.generate_table(table)?;
14639 } else {
14640 self.write_keyword("NONE");
14641 }
14642 }
14643
14644 Ok(())
14645 }
14646
14647 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
14648 self.write_keyword("CREATE");
14649
14650 if ct.or_alter {
14651 self.write_space();
14652 self.write_keyword("OR ALTER");
14653 } else if ct.or_replace {
14654 self.write_space();
14655 self.write_keyword("OR REPLACE");
14656 }
14657
14658 if ct.constraint {
14659 self.write_space();
14660 self.write_keyword("CONSTRAINT");
14661 }
14662
14663 self.write_space();
14664 self.write_keyword("TRIGGER");
14665 self.write_space();
14666 self.generate_identifier(&ct.name)?;
14667
14668 self.write_space();
14669 match ct.timing {
14670 TriggerTiming::Before => self.write_keyword("BEFORE"),
14671 TriggerTiming::After => self.write_keyword("AFTER"),
14672 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
14673 }
14674
14675 for (i, event) in ct.events.iter().enumerate() {
14677 if i > 0 {
14678 self.write_keyword(" OR");
14679 }
14680 self.write_space();
14681 match event {
14682 TriggerEvent::Insert => self.write_keyword("INSERT"),
14683 TriggerEvent::Update(cols) => {
14684 self.write_keyword("UPDATE");
14685 if let Some(cols) = cols {
14686 self.write_space();
14687 self.write_keyword("OF");
14688 for (j, col) in cols.iter().enumerate() {
14689 if j > 0 {
14690 self.write(",");
14691 }
14692 self.write_space();
14693 self.generate_identifier(col)?;
14694 }
14695 }
14696 }
14697 TriggerEvent::Delete => self.write_keyword("DELETE"),
14698 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
14699 }
14700 }
14701
14702 self.write_space();
14703 self.write_keyword("ON");
14704 self.write_space();
14705 self.generate_table(&ct.table)?;
14706
14707 if let Some(ref_clause) = &ct.referencing {
14709 self.write_space();
14710 self.write_keyword("REFERENCING");
14711 if let Some(old_table) = &ref_clause.old_table {
14712 self.write_space();
14713 self.write_keyword("OLD TABLE AS");
14714 self.write_space();
14715 self.generate_identifier(old_table)?;
14716 }
14717 if let Some(new_table) = &ref_clause.new_table {
14718 self.write_space();
14719 self.write_keyword("NEW TABLE AS");
14720 self.write_space();
14721 self.generate_identifier(new_table)?;
14722 }
14723 if let Some(old_row) = &ref_clause.old_row {
14724 self.write_space();
14725 self.write_keyword("OLD ROW AS");
14726 self.write_space();
14727 self.generate_identifier(old_row)?;
14728 }
14729 if let Some(new_row) = &ref_clause.new_row {
14730 self.write_space();
14731 self.write_keyword("NEW ROW AS");
14732 self.write_space();
14733 self.generate_identifier(new_row)?;
14734 }
14735 }
14736
14737 if let Some(deferrable) = ct.deferrable {
14739 self.write_space();
14740 if deferrable {
14741 self.write_keyword("DEFERRABLE");
14742 } else {
14743 self.write_keyword("NOT DEFERRABLE");
14744 }
14745 }
14746
14747 if let Some(initially) = ct.initially_deferred {
14748 self.write_space();
14749 self.write_keyword("INITIALLY");
14750 self.write_space();
14751 if initially {
14752 self.write_keyword("DEFERRED");
14753 } else {
14754 self.write_keyword("IMMEDIATE");
14755 }
14756 }
14757
14758 if let Some(for_each) = ct.for_each {
14759 self.write_space();
14760 self.write_keyword("FOR EACH");
14761 self.write_space();
14762 match for_each {
14763 TriggerForEach::Row => self.write_keyword("ROW"),
14764 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
14765 }
14766 }
14767
14768 if let Some(when) = &ct.when {
14770 self.write_space();
14771 self.write_keyword("WHEN");
14772 if ct.when_paren {
14773 self.write(" (");
14774 self.generate_expression(when)?;
14775 self.write(")");
14776 } else {
14777 self.write_space();
14778 self.generate_expression(when)?;
14779 }
14780 }
14781
14782 self.write_space();
14784 match &ct.body {
14785 TriggerBody::Execute { function, args } => {
14786 self.write_keyword("EXECUTE FUNCTION");
14787 self.write_space();
14788 self.generate_table(function)?;
14789 self.write("(");
14790 for (i, arg) in args.iter().enumerate() {
14791 if i > 0 {
14792 self.write(", ");
14793 }
14794 self.generate_expression(arg)?;
14795 }
14796 self.write(")");
14797 }
14798 TriggerBody::Block(block) => {
14799 self.write_keyword("BEGIN");
14800 self.write_space();
14801 self.write(block);
14802 self.write_space();
14803 self.write_keyword("END");
14804 }
14805 }
14806
14807 Ok(())
14808 }
14809
14810 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
14811 self.write_keyword("DROP TRIGGER");
14812
14813 if dt.if_exists {
14814 self.write_space();
14815 self.write_keyword("IF EXISTS");
14816 }
14817
14818 self.write_space();
14819 self.generate_identifier(&dt.name)?;
14820
14821 if let Some(table) = &dt.table {
14822 self.write_space();
14823 self.write_keyword("ON");
14824 self.write_space();
14825 self.generate_table(table)?;
14826 }
14827
14828 if dt.cascade {
14829 self.write_space();
14830 self.write_keyword("CASCADE");
14831 }
14832
14833 Ok(())
14834 }
14835
14836 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
14837 self.write_keyword("CREATE TYPE");
14838
14839 if ct.if_not_exists {
14840 self.write_space();
14841 self.write_keyword("IF NOT EXISTS");
14842 }
14843
14844 self.write_space();
14845 self.generate_table(&ct.name)?;
14846
14847 if let TypeDefinition::Base {
14848 input,
14849 output,
14850 internallength,
14851 } = &ct.definition
14852 {
14853 if input.is_empty() && output.is_empty() && internallength.is_none() {
14854 return Ok(());
14855 }
14856 }
14857
14858 self.write_space();
14859 self.write_keyword("AS");
14860 self.write_space();
14861
14862 match &ct.definition {
14863 TypeDefinition::Enum(values) => {
14864 self.write_keyword("ENUM");
14865 self.write(" (");
14866 for (i, val) in values.iter().enumerate() {
14867 if i > 0 {
14868 self.write(", ");
14869 }
14870 self.write(&format!("'{}'", val));
14871 }
14872 self.write(")");
14873 }
14874 TypeDefinition::Composite(attrs) => {
14875 self.write("(");
14876 for (i, attr) in attrs.iter().enumerate() {
14877 if i > 0 {
14878 self.write(", ");
14879 }
14880 self.generate_identifier(&attr.name)?;
14881 self.write_space();
14882 self.generate_data_type(&attr.data_type)?;
14883 if let Some(collate) = &attr.collate {
14884 self.write_space();
14885 self.write_keyword("COLLATE");
14886 self.write_space();
14887 self.generate_identifier(collate)?;
14888 }
14889 }
14890 self.write(")");
14891 }
14892 TypeDefinition::Range {
14893 subtype,
14894 subtype_diff,
14895 canonical,
14896 } => {
14897 self.write_keyword("RANGE");
14898 self.write(" (");
14899 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14900 self.write("subtype");
14901 } else {
14902 self.write_keyword("SUBTYPE");
14903 }
14904 self.write(" = ");
14905 self.generate_data_type(subtype)?;
14906 if let Some(diff) = subtype_diff {
14907 self.write(", ");
14908 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14909 self.write("subtype_diff");
14910 } else {
14911 self.write_keyword("SUBTYPE_DIFF");
14912 }
14913 self.write(" = ");
14914 self.write(diff);
14915 }
14916 if let Some(canon) = canonical {
14917 self.write(", ");
14918 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14919 self.write("canonical");
14920 } else {
14921 self.write_keyword("CANONICAL");
14922 }
14923 self.write(" = ");
14924 self.write(canon);
14925 }
14926 self.write(")");
14927 }
14928 TypeDefinition::Base {
14929 input,
14930 output,
14931 internallength,
14932 } => {
14933 self.write("(");
14934 self.write_keyword("INPUT");
14935 self.write(" = ");
14936 self.write(input);
14937 self.write(", ");
14938 self.write_keyword("OUTPUT");
14939 self.write(" = ");
14940 self.write(output);
14941 if let Some(len) = internallength {
14942 self.write(", ");
14943 self.write_keyword("INTERNALLENGTH");
14944 self.write(" = ");
14945 self.write(&len.to_string());
14946 }
14947 self.write(")");
14948 }
14949 TypeDefinition::Domain {
14950 base_type,
14951 default,
14952 constraints,
14953 } => {
14954 self.generate_data_type(base_type)?;
14955 if let Some(def) = default {
14956 self.write_space();
14957 self.write_keyword("DEFAULT");
14958 self.write_space();
14959 self.generate_expression(def)?;
14960 }
14961 for constr in constraints {
14962 self.write_space();
14963 if let Some(name) = &constr.name {
14964 self.write_keyword("CONSTRAINT");
14965 self.write_space();
14966 self.generate_identifier(name)?;
14967 self.write_space();
14968 }
14969 self.write_keyword("CHECK");
14970 self.write(" (");
14971 self.generate_expression(&constr.check)?;
14972 self.write(")");
14973 }
14974 }
14975 }
14976
14977 Ok(())
14978 }
14979
14980 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
14981 self.write_keyword("CREATE");
14982 if task.or_replace {
14983 self.write_space();
14984 self.write_keyword("OR REPLACE");
14985 }
14986 self.write_space();
14987 self.write_keyword("TASK");
14988 if task.if_not_exists {
14989 self.write_space();
14990 self.write_keyword("IF NOT EXISTS");
14991 }
14992 self.write_space();
14993 self.write(&task.name);
14994 if !task.properties.is_empty() {
14995 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
14997 self.write_space();
14998 }
14999 self.write(&task.properties);
15000 }
15001 self.write_space();
15002 self.write_keyword("AS");
15003 self.write_space();
15004 self.generate_expression(&task.body)?;
15005 Ok(())
15006 }
15007
15008 fn generate_try_catch(&mut self, try_catch: &TryCatch) -> Result<()> {
15009 self.write_keyword("BEGIN TRY");
15010 self.generate_tsql_block_statements(&try_catch.try_body)?;
15011 self.write_keyword("END TRY");
15012
15013 if let Some(catch_body) = &try_catch.catch_body {
15014 if self.config.pretty {
15015 self.write_newline();
15016 self.write_indent();
15017 } else {
15018 self.write_space();
15019 }
15020 self.write_keyword("BEGIN CATCH");
15021 self.generate_tsql_block_statements(catch_body)?;
15022 self.write_keyword("END CATCH");
15023 }
15024
15025 Ok(())
15026 }
15027
15028 fn generate_tsql_block_statements(&mut self, statements: &[Expression]) -> Result<()> {
15029 if statements.is_empty() {
15030 self.write_space();
15031 return Ok(());
15032 }
15033
15034 if self.config.pretty {
15035 self.indent_level += 1;
15036 for stmt in statements {
15037 self.write_newline();
15038 self.write_indent();
15039 self.generate_expression(stmt)?;
15040 self.write(";");
15041 }
15042 self.indent_level -= 1;
15043 self.write_newline();
15044 self.write_indent();
15045 } else {
15046 self.write_space();
15047 for (i, stmt) in statements.iter().enumerate() {
15048 if i > 0 {
15049 self.write_space();
15050 }
15051 self.generate_expression(stmt)?;
15052 self.write(";");
15053 }
15054 self.write_space();
15055 }
15056
15057 Ok(())
15058 }
15059
15060 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
15061 self.write_keyword("DROP TYPE");
15062
15063 if dt.if_exists {
15064 self.write_space();
15065 self.write_keyword("IF EXISTS");
15066 }
15067
15068 self.write_space();
15069 self.generate_table(&dt.name)?;
15070
15071 if dt.cascade {
15072 self.write_space();
15073 self.write_keyword("CASCADE");
15074 }
15075
15076 Ok(())
15077 }
15078
15079 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
15080 let saved_athena_hive_context = self.athena_hive_context;
15082 if matches!(
15083 self.config.dialect,
15084 Some(crate::dialects::DialectType::Athena)
15085 ) {
15086 self.athena_hive_context = true;
15087 }
15088
15089 for comment in &d.leading_comments {
15091 self.write_formatted_comment(comment);
15092 self.write(" ");
15093 }
15094
15095 self.write_keyword("DESCRIBE");
15096
15097 if d.extended {
15098 self.write_space();
15099 self.write_keyword("EXTENDED");
15100 } else if d.formatted {
15101 self.write_space();
15102 self.write_keyword("FORMATTED");
15103 }
15104
15105 if let Some(ref style) = d.style {
15107 self.write_space();
15108 self.write_keyword(style);
15109 }
15110
15111 let should_output_kind = match self.config.dialect {
15113 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
15115 false
15116 }
15117 Some(DialectType::Snowflake) => true,
15119 _ => d.kind.is_some(),
15120 };
15121 if should_output_kind {
15122 if let Some(ref kind) = d.kind {
15123 self.write_space();
15124 self.write_keyword(kind);
15125 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
15126 self.write_space();
15127 self.write_keyword("TABLE");
15128 }
15129 }
15130
15131 self.write_space();
15132 self.generate_expression(&d.target)?;
15133
15134 if !d.params.is_empty() {
15136 self.write("(");
15137 for (i, param) in d.params.iter().enumerate() {
15138 if i > 0 {
15139 self.write(", ");
15140 }
15141 self.write(param);
15142 }
15143 self.write(")");
15144 }
15145
15146 if let Some(ref partition) = d.partition {
15148 self.write_space();
15149 self.generate_expression(partition)?;
15150 }
15151
15152 if d.as_json {
15154 self.write_space();
15155 self.write_keyword("AS JSON");
15156 }
15157
15158 for (name, value) in &d.properties {
15160 self.write_space();
15161 self.write(name);
15162 self.write("=");
15163 self.write(value);
15164 }
15165
15166 self.athena_hive_context = saved_athena_hive_context;
15168
15169 Ok(())
15170 }
15171
15172 fn generate_show(&mut self, s: &Show) -> Result<()> {
15175 self.write_keyword("SHOW");
15176 self.write_space();
15177
15178 let show_terse = s.terse
15181 && !matches!(
15182 s.this.as_str(),
15183 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
15184 );
15185 if show_terse {
15186 self.write_keyword("TERSE");
15187 self.write_space();
15188 }
15189
15190 self.write_keyword(&s.this);
15192
15193 if let Some(ref target_expr) = s.target {
15195 self.write_space();
15196 self.generate_expression(target_expr)?;
15197 }
15198
15199 if s.history {
15201 self.write_space();
15202 self.write_keyword("HISTORY");
15203 }
15204
15205 if let Some(ref for_target) = s.for_target {
15207 self.write_space();
15208 self.write_keyword("FOR");
15209 self.write_space();
15210 self.generate_expression(for_target)?;
15211 }
15212
15213 use crate::dialects::DialectType;
15217 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
15218 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
15219 let mysql_tables_scope_as_from = is_mysql
15220 && matches!(s.this.as_str(), "TABLES" | "FULL TABLES")
15221 && s.scope_kind.as_deref() == Some("SCHEMA")
15222 && s.scope.is_some()
15223 && s.from.is_none();
15224
15225 if !is_snowflake && s.from.is_some() {
15226 if let Some(ref scope_kind) = s.scope_kind {
15230 self.write_space();
15231 self.write_keyword("IN");
15232 self.write_space();
15233 self.write_keyword(scope_kind);
15234 if let Some(ref scope) = s.scope {
15235 self.write_space();
15236 self.generate_expression(scope)?;
15237 }
15238 } else if let Some(ref scope) = s.scope {
15239 self.write_space();
15240 self.write_keyword("IN");
15241 self.write_space();
15242 self.generate_expression(scope)?;
15243 }
15244
15245 if let Some(ref from) = s.from {
15247 self.write_space();
15248 self.write_keyword("FROM");
15249 self.write_space();
15250 self.generate_expression(from)?;
15251 }
15252
15253 if let Some(ref db) = s.db {
15255 self.write_space();
15256 self.write_keyword("FROM");
15257 self.write_space();
15258 self.generate_expression(db)?;
15259 }
15260
15261 if let Some(ref like) = s.like {
15263 self.write_space();
15264 self.write_keyword("LIKE");
15265 self.write_space();
15266 self.generate_expression(like)?;
15267 }
15268 } else {
15269 if let Some(ref like) = s.like {
15273 self.write_space();
15274 self.write_keyword("LIKE");
15275 self.write_space();
15276 self.generate_expression(like)?;
15277 }
15278
15279 if mysql_tables_scope_as_from {
15281 self.write_space();
15282 self.write_keyword("FROM");
15283 self.write_space();
15284 self.generate_expression(s.scope.as_ref().unwrap())?;
15285 } else if let Some(ref scope_kind) = s.scope_kind {
15286 self.write_space();
15287 self.write_keyword("IN");
15288 self.write_space();
15289 self.write_keyword(scope_kind);
15290 if let Some(ref scope) = s.scope {
15291 self.write_space();
15292 self.generate_expression(scope)?;
15293 }
15294 } else if let Some(ref scope) = s.scope {
15295 self.write_space();
15296 self.write_keyword("IN");
15297 self.write_space();
15298 self.generate_expression(scope)?;
15299 }
15300 }
15301
15302 if let Some(ref starts_with) = s.starts_with {
15304 self.write_space();
15305 self.write_keyword("STARTS WITH");
15306 self.write_space();
15307 self.generate_expression(starts_with)?;
15308 }
15309
15310 if let Some(ref limit) = s.limit {
15312 self.write_space();
15313 self.generate_limit(limit)?;
15314 }
15315
15316 if is_snowflake {
15318 if let Some(ref from) = s.from {
15319 self.write_space();
15320 self.write_keyword("FROM");
15321 self.write_space();
15322 self.generate_expression(from)?;
15323 }
15324 }
15325
15326 if let Some(ref where_clause) = s.where_clause {
15328 self.write_space();
15329 self.write_keyword("WHERE");
15330 self.write_space();
15331 self.generate_expression(where_clause)?;
15332 }
15333
15334 if let Some(is_mutex) = s.mutex {
15336 self.write_space();
15337 if is_mutex {
15338 self.write_keyword("MUTEX");
15339 } else {
15340 self.write_keyword("STATUS");
15341 }
15342 }
15343
15344 if !s.privileges.is_empty() {
15346 self.write_space();
15347 self.write_keyword("WITH PRIVILEGES");
15348 self.write_space();
15349 for (i, priv_name) in s.privileges.iter().enumerate() {
15350 if i > 0 {
15351 self.write(", ");
15352 }
15353 self.write_keyword(priv_name);
15354 }
15355 }
15356
15357 Ok(())
15358 }
15359
15360 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
15363 use crate::dialects::DialectType;
15364 match lit {
15365 Literal::String(s) => {
15366 self.generate_string_literal(s)?;
15367 }
15368 Literal::Number(n) => {
15369 if matches!(self.config.dialect, Some(DialectType::MySQL))
15370 && n.len() > 2
15371 && (n.starts_with("0x") || n.starts_with("0X"))
15372 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
15373 {
15374 return self.generate_identifier(&Identifier {
15375 name: n.clone(),
15376 quoted: true,
15377 trailing_comments: Vec::new(),
15378 span: None,
15379 });
15380 }
15381 let n = if n.contains('_')
15385 && !matches!(
15386 self.config.dialect,
15387 Some(DialectType::ClickHouse)
15388 | Some(DialectType::DuckDB)
15389 | Some(DialectType::PostgreSQL)
15390 | Some(DialectType::Hive)
15391 | Some(DialectType::Spark)
15392 | Some(DialectType::Databricks)
15393 ) {
15394 std::borrow::Cow::Owned(n.replace('_', ""))
15395 } else {
15396 std::borrow::Cow::Borrowed(n.as_str())
15397 };
15398 if n.starts_with('.') {
15401 self.write("0");
15402 self.write(&n);
15403 } else if n.starts_with("-.") {
15404 self.write("-0");
15406 self.write(&n[1..]);
15407 } else {
15408 self.write(&n);
15409 }
15410 }
15411 Literal::HexString(h) => {
15412 match self.config.dialect {
15414 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
15415 self.write("0x");
15416 self.write(h);
15417 return Ok(());
15418 }
15419 Some(DialectType::Spark)
15420 | Some(DialectType::Databricks)
15421 | Some(DialectType::Teradata) => self.write("X'"),
15422 _ => self.write("x'"),
15423 }
15424 self.write(h);
15425 self.write("'");
15426 }
15427 Literal::HexNumber(h) => {
15428 match self.config.dialect {
15432 Some(DialectType::BigQuery)
15433 | Some(DialectType::ClickHouse)
15434 | Some(DialectType::TSQL)
15435 | Some(DialectType::Fabric) => {
15436 self.write("0x");
15437 self.write(h);
15438 }
15439 _ => {
15440 if let Ok(val) = u64::from_str_radix(h, 16) {
15442 self.write(&val.to_string());
15443 } else {
15444 self.write("0x");
15446 self.write(h);
15447 }
15448 }
15449 }
15450 }
15451 Literal::BitString(b) => {
15452 self.write("B'");
15454 self.write(b);
15455 self.write("'");
15456 }
15457 Literal::ByteString(b) => {
15458 self.write("b'");
15460 self.write_escaped_byte_string(b);
15462 self.write("'");
15463 }
15464 Literal::NationalString(s) => {
15465 let keep_n_prefix = matches!(
15468 self.config.dialect,
15469 Some(DialectType::TSQL)
15470 | Some(DialectType::Oracle)
15471 | Some(DialectType::MySQL)
15472 | None
15473 );
15474 if keep_n_prefix {
15475 self.write("N'");
15476 } else {
15477 self.write("'");
15478 }
15479 self.write(s);
15480 self.write("'");
15481 }
15482 Literal::Date(d) => {
15483 self.generate_date_literal(d)?;
15484 }
15485 Literal::Time(t) => {
15486 self.generate_time_literal(t)?;
15487 }
15488 Literal::Timestamp(ts) => {
15489 self.generate_timestamp_literal(ts)?;
15490 }
15491 Literal::Datetime(dt) => {
15492 self.generate_datetime_literal(dt)?;
15493 }
15494 Literal::TripleQuotedString(s, _quote_char) => {
15495 if matches!(
15497 self.config.dialect,
15498 Some(crate::dialects::DialectType::BigQuery)
15499 | Some(crate::dialects::DialectType::DuckDB)
15500 | Some(crate::dialects::DialectType::Snowflake)
15501 | Some(crate::dialects::DialectType::Spark)
15502 | Some(crate::dialects::DialectType::Hive)
15503 | Some(crate::dialects::DialectType::Presto)
15504 | Some(crate::dialects::DialectType::Trino)
15505 | Some(crate::dialects::DialectType::PostgreSQL)
15506 | Some(crate::dialects::DialectType::MySQL)
15507 | Some(crate::dialects::DialectType::Redshift)
15508 | Some(crate::dialects::DialectType::TSQL)
15509 | Some(crate::dialects::DialectType::Oracle)
15510 | Some(crate::dialects::DialectType::ClickHouse)
15511 | Some(crate::dialects::DialectType::Databricks)
15512 | Some(crate::dialects::DialectType::SQLite)
15513 ) {
15514 self.generate_string_literal(s)?;
15515 } else {
15516 let quotes = format!("{0}{0}{0}", _quote_char);
15518 self.write("es);
15519 self.write(s);
15520 self.write("es);
15521 }
15522 }
15523 Literal::EscapeString(s) => {
15524 use crate::dialects::DialectType;
15528 let content = if let Some(c) = s.strip_prefix("e:") {
15529 c
15530 } else if let Some(c) = s.strip_prefix("E:") {
15531 c
15532 } else {
15533 s.as_str()
15534 };
15535
15536 if matches!(
15538 self.config.dialect,
15539 Some(DialectType::MySQL) | Some(DialectType::TiDB)
15540 ) {
15541 self.write("'");
15542 self.write(&content.replace('\'', "''"));
15543 self.write("'");
15544 } else {
15545 let prefix = if matches!(
15547 self.config.dialect,
15548 Some(DialectType::SingleStore)
15549 | Some(DialectType::DuckDB)
15550 | Some(DialectType::PostgreSQL)
15551 | Some(DialectType::CockroachDB)
15552 | Some(DialectType::Materialize)
15553 | Some(DialectType::RisingWave)
15554 ) {
15555 "e'"
15556 } else {
15557 "E'"
15558 };
15559
15560 let normalized = content.replace("\\'", "''");
15562 self.write(prefix);
15563 self.write(&normalized);
15564 self.write("'");
15565 }
15566 }
15567 Literal::DollarString(s) => {
15568 use crate::dialects::DialectType;
15571 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
15573 let escape_backslash = matches!(
15575 self.config.dialect,
15576 Some(DialectType::ClickHouse) | Some(DialectType::Snowflake)
15577 );
15578 let use_backslash_quote =
15582 matches!(self.config.dialect, Some(DialectType::Snowflake));
15583
15584 let mut escaped = String::with_capacity(content.len() + 4);
15585 for ch in content.chars() {
15586 if escape_backslash && ch == '\\' {
15587 escaped.push('\\');
15589 escaped.push('\\');
15590 } else if ch == '\'' {
15591 if use_backslash_quote {
15592 escaped.push('\\');
15593 escaped.push('\'');
15594 } else {
15595 escaped.push('\'');
15596 escaped.push('\'');
15597 }
15598 } else {
15599 escaped.push(ch);
15600 }
15601 }
15602 self.write("'");
15603 self.write(&escaped);
15604 self.write("'");
15605 }
15606 Literal::RawString(s) => {
15607 use crate::dialects::DialectType;
15613
15614 let escape_backslash = matches!(
15616 self.config.dialect,
15617 Some(DialectType::BigQuery)
15618 | Some(DialectType::MySQL)
15619 | Some(DialectType::SingleStore)
15620 | Some(DialectType::TiDB)
15621 | Some(DialectType::Hive)
15622 | Some(DialectType::Spark)
15623 | Some(DialectType::Databricks)
15624 | Some(DialectType::Drill)
15625 | Some(DialectType::Snowflake)
15626 | Some(DialectType::Redshift)
15627 | Some(DialectType::ClickHouse)
15628 );
15629
15630 let backslash_escapes_quote = matches!(
15633 self.config.dialect,
15634 Some(DialectType::BigQuery)
15635 | Some(DialectType::Hive)
15636 | Some(DialectType::Spark)
15637 | Some(DialectType::Databricks)
15638 | Some(DialectType::Drill)
15639 | Some(DialectType::Snowflake)
15640 | Some(DialectType::Redshift)
15641 );
15642
15643 let supports_escape_sequences = escape_backslash;
15646
15647 let mut escaped = String::with_capacity(s.len() + 4);
15648 for ch in s.chars() {
15649 if escape_backslash && ch == '\\' {
15650 escaped.push('\\');
15652 escaped.push('\\');
15653 } else if ch == '\'' {
15654 if backslash_escapes_quote {
15655 escaped.push('\\');
15657 escaped.push('\'');
15658 } else {
15659 escaped.push('\'');
15661 escaped.push('\'');
15662 }
15663 } else if supports_escape_sequences {
15664 match ch {
15667 '\n' => {
15668 escaped.push('\\');
15669 escaped.push('n');
15670 }
15671 '\r' => {
15672 escaped.push('\\');
15673 escaped.push('r');
15674 }
15675 '\t' => {
15676 escaped.push('\\');
15677 escaped.push('t');
15678 }
15679 '\x07' => {
15680 escaped.push('\\');
15681 escaped.push('a');
15682 }
15683 '\x08' => {
15684 escaped.push('\\');
15685 escaped.push('b');
15686 }
15687 '\x0C' => {
15688 escaped.push('\\');
15689 escaped.push('f');
15690 }
15691 '\x0B' => {
15692 escaped.push('\\');
15693 escaped.push('v');
15694 }
15695 _ => escaped.push(ch),
15696 }
15697 } else {
15698 escaped.push(ch);
15699 }
15700 }
15701 self.write("'");
15702 self.write(&escaped);
15703 self.write("'");
15704 }
15705 }
15706 Ok(())
15707 }
15708
15709 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
15711 use crate::dialects::DialectType;
15712
15713 match self.config.dialect {
15714 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
15716 self.write("CAST('");
15717 self.write(d);
15718 self.write("' AS DATE)");
15719 }
15720 Some(DialectType::BigQuery) => {
15723 self.write("CAST('");
15724 self.write(d);
15725 self.write("' AS DATE)");
15726 }
15727 Some(DialectType::Exasol) => {
15730 self.write("CAST('");
15731 self.write(d);
15732 self.write("' AS DATE)");
15733 }
15734 Some(DialectType::Snowflake) => {
15737 self.write("CAST('");
15738 self.write(d);
15739 self.write("' AS DATE)");
15740 }
15741 Some(DialectType::PostgreSQL)
15743 | Some(DialectType::MySQL)
15744 | Some(DialectType::SingleStore)
15745 | Some(DialectType::TiDB)
15746 | Some(DialectType::Redshift) => {
15747 self.write("CAST('");
15748 self.write(d);
15749 self.write("' AS DATE)");
15750 }
15751 Some(DialectType::DuckDB)
15753 | Some(DialectType::Presto)
15754 | Some(DialectType::Trino)
15755 | Some(DialectType::Athena)
15756 | Some(DialectType::Spark)
15757 | Some(DialectType::Databricks)
15758 | Some(DialectType::Hive) => {
15759 self.write("CAST('");
15760 self.write(d);
15761 self.write("' AS DATE)");
15762 }
15763 Some(DialectType::Oracle) => {
15765 self.write("TO_DATE('");
15766 self.write(d);
15767 self.write("', 'YYYY-MM-DD')");
15768 }
15769 _ => {
15771 self.write_keyword("DATE");
15772 self.write(" '");
15773 self.write(d);
15774 self.write("'");
15775 }
15776 }
15777 Ok(())
15778 }
15779
15780 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
15782 use crate::dialects::DialectType;
15783
15784 match self.config.dialect {
15785 Some(DialectType::TSQL) => {
15787 self.write("CAST('");
15788 self.write(t);
15789 self.write("' AS TIME)");
15790 }
15791 _ => {
15793 self.write_keyword("TIME");
15794 self.write(" '");
15795 self.write(t);
15796 self.write("'");
15797 }
15798 }
15799 Ok(())
15800 }
15801
15802 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
15804 use crate::expressions::Literal;
15805
15806 match expr {
15807 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
15808 let Literal::Date(d) = lit.as_ref() else {
15809 unreachable!()
15810 };
15811 self.write("CAST('");
15813 self.write(d);
15814 self.write("' AS DATE)");
15815 }
15816 _ => {
15817 self.generate_expression(expr)?;
15819 }
15820 }
15821 Ok(())
15822 }
15823
15824 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
15826 use crate::dialects::DialectType;
15827
15828 match self.config.dialect {
15829 Some(DialectType::TSQL) => {
15831 self.write("CAST('");
15832 self.write(ts);
15833 self.write("' AS DATETIME2)");
15834 }
15835 Some(DialectType::BigQuery) => {
15838 self.write("CAST('");
15839 self.write(ts);
15840 self.write("' AS TIMESTAMP)");
15841 }
15842 Some(DialectType::Snowflake) => {
15845 self.write("CAST('");
15846 self.write(ts);
15847 self.write("' AS TIMESTAMP)");
15848 }
15849 Some(DialectType::Dremio) => {
15852 self.write("CAST('");
15853 self.write(ts);
15854 self.write("' AS TIMESTAMP)");
15855 }
15856 Some(DialectType::Exasol) => {
15859 self.write("CAST('");
15860 self.write(ts);
15861 self.write("' AS TIMESTAMP)");
15862 }
15863 Some(DialectType::Oracle) => {
15866 self.write("TO_TIMESTAMP('");
15867 self.write(ts);
15868 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
15869 }
15870 Some(DialectType::Presto) | Some(DialectType::Trino) => {
15872 if Self::timestamp_has_timezone(ts) {
15873 self.write("CAST('");
15874 self.write(ts);
15875 self.write("' AS TIMESTAMP WITH TIME ZONE)");
15876 } else {
15877 self.write("CAST('");
15878 self.write(ts);
15879 self.write("' AS TIMESTAMP)");
15880 }
15881 }
15882 Some(DialectType::ClickHouse) => {
15884 self.write("CAST('");
15885 self.write(ts);
15886 self.write("' AS Nullable(DateTime))");
15887 }
15888 Some(DialectType::Spark) => {
15890 self.write("CAST('");
15891 self.write(ts);
15892 self.write("' AS TIMESTAMP)");
15893 }
15894 Some(DialectType::Redshift) => {
15897 if ts == "epoch" {
15898 self.write_keyword("TIMESTAMP");
15899 self.write(" '");
15900 self.write(ts);
15901 self.write("'");
15902 } else {
15903 self.write("CAST('");
15904 self.write(ts);
15905 self.write("' AS TIMESTAMP)");
15906 }
15907 }
15908 Some(DialectType::PostgreSQL)
15910 | Some(DialectType::Hive)
15911 | Some(DialectType::SQLite)
15912 | Some(DialectType::DuckDB)
15913 | Some(DialectType::Athena)
15914 | Some(DialectType::Drill)
15915 | Some(DialectType::Teradata) => {
15916 self.write("CAST('");
15917 self.write(ts);
15918 self.write("' AS TIMESTAMP)");
15919 }
15920 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
15922 self.write("CAST('");
15923 self.write(ts);
15924 self.write("' AS DATETIME)");
15925 }
15926 Some(DialectType::Databricks) => {
15928 self.write("CAST('");
15929 self.write(ts);
15930 self.write("' AS TIMESTAMP_NTZ)");
15931 }
15932 _ => {
15934 self.write_keyword("TIMESTAMP");
15935 self.write(" '");
15936 self.write(ts);
15937 self.write("'");
15938 }
15939 }
15940 Ok(())
15941 }
15942
15943 fn timestamp_has_timezone(ts: &str) -> bool {
15946 let ts_lower = ts.to_ascii_lowercase();
15950
15951 let continent_prefixes = [
15953 "africa/",
15954 "america/",
15955 "antarctica/",
15956 "arctic/",
15957 "asia/",
15958 "atlantic/",
15959 "australia/",
15960 "europe/",
15961 "indian/",
15962 "pacific/",
15963 "etc/",
15964 "brazil/",
15965 "canada/",
15966 "chile/",
15967 "mexico/",
15968 "us/",
15969 ];
15970
15971 for prefix in &continent_prefixes {
15972 if ts_lower.contains(prefix) {
15973 return true;
15974 }
15975 }
15976
15977 let tz_abbrevs = [
15980 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
15981 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
15982 " sgt", " aest", " aedt", " acst", " acdt", " awst",
15983 ];
15984
15985 for abbrev in &tz_abbrevs {
15986 if ts_lower.ends_with(abbrev) {
15987 return true;
15988 }
15989 }
15990
15991 let trimmed = ts.trim();
15995 if let Some(last_space) = trimmed.rfind(' ') {
15996 let suffix = &trimmed[last_space + 1..];
15997 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
15998 let rest = &suffix[1..];
16000 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
16001 return true;
16002 }
16003 }
16004 }
16005
16006 false
16007 }
16008
16009 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
16011 use crate::dialects::DialectType;
16012
16013 match self.config.dialect {
16014 Some(DialectType::BigQuery) => {
16017 self.write("CAST('");
16018 self.write(dt);
16019 self.write("' AS DATETIME)");
16020 }
16021 Some(DialectType::DuckDB) => {
16023 self.write("CAST('");
16024 self.write(dt);
16025 self.write("' AS TIMESTAMP)");
16026 }
16027 _ => {
16030 self.write_keyword("DATETIME");
16031 self.write(" '");
16032 self.write(dt);
16033 self.write("'");
16034 }
16035 }
16036 Ok(())
16037 }
16038
16039 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
16041 use crate::dialects::DialectType;
16042
16043 match self.config.dialect {
16044 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
16048 self.write("'");
16050 for c in s.chars() {
16051 match c {
16052 '\'' => self.write("\\'"),
16053 '\\' => self.write("\\\\"),
16054 '\n' => self.write("\\n"),
16055 '\r' => self.write("\\r"),
16056 '\t' => self.write("\\t"),
16057 '\0' => self.write("\\0"),
16058 _ => self.output.push(c),
16059 }
16060 }
16061 self.write("'");
16062 }
16063 Some(DialectType::Drill) => {
16064 self.write("'");
16067 for c in s.chars() {
16068 match c {
16069 '\'' => self.write("''"),
16070 '\\' => self.write("\\\\"),
16071 '\n' => self.write("\\n"),
16072 '\r' => self.write("\\r"),
16073 '\t' => self.write("\\t"),
16074 '\0' => self.write("\\0"),
16075 _ => self.output.push(c),
16076 }
16077 }
16078 self.write("'");
16079 }
16080 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
16081 self.write("'");
16082 for c in s.chars() {
16083 match c {
16084 '\'' => self.write("''"),
16086 '\\' => self.write("\\\\"),
16087 '\n' => self.write("\\n"),
16088 '\r' => self.write("\\r"),
16089 '\t' => self.write("\\t"),
16090 '\0' => self.output.push('\0'),
16092 _ => self.output.push(c),
16093 }
16094 }
16095 self.write("'");
16096 }
16097 Some(DialectType::BigQuery) => {
16099 self.write("'");
16100 for c in s.chars() {
16101 match c {
16102 '\'' => self.write("\\'"),
16103 '\\' => self.write("\\\\"),
16104 '\n' => self.write("\\n"),
16105 '\r' => self.write("\\r"),
16106 '\t' => self.write("\\t"),
16107 '\0' => self.write("\\0"),
16108 '\x07' => self.write("\\a"),
16109 '\x08' => self.write("\\b"),
16110 '\x0C' => self.write("\\f"),
16111 '\x0B' => self.write("\\v"),
16112 _ => self.output.push(c),
16113 }
16114 }
16115 self.write("'");
16116 }
16117 Some(DialectType::Athena) => {
16121 if self.athena_hive_context {
16122 self.write("'");
16124 for c in s.chars() {
16125 match c {
16126 '\'' => self.write("\\'"),
16127 '\\' => self.write("\\\\"),
16128 '\n' => self.write("\\n"),
16129 '\r' => self.write("\\r"),
16130 '\t' => self.write("\\t"),
16131 '\0' => self.write("\\0"),
16132 _ => self.output.push(c),
16133 }
16134 }
16135 self.write("'");
16136 } else {
16137 self.write("'");
16139 for c in s.chars() {
16140 match c {
16141 '\'' => self.write("''"),
16142 _ => self.output.push(c),
16144 }
16145 }
16146 self.write("'");
16147 }
16148 }
16149 Some(DialectType::Snowflake) => {
16154 self.write("'");
16155 for c in s.chars() {
16156 match c {
16157 '\'' => self.write("\\'"),
16158 '\n' => self.write("\\n"),
16161 '\r' => self.write("\\r"),
16162 '\t' => self.write("\\t"),
16163 _ => self.output.push(c),
16164 }
16165 }
16166 self.write("'");
16167 }
16168 Some(DialectType::PostgreSQL) => {
16170 self.write("'");
16171 for c in s.chars() {
16172 match c {
16173 '\'' => self.write("''"),
16174 _ => self.output.push(c),
16175 }
16176 }
16177 self.write("'");
16178 }
16179 Some(DialectType::Redshift) => {
16181 self.write("'");
16182 for c in s.chars() {
16183 match c {
16184 '\'' => self.write("\\'"),
16185 _ => self.output.push(c),
16186 }
16187 }
16188 self.write("'");
16189 }
16190 Some(DialectType::Oracle) => {
16192 self.write("'");
16193 for ch in s.chars() {
16194 if ch == '\'' {
16195 self.output.push_str("''");
16196 } else {
16197 self.output.push(ch);
16198 }
16199 }
16200 self.write("'");
16201 }
16202 Some(DialectType::ClickHouse) => {
16205 self.write("'");
16206 for c in s.chars() {
16207 match c {
16208 '\'' => self.write("''"),
16209 '\\' => self.write("\\\\"),
16210 '\n' => self.write("\\n"),
16211 '\r' => self.write("\\r"),
16212 '\t' => self.write("\\t"),
16213 '\0' => self.write("\\0"),
16214 '\x07' => self.write("\\a"),
16215 '\x08' => self.write("\\b"),
16216 '\x0C' => self.write("\\f"),
16217 '\x0B' => self.write("\\v"),
16218 c if c.is_control() || (c as u32) < 0x20 => {
16220 let byte = c as u32;
16221 if byte < 256 {
16222 self.write(&format!("\\x{:02X}", byte));
16223 } else {
16224 self.output.push(c);
16225 }
16226 }
16227 _ => self.output.push(c),
16228 }
16229 }
16230 self.write("'");
16231 }
16232 _ => {
16235 self.write("'");
16236 for ch in s.chars() {
16237 if ch == '\'' {
16238 self.output.push_str("''");
16239 } else {
16240 self.output.push(ch);
16241 }
16242 }
16243 self.write("'");
16244 }
16245 }
16246 Ok(())
16247 }
16248
16249 fn write_escaped_byte_string(&mut self, s: &str) {
16252 for c in s.chars() {
16253 match c {
16254 '\'' => self.write("\\'"),
16256 '\\' => self.write("\\\\"),
16258 _ if !c.is_control() => self.output.push(c),
16260 _ => {
16262 let byte = c as u32;
16263 if byte < 256 {
16264 self.write(&format!("\\x{:02x}", byte));
16265 } else {
16266 for b in c.to_string().as_bytes() {
16268 self.write(&format!("\\x{:02x}", b));
16269 }
16270 }
16271 }
16272 }
16273 }
16274 }
16275
16276 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
16277 use crate::dialects::DialectType;
16278
16279 match self.config.dialect {
16281 Some(DialectType::TSQL) => {
16284 self.write(if b.value { "1" } else { "0" });
16285 }
16286 Some(DialectType::Oracle) => {
16288 self.write(if b.value { "1" } else { "0" });
16289 }
16290 Some(DialectType::MySQL) => {
16292 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
16293 }
16294 _ => {
16296 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
16297 }
16298 }
16299 Ok(())
16300 }
16301
16302 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
16305 let name = &id.name;
16306 let quote_style = &self.config.identifier_quote_style;
16307
16308 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
16312
16313 let output_name = if self.config.normalize_identifiers && !id.quoted {
16315 name.to_ascii_lowercase()
16316 } else {
16317 name.to_string()
16318 };
16319
16320 if needs_quoting {
16321 let quote_style = if matches!(self.config.dialect, Some(DialectType::ClickHouse))
16322 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
16323 && quote_style.start == '"'
16324 && output_name.contains('"')
16325 {
16326 &IdentifierQuoteStyle::BACKTICK
16327 } else {
16328 quote_style
16329 };
16330 let escaped_name = if quote_style.start == quote_style.end {
16332 output_name.replace(
16333 quote_style.end,
16334 &format!("{}{}", quote_style.end, quote_style.end),
16335 )
16336 } else {
16337 output_name.replace(
16338 quote_style.end,
16339 &format!("{}{}", quote_style.end, quote_style.end),
16340 )
16341 };
16342 self.write(&format!(
16343 "{}{}{}",
16344 quote_style.start, escaped_name, quote_style.end
16345 ));
16346 } else {
16347 self.write(&output_name);
16348 }
16349
16350 for comment in &id.trailing_comments {
16352 self.write(" ");
16353 self.write_formatted_comment(comment);
16354 }
16355 Ok(())
16356 }
16357
16358 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
16359 use crate::dialects::DialectType;
16360
16361 let name = &id.name;
16362
16363 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
16365 && self.athena_hive_context
16366 {
16367 &IdentifierQuoteStyle::BACKTICK
16368 } else {
16369 &self.config.identifier_quote_style
16370 };
16371
16372 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
16379 let needs_digit_quoting = starts_with_digit
16380 && !self.config.identifiers_can_start_with_digit
16381 && self.config.dialect.is_some();
16382 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
16383 && name.len() > 2
16384 && (name.starts_with("0x") || name.starts_with("0X"))
16385 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
16386 let clickhouse_unsafe_identifier =
16387 matches!(self.config.dialect, Some(DialectType::ClickHouse))
16388 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
16389 && !name.starts_with('{')
16390 && !name.contains('(')
16391 && !name.contains(')')
16392 && name != "?"
16393 && name
16394 .chars()
16395 .any(|c| !(c.is_ascii_alphanumeric() || c == '_'));
16396 let needs_quoting = id.quoted
16397 || self.is_reserved_keyword(name)
16398 || self.config.always_quote_identifiers
16399 || needs_digit_quoting
16400 || mysql_invalid_hex_identifier
16401 || clickhouse_unsafe_identifier;
16402
16403 let (base_name, suffix) = if needs_quoting {
16406 if let Some(paren_pos) = name.find('(') {
16408 let base = &name[..paren_pos];
16409 let rest = &name[paren_pos..];
16410 if rest.starts_with('(')
16412 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
16413 {
16414 let close_paren = rest.find(')').unwrap_or(rest.len());
16416 let inside = &rest[1..close_paren];
16417 if inside.chars().all(|c| c.is_ascii_digit()) {
16418 (base.to_string(), rest.to_string())
16419 } else {
16420 (name.to_string(), String::new())
16421 }
16422 } else {
16423 (name.to_string(), String::new())
16424 }
16425 } else if name.ends_with(" ASC") {
16426 let base = &name[..name.len() - 4];
16427 (base.to_string(), " ASC".to_string())
16428 } else if name.ends_with(" DESC") {
16429 let base = &name[..name.len() - 5];
16430 (base.to_string(), " DESC".to_string())
16431 } else {
16432 (name.to_string(), String::new())
16433 }
16434 } else {
16435 (name.to_string(), String::new())
16436 };
16437
16438 let output_name = if self.config.normalize_identifiers && !id.quoted {
16442 base_name.to_ascii_lowercase()
16443 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
16444 && !id.quoted
16445 && self.is_reserved_keyword(name)
16446 {
16447 base_name.to_ascii_uppercase()
16450 } else {
16451 base_name
16452 };
16453
16454 if needs_quoting {
16455 let escaped_name = if quote_style.start == quote_style.end {
16457 output_name.replace(
16459 quote_style.end,
16460 &format!("{}{}", quote_style.end, quote_style.end),
16461 )
16462 } else {
16463 output_name.replace(
16465 quote_style.end,
16466 &format!("{}{}", quote_style.end, quote_style.end),
16467 )
16468 };
16469 self.write(&format!(
16470 "{}{}{}{}",
16471 quote_style.start, escaped_name, quote_style.end, suffix
16472 ));
16473 } else {
16474 self.write(&output_name);
16475 }
16476
16477 for comment in &id.trailing_comments {
16479 self.write(" ");
16480 self.write_formatted_comment(comment);
16481 }
16482 Ok(())
16483 }
16484
16485 fn generate_column(&mut self, col: &Column) -> Result<()> {
16486 use crate::dialects::DialectType;
16487
16488 if let Some(table) = &col.table {
16489 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
16493 && !table.quoted
16494 && table.name.eq_ignore_ascii_case("LOCAL");
16495
16496 if is_exasol_local_prefix {
16497 self.write("LOCAL");
16499 } else {
16500 self.generate_identifier(table)?;
16501 }
16502 self.write(".");
16503 }
16504 self.generate_identifier(&col.name)?;
16505 if col.join_mark && self.config.supports_column_join_marks {
16508 self.write(" (+)");
16509 }
16510 for comment in &col.trailing_comments {
16512 self.write_space();
16513 self.write_formatted_comment(comment);
16514 }
16515 Ok(())
16516 }
16517
16518 fn generate_prepare(&mut self, prepare: &PrepareStatement) -> Result<()> {
16519 self.write_keyword("PREPARE");
16520 self.write_space();
16521 self.generate_identifier(&prepare.name)?;
16522
16523 if !prepare.parameter_types.is_empty() {
16524 self.write(" (");
16525 for (i, data_type) in prepare.parameter_types.iter().enumerate() {
16526 if i > 0 {
16527 self.write(", ");
16528 }
16529 self.generate_data_type(data_type)?;
16530 }
16531 self.write(")");
16532 }
16533
16534 self.write_space();
16535 self.write_keyword("AS");
16536 self.write_space();
16537 self.generate_expression(&prepare.statement)
16538 }
16539
16540 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
16543 use crate::dialects::DialectType;
16544 use crate::expressions::PseudocolumnType;
16545
16546 if pc.kind == PseudocolumnType::Sysdate
16548 && !matches!(
16549 self.config.dialect,
16550 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
16551 )
16552 {
16553 self.write_keyword("CURRENT_TIMESTAMP");
16554 if matches!(
16556 self.config.dialect,
16557 Some(DialectType::MySQL)
16558 | Some(DialectType::ClickHouse)
16559 | Some(DialectType::Spark)
16560 | Some(DialectType::Databricks)
16561 | Some(DialectType::Hive)
16562 ) {
16563 self.write("()");
16564 }
16565 } else {
16566 self.write(pc.kind.as_str());
16567 }
16568 Ok(())
16569 }
16570
16571 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
16573 use crate::dialects::DialectType;
16574
16575 let supports_connect_by = matches!(
16578 self.config.dialect,
16579 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
16580 );
16581
16582 if !supports_connect_by && self.config.dialect.is_some() {
16583 if self.config.pretty {
16585 self.write_newline();
16586 } else {
16587 self.write_space();
16588 }
16589 self.write_unsupported_comment(
16590 "CONNECT BY requires manual conversion to recursive CTE",
16591 )?;
16592 }
16593
16594 if let Some(start) = &connect.start {
16596 if self.config.pretty {
16597 self.write_newline();
16598 } else {
16599 self.write_space();
16600 }
16601 self.write_keyword("START WITH");
16602 self.write_space();
16603 self.generate_expression(start)?;
16604 }
16605
16606 if self.config.pretty {
16608 self.write_newline();
16609 } else {
16610 self.write_space();
16611 }
16612 self.write_keyword("CONNECT BY");
16613 if connect.nocycle {
16614 self.write_space();
16615 self.write_keyword("NOCYCLE");
16616 }
16617 self.write_space();
16618 self.generate_expression(&connect.connect)?;
16619
16620 Ok(())
16621 }
16622
16623 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
16625 self.generate_connect(connect)
16626 }
16627
16628 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
16630 self.write_keyword("PRIOR");
16631 self.write_space();
16632 self.generate_expression(&prior.this)?;
16633 Ok(())
16634 }
16635
16636 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
16639 self.write_keyword("CONNECT_BY_ROOT");
16640 self.write_space();
16641 self.generate_expression(&cbr.this)?;
16642 Ok(())
16643 }
16644
16645 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
16647 use crate::dialects::DialectType;
16648
16649 let supports_match_recognize = matches!(
16651 self.config.dialect,
16652 Some(DialectType::Oracle)
16653 | Some(DialectType::Snowflake)
16654 | Some(DialectType::Presto)
16655 | Some(DialectType::Trino)
16656 );
16657
16658 if let Some(source) = &mr.this {
16660 self.generate_expression(source)?;
16661 }
16662
16663 if !supports_match_recognize {
16664 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
16665 return Ok(());
16666 }
16667
16668 if self.config.pretty {
16670 self.write_newline();
16671 } else {
16672 self.write_space();
16673 }
16674
16675 self.write_keyword("MATCH_RECOGNIZE");
16676 self.write(" (");
16677
16678 if self.config.pretty {
16679 self.indent_level += 1;
16680 }
16681
16682 let mut needs_separator = false;
16683
16684 if let Some(partition_by) = &mr.partition_by {
16686 if !partition_by.is_empty() {
16687 if self.config.pretty {
16688 self.write_newline();
16689 self.write_indent();
16690 }
16691 self.write_keyword("PARTITION BY");
16692 self.write_space();
16693 for (i, expr) in partition_by.iter().enumerate() {
16694 if i > 0 {
16695 self.write(", ");
16696 }
16697 self.generate_expression(expr)?;
16698 }
16699 needs_separator = true;
16700 }
16701 }
16702
16703 if let Some(order_by) = &mr.order_by {
16705 if !order_by.is_empty() {
16706 if needs_separator {
16707 if self.config.pretty {
16708 self.write_newline();
16709 self.write_indent();
16710 } else {
16711 self.write_space();
16712 }
16713 } else if self.config.pretty {
16714 self.write_newline();
16715 self.write_indent();
16716 }
16717 self.write_keyword("ORDER BY");
16718 if self.config.pretty {
16720 self.indent_level += 1;
16721 for (i, ordered) in order_by.iter().enumerate() {
16722 if i > 0 {
16723 self.write(",");
16724 }
16725 self.write_newline();
16726 self.write_indent();
16727 self.generate_ordered(ordered)?;
16728 }
16729 self.indent_level -= 1;
16730 } else {
16731 self.write_space();
16732 for (i, ordered) in order_by.iter().enumerate() {
16733 if i > 0 {
16734 self.write(", ");
16735 }
16736 self.generate_ordered(ordered)?;
16737 }
16738 }
16739 needs_separator = true;
16740 }
16741 }
16742
16743 if let Some(measures) = &mr.measures {
16745 if !measures.is_empty() {
16746 if needs_separator {
16747 if self.config.pretty {
16748 self.write_newline();
16749 self.write_indent();
16750 } else {
16751 self.write_space();
16752 }
16753 } else if self.config.pretty {
16754 self.write_newline();
16755 self.write_indent();
16756 }
16757 self.write_keyword("MEASURES");
16758 if self.config.pretty {
16760 self.indent_level += 1;
16761 for (i, measure) in measures.iter().enumerate() {
16762 if i > 0 {
16763 self.write(",");
16764 }
16765 self.write_newline();
16766 self.write_indent();
16767 if let Some(semantics) = &measure.window_frame {
16769 match semantics {
16770 MatchRecognizeSemantics::Running => {
16771 self.write_keyword("RUNNING");
16772 self.write_space();
16773 }
16774 MatchRecognizeSemantics::Final => {
16775 self.write_keyword("FINAL");
16776 self.write_space();
16777 }
16778 }
16779 }
16780 self.generate_expression(&measure.this)?;
16781 }
16782 self.indent_level -= 1;
16783 } else {
16784 self.write_space();
16785 for (i, measure) in measures.iter().enumerate() {
16786 if i > 0 {
16787 self.write(", ");
16788 }
16789 if let Some(semantics) = &measure.window_frame {
16791 match semantics {
16792 MatchRecognizeSemantics::Running => {
16793 self.write_keyword("RUNNING");
16794 self.write_space();
16795 }
16796 MatchRecognizeSemantics::Final => {
16797 self.write_keyword("FINAL");
16798 self.write_space();
16799 }
16800 }
16801 }
16802 self.generate_expression(&measure.this)?;
16803 }
16804 }
16805 needs_separator = true;
16806 }
16807 }
16808
16809 if let Some(rows) = &mr.rows {
16811 if needs_separator {
16812 if self.config.pretty {
16813 self.write_newline();
16814 self.write_indent();
16815 } else {
16816 self.write_space();
16817 }
16818 } else if self.config.pretty {
16819 self.write_newline();
16820 self.write_indent();
16821 }
16822 match rows {
16823 MatchRecognizeRows::OneRowPerMatch => {
16824 self.write_keyword("ONE ROW PER MATCH");
16825 }
16826 MatchRecognizeRows::AllRowsPerMatch => {
16827 self.write_keyword("ALL ROWS PER MATCH");
16828 }
16829 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
16830 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
16831 }
16832 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
16833 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
16834 }
16835 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
16836 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
16837 }
16838 }
16839 needs_separator = true;
16840 }
16841
16842 if let Some(after) = &mr.after {
16844 if needs_separator {
16845 if self.config.pretty {
16846 self.write_newline();
16847 self.write_indent();
16848 } else {
16849 self.write_space();
16850 }
16851 } else if self.config.pretty {
16852 self.write_newline();
16853 self.write_indent();
16854 }
16855 match after {
16856 MatchRecognizeAfter::PastLastRow => {
16857 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
16858 }
16859 MatchRecognizeAfter::ToNextRow => {
16860 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
16861 }
16862 MatchRecognizeAfter::ToFirst(ident) => {
16863 self.write_keyword("AFTER MATCH SKIP TO FIRST");
16864 self.write_space();
16865 self.generate_identifier(ident)?;
16866 }
16867 MatchRecognizeAfter::ToLast(ident) => {
16868 self.write_keyword("AFTER MATCH SKIP TO LAST");
16869 self.write_space();
16870 self.generate_identifier(ident)?;
16871 }
16872 }
16873 needs_separator = true;
16874 }
16875
16876 if let Some(pattern) = &mr.pattern {
16878 if needs_separator {
16879 if self.config.pretty {
16880 self.write_newline();
16881 self.write_indent();
16882 } else {
16883 self.write_space();
16884 }
16885 } else if self.config.pretty {
16886 self.write_newline();
16887 self.write_indent();
16888 }
16889 self.write_keyword("PATTERN");
16890 self.write_space();
16891 self.write("(");
16892 self.write(pattern);
16893 self.write(")");
16894 needs_separator = true;
16895 }
16896
16897 if let Some(define) = &mr.define {
16899 if !define.is_empty() {
16900 if needs_separator {
16901 if self.config.pretty {
16902 self.write_newline();
16903 self.write_indent();
16904 } else {
16905 self.write_space();
16906 }
16907 } else if self.config.pretty {
16908 self.write_newline();
16909 self.write_indent();
16910 }
16911 self.write_keyword("DEFINE");
16912 if self.config.pretty {
16914 self.indent_level += 1;
16915 for (i, (name, expr)) in define.iter().enumerate() {
16916 if i > 0 {
16917 self.write(",");
16918 }
16919 self.write_newline();
16920 self.write_indent();
16921 self.generate_identifier(name)?;
16922 self.write(" AS ");
16923 self.generate_expression(expr)?;
16924 }
16925 self.indent_level -= 1;
16926 } else {
16927 self.write_space();
16928 for (i, (name, expr)) in define.iter().enumerate() {
16929 if i > 0 {
16930 self.write(", ");
16931 }
16932 self.generate_identifier(name)?;
16933 self.write(" AS ");
16934 self.generate_expression(expr)?;
16935 }
16936 }
16937 }
16938 }
16939
16940 if self.config.pretty {
16941 self.indent_level -= 1;
16942 self.write_newline();
16943 }
16944 self.write(")");
16945
16946 if let Some(alias) = &mr.alias {
16948 self.write(" ");
16949 if mr.alias_explicit_as {
16950 self.write_keyword("AS");
16951 self.write(" ");
16952 }
16953 self.generate_identifier(alias)?;
16954 }
16955
16956 Ok(())
16957 }
16958
16959 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
16961 use crate::dialects::DialectType;
16962
16963 let supports_hints = matches!(
16965 self.config.dialect,
16966 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
16968 Some(DialectType::Spark) | Some(DialectType::Hive) |
16969 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
16970 );
16971
16972 if !supports_hints || hint.expressions.is_empty() {
16973 return Ok(());
16974 }
16975
16976 let mut hint_strings: Vec<String> = Vec::new();
16979 for expr in &hint.expressions {
16980 match expr {
16981 HintExpression::Raw(text) => {
16982 let parsed = self.parse_raw_hint_text(text);
16984 hint_strings.extend(parsed);
16985 }
16986 _ => {
16987 hint_strings.push(self.hint_expression_to_string(expr)?);
16988 }
16989 }
16990 }
16991
16992 let use_multiline = self.config.pretty && hint_strings.len() > 1;
16996
16997 if use_multiline {
16998 self.write(" /*+ ");
17000 for (i, hint_str) in hint_strings.iter().enumerate() {
17001 if i > 0 {
17002 self.write_newline();
17003 self.write(" "); }
17005 self.write(hint_str);
17006 }
17007 self.write(" */");
17008 } else {
17009 self.write(" /*+ ");
17011 let sep = match self.config.dialect {
17012 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
17013 _ => " ",
17014 };
17015 for (i, hint_str) in hint_strings.iter().enumerate() {
17016 if i > 0 {
17017 self.write(sep);
17018 }
17019 self.write(hint_str);
17020 }
17021 self.write(" */");
17022 }
17023
17024 Ok(())
17025 }
17026
17027 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
17031 let mut results = Vec::new();
17032 let mut chars = text.chars().peekable();
17033 let mut current = String::new();
17034 let mut paren_depth = 0;
17035 let mut has_unparseable_content = false;
17036 let mut position_after_last_function = 0;
17037 let mut char_position = 0;
17038
17039 while let Some(c) = chars.next() {
17040 char_position += c.len_utf8();
17041 match c {
17042 '(' => {
17043 paren_depth += 1;
17044 current.push(c);
17045 }
17046 ')' => {
17047 paren_depth -= 1;
17048 current.push(c);
17049 if paren_depth == 0 {
17051 let trimmed = current.trim().to_string();
17052 if !trimmed.is_empty() {
17053 let formatted = self.format_hint_function(&trimmed);
17055 results.push(formatted);
17056 }
17057 current.clear();
17058 position_after_last_function = char_position;
17059 }
17060 }
17061 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
17062 }
17064 _ if paren_depth == 0 => {
17065 current.push(c);
17067 }
17068 _ => {
17069 current.push(c);
17070 }
17071 }
17072 }
17073
17074 let remaining_text = text[position_after_last_function..].trim();
17076 if !remaining_text.is_empty() {
17077 let words: Vec<&str> = remaining_text.split_whitespace().collect();
17081 let looks_like_hint_functions = words.iter().all(|word| {
17082 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
17084 });
17085
17086 if !looks_like_hint_functions && words.len() > 1 {
17087 has_unparseable_content = true;
17088 }
17089 }
17090
17091 if has_unparseable_content {
17093 return vec![text.trim().to_string()];
17094 }
17095
17096 if results.is_empty() {
17098 results.push(text.trim().to_string());
17099 }
17100
17101 results
17102 }
17103
17104 fn format_hint_function(&self, hint: &str) -> String {
17107 if !self.config.pretty {
17108 return hint.to_string();
17109 }
17110
17111 if let Some(paren_pos) = hint.find('(') {
17113 if hint.ends_with(')') {
17114 let name = &hint[..paren_pos];
17115 let args_str = &hint[paren_pos + 1..hint.len() - 1];
17116
17117 let args: Vec<&str> = args_str.split_whitespace().collect();
17119
17120 let total_args_width: usize =
17122 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() {
17126 let mut result = format!("{}(\n", name);
17127 for arg in &args {
17128 result.push_str(" "); result.push_str(arg);
17130 result.push('\n');
17131 }
17132 result.push_str(" )"); return result;
17134 }
17135 }
17136 }
17137
17138 hint.to_string()
17139 }
17140
17141 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
17143 match expr {
17144 HintExpression::Function { name, args } => {
17145 let arg_strings: Vec<String> = args
17147 .iter()
17148 .map(|arg| {
17149 let mut gen = Generator::with_arc_config(self.config.clone());
17150 gen.generate_expression(arg)?;
17151 Ok(gen.output)
17152 })
17153 .collect::<Result<Vec<_>>>()?;
17154
17155 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
17157 + arg_strings.len().saturating_sub(1); let args_multiline =
17162 self.config.pretty && total_args_width > self.config.max_text_width;
17163
17164 if args_multiline && !arg_strings.is_empty() {
17165 let mut result = format!("{}(\n", name);
17167 for arg_str in &arg_strings {
17168 result.push_str(" "); result.push_str(arg_str);
17170 result.push('\n');
17171 }
17172 result.push_str(" )"); Ok(result)
17174 } else {
17175 let args_str = arg_strings.join(" ");
17177 Ok(format!("{}({})", name, args_str))
17178 }
17179 }
17180 HintExpression::Identifier(name) => Ok(name.clone()),
17181 HintExpression::Raw(text) => {
17182 if self.config.pretty {
17184 Ok(self.format_hint_function(text))
17185 } else {
17186 Ok(text.clone())
17187 }
17188 }
17189 }
17190 }
17191
17192 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
17193 if table.only {
17195 self.write_keyword("ONLY");
17196 self.write_space();
17197 }
17198
17199 if let Some(ref identifier_func) = table.identifier_func {
17201 self.generate_expression(identifier_func)?;
17202 if !table.name.name.is_empty() {
17204 if let Some(catalog) = &table.catalog {
17205 self.write(".");
17206 self.generate_identifier(catalog)?;
17207 }
17208 if let Some(schema) = &table.schema {
17209 self.write(".");
17210 self.generate_identifier(schema)?;
17211 }
17212 self.write(".");
17213 self.generate_identifier(&table.name)?;
17214 }
17215 } else {
17216 if let Some(catalog) = &table.catalog {
17217 self.generate_identifier(catalog)?;
17218 self.write(".");
17219 }
17220 if let Some(schema) = &table.schema {
17221 self.generate_identifier(schema)?;
17222 self.write(".");
17223 }
17224 self.generate_identifier(&table.name)?;
17225 }
17226
17227 if let Some(changes) = &table.changes {
17229 self.write(" ");
17230 self.generate_changes(changes)?;
17231 }
17232
17233 if !table.partitions.is_empty() {
17235 self.write_space();
17236 self.write_keyword("PARTITION");
17237 self.write("(");
17238 for (i, partition) in table.partitions.iter().enumerate() {
17239 if i > 0 {
17240 self.write(", ");
17241 }
17242 self.generate_identifier(partition)?;
17243 }
17244 self.write(")");
17245 }
17246
17247 if table.changes.is_none() {
17250 if let Some(when) = &table.when {
17251 self.write_space();
17252 self.generate_historical_data(when)?;
17253 }
17254 }
17255
17256 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
17258 if !system_time_post_alias {
17259 if let Some(ref system_time) = table.system_time {
17260 self.write_space();
17261 self.write(system_time);
17262 }
17263 }
17264
17265 if let Some(ref version) = table.version {
17267 self.write_space();
17268 self.generate_version(version)?;
17269 }
17270
17271 let alias_post_tablesample = self.config.alias_post_tablesample;
17275
17276 if alias_post_tablesample {
17277 self.generate_table_sample_clause(table)?;
17279 }
17280
17281 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
17284 && table.hints.iter().any(|h| {
17285 if let Expression::Identifier(id) = h {
17286 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
17287 } else {
17288 false
17289 }
17290 });
17291 if !table.hints.is_empty() && !is_sqlite_hint {
17292 for hint in &table.hints {
17293 self.write_space();
17294 self.generate_expression(hint)?;
17295 }
17296 }
17297
17298 if let Some(alias) = &table.alias {
17299 self.write_space();
17300 let always_use_as = self.config.dialect.is_none()
17303 || matches!(
17304 self.config.dialect,
17305 Some(DialectType::Generic)
17306 | Some(DialectType::PostgreSQL)
17307 | Some(DialectType::Redshift)
17308 | Some(DialectType::Snowflake)
17309 | Some(DialectType::BigQuery)
17310 | Some(DialectType::DuckDB)
17311 | Some(DialectType::Presto)
17312 | Some(DialectType::Trino)
17313 | Some(DialectType::TSQL)
17314 | Some(DialectType::Fabric)
17315 | Some(DialectType::MySQL)
17316 | Some(DialectType::Spark)
17317 | Some(DialectType::Hive)
17318 | Some(DialectType::SQLite)
17319 | Some(DialectType::Drill)
17320 );
17321 let is_stage_ref = table.name.name.starts_with('@');
17322 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
17324 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
17325 self.write_keyword("AS");
17326 self.write_space();
17327 }
17328 self.generate_identifier(alias)?;
17329
17330 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
17333 self.write("(");
17334 for (i, col_alias) in table.column_aliases.iter().enumerate() {
17335 if i > 0 {
17336 self.write(", ");
17337 }
17338 self.generate_identifier(col_alias)?;
17339 }
17340 self.write(")");
17341 }
17342 }
17343
17344 if system_time_post_alias {
17346 if let Some(ref system_time) = table.system_time {
17347 self.write_space();
17348 self.write(system_time);
17349 }
17350 }
17351
17352 if !alias_post_tablesample {
17354 self.generate_table_sample_clause(table)?;
17355 }
17356
17357 if is_sqlite_hint {
17359 for hint in &table.hints {
17360 self.write_space();
17361 self.generate_expression(hint)?;
17362 }
17363 }
17364
17365 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
17367 self.write_space();
17368 self.write_keyword("FINAL");
17369 }
17370
17371 for comment in &table.trailing_comments {
17373 self.write_space();
17374 self.write_formatted_comment(comment);
17375 }
17376 Ok(())
17380 }
17381
17382 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
17384 if let Some(ref ts) = table.table_sample {
17385 self.write_space();
17386 if ts.is_using_sample {
17387 self.write_keyword("USING SAMPLE");
17388 } else {
17389 self.write_keyword(self.config.tablesample_keywords);
17391 }
17392 self.generate_sample_body(ts)?;
17393 if let Some(ref seed) = ts.seed {
17395 self.write_space();
17396 self.write_keyword(self.config.tablesample_seed_keyword);
17397 self.write(" (");
17398 self.generate_expression(seed)?;
17399 self.write(")");
17400 }
17401 }
17402 Ok(())
17403 }
17404
17405 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
17406 if sr.quoted {
17410 self.write("'");
17411 }
17412
17413 self.write(&sr.name);
17414 if let Some(path) = &sr.path {
17415 self.write(path);
17416 }
17417
17418 if sr.quoted {
17419 self.write("'");
17420 }
17421
17422 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
17424 if has_options {
17425 self.write(" (");
17426 let mut first = true;
17427
17428 if let Some(file_format) = &sr.file_format {
17429 if !first {
17430 self.write(", ");
17431 }
17432 self.write_keyword("FILE_FORMAT");
17433 self.write(" => ");
17434 self.generate_expression(file_format)?;
17435 first = false;
17436 }
17437
17438 if let Some(pattern) = &sr.pattern {
17439 if !first {
17440 self.write(", ");
17441 }
17442 self.write_keyword("PATTERN");
17443 self.write(" => '");
17444 self.write(pattern);
17445 self.write("'");
17446 }
17447
17448 self.write(")");
17449 }
17450 Ok(())
17451 }
17452
17453 fn generate_star(&mut self, star: &Star) -> Result<()> {
17454 use crate::dialects::DialectType;
17455
17456 if let Some(table) = &star.table {
17457 self.generate_identifier(table)?;
17458 self.write(".");
17459 }
17460 self.write("*");
17461
17462 if let Some(except) = &star.except {
17464 if !except.is_empty() {
17465 self.write_space();
17466 match self.config.dialect {
17468 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
17469 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
17470 self.write_keyword("EXCLUDE")
17471 }
17472 _ => self.write_keyword("EXCEPT"), }
17474 self.write(" (");
17475 for (i, col) in except.iter().enumerate() {
17476 if i > 0 {
17477 self.write(", ");
17478 }
17479 self.generate_identifier(col)?;
17480 }
17481 self.write(")");
17482 }
17483 }
17484
17485 if let Some(replace) = &star.replace {
17487 if !replace.is_empty() {
17488 self.write_space();
17489 self.write_keyword("REPLACE");
17490 self.write(" (");
17491 for (i, alias) in replace.iter().enumerate() {
17492 if i > 0 {
17493 self.write(", ");
17494 }
17495 self.generate_expression(&alias.this)?;
17496 self.write_space();
17497 self.write_keyword("AS");
17498 self.write_space();
17499 self.generate_identifier(&alias.alias)?;
17500 }
17501 self.write(")");
17502 }
17503 }
17504
17505 if let Some(rename) = &star.rename {
17507 if !rename.is_empty() {
17508 self.write_space();
17509 self.write_keyword("RENAME");
17510 self.write(" (");
17511 for (i, (old_name, new_name)) in rename.iter().enumerate() {
17512 if i > 0 {
17513 self.write(", ");
17514 }
17515 self.generate_identifier(old_name)?;
17516 self.write_space();
17517 self.write_keyword("AS");
17518 self.write_space();
17519 self.generate_identifier(new_name)?;
17520 }
17521 self.write(")");
17522 }
17523 }
17524
17525 for comment in &star.trailing_comments {
17527 self.write_space();
17528 self.write_formatted_comment(comment);
17529 }
17530
17531 Ok(())
17532 }
17533
17534 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
17536 self.write("{");
17537 match expr {
17538 Expression::Star(star) => {
17539 self.generate_star(star)?;
17541 }
17542 Expression::ILike(ilike) => {
17543 self.generate_expression(&ilike.left)?;
17545 self.write_space();
17546 self.write_keyword("ILIKE");
17547 self.write_space();
17548 self.generate_expression(&ilike.right)?;
17549 }
17550 _ => {
17551 self.generate_expression(expr)?;
17552 }
17553 }
17554 self.write("}");
17555 Ok(())
17556 }
17557
17558 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
17559 match &alias.this {
17563 Expression::Column(col) => {
17564 if let Some(table) = &col.table {
17566 self.generate_identifier(table)?;
17567 self.write(".");
17568 }
17569 self.generate_identifier(&col.name)?;
17570 }
17571 _ => {
17572 self.generate_expression(&alias.this)?;
17573 }
17574 }
17575
17576 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
17580 for comment in &alias.pre_alias_comments {
17581 self.write_space();
17582 self.write_formatted_comment(comment);
17583 }
17584 }
17585
17586 use crate::dialects::DialectType;
17587
17588 let is_table_source = matches!(
17594 &alias.this,
17595 Expression::JSONTable(_)
17596 | Expression::XMLTable(_)
17597 | Expression::TableFromRows(_)
17598 | Expression::Unnest(_)
17599 | Expression::MatchRecognize(_)
17600 | Expression::Select(_)
17601 | Expression::Subquery(_)
17602 | Expression::Paren(_)
17603 | Expression::JoinedTable(_)
17604 );
17605 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
17606 let skip_as = is_table_source && dialect_skips_table_alias_as;
17607
17608 self.write_space();
17609 if !skip_as {
17610 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
17611 if let Some(ref alias_keyword) = alias.alias_keyword {
17612 self.write(alias_keyword);
17613 } else {
17614 self.write_keyword("AS");
17615 }
17616 } else {
17617 self.write_keyword("AS");
17618 }
17619 self.write_space();
17620 }
17621
17622 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
17624
17625 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
17627 self.write("(");
17629 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17630 if i > 0 {
17631 self.write(", ");
17632 }
17633 self.generate_alias_identifier(col_alias)?;
17634 }
17635 self.write(")");
17636 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
17637 self.generate_alias_identifier(&alias.alias)?;
17639 self.write("(");
17640 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17641 if i > 0 {
17642 self.write(", ");
17643 }
17644 self.generate_alias_identifier(col_alias)?;
17645 }
17646 self.write(")");
17647 } else {
17648 self.generate_alias_identifier(&alias.alias)?;
17650 }
17651
17652 for comment in &alias.trailing_comments {
17654 self.write_space();
17655 self.write_formatted_comment(comment);
17656 }
17657
17658 if alias.trailing_comments.is_empty() {
17663 for comment in &alias.pre_alias_comments {
17664 self.write_space();
17665 self.write_formatted_comment(comment);
17666 }
17667 }
17668
17669 Ok(())
17670 }
17671
17672 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
17673 use crate::dialects::DialectType;
17674
17675 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
17677 self.generate_expression(&cast.this)?;
17678 self.write(" :> ");
17679 self.generate_data_type(&cast.to)?;
17680 return Ok(());
17681 }
17682
17683 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
17685 let is_unknown_type = matches!(cast.to, DataType::Unknown)
17686 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
17687 if is_unknown_type {
17688 if let Some(format) = &cast.format {
17689 self.write_keyword("CAST");
17690 self.write("(");
17691 self.generate_expression(&cast.this)?;
17692 self.write_space();
17693 self.write_keyword("AS");
17694 self.write_space();
17695 self.write_keyword("FORMAT");
17696 self.write_space();
17697 self.generate_expression(format)?;
17698 self.write(")");
17699 return Ok(());
17700 }
17701 }
17702 }
17703
17704 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
17707 if let Some(format) = &cast.format {
17708 let is_date = matches!(cast.to, DataType::Date);
17710 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
17711
17712 if is_date || is_timestamp {
17713 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
17714 self.write_keyword(func_name);
17715 self.write("(");
17716 self.generate_expression(&cast.this)?;
17717 self.write(", ");
17718
17719 if let Expression::Literal(lit) = format.as_ref() {
17722 if let Literal::String(fmt_str) = lit.as_ref() {
17723 let normalized = self.normalize_oracle_format(fmt_str);
17724 self.write("'");
17725 self.write(&normalized);
17726 self.write("'");
17727 }
17728 } else {
17729 self.generate_expression(format)?;
17730 }
17731
17732 self.write(")");
17733 return Ok(());
17734 }
17735 }
17736 }
17737
17738 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
17741 if let Expression::Array(arr) = &cast.this {
17742 self.generate_data_type(&cast.to)?;
17743 self.write("[");
17745 for (i, expr) in arr.expressions.iter().enumerate() {
17746 if i > 0 {
17747 self.write(", ");
17748 }
17749 self.generate_expression(expr)?;
17750 }
17751 self.write("]");
17752 return Ok(());
17753 }
17754 if matches!(&cast.this, Expression::ArrayFunc(_)) {
17755 self.generate_data_type(&cast.to)?;
17756 self.generate_expression(&cast.this)?;
17757 return Ok(());
17758 }
17759 }
17760
17761 if matches!(
17764 self.config.dialect,
17765 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
17766 ) {
17767 if let Expression::Struct(ref s) = cast.this {
17768 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
17769 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
17770 self.write_keyword("CAST");
17771 self.write("(");
17772 self.generate_struct_as_row(s)?;
17773 self.write_space();
17774 self.write_keyword("AS");
17775 self.write_space();
17776 self.generate_data_type(&cast.to)?;
17777 self.write(")");
17778 return Ok(());
17779 }
17780 }
17781 }
17782
17783 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
17786
17787 if use_double_colon {
17788 self.generate_expression(&cast.this)?;
17790 self.write("::");
17791 self.generate_data_type(&cast.to)?;
17792 } else {
17793 self.write_keyword("CAST");
17795 self.write("(");
17796 self.generate_expression(&cast.this)?;
17797 self.write_space();
17798 self.write_keyword("AS");
17799 self.write_space();
17800 if matches!(
17803 self.config.dialect,
17804 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
17805 ) {
17806 match &cast.to {
17807 DataType::Custom { ref name } => {
17808 if name.eq_ignore_ascii_case("LONGTEXT")
17809 || name.eq_ignore_ascii_case("MEDIUMTEXT")
17810 || name.eq_ignore_ascii_case("TINYTEXT")
17811 || name.eq_ignore_ascii_case("LONGBLOB")
17812 || name.eq_ignore_ascii_case("MEDIUMBLOB")
17813 || name.eq_ignore_ascii_case("TINYBLOB")
17814 {
17815 self.write_keyword("CHAR");
17816 } else {
17817 self.generate_data_type(&cast.to)?;
17818 }
17819 }
17820 DataType::VarChar { length, .. } => {
17821 self.write_keyword("CHAR");
17823 if let Some(n) = length {
17824 self.write(&format!("({})", n));
17825 }
17826 }
17827 DataType::Text => {
17828 self.write_keyword("CHAR");
17830 }
17831 DataType::Timestamp {
17832 precision,
17833 timezone: false,
17834 } => {
17835 self.write_keyword("DATETIME");
17837 if let Some(p) = precision {
17838 self.write(&format!("({})", p));
17839 }
17840 }
17841 _ => {
17842 self.generate_data_type(&cast.to)?;
17843 }
17844 }
17845 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
17846 match &cast.to {
17848 DataType::String { length } => {
17849 self.write_keyword("VARCHAR");
17850 if let Some(n) = length {
17851 self.write(&format!("({})", n));
17852 }
17853 }
17854 _ => {
17855 self.generate_data_type(&cast.to)?;
17856 }
17857 }
17858 } else {
17859 self.generate_data_type(&cast.to)?;
17860 }
17861
17862 if let Some(default) = &cast.default {
17864 self.write_space();
17865 self.write_keyword("DEFAULT");
17866 self.write_space();
17867 self.generate_expression(default)?;
17868 self.write_space();
17869 self.write_keyword("ON");
17870 self.write_space();
17871 self.write_keyword("CONVERSION");
17872 self.write_space();
17873 self.write_keyword("ERROR");
17874 }
17875
17876 if let Some(format) = &cast.format {
17879 if matches!(
17881 self.config.dialect,
17882 Some(crate::dialects::DialectType::Oracle)
17883 ) {
17884 self.write(", ");
17885 } else {
17886 self.write_space();
17887 self.write_keyword("FORMAT");
17888 self.write_space();
17889 }
17890 self.generate_expression(format)?;
17891 }
17892
17893 self.write(")");
17894 for comment in &cast.trailing_comments {
17896 self.write_space();
17897 self.write_formatted_comment(comment);
17898 }
17899 }
17900 Ok(())
17901 }
17902
17903 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
17906 self.write_keyword("ROW");
17907 self.write("(");
17908 for (i, (_, expr)) in s.fields.iter().enumerate() {
17909 if i > 0 {
17910 self.write(", ");
17911 }
17912 if let Expression::Struct(ref inner_s) = expr {
17914 self.generate_struct_as_row(inner_s)?;
17915 } else {
17916 self.generate_expression(expr)?;
17917 }
17918 }
17919 self.write(")");
17920 Ok(())
17921 }
17922
17923 fn normalize_oracle_format(&self, format: &str) -> String {
17926 let mut result = String::new();
17929 let chars: Vec<char> = format.chars().collect();
17930 let mut i = 0;
17931
17932 while i < chars.len() {
17933 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
17934 if i + 2 < chars.len() {
17936 let next = chars[i + 2];
17937 if next == '1' || next == '2' {
17938 result.push('H');
17940 result.push('H');
17941 i += 2;
17942 continue;
17943 }
17944 }
17945 result.push_str("HH12");
17947 i += 2;
17948 } else {
17949 result.push(chars[i]);
17950 i += 1;
17951 }
17952 }
17953
17954 result
17955 }
17956
17957 fn dialect_prefers_double_colon(&self) -> bool {
17960 matches!(self.config.dialect, Some(DialectType::ClickHouse))
17961 }
17962
17963 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17965 use crate::dialects::DialectType;
17966
17967 let use_percent_operator = matches!(
17969 self.config.dialect,
17970 Some(DialectType::Snowflake)
17971 | Some(DialectType::MySQL)
17972 | Some(DialectType::Presto)
17973 | Some(DialectType::Trino)
17974 | Some(DialectType::PostgreSQL)
17975 | Some(DialectType::DuckDB)
17976 | Some(DialectType::Hive)
17977 | Some(DialectType::Spark)
17978 | Some(DialectType::Databricks)
17979 | Some(DialectType::Athena)
17980 | Some(DialectType::TSQL)
17981 | Some(DialectType::Fabric)
17982 );
17983
17984 if use_percent_operator {
17985 let needs_paren = |e: &Expression| {
17988 matches!(
17989 e,
17990 Expression::Add(_)
17991 | Expression::Sub(_)
17992 | Expression::Mul(_)
17993 | Expression::Div(_)
17994 | Expression::Mod(_)
17995 | Expression::ModFunc(_)
17996 )
17997 };
17998 if needs_paren(&f.this) {
17999 self.write("(");
18000 self.generate_expression(&f.this)?;
18001 self.write(")");
18002 } else {
18003 self.generate_expression(&f.this)?;
18004 }
18005 self.write(" % ");
18006 if needs_paren(&f.expression) {
18007 self.write("(");
18008 self.generate_expression(&f.expression)?;
18009 self.write(")");
18010 } else {
18011 self.generate_expression(&f.expression)?;
18012 }
18013 Ok(())
18014 } else {
18015 self.generate_binary_func("MOD", &f.this, &f.expression)
18016 }
18017 }
18018
18019 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
18021 use crate::dialects::DialectType;
18022
18023 let func_name = match self.config.dialect {
18025 Some(DialectType::Snowflake) => "COALESCE",
18026 _ => "IFNULL",
18027 };
18028
18029 self.generate_binary_func(func_name, &f.this, &f.expression)
18030 }
18031
18032 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
18034 if let Some(ref original_name) = f.original_name {
18036 return self.generate_binary_func(original_name, &f.this, &f.expression);
18037 }
18038
18039 use crate::dialects::DialectType;
18041 let func_name = match self.config.dialect {
18042 Some(DialectType::Snowflake)
18043 | Some(DialectType::ClickHouse)
18044 | Some(DialectType::PostgreSQL)
18045 | Some(DialectType::Presto)
18046 | Some(DialectType::Trino)
18047 | Some(DialectType::Athena)
18048 | Some(DialectType::DuckDB)
18049 | Some(DialectType::BigQuery)
18050 | Some(DialectType::Spark)
18051 | Some(DialectType::Databricks)
18052 | Some(DialectType::Hive) => "COALESCE",
18053 Some(DialectType::MySQL)
18054 | Some(DialectType::Doris)
18055 | Some(DialectType::StarRocks)
18056 | Some(DialectType::SingleStore)
18057 | Some(DialectType::TiDB) => "IFNULL",
18058 _ => "NVL",
18059 };
18060
18061 self.generate_binary_func(func_name, &f.this, &f.expression)
18062 }
18063
18064 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
18066 use crate::dialects::DialectType;
18067
18068 let func_name = match self.config.dialect {
18070 Some(DialectType::Snowflake) => "STDDEV",
18071 _ => "STDDEV_SAMP",
18072 };
18073
18074 self.generate_agg_func(func_name, f)
18075 }
18076
18077 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
18078 self.generate_expression(&coll.this)?;
18079 self.write_space();
18080 self.write_keyword("COLLATE");
18081 self.write_space();
18082 if coll.quoted {
18083 self.write("'");
18085 self.write(&coll.collation);
18086 self.write("'");
18087 } else if coll.double_quoted {
18088 self.write("\"");
18090 self.write(&coll.collation);
18091 self.write("\"");
18092 } else {
18093 self.write(&coll.collation);
18095 }
18096 Ok(())
18097 }
18098
18099 fn generate_case(&mut self, case: &Case) -> Result<()> {
18100 let multiline_case = if self.config.pretty {
18102 let mut statements: Vec<String> = Vec::new();
18104 let operand_str = if let Some(operand) = &case.operand {
18105 let s = self.generate_to_string(operand)?;
18106 statements.push(format!("CASE {}", s));
18107 s
18108 } else {
18109 statements.push("CASE".to_string());
18110 String::new()
18111 };
18112 let _ = operand_str;
18113 for (condition, result) in &case.whens {
18114 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
18115 statements.push(format!("THEN {}", self.generate_to_string(result)?));
18116 }
18117 if let Some(else_) = &case.else_ {
18118 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
18119 }
18120 statements.push("END".to_string());
18121 self.too_wide(&statements)
18122 } else {
18123 false
18124 };
18125
18126 self.write_keyword("CASE");
18127 if let Some(operand) = &case.operand {
18128 self.write_space();
18129 self.generate_expression(operand)?;
18130 }
18131 if multiline_case {
18132 self.indent_level += 1;
18133 }
18134 for (condition, result) in &case.whens {
18135 if multiline_case {
18136 self.write_newline();
18137 self.write_indent();
18138 } else {
18139 self.write_space();
18140 }
18141 self.write_keyword("WHEN");
18142 self.write_space();
18143 self.generate_expression(condition)?;
18144 if multiline_case {
18145 self.write_newline();
18146 self.write_indent();
18147 } else {
18148 self.write_space();
18149 }
18150 self.write_keyword("THEN");
18151 self.write_space();
18152 self.generate_expression(result)?;
18153 }
18154 if let Some(else_) = &case.else_ {
18155 if multiline_case {
18156 self.write_newline();
18157 self.write_indent();
18158 } else {
18159 self.write_space();
18160 }
18161 self.write_keyword("ELSE");
18162 self.write_space();
18163 self.generate_expression(else_)?;
18164 }
18165 if multiline_case {
18166 self.indent_level -= 1;
18167 self.write_newline();
18168 self.write_indent();
18169 } else {
18170 self.write_space();
18171 }
18172 self.write_keyword("END");
18173 for comment in &case.comments {
18175 self.write(" ");
18176 self.write_formatted_comment(comment);
18177 }
18178 Ok(())
18179 }
18180
18181 fn generate_function(&mut self, func: &Function) -> Result<()> {
18182 let normalized_name = if func.name.eq_ignore_ascii_case("GROUPING")
18184 && func.args.len() > 1
18185 && matches!(
18186 self.config.dialect,
18187 Some(DialectType::TSQL | DialectType::Fabric)
18188 ) {
18189 Cow::Borrowed("GROUPING_ID")
18190 } else if matches!(self.config.dialect, Some(DialectType::Snowflake))
18191 && func.name.to_ascii_uppercase().starts_with("IDENTIFIER(")
18192 {
18193 Cow::Borrowed(func.name.as_str())
18194 } else {
18195 self.normalize_func_name(&func.name)
18196 };
18197
18198 if matches!(self.config.dialect, Some(DialectType::DuckDB))
18200 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
18201 {
18202 self.write("LIST_FILTER(");
18203 self.write("[");
18204 for (i, arg) in func.args.iter().enumerate() {
18205 if i > 0 {
18206 self.write(", ");
18207 }
18208 self.generate_expression(arg)?;
18209 }
18210 self.write("], _u -> NOT _u IS NULL)");
18211 return Ok(());
18212 }
18213
18214 if matches!(self.config.dialect, Some(DialectType::Snowflake))
18217 && func.name.eq_ignore_ascii_case("TO_VARIANT")
18218 && func.args.len() == 1
18219 {
18220 let array_expressions = match &func.args[0] {
18221 Expression::ArrayFunc(arr) => Some(&arr.expressions),
18222 Expression::Array(arr) => Some(&arr.expressions),
18223 _ => None,
18224 };
18225 if let Some(expressions) = array_expressions {
18226 self.write_keyword("TO_VARIANT");
18227 self.write("(");
18228 self.write_keyword("ARRAY_CONSTRUCT");
18229 self.write("(");
18230 for (i, arg) in expressions.iter().enumerate() {
18231 if i > 0 {
18232 self.write(", ");
18233 }
18234 self.generate_expression(arg)?;
18235 }
18236 self.write(")");
18237 self.write(")");
18238 return Ok(());
18239 }
18240 }
18241
18242 if func.name.eq_ignore_ascii_case("STRUCT")
18244 && !matches!(
18245 self.config.dialect,
18246 Some(DialectType::BigQuery)
18247 | Some(DialectType::Spark)
18248 | Some(DialectType::Databricks)
18249 | Some(DialectType::Hive)
18250 | None
18251 )
18252 {
18253 return self.generate_struct_function_cross_dialect(func);
18254 }
18255
18256 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
18259 self.generate_expression(&func.args[0])?;
18260 self.write("::?");
18261 if let Expression::Literal(lit) = &func.args[1] {
18263 if let crate::expressions::Literal::String(key) = lit.as_ref() {
18264 self.write(key);
18265 }
18266 } else {
18267 self.generate_expression(&func.args[1])?;
18268 }
18269 return Ok(());
18270 }
18271
18272 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
18274 self.generate_expression(&func.args[0])?;
18275 self.write(" # ");
18276 self.generate_expression(&func.args[1])?;
18277 return Ok(());
18278 }
18279
18280 if matches!(
18282 self.config.dialect,
18283 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
18284 ) && func.name.eq_ignore_ascii_case("TRY")
18285 && func.args.len() == 1
18286 {
18287 self.generate_expression(&func.args[0])?;
18288 return Ok(());
18289 }
18290
18291 if self.config.dialect == Some(DialectType::ClickHouse)
18293 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
18294 && func.args.len() == 1
18295 {
18296 self.write("dateTrunc('DAY', ");
18297 self.generate_expression(&func.args[0])?;
18298 self.write(")");
18299 return Ok(());
18300 }
18301
18302 if self.config.dialect == Some(DialectType::ClickHouse)
18304 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
18305 && func.args.len() == 2
18306 {
18307 self.write("dateTrunc(");
18308 self.generate_expression(&func.args[0])?;
18309 self.write(", ");
18310 self.generate_expression(&func.args[1])?;
18311 self.write(")");
18312 return Ok(());
18313 }
18314
18315 if matches!(
18317 self.config.dialect,
18318 Some(DialectType::Presto | DialectType::Trino | DialectType::Athena)
18319 ) && func.name.eq_ignore_ascii_case("SUBSTRING")
18320 {
18321 self.write_keyword("SUBSTR");
18322 self.write("(");
18323 for (i, arg) in func.args.iter().enumerate() {
18324 if i > 0 {
18325 self.write(", ");
18326 }
18327 self.generate_expression(arg)?;
18328 }
18329 self.write(")");
18330 return Ok(());
18331 }
18332
18333 if self.config.dialect == Some(DialectType::Snowflake)
18334 && func.name.eq_ignore_ascii_case("LIST_DISTINCT")
18335 && func.args.len() == 1
18336 {
18337 self.write_keyword("ARRAY_DISTINCT");
18338 self.write("(");
18339 self.write_keyword("ARRAY_COMPACT");
18340 self.write("(");
18341 self.generate_expression(&func.args[0])?;
18342 self.write("))");
18343 return Ok(());
18344 }
18345
18346 if self.config.dialect == Some(DialectType::Snowflake)
18347 && func.name.eq_ignore_ascii_case("LIST")
18348 && func.args.len() == 1
18349 && !matches!(func.args.first(), Some(Expression::Select(_)))
18350 {
18351 self.write_keyword("ARRAY_AGG");
18352 self.write("(");
18353 self.generate_expression(&func.args[0])?;
18354 self.write(")");
18355 return Ok(());
18356 }
18357
18358 if self.config.dialect == Some(DialectType::Redshift)
18360 && func.name.eq_ignore_ascii_case("CONCAT")
18361 && func.args.len() >= 2
18362 {
18363 for (i, arg) in func.args.iter().enumerate() {
18364 if i > 0 {
18365 self.write(" || ");
18366 }
18367 self.generate_expression(arg)?;
18368 }
18369 return Ok(());
18370 }
18371
18372 if self.config.dialect == Some(DialectType::Redshift)
18374 && func.name.eq_ignore_ascii_case("CONCAT_WS")
18375 && func.args.len() >= 2
18376 {
18377 let sep = &func.args[0];
18378 for (i, arg) in func.args.iter().skip(1).enumerate() {
18379 if i > 0 {
18380 self.write(" || ");
18381 self.generate_expression(sep)?;
18382 self.write(" || ");
18383 }
18384 self.generate_expression(arg)?;
18385 }
18386 return Ok(());
18387 }
18388
18389 if self.config.dialect == Some(DialectType::Redshift)
18392 && (func.name.eq_ignore_ascii_case("DATEDIFF")
18393 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
18394 && func.args.len() == 3
18395 {
18396 self.write_keyword("DATEDIFF");
18397 self.write("(");
18398 self.write_redshift_date_part(&func.args[0]);
18400 self.write(", ");
18401 self.generate_expression(&func.args[1])?;
18402 self.write(", ");
18403 self.generate_expression(&func.args[2])?;
18404 self.write(")");
18405 return Ok(());
18406 }
18407
18408 if self.config.dialect == Some(DialectType::Redshift)
18411 && (func.name.eq_ignore_ascii_case("DATEADD")
18412 || func.name.eq_ignore_ascii_case("DATE_ADD"))
18413 && func.args.len() == 3
18414 {
18415 self.write_keyword("DATEADD");
18416 self.write("(");
18417 self.write_redshift_date_part(&func.args[0]);
18419 self.write(", ");
18420 self.generate_expression(&func.args[1])?;
18421 self.write(", ");
18422 self.generate_expression(&func.args[2])?;
18423 self.write(")");
18424 return Ok(());
18425 }
18426
18427 if func.name.eq_ignore_ascii_case("UUID_STRING")
18429 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
18430 {
18431 if matches!(
18432 self.config.dialect,
18433 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
18434 ) {
18435 self.write_keyword("CAST");
18436 self.write("(");
18437 self.write_keyword("UUID");
18438 self.write("() ");
18439 self.write_keyword("AS");
18440 self.write(" ");
18441 self.write_keyword("STRING");
18442 self.write(")");
18443 return Ok(());
18444 }
18445
18446 if matches!(
18447 self.config.dialect,
18448 Some(DialectType::Presto | DialectType::Trino)
18449 ) {
18450 self.write_keyword("CAST");
18451 self.write("(");
18452 self.write_keyword("UUID");
18453 self.write("() ");
18454 self.write_keyword("AS");
18455 self.write(" ");
18456 self.write_keyword("VARCHAR");
18457 self.write(")");
18458 return Ok(());
18459 }
18460
18461 if self.config.dialect == Some(DialectType::DuckDB) && func.args.len() == 2 {
18462 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(");
18463 self.generate_expression(&func.args[0])?;
18464 self.write(", '-', '')) || ENCODE(");
18465 self.generate_expression(&func.args[1])?;
18466 self.write(")), 1, 32) AS h))");
18467 return Ok(());
18468 }
18469
18470 let func_name = match self.config.dialect {
18471 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
18472 Some(DialectType::BigQuery) => "GENERATE_UUID",
18473 _ => "UUID",
18474 };
18475 self.write_keyword(func_name);
18476 self.write("()");
18477 return Ok(());
18478 }
18479
18480 if matches!(self.config.dialect, Some(DialectType::Snowflake))
18484 && func.name.eq_ignore_ascii_case("GENERATOR")
18485 {
18486 let has_positional_args =
18487 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
18488 if has_positional_args {
18489 let param_names = ["ROWCOUNT", "TIMELIMIT"];
18490 self.write_keyword("GENERATOR");
18491 self.write("(");
18492 for (i, arg) in func.args.iter().enumerate() {
18493 if i > 0 {
18494 self.write(", ");
18495 }
18496 if i < param_names.len() {
18497 self.write_keyword(param_names[i]);
18498 self.write(" => ");
18499 self.generate_expression(arg)?;
18500 } else {
18501 self.generate_expression(arg)?;
18502 }
18503 }
18504 self.write(")");
18505 return Ok(());
18506 }
18507 }
18508
18509 if self.config.dialect == Some(DialectType::Redshift)
18512 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
18513 && func.args.len() == 2
18514 {
18515 self.write_keyword("DATE_TRUNC");
18516 self.write("(");
18517 self.write_redshift_date_part_quoted(&func.args[0]);
18519 self.write(", ");
18520 self.generate_expression(&func.args[1])?;
18521 self.write(")");
18522 return Ok(());
18523 }
18524
18525 if matches!(
18527 self.config.dialect,
18528 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18529 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
18530 || func.name.eq_ignore_ascii_case("DATEPART"))
18531 && func.args.len() == 2
18532 {
18533 if let Some(part) = self.extract_date_part_string(&func.args[0]) {
18534 let date_part = self.classify_tsql_date_part_name(&part);
18535 self.generate_tsql_date_part(date_part, &func.args[1])?;
18536 } else {
18537 self.write_keyword("DATEPART");
18538 self.write("(");
18539 self.generate_expression(&func.args[0])?;
18540 self.write(", ");
18541 self.generate_expression(&func.args[1])?;
18542 self.write(")");
18543 }
18544 return Ok(());
18545 }
18546
18547 if matches!(
18549 self.config.dialect,
18550 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18551 ) && (func.name.eq_ignore_ascii_case("DATETRUNC")
18552 || func.name.eq_ignore_ascii_case("DATE_TRUNC"))
18553 && func.args.len() == 2
18554 {
18555 if let Some(part) = self.extract_date_part_string(&func.args[0]) {
18556 let date_part = self.classify_tsql_date_trunc_name(&part);
18557 self.generate_tsql_date_trunc(date_part, &func.args[1])?;
18558 } else {
18559 self.write_keyword("DATETRUNC");
18560 self.write("(");
18561 self.generate_expression(&func.args[0])?;
18562 self.write(", ");
18563 self.generate_expression(&func.args[1])?;
18564 self.write(")");
18565 }
18566 return Ok(());
18567 }
18568
18569 if matches!(
18571 self.config.dialect,
18572 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
18573 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
18574 || func.name.eq_ignore_ascii_case("DATEPART"))
18575 && func.args.len() == 2
18576 {
18577 self.write_keyword("EXTRACT");
18578 self.write("(");
18579 match &func.args[0] {
18581 Expression::Literal(lit)
18582 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18583 {
18584 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18585 unreachable!()
18586 };
18587 self.write(&s.to_ascii_lowercase());
18588 }
18589 _ => self.generate_expression(&func.args[0])?,
18590 }
18591 self.write_space();
18592 self.write_keyword("FROM");
18593 self.write_space();
18594 self.generate_expression(&func.args[1])?;
18595 self.write(")");
18596 return Ok(());
18597 }
18598
18599 if self.config.dialect == Some(DialectType::PostgreSQL)
18601 && matches!(
18602 func.name.to_ascii_uppercase().as_str(),
18603 "DATE_ADD" | "DATE_SUB"
18604 )
18605 && func.args.len() == 2
18606 && matches!(func.args[1], Expression::Interval(_))
18607 {
18608 self.generate_expression(&func.args[0])?;
18609 self.write_space();
18610 if func.name.eq_ignore_ascii_case("DATE_SUB") {
18611 self.write("-");
18612 } else {
18613 self.write("+");
18614 }
18615 self.write_space();
18616 self.generate_expression(&func.args[1])?;
18617 return Ok(());
18618 }
18619
18620 if self.config.dialect == Some(DialectType::Dremio)
18623 && (func.name.eq_ignore_ascii_case("DATE_PART")
18624 || func.name.eq_ignore_ascii_case("DATEPART"))
18625 && func.args.len() == 2
18626 {
18627 self.write_keyword("EXTRACT");
18628 self.write("(");
18629 self.generate_expression(&func.args[0])?;
18630 self.write_space();
18631 self.write_keyword("FROM");
18632 self.write_space();
18633 self.generate_dremio_date_expression(&func.args[1])?;
18635 self.write(")");
18636 return Ok(());
18637 }
18638
18639 if self.config.dialect == Some(DialectType::Dremio)
18641 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
18642 && func.args.is_empty()
18643 {
18644 self.write_keyword("CURRENT_DATE_UTC");
18645 return Ok(());
18646 }
18647
18648 if self.config.dialect == Some(DialectType::Dremio)
18652 && func.name.eq_ignore_ascii_case("DATETYPE")
18653 && func.args.len() == 3
18654 {
18655 fn get_int_literal(expr: &Expression) -> Option<i64> {
18657 if let Expression::Literal(lit) = expr {
18658 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
18659 s.parse::<i64>().ok()
18660 } else {
18661 None
18662 }
18663 } else {
18664 None
18665 }
18666 }
18667
18668 if let (Some(year), Some(month), Some(day)) = (
18670 get_int_literal(&func.args[0]),
18671 get_int_literal(&func.args[1]),
18672 get_int_literal(&func.args[2]),
18673 ) {
18674 self.write_keyword("DATE");
18676 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
18677 return Ok(());
18678 }
18679
18680 self.write_keyword("CAST");
18682 self.write("(");
18683 self.write_keyword("CONCAT");
18684 self.write("(");
18685 self.generate_expression(&func.args[0])?;
18686 self.write(", '-', ");
18687 self.generate_expression(&func.args[1])?;
18688 self.write(", '-', ");
18689 self.generate_expression(&func.args[2])?;
18690 self.write(")");
18691 self.write_space();
18692 self.write_keyword("AS");
18693 self.write_space();
18694 self.write_keyword("DATE");
18695 self.write(")");
18696 return Ok(());
18697 }
18698
18699 let is_presto_like = matches!(
18702 self.config.dialect,
18703 Some(DialectType::Presto) | Some(DialectType::Trino)
18704 );
18705 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
18706 self.write_keyword("DATE_ADD");
18707 self.write("(");
18708 self.generate_expression(&func.args[0])?;
18710 self.write(", ");
18711 let interval = &func.args[1];
18713 let needs_cast = !self.returns_integer_type(interval);
18714 if needs_cast {
18715 self.write_keyword("CAST");
18716 self.write("(");
18717 }
18718 self.generate_expression(interval)?;
18719 if needs_cast {
18720 self.write_space();
18721 self.write_keyword("AS");
18722 self.write_space();
18723 self.write_keyword("BIGINT");
18724 self.write(")");
18725 }
18726 self.write(", ");
18727 self.generate_expression(&func.args[2])?;
18729 self.write(")");
18730 return Ok(());
18731 }
18732
18733 let use_brackets = func.use_bracket_syntax;
18735
18736 let has_ordinality = func.name.len() >= 16
18741 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
18742 let output_name = if has_ordinality {
18743 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
18744 self.normalize_func_name(base_name)
18745 } else {
18746 normalized_name.clone()
18747 };
18748
18749 let quote_source_clickhouse_function =
18752 matches!(self.config.dialect, Some(DialectType::ClickHouse))
18753 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
18754 && func.quoted;
18755
18756 if quote_source_clickhouse_function {
18757 self.generate_identifier(&Identifier {
18758 name: func.name.clone(),
18759 quoted: true,
18760 trailing_comments: Vec::new(),
18761 span: None,
18762 })?;
18763 } else if func.name.contains('.') && !has_ordinality {
18764 if func.quoted {
18767 self.write("`");
18768 self.write(&func.name);
18769 self.write("`");
18770 } else {
18771 self.write(&func.name);
18772 }
18773 } else {
18774 self.write(&output_name);
18775 }
18776
18777 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
18780 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
18781 || func.name.eq_ignore_ascii_case("SESSION_USER")
18782 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
18783 {
18784 matches!(
18785 self.config.dialect,
18786 Some(DialectType::Snowflake)
18787 | Some(DialectType::Spark)
18788 | Some(DialectType::Databricks)
18789 | Some(DialectType::Hive)
18790 )
18791 } else {
18792 false
18793 };
18794 !needs_parens
18795 };
18796 if force_parens {
18797 for comment in &func.trailing_comments {
18799 self.write_space();
18800 self.write_formatted_comment(comment);
18801 }
18802 return Ok(());
18803 }
18804
18805 if func.name.eq_ignore_ascii_case("CUBE")
18807 || func.name.eq_ignore_ascii_case("ROLLUP")
18808 || func.name.eq_ignore_ascii_case("GROUPING SETS")
18809 {
18810 self.write(" (");
18811 } else if use_brackets {
18812 self.write("[");
18813 } else {
18814 self.write("(");
18815 }
18816 if func.distinct {
18817 self.write_keyword("DISTINCT");
18818 self.write_space();
18819 }
18820
18821 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
18823 && (func.name.eq_ignore_ascii_case("TABLE")
18824 || func.name.eq_ignore_ascii_case("FLATTEN"));
18825 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
18827 || func.name.eq_ignore_ascii_case("CUBE")
18828 || func.name.eq_ignore_ascii_case("ROLLUP");
18829 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
18830 if is_grouping_func {
18831 true
18832 } else {
18833 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
18835 for arg in &func.args {
18836 let mut temp_gen = Generator::with_arc_config(self.config.clone());
18837 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
18839 expr_strings.push(temp_gen.output);
18840 }
18841 self.too_wide(&expr_strings)
18842 }
18843 } else {
18844 false
18845 };
18846
18847 if should_split {
18848 self.write_newline();
18850 self.indent_level += 1;
18851 for (i, arg) in func.args.iter().enumerate() {
18852 self.write_indent();
18853 self.generate_expression(arg)?;
18854 if i + 1 < func.args.len() {
18855 self.write(",");
18856 }
18857 self.write_newline();
18858 }
18859 self.indent_level -= 1;
18860 self.write_indent();
18861 } else {
18862 for (i, arg) in func.args.iter().enumerate() {
18864 if i > 0 {
18865 self.write(", ");
18866 }
18867 self.generate_expression(arg)?;
18868 }
18869 }
18870
18871 if use_brackets {
18872 self.write("]");
18873 } else {
18874 self.write(")");
18875 }
18876 if has_ordinality {
18878 self.write_space();
18879 self.write_keyword("WITH ORDINALITY");
18880 }
18881 for comment in &func.trailing_comments {
18883 self.write_space();
18884 self.write_formatted_comment(comment);
18885 }
18886 Ok(())
18887 }
18888
18889 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
18890 self.generate_expression(&fe.this)?;
18891 self.write_keyword(" EMITS ");
18892 self.generate_expression(&fe.emits)?;
18893 Ok(())
18894 }
18895
18896 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
18897 let mut normalized_name = self.normalize_func_name(&func.name);
18899
18900 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
18902 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
18903 match self.config.dialect {
18904 Some(DialectType::ClickHouse) => {
18905 normalized_name = if is_max {
18906 Cow::Borrowed("argMax")
18907 } else {
18908 Cow::Borrowed("argMin")
18909 };
18910 }
18911 Some(DialectType::DuckDB) => {
18912 normalized_name = if is_max {
18913 Cow::Borrowed("ARG_MAX")
18914 } else {
18915 Cow::Borrowed("ARG_MIN")
18916 };
18917 }
18918 _ => {}
18919 }
18920 }
18921 self.write(normalized_name.as_ref());
18922 self.write("(");
18923 if func.distinct {
18924 self.write_keyword("DISTINCT");
18925 self.write_space();
18926 }
18927
18928 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
18932 let needs_multi_arg_transform =
18933 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
18934
18935 if needs_multi_arg_transform {
18936 self.write_keyword("CASE");
18938 for arg in &func.args {
18939 self.write_space();
18940 self.write_keyword("WHEN");
18941 self.write_space();
18942 self.generate_expression(arg)?;
18943 self.write_space();
18944 self.write_keyword("IS NULL THEN NULL");
18945 }
18946 self.write_space();
18947 self.write_keyword("ELSE");
18948 self.write(" (");
18949 for (i, arg) in func.args.iter().enumerate() {
18950 if i > 0 {
18951 self.write(", ");
18952 }
18953 self.generate_expression(arg)?;
18954 }
18955 self.write(")");
18956 self.write_space();
18957 self.write_keyword("END");
18958 } else {
18959 for (i, arg) in func.args.iter().enumerate() {
18960 if i > 0 {
18961 self.write(", ");
18962 }
18963 self.generate_expression(arg)?;
18964 }
18965 }
18966
18967 let clickhouse_ignore_nulls_outside =
18969 matches!(self.config.dialect, Some(DialectType::ClickHouse));
18970 if self.config.ignore_nulls_in_func
18971 && !matches!(
18972 self.config.dialect,
18973 Some(DialectType::DuckDB) | Some(DialectType::ClickHouse)
18974 )
18975 {
18976 if let Some(ignore) = func.ignore_nulls {
18977 self.write_space();
18978 if ignore {
18979 self.write_keyword("IGNORE NULLS");
18980 } else {
18981 self.write_keyword("RESPECT NULLS");
18982 }
18983 }
18984 }
18985
18986 if !func.order_by.is_empty() {
18988 self.write_space();
18989 self.write_keyword("ORDER BY");
18990 self.write_space();
18991 for (i, ord) in func.order_by.iter().enumerate() {
18992 if i > 0 {
18993 self.write(", ");
18994 }
18995 self.generate_ordered(ord)?;
18996 }
18997 }
18998
18999 if let Some(limit) = &func.limit {
19001 self.write_space();
19002 self.write_keyword("LIMIT");
19003 self.write_space();
19004 if let Expression::Tuple(t) = limit.as_ref() {
19006 if t.expressions.len() == 2 {
19007 self.generate_expression(&t.expressions[0])?;
19008 self.write(", ");
19009 self.generate_expression(&t.expressions[1])?;
19010 } else {
19011 self.generate_expression(limit)?;
19012 }
19013 } else {
19014 self.generate_expression(limit)?;
19015 }
19016 }
19017
19018 self.write(")");
19019
19020 if (!self.config.ignore_nulls_in_func || clickhouse_ignore_nulls_outside)
19022 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19023 {
19024 if let Some(ignore) = func.ignore_nulls {
19025 self.write_space();
19026 if ignore {
19027 self.write_keyword("IGNORE NULLS");
19028 } else {
19029 self.write_keyword("RESPECT NULLS");
19030 }
19031 }
19032 }
19033
19034 if let Some(filter) = &func.filter {
19035 self.write_space();
19036 self.write_keyword("FILTER");
19037 self.write("(");
19038 self.write_keyword("WHERE");
19039 self.write_space();
19040 self.generate_expression(filter)?;
19041 self.write(")");
19042 }
19043
19044 Ok(())
19045 }
19046
19047 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
19048 self.generate_expression(&wf.this)?;
19049
19050 if let Some(keep) = &wf.keep {
19052 self.write_space();
19053 self.write_keyword("KEEP");
19054 self.write(" (");
19055 self.write_keyword("DENSE_RANK");
19056 self.write_space();
19057 if keep.first {
19058 self.write_keyword("FIRST");
19059 } else {
19060 self.write_keyword("LAST");
19061 }
19062 self.write_space();
19063 self.write_keyword("ORDER BY");
19064 self.write_space();
19065 for (i, ord) in keep.order_by.iter().enumerate() {
19066 if i > 0 {
19067 self.write(", ");
19068 }
19069 self.generate_ordered(ord)?;
19070 }
19071 self.write(")");
19072 }
19073
19074 let has_over = !wf.over.partition_by.is_empty()
19076 || !wf.over.order_by.is_empty()
19077 || wf.over.frame.is_some()
19078 || wf.over.window_name.is_some();
19079
19080 if has_over {
19082 self.write_space();
19083 self.write_keyword("OVER");
19084
19085 let has_specs = !wf.over.partition_by.is_empty()
19087 || !wf.over.order_by.is_empty()
19088 || wf.over.frame.is_some();
19089
19090 if wf.over.window_name.is_some() && !has_specs {
19091 self.write_space();
19093 self.write(&wf.over.window_name.as_ref().unwrap().name);
19094 } else {
19095 self.write(" (");
19097 self.generate_over(&wf.over)?;
19098 self.write(")");
19099 }
19100 } else if wf.keep.is_none() {
19101 self.write_space();
19103 self.write_keyword("OVER");
19104 self.write(" ()");
19105 }
19106
19107 Ok(())
19108 }
19109
19110 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
19112 self.generate_expression(&wg.this)?;
19113 self.write_space();
19114 self.write_keyword("WITHIN GROUP");
19115 self.write(" (");
19116 self.write_keyword("ORDER BY");
19117 self.write_space();
19118 for (i, ord) in wg.order_by.iter().enumerate() {
19119 if i > 0 {
19120 self.write(", ");
19121 }
19122 self.generate_ordered(ord)?;
19123 }
19124 self.write(")");
19125 Ok(())
19126 }
19127
19128 fn generate_over(&mut self, over: &Over) -> Result<()> {
19130 let mut has_content = false;
19131
19132 if let Some(name) = &over.window_name {
19134 self.write(&name.name);
19135 has_content = true;
19136 }
19137
19138 if !over.partition_by.is_empty() {
19140 if has_content {
19141 self.write_space();
19142 }
19143 self.write_keyword("PARTITION BY");
19144 self.write_space();
19145 for (i, expr) in over.partition_by.iter().enumerate() {
19146 if i > 0 {
19147 self.write(", ");
19148 }
19149 self.generate_expression(expr)?;
19150 }
19151 has_content = true;
19152 }
19153
19154 if !over.order_by.is_empty() {
19156 if has_content {
19157 self.write_space();
19158 }
19159 self.write_keyword("ORDER BY");
19160 self.write_space();
19161 for (i, ordered) in over.order_by.iter().enumerate() {
19162 if i > 0 {
19163 self.write(", ");
19164 }
19165 self.generate_ordered(ordered)?;
19166 }
19167 has_content = true;
19168 }
19169
19170 if let Some(frame) = &over.frame {
19172 if has_content {
19173 self.write_space();
19174 }
19175 self.generate_window_frame(frame)?;
19176 }
19177
19178 Ok(())
19179 }
19180
19181 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
19182 let lowercase_frame = self.config.lowercase_window_frame_keywords;
19184
19185 if !lowercase_frame {
19187 if let Some(kind_text) = &frame.kind_text {
19188 self.write(kind_text);
19189 } else {
19190 match frame.kind {
19191 WindowFrameKind::Rows => self.write_keyword("ROWS"),
19192 WindowFrameKind::Range => self.write_keyword("RANGE"),
19193 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
19194 }
19195 }
19196 } else {
19197 match frame.kind {
19198 WindowFrameKind::Rows => self.write("rows"),
19199 WindowFrameKind::Range => self.write("range"),
19200 WindowFrameKind::Groups => self.write("groups"),
19201 }
19202 }
19203
19204 self.write_space();
19207 let should_normalize = self.config.normalize_window_frame_between
19208 && frame.end.is_none()
19209 && matches!(
19210 frame.start,
19211 WindowFrameBound::Preceding(_)
19212 | WindowFrameBound::Following(_)
19213 | WindowFrameBound::UnboundedPreceding
19214 | WindowFrameBound::UnboundedFollowing
19215 );
19216
19217 if let Some(end) = &frame.end {
19218 self.write_keyword("BETWEEN");
19220 self.write_space();
19221 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
19222 self.write_space();
19223 self.write_keyword("AND");
19224 self.write_space();
19225 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
19226 } else if should_normalize {
19227 self.write_keyword("BETWEEN");
19229 self.write_space();
19230 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
19231 self.write_space();
19232 self.write_keyword("AND");
19233 self.write_space();
19234 self.write_keyword("CURRENT ROW");
19235 } else {
19236 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
19238 }
19239
19240 if let Some(exclude) = &frame.exclude {
19242 self.write_space();
19243 self.write_keyword("EXCLUDE");
19244 self.write_space();
19245 match exclude {
19246 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
19247 WindowFrameExclude::Group => self.write_keyword("GROUP"),
19248 WindowFrameExclude::Ties => self.write_keyword("TIES"),
19249 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
19250 }
19251 }
19252
19253 Ok(())
19254 }
19255
19256 fn generate_window_frame_bound(
19257 &mut self,
19258 bound: &WindowFrameBound,
19259 side_text: Option<&str>,
19260 ) -> Result<()> {
19261 let lowercase_frame = self.config.lowercase_window_frame_keywords;
19263
19264 match bound {
19265 WindowFrameBound::CurrentRow => {
19266 self.write_keyword("CURRENT ROW");
19267 }
19268 WindowFrameBound::UnboundedPreceding => {
19269 self.write_keyword("UNBOUNDED");
19270 self.write_space();
19271 if lowercase_frame {
19272 self.write("preceding");
19273 } else if let Some(text) = side_text {
19274 self.write(text);
19275 } else {
19276 self.write_keyword("PRECEDING");
19277 }
19278 }
19279 WindowFrameBound::UnboundedFollowing => {
19280 self.write_keyword("UNBOUNDED");
19281 self.write_space();
19282 if lowercase_frame {
19283 self.write("following");
19284 } else if let Some(text) = side_text {
19285 self.write(text);
19286 } else {
19287 self.write_keyword("FOLLOWING");
19288 }
19289 }
19290 WindowFrameBound::Preceding(expr) => {
19291 self.generate_expression(expr)?;
19292 self.write_space();
19293 if lowercase_frame {
19294 self.write("preceding");
19295 } else if let Some(text) = side_text {
19296 self.write(text);
19297 } else {
19298 self.write_keyword("PRECEDING");
19299 }
19300 }
19301 WindowFrameBound::Following(expr) => {
19302 self.generate_expression(expr)?;
19303 self.write_space();
19304 if lowercase_frame {
19305 self.write("following");
19306 } else if let Some(text) = side_text {
19307 self.write(text);
19308 } else {
19309 self.write_keyword("FOLLOWING");
19310 }
19311 }
19312 WindowFrameBound::BarePreceding => {
19313 if lowercase_frame {
19314 self.write("preceding");
19315 } else if let Some(text) = side_text {
19316 self.write(text);
19317 } else {
19318 self.write_keyword("PRECEDING");
19319 }
19320 }
19321 WindowFrameBound::BareFollowing => {
19322 if lowercase_frame {
19323 self.write("following");
19324 } else if let Some(text) = side_text {
19325 self.write(text);
19326 } else {
19327 self.write_keyword("FOLLOWING");
19328 }
19329 }
19330 WindowFrameBound::Value(expr) => {
19331 self.generate_expression(expr)?;
19333 }
19334 }
19335 Ok(())
19336 }
19337
19338 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
19339 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
19342 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
19343 && !matches!(&interval.this, Some(Expression::Literal(_)));
19344
19345 if self.config.single_string_interval {
19348 if let (
19349 Some(Expression::Literal(lit)),
19350 Some(IntervalUnitSpec::Simple {
19351 ref unit,
19352 ref use_plural,
19353 }),
19354 ) = (&interval.this, &interval.unit)
19355 {
19356 if let Literal::String(ref val) = lit.as_ref() {
19357 self.write_keyword("INTERVAL");
19358 self.write_space();
19359 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
19360 let unit_str = self.interval_unit_str(unit, effective_plural);
19361 self.write("'");
19362 self.write(val);
19363 self.write(" ");
19364 self.write(&unit_str);
19365 self.write("'");
19366 return Ok(());
19367 }
19368 }
19369 }
19370
19371 if !skip_interval_keyword {
19372 self.write_keyword("INTERVAL");
19373 }
19374
19375 if let Some(ref value) = interval.this {
19377 if !skip_interval_keyword {
19378 self.write_space();
19379 }
19380 let needs_parens = interval.unit.is_some()
19384 && matches!(
19385 value,
19386 Expression::Add(_)
19387 | Expression::Sub(_)
19388 | Expression::Mul(_)
19389 | Expression::Div(_)
19390 | Expression::Mod(_)
19391 | Expression::BitwiseAnd(_)
19392 | Expression::BitwiseOr(_)
19393 | Expression::BitwiseXor(_)
19394 );
19395 if needs_parens {
19396 self.write("(");
19397 }
19398 self.generate_expression(value)?;
19399 if needs_parens {
19400 self.write(")");
19401 }
19402 }
19403
19404 if let Some(ref unit_spec) = interval.unit {
19406 self.write_space();
19407 self.write_interval_unit_spec(unit_spec)?;
19408 }
19409
19410 Ok(())
19411 }
19412
19413 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
19415 match (unit, use_plural) {
19416 (IntervalUnit::Year, false) => "YEAR",
19417 (IntervalUnit::Year, true) => "YEARS",
19418 (IntervalUnit::Quarter, false) => "QUARTER",
19419 (IntervalUnit::Quarter, true) => "QUARTERS",
19420 (IntervalUnit::Month, false) => "MONTH",
19421 (IntervalUnit::Month, true) => "MONTHS",
19422 (IntervalUnit::Week, false) => "WEEK",
19423 (IntervalUnit::Week, true) => "WEEKS",
19424 (IntervalUnit::Day, false) => "DAY",
19425 (IntervalUnit::Day, true) => "DAYS",
19426 (IntervalUnit::Hour, false) => "HOUR",
19427 (IntervalUnit::Hour, true) => "HOURS",
19428 (IntervalUnit::Minute, false) => "MINUTE",
19429 (IntervalUnit::Minute, true) => "MINUTES",
19430 (IntervalUnit::Second, false) => "SECOND",
19431 (IntervalUnit::Second, true) => "SECONDS",
19432 (IntervalUnit::Millisecond, false) => "MILLISECOND",
19433 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
19434 (IntervalUnit::Microsecond, false) => "MICROSECOND",
19435 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
19436 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
19437 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
19438 }
19439 }
19440
19441 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
19442 match unit_spec {
19443 IntervalUnitSpec::Simple { unit, use_plural } => {
19444 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
19446 self.write_simple_interval_unit(unit, effective_plural);
19447 }
19448 IntervalUnitSpec::Span(span) => {
19449 self.write_simple_interval_unit(&span.this, false);
19450 self.write_space();
19451 self.write_keyword("TO");
19452 self.write_space();
19453 self.write_simple_interval_unit(&span.expression, false);
19454 }
19455 IntervalUnitSpec::ExprSpan(span) => {
19456 self.generate_expression(&span.this)?;
19458 self.write_space();
19459 self.write_keyword("TO");
19460 self.write_space();
19461 self.generate_expression(&span.expression)?;
19462 }
19463 IntervalUnitSpec::Expr(expr) => {
19464 self.generate_expression(expr)?;
19465 }
19466 }
19467 Ok(())
19468 }
19469
19470 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
19471 match (unit, use_plural) {
19473 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
19474 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
19475 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
19476 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
19477 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
19478 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
19479 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
19480 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
19481 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
19482 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
19483 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
19484 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
19485 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
19486 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
19487 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
19488 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
19489 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
19490 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
19491 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
19492 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
19493 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
19494 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
19495 }
19496 }
19497
19498 fn write_redshift_date_part(&mut self, expr: &Expression) {
19501 let part_str = self.extract_date_part_string(expr);
19502 if let Some(part) = part_str {
19503 let normalized = self.normalize_date_part(&part);
19504 self.write_keyword(&normalized);
19505 } else {
19506 let _ = self.generate_expression(expr);
19508 }
19509 }
19510
19511 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
19514 let part_str = self.extract_date_part_string(expr);
19515 if let Some(part) = part_str {
19516 let normalized = self.normalize_date_part(&part);
19517 self.write("'");
19518 self.write(&normalized);
19519 self.write("'");
19520 } else {
19521 let _ = self.generate_expression(expr);
19523 }
19524 }
19525
19526 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
19528 match expr {
19529 Expression::Literal(lit)
19530 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
19531 {
19532 let crate::expressions::Literal::String(s) = lit.as_ref() else {
19533 unreachable!()
19534 };
19535 Some(s.clone())
19536 }
19537 Expression::Identifier(id) => Some(id.name.clone()),
19538 Expression::Var(v) => Some(v.this.clone()),
19539 Expression::Column(col) if col.table.is_none() => {
19540 Some(col.name.name.clone())
19542 }
19543 Expression::Cast(cast)
19544 if cast.format.is_none()
19545 && cast.default.is_none()
19546 && Self::is_string_data_type(&cast.to)
19547 && matches!(
19548 &cast.this,
19549 Expression::Literal(lit)
19550 if matches!(lit.as_ref(), crate::expressions::Literal::String(_))
19551 ) =>
19552 {
19553 self.extract_date_part_string(&cast.this)
19554 }
19555 _ => None,
19556 }
19557 }
19558
19559 fn classify_tsql_datetime_field(&self, field: &DateTimeField) -> TsqlDatePart {
19560 match field {
19561 DateTimeField::Year => TsqlDatePart::Native("YEAR".to_string()),
19562 DateTimeField::Month => TsqlDatePart::Native("MONTH".to_string()),
19563 DateTimeField::Day => TsqlDatePart::Native("DAY".to_string()),
19564 DateTimeField::Hour => TsqlDatePart::Native("HOUR".to_string()),
19565 DateTimeField::Minute => TsqlDatePart::Native("MINUTE".to_string()),
19566 DateTimeField::Second => TsqlDatePart::Native("SECOND".to_string()),
19567 DateTimeField::Millisecond => TsqlDatePart::Native("MILLISECOND".to_string()),
19568 DateTimeField::Microsecond => TsqlDatePart::Native("MICROSECOND".to_string()),
19569 DateTimeField::DayOfWeek => TsqlDatePart::Native("WEEKDAY".to_string()),
19570 DateTimeField::DayOfYear => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19571 DateTimeField::Week => TsqlDatePart::Native("WEEK".to_string()),
19572 DateTimeField::WeekWithModifier(modifier) => {
19573 TsqlDatePart::Unsupported(format!("WEEK({modifier})"))
19574 }
19575 DateTimeField::Quarter => TsqlDatePart::Native("QUARTER".to_string()),
19576 DateTimeField::Epoch => TsqlDatePart::Epoch,
19577 DateTimeField::TimezoneMinute => TsqlDatePart::Native("TZOFFSET".to_string()),
19578 DateTimeField::Timezone => TsqlDatePart::Unsupported("TIMEZONE".to_string()),
19579 DateTimeField::TimezoneHour => TsqlDatePart::Unsupported("TIMEZONE_HOUR".to_string()),
19580 DateTimeField::Date => TsqlDatePart::Unsupported("DATE".to_string()),
19581 DateTimeField::Time => TsqlDatePart::Unsupported("TIME".to_string()),
19582 DateTimeField::Custom(name) => self.classify_tsql_date_part_name(name),
19583 }
19584 }
19585
19586 fn classify_tsql_date_part_name(&self, part: &str) -> TsqlDatePart {
19587 let trimmed = part.trim();
19588 let upper = trimmed.to_ascii_uppercase();
19589 match upper.as_str() {
19590 "YEAR" => TsqlDatePart::Native(trimmed.to_string()),
19591 "YY" | "YYY" | "YYYY" | "YR" | "YEARS" | "YRS" => {
19592 TsqlDatePart::Native("YEAR".to_string())
19593 }
19594 "QUARTER" => TsqlDatePart::Native(trimmed.to_string()),
19595 "Q" | "QQ" | "QTR" | "QTRS" | "QUARTERS" => TsqlDatePart::Native("QUARTER".to_string()),
19596 "MONTH" => TsqlDatePart::Native(trimmed.to_string()),
19597 "MM" | "M" | "MON" | "MONS" | "MONTHS" => TsqlDatePart::Native("MONTH".to_string()),
19598 "DAYOFYEAR" => TsqlDatePart::Native(trimmed.to_string()),
19599 "DOY" | "DY" | "Y" => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19600 "DAY" => TsqlDatePart::Native(trimmed.to_string()),
19601 "D" | "DD" | "DAYS" | "DAYOFMONTH" => TsqlDatePart::Native("DAY".to_string()),
19602 "WEEK" | "W" | "WK" | "WW" | "WEEKOFYEAR" | "WOY" | "WY" | "WEEKS" => {
19603 if upper == "WEEK" {
19604 TsqlDatePart::Native(trimmed.to_string())
19605 } else {
19606 TsqlDatePart::Native("WEEK".to_string())
19607 }
19608 }
19609 "WEEKDAY" => TsqlDatePart::Native(trimmed.to_string()),
19610 "DAYOFWEEK" | "DOW" | "DW" => TsqlDatePart::Native("WEEKDAY".to_string()),
19611 "ISODOW" | "ISO_DOW" | "DOW_ISO" | "DW_ISO" | "ISO_DAYOFWEEK" | "ISO_WEEKDAY"
19612 | "DAYOFWEEKISO" | "DAYOFWEEK_ISO" | "WEEKDAY_ISO" => TsqlDatePart::IsoDayOfWeek,
19613 "HOUR" => TsqlDatePart::Native(trimmed.to_string()),
19614 "H" | "HH" | "HR" | "HOURS" | "HRS" => TsqlDatePart::Native("HOUR".to_string()),
19615 "MINUTE" => TsqlDatePart::Native(trimmed.to_string()),
19616 "MI" | "MIN" | "MINUTES" | "MINS" | "N" => TsqlDatePart::Native("MINUTE".to_string()),
19617 "SECOND" => TsqlDatePart::Native(trimmed.to_string()),
19618 "S" | "SEC" | "SECONDS" | "SECS" | "SS" => TsqlDatePart::Native("SECOND".to_string()),
19619 "MILLISECOND" | "MS" | "MSEC" | "MSECS" | "MSECOND" | "MSECONDS" | "MILLISEC"
19620 | "MILLISECS" | "MILLISECON" | "MILLISECONDS" => {
19621 if upper == "MILLISECOND" {
19622 TsqlDatePart::Native(trimmed.to_string())
19623 } else {
19624 TsqlDatePart::Native("MILLISECOND".to_string())
19625 }
19626 }
19627 "MICROSECOND" | "US" | "USEC" | "USECS" | "MICROSEC" | "MICROSECS" | "USECOND"
19628 | "USECONDS" | "MICROSECONDS" | "MCS" => {
19629 if upper == "MICROSECOND" {
19630 TsqlDatePart::Native(trimmed.to_string())
19631 } else {
19632 TsqlDatePart::Native("MICROSECOND".to_string())
19633 }
19634 }
19635 "NANOSECOND" | "NS" | "NSEC" | "NANOSEC" | "NSECOND" | "NSECONDS" | "NANOSECS" => {
19636 if upper == "NANOSECOND" {
19637 TsqlDatePart::Native(trimmed.to_string())
19638 } else {
19639 TsqlDatePart::Native("NANOSECOND".to_string())
19640 }
19641 }
19642 "TZOFFSET" => TsqlDatePart::Native(trimmed.to_string()),
19643 "TZ" | "TZM" | "TIMEZONE_MINUTE" => TsqlDatePart::Native("TZOFFSET".to_string()),
19644 "ISO_WEEK" | "ISOWEEK" | "ISOWK" | "ISOWW" | "WEEKISO" | "WEEKOFYEARISO"
19645 | "WEEKOFYEAR_ISO" | "WEEK_ISO" => {
19646 if upper == "ISO_WEEK" {
19647 TsqlDatePart::Native(trimmed.to_string())
19648 } else {
19649 TsqlDatePart::Native("ISO_WEEK".to_string())
19650 }
19651 }
19652 "EPOCH" | "EPOCH_SECOND" | "EPOCH_SECONDS" => TsqlDatePart::Epoch,
19653 "DECADE" | "DECADES" | "DEC" | "DECS" | "CENTURY" | "CENTURIES" | "CENT" | "CENTS"
19654 | "MILLENNIUM" | "MILLENIA" | "MIL" | "MILS" | "TIMEZONE" | "TIMEZONE_HOUR" | "TZH"
19655 | "DATE" | "TIME" => TsqlDatePart::Unsupported(upper),
19656 _ => TsqlDatePart::Unsupported(upper),
19657 }
19658 }
19659
19660 fn classify_tsql_date_trunc_field(&self, field: &DateTimeField) -> TsqlDatePart {
19661 match field {
19662 DateTimeField::Year => TsqlDatePart::Native("YEAR".to_string()),
19663 DateTimeField::Month => TsqlDatePart::Native("MONTH".to_string()),
19664 DateTimeField::Day => TsqlDatePart::Native("DAY".to_string()),
19665 DateTimeField::Hour => TsqlDatePart::Native("HOUR".to_string()),
19666 DateTimeField::Minute => TsqlDatePart::Native("MINUTE".to_string()),
19667 DateTimeField::Second => TsqlDatePart::Native("SECOND".to_string()),
19668 DateTimeField::Millisecond => TsqlDatePart::Native("MILLISECOND".to_string()),
19669 DateTimeField::Microsecond => TsqlDatePart::Native("MICROSECOND".to_string()),
19670 DateTimeField::DayOfYear => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19671 DateTimeField::Week => TsqlDatePart::Native("WEEK".to_string()),
19672 DateTimeField::WeekWithModifier(modifier) => {
19673 match modifier.to_ascii_uppercase().as_str() {
19674 "MONDAY" | "ISO" | "ISO_WEEK" => TsqlDatePart::Native("ISO_WEEK".to_string()),
19675 "SUNDAY" => TsqlDatePart::Native("WEEK".to_string()),
19676 _ => TsqlDatePart::Unsupported(format!("WEEK({modifier})")),
19677 }
19678 }
19679 DateTimeField::Quarter => TsqlDatePart::Native("QUARTER".to_string()),
19680 DateTimeField::DayOfWeek => TsqlDatePart::Unsupported("WEEKDAY".to_string()),
19681 DateTimeField::Epoch => TsqlDatePart::Unsupported("EPOCH".to_string()),
19682 DateTimeField::Timezone => TsqlDatePart::Unsupported("TIMEZONE".to_string()),
19683 DateTimeField::TimezoneHour => TsqlDatePart::Unsupported("TIMEZONE_HOUR".to_string()),
19684 DateTimeField::TimezoneMinute => {
19685 TsqlDatePart::Unsupported("TIMEZONE_MINUTE".to_string())
19686 }
19687 DateTimeField::Date => TsqlDatePart::Unsupported("DATE".to_string()),
19688 DateTimeField::Time => TsqlDatePart::Unsupported("TIME".to_string()),
19689 DateTimeField::Custom(name) => self.classify_tsql_date_trunc_name(name),
19690 }
19691 }
19692
19693 fn classify_tsql_date_trunc_name(&self, part: &str) -> TsqlDatePart {
19694 let upper = part.trim().to_ascii_uppercase();
19695 match upper.as_str() {
19696 "YEAR" | "YY" | "YYY" | "YYYY" | "YR" | "YEARS" | "YRS" => {
19697 TsqlDatePart::Native("YEAR".to_string())
19698 }
19699 "QUARTER" | "Q" | "QQ" | "QTR" | "QTRS" | "QUARTERS" => {
19700 TsqlDatePart::Native("QUARTER".to_string())
19701 }
19702 "MONTH" | "MM" | "M" | "MON" | "MONS" | "MONTHS" => {
19703 TsqlDatePart::Native("MONTH".to_string())
19704 }
19705 "DAYOFYEAR" | "DOY" | "DY" | "Y" => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19706 "DAY" | "D" | "DD" | "DAYS" | "DAYOFMONTH" => TsqlDatePart::Native("DAY".to_string()),
19707 "WEEK" | "W" | "WK" | "WW" | "WEEKS" | "WEEKOFYEAR" | "WOY" | "WY" => {
19708 TsqlDatePart::Native("WEEK".to_string())
19709 }
19710 "ISO_WEEK" | "ISOWEEK" | "ISOWK" | "ISOWW" | "WEEKISO" | "WEEKOFYEARISO"
19711 | "WEEKOFYEAR_ISO" | "WEEK_ISO" => TsqlDatePart::Native("ISO_WEEK".to_string()),
19712 "HOUR" | "H" | "HH" | "HR" | "HOURS" | "HRS" => {
19713 TsqlDatePart::Native("HOUR".to_string())
19714 }
19715 "MINUTE" | "MI" | "MIN" | "MINUTES" | "MINS" | "N" => {
19716 TsqlDatePart::Native("MINUTE".to_string())
19717 }
19718 "SECOND" | "S" | "SEC" | "SECONDS" | "SECS" | "SS" => {
19719 TsqlDatePart::Native("SECOND".to_string())
19720 }
19721 "MILLISECOND" | "MS" | "MSEC" | "MSECS" | "MSECOND" | "MSECONDS" | "MILLISEC"
19722 | "MILLISECS" | "MILLISECON" | "MILLISECONDS" => {
19723 TsqlDatePart::Native("MILLISECOND".to_string())
19724 }
19725 "MICROSECOND" | "US" | "USEC" | "USECS" | "MICROSEC" | "MICROSECS" | "USECOND"
19726 | "USECONDS" | "MICROSECONDS" | "MCS" => {
19727 TsqlDatePart::Native("MICROSECOND".to_string())
19728 }
19729 "WEEKDAY" | "DAYOFWEEK" | "DOW" | "DW" | "ISODOW" | "ISO_DOW" | "DOW_ISO"
19730 | "DW_ISO" | "ISO_DAYOFWEEK" | "ISO_WEEKDAY" | "DAYOFWEEKISO" | "DAYOFWEEK_ISO"
19731 | "WEEKDAY_ISO" | "NANOSECOND" | "NS" | "NSEC" | "NANOSEC" | "NSECOND" | "NSECONDS"
19732 | "NANOSECS" | "TZOFFSET" | "TZ" | "TZM" | "TIMEZONE" | "TIMEZONE_HOUR"
19733 | "TIMEZONE_MINUTE" | "TZH" | "EPOCH" | "EPOCH_SECOND" | "EPOCH_SECONDS" | "DECADE"
19734 | "DECADES" | "DEC" | "DECS" | "CENTURY" | "CENTURIES" | "CENT" | "CENTS"
19735 | "MILLENNIUM" | "MILLENIA" | "MIL" | "MILS" | "DATE" | "TIME" => {
19736 TsqlDatePart::Unsupported(upper)
19737 }
19738 _ => TsqlDatePart::Unsupported(upper),
19739 }
19740 }
19741
19742 fn generate_tsql_date_part(&mut self, part: TsqlDatePart, expr: &Expression) -> Result<()> {
19743 match part {
19744 TsqlDatePart::Native(name) => self.generate_tsql_native_datepart(&name, expr),
19745 TsqlDatePart::Epoch => self.generate_tsql_epoch_seconds(expr),
19746 TsqlDatePart::IsoDayOfWeek => self.generate_tsql_iso_day_of_week(expr),
19747 TsqlDatePart::Unsupported(name) => {
19748 self.unsupported(format!("DATEPART {name} is not supported by T-SQL/Fabric"))?;
19749 self.write_keyword("DATEPART");
19750 self.write("(");
19751 self.write_keyword(&name);
19752 self.write(", ");
19753 self.generate_expression(expr)?;
19754 self.write(")");
19755 Ok(())
19756 }
19757 }
19758 }
19759
19760 fn generate_tsql_native_datepart(&mut self, name: &str, expr: &Expression) -> Result<()> {
19761 self.write_keyword("DATEPART");
19762 self.write("(");
19763 self.write_keyword(name);
19764 self.write(", ");
19765 self.generate_expression(expr)?;
19766 self.write(")");
19767 Ok(())
19768 }
19769
19770 fn generate_tsql_epoch_seconds(&mut self, expr: &Expression) -> Result<()> {
19771 self.write_keyword("DATEDIFF");
19772 self.write("(SECOND, ");
19773 self.write_keyword("CAST");
19774 self.write("('1970-01-01' AS ");
19775 self.write_keyword("DATETIME2");
19776 self.write("), ");
19777 self.generate_expression(expr)?;
19778 self.write(")");
19779 Ok(())
19780 }
19781
19782 fn generate_tsql_iso_day_of_week(&mut self, expr: &Expression) -> Result<()> {
19783 self.write("(((DATEPART(WEEKDAY, ");
19784 self.generate_expression(expr)?;
19785 self.write(") + @@DATEFIRST - 2) % 7) + 1)");
19786 Ok(())
19787 }
19788
19789 fn generate_tsql_date_trunc(&mut self, part: TsqlDatePart, expr: &Expression) -> Result<()> {
19790 match part {
19791 TsqlDatePart::Native(name) => {
19792 self.write_keyword("DATETRUNC");
19793 self.write("(");
19794 self.write_keyword(&name);
19795 self.write(", ");
19796 self.generate_expression(expr)?;
19797 self.write(")");
19798 Ok(())
19799 }
19800 TsqlDatePart::Epoch => {
19801 self.generate_tsql_unsupported_date_trunc("EPOCH".to_string(), expr)
19802 }
19803 TsqlDatePart::IsoDayOfWeek => {
19804 self.generate_tsql_unsupported_date_trunc("ISODOW".to_string(), expr)
19805 }
19806 TsqlDatePart::Unsupported(name) => {
19807 self.generate_tsql_unsupported_date_trunc(name, expr)
19808 }
19809 }
19810 }
19811
19812 fn generate_tsql_unsupported_date_trunc(
19813 &mut self,
19814 name: String,
19815 expr: &Expression,
19816 ) -> Result<()> {
19817 self.unsupported(format!("DATETRUNC {name} is not supported by T-SQL/Fabric"))?;
19818 self.write_keyword("DATETRUNC");
19819 self.write("(");
19820 self.write_keyword(&name);
19821 self.write(", ");
19822 self.generate_expression(expr)?;
19823 self.write(")");
19824 Ok(())
19825 }
19826
19827 fn normalize_date_part(&self, part: &str) -> String {
19830 let mut buf = [0u8; 64];
19831 let lower: &str = if part.len() <= 64 {
19832 for (i, b) in part.bytes().enumerate() {
19833 buf[i] = b.to_ascii_lowercase();
19834 }
19835 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
19836 } else {
19837 return part.to_ascii_uppercase();
19838 };
19839 match lower {
19840 "day" | "days" | "d" => "DAY".to_string(),
19841 "month" | "months" | "mon" | "mons" | "mm" => "MONTH".to_string(),
19842 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
19843 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
19844 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
19845 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
19846 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
19847 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
19848 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
19849 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
19850 _ => part.to_ascii_uppercase(),
19851 }
19852 }
19853
19854 fn write_datetime_field(&mut self, field: &DateTimeField) {
19855 match field {
19856 DateTimeField::Year => self.write_keyword("YEAR"),
19857 DateTimeField::Month => self.write_keyword("MONTH"),
19858 DateTimeField::Day => self.write_keyword("DAY"),
19859 DateTimeField::Hour => self.write_keyword("HOUR"),
19860 DateTimeField::Minute => self.write_keyword("MINUTE"),
19861 DateTimeField::Second => self.write_keyword("SECOND"),
19862 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
19863 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
19864 DateTimeField::DayOfWeek => {
19865 let name = match self.config.dialect {
19866 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
19867 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
19868 _ => "DOW",
19869 };
19870 self.write_keyword(name);
19871 }
19872 DateTimeField::DayOfYear => {
19873 let name = match self.config.dialect {
19874 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
19875 _ => "DOY",
19876 };
19877 self.write_keyword(name);
19878 }
19879 DateTimeField::Week => self.write_keyword("WEEK"),
19880 DateTimeField::WeekWithModifier(modifier) => {
19881 self.write_keyword("WEEK");
19882 self.write("(");
19883 self.write(modifier);
19884 self.write(")");
19885 }
19886 DateTimeField::Quarter => self.write_keyword("QUARTER"),
19887 DateTimeField::Epoch => self.write_keyword("EPOCH"),
19888 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
19889 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
19890 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
19891 DateTimeField::Date => self.write_keyword("DATE"),
19892 DateTimeField::Time => self.write_keyword("TIME"),
19893 DateTimeField::Custom(name) => self.write(name),
19894 }
19895 }
19896
19897 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
19899 match field {
19900 DateTimeField::Year => self.write("year"),
19901 DateTimeField::Month => self.write("month"),
19902 DateTimeField::Day => self.write("day"),
19903 DateTimeField::Hour => self.write("hour"),
19904 DateTimeField::Minute => self.write("minute"),
19905 DateTimeField::Second => self.write("second"),
19906 DateTimeField::Millisecond => self.write("millisecond"),
19907 DateTimeField::Microsecond => self.write("microsecond"),
19908 DateTimeField::DayOfWeek => self.write("dow"),
19909 DateTimeField::DayOfYear => self.write("doy"),
19910 DateTimeField::Week => self.write("week"),
19911 DateTimeField::WeekWithModifier(modifier) => {
19912 self.write("week(");
19913 self.write(modifier);
19914 self.write(")");
19915 }
19916 DateTimeField::Quarter => self.write("quarter"),
19917 DateTimeField::Epoch => self.write("epoch"),
19918 DateTimeField::Timezone => self.write("timezone"),
19919 DateTimeField::TimezoneHour => self.write("timezone_hour"),
19920 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
19921 DateTimeField::Date => self.write("date"),
19922 DateTimeField::Time => self.write("time"),
19923 DateTimeField::Custom(name) => self.write(name),
19924 }
19925 }
19926
19927 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
19930 self.write_keyword(name);
19931 self.write("(");
19932 self.generate_expression(arg)?;
19933 self.write(")");
19934 Ok(())
19935 }
19936
19937 fn generate_unary_func(
19939 &mut self,
19940 default_name: &str,
19941 f: &crate::expressions::UnaryFunc,
19942 ) -> Result<()> {
19943 let name = f.original_name.as_deref().unwrap_or(default_name);
19944 self.write_keyword(name);
19945 self.write("(");
19946 self.generate_expression(&f.this)?;
19947 self.write(")");
19948 Ok(())
19949 }
19950
19951 fn generate_sqrt_cbrt(
19953 &mut self,
19954 f: &crate::expressions::UnaryFunc,
19955 func_name: &str,
19956 _op: &str,
19957 ) -> Result<()> {
19958 self.write_keyword(func_name);
19961 self.write("(");
19962 self.generate_expression(&f.this)?;
19963 self.write(")");
19964 Ok(())
19965 }
19966
19967 fn generate_binary_func(
19968 &mut self,
19969 name: &str,
19970 arg1: &Expression,
19971 arg2: &Expression,
19972 ) -> Result<()> {
19973 self.write_keyword(name);
19974 self.write("(");
19975 self.generate_expression(arg1)?;
19976 self.write(", ");
19977 self.generate_expression(arg2)?;
19978 self.write(")");
19979 Ok(())
19980 }
19981
19982 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
19986 let func_name = f.name.as_deref().unwrap_or("CHAR");
19988 self.write_keyword(func_name);
19989 self.write("(");
19990 for (i, arg) in f.args.iter().enumerate() {
19991 if i > 0 {
19992 self.write(", ");
19993 }
19994 self.generate_expression(arg)?;
19995 }
19996 if let Some(ref charset) = f.charset {
19997 self.write(" ");
19998 self.write_keyword("USING");
19999 self.write(" ");
20000 self.write(charset);
20001 }
20002 self.write(")");
20003 Ok(())
20004 }
20005
20006 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
20007 use crate::dialects::DialectType;
20008
20009 match self.config.dialect {
20010 Some(DialectType::Teradata) => {
20011 self.generate_expression(&f.this)?;
20013 self.write(" ** ");
20014 self.generate_expression(&f.expression)?;
20015 Ok(())
20016 }
20017 _ => {
20018 self.generate_binary_func("POWER", &f.this, &f.expression)
20020 }
20021 }
20022 }
20023
20024 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
20025 self.write_func_name(name);
20026 self.write("(");
20027 for (i, arg) in args.iter().enumerate() {
20028 if i > 0 {
20029 self.write(", ");
20030 }
20031 self.generate_expression(arg)?;
20032 }
20033 self.write(")");
20034 Ok(())
20035 }
20036
20037 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
20040 self.write_keyword("CONCAT_WS");
20041 self.write("(");
20042 self.generate_expression(&f.separator)?;
20043 for expr in &f.expressions {
20044 self.write(", ");
20045 self.generate_expression(expr)?;
20046 }
20047 self.write(")");
20048 Ok(())
20049 }
20050
20051 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
20052 if let Expression::Concat(op) = expr {
20053 Self::collect_concat_operands(&op.left, out);
20054 Self::collect_concat_operands(&op.right, out);
20055 } else {
20056 out.push(expr);
20057 }
20058 }
20059
20060 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
20061 let mut operands = Vec::new();
20062 Self::collect_concat_operands(&op.left, &mut operands);
20063 Self::collect_concat_operands(&op.right, &mut operands);
20064
20065 self.write_keyword("CONCAT");
20066 self.write("(");
20067 for (i, operand) in operands.iter().enumerate() {
20068 if i > 0 {
20069 self.write(", ");
20070 }
20071 self.generate_expression(operand)?;
20072 }
20073 self.write(")");
20074 Ok(())
20075 }
20076
20077 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
20078 if let Expression::DPipe(dpipe) = expr {
20079 Self::collect_dpipe_operands(&dpipe.this, out);
20080 Self::collect_dpipe_operands(&dpipe.expression, out);
20081 } else {
20082 out.push(expr);
20083 }
20084 }
20085
20086 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
20087 let mut operands = Vec::new();
20088 Self::collect_dpipe_operands(&e.this, &mut operands);
20089 Self::collect_dpipe_operands(&e.expression, &mut operands);
20090
20091 self.write_keyword("CONCAT");
20092 self.write("(");
20093 for (i, operand) in operands.iter().enumerate() {
20094 if i > 0 {
20095 self.write(", ");
20096 }
20097 self.generate_expression(operand)?;
20098 }
20099 self.write(")");
20100 Ok(())
20101 }
20102
20103 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
20104 let use_substr = matches!(
20106 self.config.dialect,
20107 Some(
20108 DialectType::Oracle
20109 | DialectType::Presto
20110 | DialectType::Trino
20111 | DialectType::Athena
20112 )
20113 );
20114 if use_substr {
20115 self.write_keyword("SUBSTR");
20116 } else {
20117 self.write_keyword("SUBSTRING");
20118 }
20119 self.write("(");
20120 self.generate_expression(&f.this)?;
20121 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
20123 let use_comma_syntax = matches!(
20125 self.config.dialect,
20126 Some(DialectType::Spark)
20127 | Some(DialectType::Hive)
20128 | Some(DialectType::Databricks)
20129 | Some(DialectType::TSQL)
20130 | Some(DialectType::Fabric)
20131 );
20132 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
20133 self.write_space();
20135 self.write_keyword("FROM");
20136 self.write_space();
20137 self.generate_expression(&f.start)?;
20138 if let Some(length) = &f.length {
20139 self.write_space();
20140 self.write_keyword("FOR");
20141 self.write_space();
20142 self.generate_expression(length)?;
20143 }
20144 } else {
20145 self.write(", ");
20147 self.generate_expression(&f.start)?;
20148 if let Some(length) = &f.length {
20149 self.write(", ");
20150 self.generate_expression(length)?;
20151 }
20152 }
20153 self.write(")");
20154 Ok(())
20155 }
20156
20157 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
20158 self.write_keyword("OVERLAY");
20159 self.write("(");
20160 self.generate_expression(&f.this)?;
20161 self.write_space();
20162 self.write_keyword("PLACING");
20163 self.write_space();
20164 self.generate_expression(&f.replacement)?;
20165 self.write_space();
20166 self.write_keyword("FROM");
20167 self.write_space();
20168 self.generate_expression(&f.from)?;
20169 if let Some(length) = &f.length {
20170 self.write_space();
20171 self.write_keyword("FOR");
20172 self.write_space();
20173 self.generate_expression(length)?;
20174 }
20175 self.write(")");
20176 Ok(())
20177 }
20178
20179 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
20180 if f.position_explicit && f.characters.is_none() {
20183 match f.position {
20184 TrimPosition::Leading => {
20185 self.write_keyword("LTRIM");
20186 self.write("(");
20187 self.generate_expression(&f.this)?;
20188 self.write(")");
20189 return Ok(());
20190 }
20191 TrimPosition::Trailing => {
20192 self.write_keyword("RTRIM");
20193 self.write("(");
20194 self.generate_expression(&f.this)?;
20195 self.write(")");
20196 return Ok(());
20197 }
20198 TrimPosition::Both => {
20199 }
20202 }
20203 }
20204
20205 self.write_keyword("TRIM");
20206 self.write("(");
20207 let force_standard = f.characters.is_some()
20210 && !f.sql_standard_syntax
20211 && matches!(
20212 self.config.dialect,
20213 Some(DialectType::Hive)
20214 | Some(DialectType::Spark)
20215 | Some(DialectType::Databricks)
20216 | Some(DialectType::ClickHouse)
20217 );
20218 let use_standard = (f.sql_standard_syntax || force_standard)
20219 && !(f.position_explicit
20220 && f.characters.is_none()
20221 && matches!(f.position, TrimPosition::Both));
20222 if use_standard {
20223 if f.position_explicit {
20226 match f.position {
20227 TrimPosition::Both => self.write_keyword("BOTH"),
20228 TrimPosition::Leading => self.write_keyword("LEADING"),
20229 TrimPosition::Trailing => self.write_keyword("TRAILING"),
20230 }
20231 self.write_space();
20232 }
20233 if let Some(chars) = &f.characters {
20234 self.generate_expression(chars)?;
20235 self.write_space();
20236 }
20237 self.write_keyword("FROM");
20238 self.write_space();
20239 self.generate_expression(&f.this)?;
20240 } else {
20241 self.generate_expression(&f.this)?;
20243 if let Some(chars) = &f.characters {
20244 self.write(", ");
20245 self.generate_expression(chars)?;
20246 }
20247 }
20248 self.write(")");
20249 Ok(())
20250 }
20251
20252 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
20253 self.write_keyword("REPLACE");
20254 self.write("(");
20255 self.generate_expression(&f.this)?;
20256 self.write(", ");
20257 self.generate_expression(&f.old)?;
20258 self.write(", ");
20259 self.generate_expression(&f.new)?;
20260 self.write(")");
20261 Ok(())
20262 }
20263
20264 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
20265 self.write_keyword(name);
20266 self.write("(");
20267 self.generate_expression(&f.this)?;
20268 self.write(", ");
20269 self.generate_expression(&f.length)?;
20270 self.write(")");
20271 Ok(())
20272 }
20273
20274 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
20275 self.write_keyword("REPEAT");
20276 self.write("(");
20277 self.generate_expression(&f.this)?;
20278 self.write(", ");
20279 self.generate_expression(&f.times)?;
20280 self.write(")");
20281 Ok(())
20282 }
20283
20284 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
20285 self.write_keyword(name);
20286 self.write("(");
20287 self.generate_expression(&f.this)?;
20288 self.write(", ");
20289 self.generate_expression(&f.length)?;
20290 if let Some(fill) = &f.fill {
20291 self.write(", ");
20292 self.generate_expression(fill)?;
20293 }
20294 self.write(")");
20295 Ok(())
20296 }
20297
20298 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
20299 self.write_keyword("SPLIT");
20300 self.write("(");
20301 self.generate_expression(&f.this)?;
20302 self.write(", ");
20303 self.generate_expression(&f.delimiter)?;
20304 self.write(")");
20305 Ok(())
20306 }
20307
20308 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
20309 use crate::dialects::DialectType;
20310 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
20312 self.generate_expression(&f.this)?;
20313 self.write(" ~ ");
20314 self.generate_expression(&f.pattern)?;
20315 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && f.flags.is_none()
20316 {
20317 self.write("match(");
20319 self.generate_expression(&f.this)?;
20320 self.write(", ");
20321 self.generate_expression(&f.pattern)?;
20322 self.write(")");
20323 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
20324 self.generate_expression(&f.this)?;
20326 self.write_keyword(" REGEXP_LIKE ");
20327 self.generate_expression(&f.pattern)?;
20328 } else if matches!(
20329 self.config.dialect,
20330 Some(DialectType::SingleStore)
20331 | Some(DialectType::Spark)
20332 | Some(DialectType::Hive)
20333 | Some(DialectType::Databricks)
20334 ) && f.flags.is_none()
20335 {
20336 self.generate_expression(&f.this)?;
20338 self.write_keyword(" RLIKE ");
20339 self.generate_expression(&f.pattern)?;
20340 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
20341 self.write_keyword("REGEXP");
20343 self.write("(");
20344 self.generate_expression(&f.this)?;
20345 self.write(", ");
20346 self.generate_expression(&f.pattern)?;
20347 if let Some(flags) = &f.flags {
20348 self.write(", ");
20349 self.generate_expression(flags)?;
20350 }
20351 self.write(")");
20352 } else {
20353 self.write_keyword("REGEXP_LIKE");
20354 self.write("(");
20355 self.generate_expression(&f.this)?;
20356 self.write(", ");
20357 self.generate_expression(&f.pattern)?;
20358 if let Some(flags) = &f.flags {
20359 self.write(", ");
20360 self.generate_expression(flags)?;
20361 }
20362 self.write(")");
20363 }
20364 Ok(())
20365 }
20366
20367 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
20368 self.write_keyword("REGEXP_REPLACE");
20369 self.write("(");
20370 self.generate_expression(&f.this)?;
20371 self.write(", ");
20372 self.generate_expression(&f.pattern)?;
20373 self.write(", ");
20374 self.generate_expression(&f.replacement)?;
20375 if let Some(flags) = &f.flags {
20376 self.write(", ");
20377 self.generate_expression(flags)?;
20378 }
20379 self.write(")");
20380 Ok(())
20381 }
20382
20383 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
20384 self.write_keyword("REGEXP_EXTRACT");
20385 self.write("(");
20386 self.generate_expression(&f.this)?;
20387 self.write(", ");
20388 self.generate_expression(&f.pattern)?;
20389 if let Some(group) = &f.group {
20390 self.write(", ");
20391 self.generate_expression(group)?;
20392 }
20393 self.write(")");
20394 Ok(())
20395 }
20396
20397 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
20400 self.write_keyword("ROUND");
20401 self.write("(");
20402 self.generate_expression(&f.this)?;
20403 if let Some(decimals) = &f.decimals {
20404 self.write(", ");
20405 self.generate_expression(decimals)?;
20406 }
20407 self.write(")");
20408 Ok(())
20409 }
20410
20411 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
20412 self.write_keyword("FLOOR");
20413 self.write("(");
20414 self.generate_expression(&f.this)?;
20415 if let Some(to) = &f.to {
20417 self.write(" ");
20418 self.write_keyword("TO");
20419 self.write(" ");
20420 self.generate_expression(to)?;
20421 } else if let Some(scale) = &f.scale {
20422 self.write(", ");
20423 self.generate_expression(scale)?;
20424 }
20425 self.write(")");
20426 Ok(())
20427 }
20428
20429 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
20430 self.write_keyword("CEIL");
20431 self.write("(");
20432 self.generate_expression(&f.this)?;
20433 if let Some(to) = &f.to {
20435 self.write(" ");
20436 self.write_keyword("TO");
20437 self.write(" ");
20438 self.generate_expression(to)?;
20439 } else if let Some(decimals) = &f.decimals {
20440 self.write(", ");
20441 self.generate_expression(decimals)?;
20442 }
20443 self.write(")");
20444 Ok(())
20445 }
20446
20447 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
20448 use crate::expressions::Literal;
20449
20450 if let Some(base) = &f.base {
20451 if self.is_log_base_none() {
20454 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
20455 {
20456 self.write_func_name("LOG2");
20457 self.write("(");
20458 self.generate_expression(&f.this)?;
20459 self.write(")");
20460 return Ok(());
20461 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
20462 {
20463 self.write_func_name("LOG10");
20464 self.write("(");
20465 self.generate_expression(&f.this)?;
20466 self.write(")");
20467 return Ok(());
20468 }
20469 }
20471
20472 self.write_func_name("LOG");
20473 self.write("(");
20474 if self.is_log_value_first() {
20475 self.generate_expression(&f.this)?;
20477 self.write(", ");
20478 self.generate_expression(base)?;
20479 } else {
20480 self.generate_expression(base)?;
20482 self.write(", ");
20483 self.generate_expression(&f.this)?;
20484 }
20485 self.write(")");
20486 } else {
20487 self.write_func_name("LOG");
20489 self.write("(");
20490 self.generate_expression(&f.this)?;
20491 self.write(")");
20492 }
20493 Ok(())
20494 }
20495
20496 fn is_log_value_first(&self) -> bool {
20499 use crate::dialects::DialectType;
20500 matches!(
20501 self.config.dialect,
20502 Some(DialectType::BigQuery)
20503 | Some(DialectType::TSQL)
20504 | Some(DialectType::Tableau)
20505 | Some(DialectType::Fabric)
20506 )
20507 }
20508
20509 fn is_log_base_none(&self) -> bool {
20512 use crate::dialects::DialectType;
20513 matches!(
20514 self.config.dialect,
20515 Some(DialectType::Presto)
20516 | Some(DialectType::Trino)
20517 | Some(DialectType::ClickHouse)
20518 | Some(DialectType::Athena)
20519 )
20520 }
20521
20522 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
20525 self.write_keyword("CURRENT_TIME");
20526 if let Some(precision) = f.precision {
20527 self.write(&format!("({})", precision));
20528 } else if matches!(
20529 self.config.dialect,
20530 Some(crate::dialects::DialectType::MySQL)
20531 | Some(crate::dialects::DialectType::SingleStore)
20532 | Some(crate::dialects::DialectType::TiDB)
20533 ) {
20534 self.write("()");
20535 }
20536 Ok(())
20537 }
20538
20539 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
20540 use crate::dialects::DialectType;
20541
20542 if f.sysdate {
20544 match self.config.dialect {
20545 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
20546 self.write_keyword("SYSDATE");
20547 return Ok(());
20548 }
20549 Some(DialectType::Snowflake) => {
20550 self.write_keyword("SYSDATE");
20552 self.write("()");
20553 return Ok(());
20554 }
20555 _ => {
20556 }
20558 }
20559 }
20560
20561 self.write_keyword("CURRENT_TIMESTAMP");
20562 if let Some(precision) = f.precision {
20564 self.write(&format!("({})", precision));
20565 } else if matches!(
20566 self.config.dialect,
20567 Some(crate::dialects::DialectType::MySQL)
20568 | Some(crate::dialects::DialectType::SingleStore)
20569 | Some(crate::dialects::DialectType::TiDB)
20570 | Some(crate::dialects::DialectType::Spark)
20571 | Some(crate::dialects::DialectType::Hive)
20572 | Some(crate::dialects::DialectType::Databricks)
20573 | Some(crate::dialects::DialectType::ClickHouse)
20574 | Some(crate::dialects::DialectType::BigQuery)
20575 | Some(crate::dialects::DialectType::Snowflake)
20576 | Some(crate::dialects::DialectType::Exasol)
20577 ) {
20578 self.write("()");
20579 }
20580 Ok(())
20581 }
20582
20583 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
20584 if self.config.dialect == Some(DialectType::Exasol) {
20586 self.write_keyword("CONVERT_TZ");
20587 self.write("(");
20588 self.generate_expression(&f.this)?;
20589 self.write(", 'UTC', ");
20590 self.generate_expression(&f.zone)?;
20591 self.write(")");
20592 return Ok(());
20593 }
20594
20595 self.generate_expression(&f.this)?;
20596 self.write_space();
20597 self.write_keyword("AT TIME ZONE");
20598 self.write_space();
20599 self.generate_expression(&f.zone)?;
20600 Ok(())
20601 }
20602
20603 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
20604 use crate::dialects::DialectType;
20605
20606 let is_presto_like = matches!(
20609 self.config.dialect,
20610 Some(DialectType::Presto) | Some(DialectType::Trino)
20611 );
20612
20613 if is_presto_like {
20614 self.write_keyword(name);
20615 self.write("(");
20616 self.write("'");
20618 self.write_simple_interval_unit(&f.unit, false);
20619 self.write("'");
20620 self.write(", ");
20621 let needs_cast = !self.returns_integer_type(&f.interval);
20623 if needs_cast {
20624 self.write_keyword("CAST");
20625 self.write("(");
20626 }
20627 self.generate_expression(&f.interval)?;
20628 if needs_cast {
20629 self.write_space();
20630 self.write_keyword("AS");
20631 self.write_space();
20632 self.write_keyword("BIGINT");
20633 self.write(")");
20634 }
20635 self.write(", ");
20636 self.generate_expression(&f.this)?;
20637 self.write(")");
20638 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20639 self.generate_expression(&f.this)?;
20640 self.write_space();
20641 if name.eq_ignore_ascii_case("DATE_SUB") {
20642 self.write("-");
20643 } else {
20644 self.write("+");
20645 }
20646 self.write_space();
20647 self.write_keyword("INTERVAL");
20648 self.write_space();
20649 self.write("'");
20650 let mut interval_gen = Generator::with_arc_config(self.config.clone());
20651 let interval_sql = interval_gen.generate(&f.interval)?;
20652 self.write(&interval_sql);
20653 self.write(" ");
20654 self.write_simple_interval_unit(&f.unit, false);
20655 self.write("'");
20656 } else {
20657 self.write_keyword(name);
20658 self.write("(");
20659 self.generate_expression(&f.this)?;
20660 self.write(", ");
20661 self.write_keyword("INTERVAL");
20662 self.write_space();
20663 self.generate_expression(&f.interval)?;
20664 self.write_space();
20665 self.write_simple_interval_unit(&f.unit, false); self.write(")");
20667 }
20668 Ok(())
20669 }
20670
20671 fn returns_integer_type(&self, expr: &Expression) -> bool {
20674 use crate::expressions::{DataType, Literal};
20675 match expr {
20676 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
20678 let Literal::Number(n) = lit.as_ref() else {
20679 unreachable!()
20680 };
20681 !n.contains('.')
20682 }
20683
20684 Expression::Floor(f) => self.returns_integer_type(&f.this),
20686
20687 Expression::Round(f) => {
20689 f.decimals.is_none() && self.returns_integer_type(&f.this)
20691 }
20692
20693 Expression::Sign(f) => self.returns_integer_type(&f.this),
20695
20696 Expression::Abs(f) => self.returns_integer_type(&f.this),
20698
20699 Expression::Mul(op) => {
20701 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20702 }
20703 Expression::Add(op) => {
20704 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20705 }
20706 Expression::Sub(op) => {
20707 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20708 }
20709 Expression::Mod(op) => self.returns_integer_type(&op.left),
20710
20711 Expression::Cast(c) => matches!(
20713 &c.to,
20714 DataType::BigInt { .. }
20715 | DataType::Int { .. }
20716 | DataType::SmallInt { .. }
20717 | DataType::TinyInt { .. }
20718 ),
20719
20720 Expression::Neg(op) => self.returns_integer_type(&op.this),
20722
20723 Expression::Paren(p) => self.returns_integer_type(&p.this),
20725
20726 _ => false,
20729 }
20730 }
20731
20732 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
20733 self.write_keyword("DATEDIFF");
20734 self.write("(");
20735 if let Some(unit) = &f.unit {
20736 self.write_simple_interval_unit(unit, false); self.write(", ");
20738 }
20739 if self.config.dialect == Some(DialectType::Snowflake) {
20740 self.generate_expression(&f.expression)?;
20741 self.write(", ");
20742 self.generate_expression(&f.this)?;
20743 } else {
20744 self.generate_expression(&f.this)?;
20745 self.write(", ");
20746 self.generate_expression(&f.expression)?;
20747 }
20748 self.write(")");
20749 Ok(())
20750 }
20751
20752 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
20753 if matches!(
20754 self.config.dialect,
20755 Some(DialectType::TSQL) | Some(DialectType::Fabric)
20756 ) {
20757 let date_part = self.classify_tsql_date_trunc_field(&f.unit);
20758 self.generate_tsql_date_trunc(date_part, &f.this)?;
20759 return Ok(());
20760 }
20761 if self.config.dialect == Some(DialectType::ClickHouse) {
20762 self.write("dateTrunc");
20763 } else {
20764 self.write_keyword("DATE_TRUNC");
20765 }
20766 self.write("('");
20767 self.write_datetime_field(&f.unit);
20768 self.write("', ");
20769 self.generate_expression(&f.this)?;
20770 self.write(")");
20771 Ok(())
20772 }
20773
20774 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
20775 use crate::dialects::DialectType;
20776 use crate::expressions::DateTimeField;
20777
20778 self.write_keyword("LAST_DAY");
20779 self.write("(");
20780 self.generate_expression(&f.this)?;
20781 if let Some(unit) = &f.unit {
20782 self.write(", ");
20783 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
20786 if let DateTimeField::WeekWithModifier(_) = unit {
20787 self.write_keyword("WEEK");
20788 } else {
20789 self.write_datetime_field(unit);
20790 }
20791 } else {
20792 self.write_datetime_field(unit);
20793 }
20794 }
20795 self.write(")");
20796 Ok(())
20797 }
20798
20799 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
20800 if matches!(
20802 self.config.dialect,
20803 Some(DialectType::TSQL) | Some(DialectType::Fabric)
20804 ) {
20805 let date_part = self.classify_tsql_datetime_field(&f.field);
20806 self.generate_tsql_date_part(date_part, &f.this)?;
20807 return Ok(());
20808 }
20809 self.write_keyword("EXTRACT");
20810 self.write("(");
20811 if matches!(
20813 self.config.dialect,
20814 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
20815 ) {
20816 self.write_datetime_field_lower(&f.field);
20817 } else {
20818 self.write_datetime_field(&f.field);
20819 }
20820 self.write_space();
20821 self.write_keyword("FROM");
20822 self.write_space();
20823 self.generate_expression(&f.this)?;
20824 self.write(")");
20825 Ok(())
20826 }
20827
20828 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
20829 self.write_keyword("TO_DATE");
20830 self.write("(");
20831 self.generate_expression(&f.this)?;
20832 if let Some(format) = &f.format {
20833 self.write(", ");
20834 self.generate_expression(format)?;
20835 }
20836 self.write(")");
20837 Ok(())
20838 }
20839
20840 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
20841 self.write_keyword("TO_TIMESTAMP");
20842 self.write("(");
20843 self.generate_expression(&f.this)?;
20844 if let Some(format) = &f.format {
20845 self.write(", ");
20846 self.generate_expression(format)?;
20847 }
20848 self.write(")");
20849 Ok(())
20850 }
20851
20852 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
20855 use crate::dialects::DialectType;
20856
20857 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
20859 self.write_keyword("CASE WHEN");
20860 self.write_space();
20861 self.generate_expression(&f.condition)?;
20862 self.write_space();
20863 self.write_keyword("THEN");
20864 self.write_space();
20865 self.generate_expression(&f.true_value)?;
20866 if let Some(false_val) = &f.false_value {
20867 self.write_space();
20868 self.write_keyword("ELSE");
20869 self.write_space();
20870 self.generate_expression(false_val)?;
20871 }
20872 self.write_space();
20873 self.write_keyword("END");
20874 return Ok(());
20875 }
20876
20877 if self.config.dialect == Some(DialectType::Exasol) {
20879 self.write_keyword("IF");
20880 self.write_space();
20881 self.generate_expression(&f.condition)?;
20882 self.write_space();
20883 self.write_keyword("THEN");
20884 self.write_space();
20885 self.generate_expression(&f.true_value)?;
20886 if let Some(false_val) = &f.false_value {
20887 self.write_space();
20888 self.write_keyword("ELSE");
20889 self.write_space();
20890 self.generate_expression(false_val)?;
20891 }
20892 self.write_space();
20893 self.write_keyword("ENDIF");
20894 return Ok(());
20895 }
20896
20897 let func_name = match self.config.dialect {
20899 Some(DialectType::ClickHouse) => f.original_name.as_deref().unwrap_or("IF"),
20900 Some(DialectType::Snowflake) => "IFF",
20901 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
20902 Some(DialectType::Drill) => "`IF`",
20903 _ => "IF",
20904 };
20905 self.write(func_name);
20906 self.write("(");
20907 self.generate_expression(&f.condition)?;
20908 self.write(", ");
20909 self.generate_expression(&f.true_value)?;
20910 if let Some(false_val) = &f.false_value {
20911 self.write(", ");
20912 self.generate_expression(false_val)?;
20913 }
20914 self.write(")");
20915 Ok(())
20916 }
20917
20918 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
20919 self.write_keyword("NVL2");
20920 self.write("(");
20921 self.generate_expression(&f.this)?;
20922 self.write(", ");
20923 self.generate_expression(&f.true_value)?;
20924 self.write(", ");
20925 self.generate_expression(&f.false_value)?;
20926 self.write(")");
20927 Ok(())
20928 }
20929
20930 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
20933 let count_name = match self.config.normalize_functions {
20935 NormalizeFunctions::Upper => "COUNT".to_string(),
20936 NormalizeFunctions::Lower => "count".to_string(),
20937 NormalizeFunctions::None => f
20938 .original_name
20939 .clone()
20940 .unwrap_or_else(|| "COUNT".to_string()),
20941 };
20942 self.write(&count_name);
20943 self.write("(");
20944 if f.distinct {
20945 self.write_keyword("DISTINCT");
20946 self.write_space();
20947 }
20948 if f.star {
20949 self.write("*");
20950 } else if let Some(ref expr) = f.this {
20951 if let Expression::Tuple(tuple) = expr {
20953 let needs_transform =
20957 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
20958
20959 if needs_transform {
20960 self.write_keyword("CASE");
20962 for e in &tuple.expressions {
20963 self.write_space();
20964 self.write_keyword("WHEN");
20965 self.write_space();
20966 self.generate_expression(e)?;
20967 self.write_space();
20968 self.write_keyword("IS NULL THEN NULL");
20969 }
20970 self.write_space();
20971 self.write_keyword("ELSE");
20972 self.write(" (");
20973 for (i, e) in tuple.expressions.iter().enumerate() {
20974 if i > 0 {
20975 self.write(", ");
20976 }
20977 self.generate_expression(e)?;
20978 }
20979 self.write(")");
20980 self.write_space();
20981 self.write_keyword("END");
20982 } else {
20983 for (i, e) in tuple.expressions.iter().enumerate() {
20984 if i > 0 {
20985 self.write(", ");
20986 }
20987 self.generate_expression(e)?;
20988 }
20989 }
20990 } else {
20991 self.generate_expression(expr)?;
20992 }
20993 }
20994 let clickhouse_ignore_nulls_outside =
20995 matches!(self.config.dialect, Some(DialectType::ClickHouse));
20996 if let Some(ignore) = f.ignore_nulls.filter(|_| !clickhouse_ignore_nulls_outside) {
20997 self.write_space();
20998 if ignore {
20999 self.write_keyword("IGNORE NULLS");
21000 } else {
21001 self.write_keyword("RESPECT NULLS");
21002 }
21003 }
21004 self.write(")");
21005 if let Some(ignore) = f.ignore_nulls.filter(|_| clickhouse_ignore_nulls_outside) {
21006 self.write_space();
21007 if ignore {
21008 self.write_keyword("IGNORE NULLS");
21009 } else {
21010 self.write_keyword("RESPECT NULLS");
21011 }
21012 }
21013 if let Some(ref filter) = f.filter {
21014 self.write_space();
21015 self.write_keyword("FILTER");
21016 self.write("(");
21017 self.write_keyword("WHERE");
21018 self.write_space();
21019 self.generate_expression(filter)?;
21020 self.write(")");
21021 }
21022 Ok(())
21023 }
21024
21025 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
21026 let func_name: Cow<'_, str> = match self.config.normalize_functions {
21028 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
21029 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
21030 NormalizeFunctions::None => {
21031 if let Some(ref original) = f.name {
21034 Cow::Owned(original.clone())
21035 } else {
21036 Cow::Owned(name.to_ascii_lowercase())
21037 }
21038 }
21039 };
21040 self.write(func_name.as_ref());
21041 self.write("(");
21042 if f.distinct {
21043 self.write_keyword("DISTINCT");
21044 self.write_space();
21045 }
21046 let is_zero_arg_mode =
21049 name.eq_ignore_ascii_case("MODE") && matches!(f.this, Expression::Null(_));
21050 if !is_zero_arg_mode {
21051 self.generate_expression(&f.this)?;
21052 }
21053 if self.config.ignore_nulls_in_func
21056 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
21057 {
21058 match f.ignore_nulls {
21059 Some(true) => {
21060 self.write_space();
21061 self.write_keyword("IGNORE NULLS");
21062 }
21063 Some(false) => {
21064 self.write_space();
21065 self.write_keyword("RESPECT NULLS");
21066 }
21067 None => {}
21068 }
21069 }
21070 if let Some((ref expr, is_max)) = f.having_max {
21073 self.write_space();
21074 self.write_keyword("HAVING");
21075 self.write_space();
21076 if is_max {
21077 self.write_keyword("MAX");
21078 } else {
21079 self.write_keyword("MIN");
21080 }
21081 self.write_space();
21082 self.generate_expression(expr)?;
21083 }
21084 if !f.order_by.is_empty() {
21086 self.write_space();
21087 self.write_keyword("ORDER BY");
21088 self.write_space();
21089 for (i, ord) in f.order_by.iter().enumerate() {
21090 if i > 0 {
21091 self.write(", ");
21092 }
21093 self.generate_ordered(ord)?;
21094 }
21095 }
21096 if let Some(ref limit) = f.limit {
21098 self.write_space();
21099 self.write_keyword("LIMIT");
21100 self.write_space();
21101 if let Expression::Tuple(t) = limit.as_ref() {
21103 if t.expressions.len() == 2 {
21104 self.generate_expression(&t.expressions[0])?;
21105 self.write(", ");
21106 self.generate_expression(&t.expressions[1])?;
21107 } else {
21108 self.generate_expression(limit)?;
21109 }
21110 } else {
21111 self.generate_expression(limit)?;
21112 }
21113 }
21114 self.write(")");
21115 if !self.config.ignore_nulls_in_func
21118 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
21119 {
21120 match f.ignore_nulls {
21121 Some(true) => {
21122 self.write_space();
21123 self.write_keyword("IGNORE NULLS");
21124 }
21125 Some(false) => {
21126 self.write_space();
21127 self.write_keyword("RESPECT NULLS");
21128 }
21129 None => {}
21130 }
21131 }
21132 if let Some(ref filter) = f.filter {
21133 self.write_space();
21134 self.write_keyword("FILTER");
21135 self.write("(");
21136 self.write_keyword("WHERE");
21137 self.write_space();
21138 self.generate_expression(filter)?;
21139 self.write(")");
21140 }
21141 Ok(())
21142 }
21143
21144 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
21147 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
21149 let func_name: Cow<'_, str> = match self.config.normalize_functions {
21151 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
21152 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
21153 NormalizeFunctions::None => {
21154 if let Some(ref original) = f.name {
21155 Cow::Owned(original.clone())
21156 } else {
21157 Cow::Owned(name.to_ascii_lowercase())
21158 }
21159 }
21160 };
21161 self.write(func_name.as_ref());
21162 self.write("(");
21163 if f.distinct {
21164 self.write_keyword("DISTINCT");
21165 self.write_space();
21166 }
21167 if !matches!(f.this, Expression::Null(_)) {
21168 self.generate_expression(&f.this)?;
21169 }
21170 self.write(", ");
21171 self.write_keyword("TRUE");
21172 self.write(")");
21173 return Ok(());
21174 }
21175 self.generate_agg_func(name, f)
21176 }
21177
21178 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
21179 self.write_keyword("GROUP_CONCAT");
21180 self.write("(");
21181 if f.distinct {
21182 self.write_keyword("DISTINCT");
21183 self.write_space();
21184 }
21185 self.generate_expression(&f.this)?;
21186 if let Some(ref order_by) = f.order_by {
21187 self.write_space();
21188 self.write_keyword("ORDER BY");
21189 self.write_space();
21190 for (i, ord) in order_by.iter().enumerate() {
21191 if i > 0 {
21192 self.write(", ");
21193 }
21194 self.generate_ordered(ord)?;
21195 }
21196 }
21197 if let Some(ref sep) = f.separator {
21198 if matches!(
21201 self.config.dialect,
21202 Some(crate::dialects::DialectType::SQLite)
21203 ) {
21204 self.write(", ");
21205 self.generate_expression(sep)?;
21206 } else {
21207 self.write_space();
21208 self.write_keyword("SEPARATOR");
21209 self.write_space();
21210 self.generate_expression(sep)?;
21211 }
21212 }
21213 if let Some(ref limit) = f.limit {
21214 self.write_space();
21215 self.write_keyword("LIMIT");
21216 self.write_space();
21217 self.generate_expression(limit)?;
21218 }
21219 self.write(")");
21220 if let Some(ref filter) = f.filter {
21221 self.write_space();
21222 self.write_keyword("FILTER");
21223 self.write("(");
21224 self.write_keyword("WHERE");
21225 self.write_space();
21226 self.generate_expression(filter)?;
21227 self.write(")");
21228 }
21229 Ok(())
21230 }
21231
21232 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
21233 let uses_within_group_order = matches!(
21234 self.config.dialect,
21235 Some(crate::dialects::DialectType::TSQL | crate::dialects::DialectType::Fabric)
21236 );
21237 self.write_keyword("STRING_AGG");
21238 self.write("(");
21239 if f.distinct {
21240 self.write_keyword("DISTINCT");
21241 self.write_space();
21242 }
21243 self.generate_expression(&f.this)?;
21244 if let Some(ref separator) = f.separator {
21245 self.write(", ");
21246 self.generate_string_agg_separator(separator)?;
21247 }
21248 if !uses_within_group_order {
21250 if let Some(ref order_by) = f.order_by {
21251 self.write_space();
21252 self.write_keyword("ORDER BY");
21253 self.write_space();
21254 for (i, ord) in order_by.iter().enumerate() {
21255 if i > 0 {
21256 self.write(", ");
21257 }
21258 self.generate_ordered(ord)?;
21259 }
21260 }
21261 }
21262 if let Some(ref limit) = f.limit {
21263 self.write_space();
21264 self.write_keyword("LIMIT");
21265 self.write_space();
21266 self.generate_expression(limit)?;
21267 }
21268 self.write(")");
21269 if uses_within_group_order {
21270 if let Some(ref order_by) = f.order_by {
21271 self.write_space();
21272 self.write_keyword("WITHIN GROUP");
21273 self.write(" (");
21274 self.write_keyword("ORDER BY");
21275 self.write_space();
21276 for (i, ord) in order_by.iter().enumerate() {
21277 if i > 0 {
21278 self.write(", ");
21279 }
21280 self.generate_ordered(ord)?;
21281 }
21282 self.write(")");
21283 }
21284 }
21285 if let Some(ref filter) = f.filter {
21286 self.write_space();
21287 self.write_keyword("FILTER");
21288 self.write("(");
21289 self.write_keyword("WHERE");
21290 self.write_space();
21291 self.generate_expression(filter)?;
21292 self.write(")");
21293 }
21294 Ok(())
21295 }
21296
21297 fn generate_string_agg_separator(&mut self, separator: &Expression) -> Result<()> {
21298 if matches!(
21299 self.config.dialect,
21300 Some(crate::dialects::DialectType::TSQL | crate::dialects::DialectType::Fabric)
21301 ) {
21302 if let Some(inner) = Self::tsql_string_agg_literal_separator_cast_inner(separator) {
21303 return self.generate_expression(inner);
21304 }
21305 }
21306
21307 self.generate_expression(separator)
21308 }
21309
21310 fn tsql_string_agg_literal_separator_cast_inner(separator: &Expression) -> Option<&Expression> {
21311 let Expression::Cast(cast) = separator else {
21312 return None;
21313 };
21314
21315 if cast.format.is_some() || cast.default.is_some() {
21316 return None;
21317 }
21318
21319 if !Self::is_string_data_type(&cast.to) {
21320 return None;
21321 }
21322
21323 match &cast.this {
21324 Expression::Literal(literal) if literal.is_string() => Some(&cast.this),
21325 _ => None,
21326 }
21327 }
21328
21329 fn is_string_data_type(data_type: &DataType) -> bool {
21330 matches!(
21331 data_type,
21332 DataType::Char { .. }
21333 | DataType::VarChar { .. }
21334 | DataType::String { .. }
21335 | DataType::Text
21336 | DataType::TextWithLength { .. }
21337 ) || matches!(
21338 data_type,
21339 DataType::Custom { name, .. }
21340 if name.eq_ignore_ascii_case("VARCHAR")
21341 || name.eq_ignore_ascii_case("NVARCHAR")
21342 || name.eq_ignore_ascii_case("VARCHAR(MAX)")
21343 || name.eq_ignore_ascii_case("NVARCHAR(MAX)")
21344 )
21345 }
21346
21347 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
21348 use crate::dialects::DialectType;
21349 let order_inside_args = matches!(self.config.dialect, Some(DialectType::DuckDB));
21350 self.write_keyword("LISTAGG");
21351 self.write("(");
21352 if f.distinct {
21353 self.write_keyword("DISTINCT");
21354 self.write_space();
21355 }
21356 self.generate_expression(&f.this)?;
21357 if let Some(ref sep) = f.separator {
21358 self.write(", ");
21359 self.generate_expression(sep)?;
21360 } else if matches!(
21361 self.config.dialect,
21362 Some(DialectType::Trino) | Some(DialectType::Presto)
21363 ) {
21364 self.write(", ','");
21366 }
21367 if let Some(ref overflow) = f.on_overflow {
21368 self.write_space();
21369 self.write_keyword("ON OVERFLOW");
21370 self.write_space();
21371 match overflow {
21372 ListAggOverflow::Error => self.write_keyword("ERROR"),
21373 ListAggOverflow::Truncate { filler, with_count } => {
21374 self.write_keyword("TRUNCATE");
21375 if let Some(ref fill) = filler {
21376 self.write_space();
21377 self.generate_expression(fill)?;
21378 }
21379 if *with_count {
21380 self.write_space();
21381 self.write_keyword("WITH COUNT");
21382 } else {
21383 self.write_space();
21384 self.write_keyword("WITHOUT COUNT");
21385 }
21386 }
21387 }
21388 }
21389 if order_inside_args {
21390 if let Some(ref order_by) = f.order_by {
21391 self.write_space();
21392 self.write_keyword("ORDER BY");
21393 self.write_space();
21394 for (i, ord) in order_by.iter().enumerate() {
21395 if i > 0 {
21396 self.write(", ");
21397 }
21398 self.generate_ordered(ord)?;
21399 }
21400 }
21401 }
21402 self.write(")");
21403 if !order_inside_args {
21404 if let Some(ref order_by) = f.order_by {
21405 self.write_space();
21406 self.write_keyword("WITHIN GROUP");
21407 self.write(" (");
21408 self.write_keyword("ORDER BY");
21409 self.write_space();
21410 for (i, ord) in order_by.iter().enumerate() {
21411 if i > 0 {
21412 self.write(", ");
21413 }
21414 self.generate_ordered(ord)?;
21415 }
21416 self.write(")");
21417 }
21418 }
21419 if let Some(ref filter) = f.filter {
21420 self.write_space();
21421 self.write_keyword("FILTER");
21422 self.write("(");
21423 self.write_keyword("WHERE");
21424 self.write_space();
21425 self.generate_expression(filter)?;
21426 self.write(")");
21427 }
21428 Ok(())
21429 }
21430
21431 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
21432 self.write_keyword("SUM_IF");
21433 self.write("(");
21434 self.generate_expression(&f.this)?;
21435 self.write(", ");
21436 self.generate_expression(&f.condition)?;
21437 self.write(")");
21438 if let Some(ref filter) = f.filter {
21439 self.write_space();
21440 self.write_keyword("FILTER");
21441 self.write("(");
21442 self.write_keyword("WHERE");
21443 self.write_space();
21444 self.generate_expression(filter)?;
21445 self.write(")");
21446 }
21447 Ok(())
21448 }
21449
21450 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
21451 self.write_keyword("APPROX_PERCENTILE");
21452 self.write("(");
21453 self.generate_expression(&f.this)?;
21454 self.write(", ");
21455 self.generate_expression(&f.percentile)?;
21456 if let Some(ref acc) = f.accuracy {
21457 self.write(", ");
21458 self.generate_expression(acc)?;
21459 }
21460 self.write(")");
21461 if let Some(ref filter) = f.filter {
21462 self.write_space();
21463 self.write_keyword("FILTER");
21464 self.write("(");
21465 self.write_keyword("WHERE");
21466 self.write_space();
21467 self.generate_expression(filter)?;
21468 self.write(")");
21469 }
21470 Ok(())
21471 }
21472
21473 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
21474 self.write_keyword(name);
21475 self.write("(");
21476 self.generate_expression(&f.percentile)?;
21477 self.write(")");
21478 if let Some(ref order_by) = f.order_by {
21479 self.write_space();
21480 self.write_keyword("WITHIN GROUP");
21481 self.write(" (");
21482 self.write_keyword("ORDER BY");
21483 self.write_space();
21484 self.generate_expression(&f.this)?;
21485 for ord in order_by.iter() {
21486 if ord.desc {
21487 self.write_space();
21488 self.write_keyword("DESC");
21489 }
21490 }
21491 self.write(")");
21492 }
21493 if let Some(ref filter) = f.filter {
21494 self.write_space();
21495 self.write_keyword("FILTER");
21496 self.write("(");
21497 self.write_keyword("WHERE");
21498 self.write_space();
21499 self.generate_expression(filter)?;
21500 self.write(")");
21501 }
21502 Ok(())
21503 }
21504
21505 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
21508 self.write_keyword("NTILE");
21509 self.write("(");
21510 if let Some(num_buckets) = &f.num_buckets {
21511 self.generate_expression(num_buckets)?;
21512 }
21513 if let Some(order_by) = &f.order_by {
21514 self.write_keyword(" ORDER BY ");
21515 for (i, ob) in order_by.iter().enumerate() {
21516 if i > 0 {
21517 self.write(", ");
21518 }
21519 self.generate_ordered(ob)?;
21520 }
21521 }
21522 self.write(")");
21523 Ok(())
21524 }
21525
21526 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
21527 self.write_keyword(name);
21528 self.write("(");
21529 self.generate_expression(&f.this)?;
21530 if let Some(ref offset) = f.offset {
21531 self.write(", ");
21532 self.generate_expression(offset)?;
21533 if let Some(ref default) = f.default {
21534 self.write(", ");
21535 self.generate_expression(default)?;
21536 }
21537 }
21538 if self.config.ignore_nulls_in_func {
21540 match f.ignore_nulls {
21541 Some(true) => {
21542 self.write_space();
21543 self.write_keyword("IGNORE NULLS");
21544 }
21545 Some(false) => {
21546 self.write_space();
21547 self.write_keyword("RESPECT NULLS");
21548 }
21549 None => {}
21550 }
21551 }
21552 self.write(")");
21553 if !self.config.ignore_nulls_in_func {
21555 match f.ignore_nulls {
21556 Some(true) => {
21557 self.write_space();
21558 self.write_keyword("IGNORE NULLS");
21559 }
21560 Some(false) => {
21561 self.write_space();
21562 self.write_keyword("RESPECT NULLS");
21563 }
21564 None => {}
21565 }
21566 }
21567 Ok(())
21568 }
21569
21570 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
21571 self.write_keyword(name);
21572 self.write("(");
21573 self.generate_expression(&f.this)?;
21574 if !f.order_by.is_empty() {
21576 self.write_space();
21577 self.write_keyword("ORDER BY");
21578 self.write_space();
21579 for (i, ordered) in f.order_by.iter().enumerate() {
21580 if i > 0 {
21581 self.write(", ");
21582 }
21583 self.generate_ordered(ordered)?;
21584 }
21585 }
21586 if self.config.ignore_nulls_in_func {
21588 match f.ignore_nulls {
21589 Some(true) => {
21590 self.write_space();
21591 self.write_keyword("IGNORE NULLS");
21592 }
21593 Some(false) => {
21594 self.write_space();
21595 self.write_keyword("RESPECT NULLS");
21596 }
21597 None => {}
21598 }
21599 }
21600 self.write(")");
21601 if !self.config.ignore_nulls_in_func {
21603 match f.ignore_nulls {
21604 Some(true) => {
21605 self.write_space();
21606 self.write_keyword("IGNORE NULLS");
21607 }
21608 Some(false) => {
21609 self.write_space();
21610 self.write_keyword("RESPECT NULLS");
21611 }
21612 None => {}
21613 }
21614 }
21615 Ok(())
21616 }
21617
21618 fn generate_value_func_with_ignore_nulls_bool(
21621 &mut self,
21622 name: &str,
21623 f: &ValueFunc,
21624 ) -> Result<()> {
21625 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
21626 self.write_keyword(name);
21627 self.write("(");
21628 self.generate_expression(&f.this)?;
21629 self.write(", ");
21630 self.write_keyword("TRUE");
21631 self.write(")");
21632 return Ok(());
21633 }
21634 self.generate_value_func(name, f)
21635 }
21636
21637 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
21638 self.write_keyword("NTH_VALUE");
21639 self.write("(");
21640 self.generate_expression(&f.this)?;
21641 self.write(", ");
21642 self.generate_expression(&f.offset)?;
21643 if self.config.ignore_nulls_in_func {
21645 match f.ignore_nulls {
21646 Some(true) => {
21647 self.write_space();
21648 self.write_keyword("IGNORE NULLS");
21649 }
21650 Some(false) => {
21651 self.write_space();
21652 self.write_keyword("RESPECT NULLS");
21653 }
21654 None => {}
21655 }
21656 }
21657 self.write(")");
21658 if matches!(
21660 self.config.dialect,
21661 Some(crate::dialects::DialectType::Snowflake)
21662 ) {
21663 match f.from_first {
21664 Some(true) => {
21665 self.write_space();
21666 self.write_keyword("FROM FIRST");
21667 }
21668 Some(false) => {
21669 self.write_space();
21670 self.write_keyword("FROM LAST");
21671 }
21672 None => {}
21673 }
21674 }
21675 if !self.config.ignore_nulls_in_func {
21677 match f.ignore_nulls {
21678 Some(true) => {
21679 self.write_space();
21680 self.write_keyword("IGNORE NULLS");
21681 }
21682 Some(false) => {
21683 self.write_space();
21684 self.write_keyword("RESPECT NULLS");
21685 }
21686 None => {}
21687 }
21688 }
21689 Ok(())
21690 }
21691
21692 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
21695 if matches!(
21698 self.config.dialect,
21699 Some(crate::dialects::DialectType::ClickHouse)
21700 ) {
21701 self.write_keyword("POSITION");
21702 self.write("(");
21703 self.generate_expression(&f.string)?;
21704 self.write(", ");
21705 self.generate_expression(&f.substring)?;
21706 if let Some(ref start) = f.start {
21707 self.write(", ");
21708 self.generate_expression(start)?;
21709 }
21710 self.write(")");
21711 return Ok(());
21712 }
21713
21714 self.write_keyword("POSITION");
21715 self.write("(");
21716 self.generate_expression(&f.substring)?;
21717 self.write_space();
21718 self.write_keyword("IN");
21719 self.write_space();
21720 self.generate_expression(&f.string)?;
21721 if let Some(ref start) = f.start {
21722 self.write(", ");
21723 self.generate_expression(start)?;
21724 }
21725 self.write(")");
21726 Ok(())
21727 }
21728
21729 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
21732 if f.lower.is_some() || f.upper.is_some() {
21734 self.write_keyword("RANDOM");
21735 self.write("(");
21736 if let Some(ref lower) = f.lower {
21737 self.generate_expression(lower)?;
21738 }
21739 if let Some(ref upper) = f.upper {
21740 self.write(", ");
21741 self.generate_expression(upper)?;
21742 }
21743 self.write(")");
21744 return Ok(());
21745 }
21746 let func_name = match self.config.dialect {
21748 Some(crate::dialects::DialectType::Snowflake)
21749 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
21750 _ => "RAND",
21751 };
21752 self.write_keyword(func_name);
21753 self.write("(");
21754 if !matches!(
21756 self.config.dialect,
21757 Some(crate::dialects::DialectType::DuckDB)
21758 ) {
21759 if let Some(ref seed) = f.seed {
21760 self.generate_expression(seed)?;
21761 }
21762 }
21763 self.write(")");
21764 Ok(())
21765 }
21766
21767 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
21768 self.write_keyword("TRUNCATE");
21769 self.write("(");
21770 self.generate_expression(&f.this)?;
21771 if let Some(ref decimals) = f.decimals {
21772 self.write(", ");
21773 self.generate_expression(decimals)?;
21774 }
21775 self.write(")");
21776 Ok(())
21777 }
21778
21779 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
21782 self.write_keyword("DECODE");
21783 self.write("(");
21784 self.generate_expression(&f.this)?;
21785 for (search, result) in &f.search_results {
21786 self.write(", ");
21787 self.generate_expression(search)?;
21788 self.write(", ");
21789 self.generate_expression(result)?;
21790 }
21791 if let Some(ref default) = f.default {
21792 self.write(", ");
21793 self.generate_expression(default)?;
21794 }
21795 self.write(")");
21796 Ok(())
21797 }
21798
21799 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
21802 self.write_keyword(name);
21803 self.write("(");
21804 self.generate_expression(&f.this)?;
21805 self.write(", ");
21806 self.generate_expression(&f.format)?;
21807 self.write(")");
21808 Ok(())
21809 }
21810
21811 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
21812 self.write_keyword("FROM_UNIXTIME");
21813 self.write("(");
21814 self.generate_expression(&f.this)?;
21815 if let Some(ref format) = f.format {
21816 self.write(", ");
21817 self.generate_expression(format)?;
21818 }
21819 self.write(")");
21820 Ok(())
21821 }
21822
21823 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
21824 self.write_keyword("UNIX_TIMESTAMP");
21825 self.write("(");
21826 if let Some(ref expr) = f.this {
21827 self.generate_expression(expr)?;
21828 if let Some(ref format) = f.format {
21829 self.write(", ");
21830 self.generate_expression(format)?;
21831 }
21832 } else if matches!(
21833 self.config.dialect,
21834 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
21835 ) {
21836 self.write_keyword("CURRENT_TIMESTAMP");
21838 self.write("()");
21839 }
21840 self.write(")");
21841 Ok(())
21842 }
21843
21844 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
21845 self.write_keyword("MAKE_DATE");
21846 self.write("(");
21847 self.generate_expression(&f.year)?;
21848 self.write(", ");
21849 self.generate_expression(&f.month)?;
21850 self.write(", ");
21851 self.generate_expression(&f.day)?;
21852 self.write(")");
21853 Ok(())
21854 }
21855
21856 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
21857 self.write_keyword("MAKE_TIMESTAMP");
21858 self.write("(");
21859 self.generate_expression(&f.year)?;
21860 self.write(", ");
21861 self.generate_expression(&f.month)?;
21862 self.write(", ");
21863 self.generate_expression(&f.day)?;
21864 self.write(", ");
21865 self.generate_expression(&f.hour)?;
21866 self.write(", ");
21867 self.generate_expression(&f.minute)?;
21868 self.write(", ");
21869 self.generate_expression(&f.second)?;
21870 if let Some(ref tz) = f.timezone {
21871 self.write(", ");
21872 self.generate_expression(tz)?;
21873 }
21874 self.write(")");
21875 Ok(())
21876 }
21877
21878 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
21880 match expr {
21881 Expression::Struct(s) => {
21882 if s.fields.iter().all(|(name, _)| name.is_some()) {
21883 Some(
21884 s.fields
21885 .iter()
21886 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
21887 .collect(),
21888 )
21889 } else {
21890 None
21891 }
21892 }
21893 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
21894 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
21896 Some(
21897 f.args
21898 .iter()
21899 .filter_map(|a| {
21900 if let Expression::Alias(alias) = a {
21901 Some(alias.alias.name.clone())
21902 } else {
21903 None
21904 }
21905 })
21906 .collect(),
21907 )
21908 } else {
21909 None
21910 }
21911 }
21912 _ => None,
21913 }
21914 }
21915
21916 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
21918 match expr {
21919 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
21920 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
21921 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
21922 }
21923 _ => false,
21924 }
21925 }
21926
21927 fn struct_field_count(expr: &Expression) -> usize {
21929 match expr {
21930 Expression::Struct(s) => s.fields.len(),
21931 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
21932 _ => 0,
21933 }
21934 }
21935
21936 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
21938 match expr {
21939 Expression::Struct(s) => {
21940 let mut new_fields = Vec::with_capacity(s.fields.len());
21941 for (i, (name, value)) in s.fields.iter().enumerate() {
21942 if name.is_none() && i < field_names.len() {
21943 new_fields.push((Some(field_names[i].clone()), value.clone()));
21944 } else {
21945 new_fields.push((name.clone(), value.clone()));
21946 }
21947 }
21948 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
21949 }
21950 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
21951 let mut new_args = Vec::with_capacity(f.args.len());
21952 for (i, arg) in f.args.iter().enumerate() {
21953 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
21954 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
21956 this: arg.clone(),
21957 alias: crate::expressions::Identifier::new(field_names[i].clone()),
21958 column_aliases: Vec::new(),
21959 alias_explicit_as: false,
21960 alias_keyword: None,
21961 pre_alias_comments: Vec::new(),
21962 trailing_comments: Vec::new(),
21963 inferred_type: None,
21964 })));
21965 } else {
21966 new_args.push(arg.clone());
21967 }
21968 }
21969 Expression::Function(Box::new(crate::expressions::Function {
21970 name: f.name.clone(),
21971 args: new_args,
21972 distinct: f.distinct,
21973 trailing_comments: f.trailing_comments.clone(),
21974 use_bracket_syntax: f.use_bracket_syntax,
21975 no_parens: f.no_parens,
21976 quoted: f.quoted,
21977 span: None,
21978 inferred_type: None,
21979 }))
21980 }
21981 _ => expr.clone(),
21982 }
21983 }
21984
21985 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
21989 let first = match expressions.first() {
21990 Some(e) => e,
21991 None => return expressions.to_vec(),
21992 };
21993
21994 let field_names = match Self::extract_struct_field_names(first) {
21995 Some(names) if !names.is_empty() => names,
21996 _ => return expressions.to_vec(),
21997 };
21998
21999 let mut result = Vec::with_capacity(expressions.len());
22000 for (idx, expr) in expressions.iter().enumerate() {
22001 if idx == 0 {
22002 result.push(expr.clone());
22003 continue;
22004 }
22005 if Self::struct_field_count(expr) == field_names.len()
22007 && Self::struct_has_unnamed_fields(expr)
22008 {
22009 result.push(Self::apply_struct_field_names(expr, &field_names));
22010 } else {
22011 result.push(expr.clone());
22012 }
22013 }
22014 result
22015 }
22016
22017 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
22020 let needs_inheritance = matches!(
22023 self.config.dialect,
22024 Some(DialectType::DuckDB)
22025 | Some(DialectType::Spark)
22026 | Some(DialectType::Databricks)
22027 | Some(DialectType::Hive)
22028 | Some(DialectType::Snowflake)
22029 | Some(DialectType::Presto)
22030 | Some(DialectType::Trino)
22031 );
22032 let propagated: Vec<Expression>;
22033 let expressions = if needs_inheritance && f.expressions.len() > 1 {
22034 propagated = Self::inherit_struct_field_names(&f.expressions);
22035 &propagated
22036 } else {
22037 &f.expressions
22038 };
22039
22040 let should_split = if self.config.pretty && !expressions.is_empty() {
22042 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
22043 for expr in expressions {
22044 let mut temp_gen = Generator::with_arc_config(self.config.clone());
22045 Arc::make_mut(&mut temp_gen.config).pretty = false;
22046 temp_gen.generate_expression(expr)?;
22047 expr_strings.push(temp_gen.output);
22048 }
22049 self.too_wide(&expr_strings)
22050 } else {
22051 false
22052 };
22053
22054 if f.bracket_notation {
22055 let (open, close) = match self.config.dialect {
22059 None
22060 | Some(DialectType::Generic)
22061 | Some(DialectType::Spark)
22062 | Some(DialectType::Databricks)
22063 | Some(DialectType::Hive) => {
22064 self.write_keyword("ARRAY");
22065 ("(", ")")
22066 }
22067 Some(DialectType::Presto)
22068 | Some(DialectType::Trino)
22069 | Some(DialectType::PostgreSQL)
22070 | Some(DialectType::Redshift)
22071 | Some(DialectType::Materialize)
22072 | Some(DialectType::RisingWave)
22073 | Some(DialectType::CockroachDB) => {
22074 self.write_keyword("ARRAY");
22075 ("[", "]")
22076 }
22077 _ => ("[", "]"),
22078 };
22079 self.write(open);
22080 if should_split {
22081 self.write_newline();
22082 self.indent_level += 1;
22083 for (i, expr) in expressions.iter().enumerate() {
22084 self.write_indent();
22085 self.generate_expression(expr)?;
22086 if i + 1 < expressions.len() {
22087 self.write(",");
22088 }
22089 self.write_newline();
22090 }
22091 self.indent_level -= 1;
22092 self.write_indent();
22093 } else {
22094 for (i, expr) in expressions.iter().enumerate() {
22095 if i > 0 {
22096 self.write(", ");
22097 }
22098 self.generate_expression(expr)?;
22099 }
22100 }
22101 self.write(close);
22102 } else {
22103 if f.use_list_keyword {
22105 self.write_keyword("LIST");
22106 } else {
22107 self.write_keyword("ARRAY");
22108 }
22109 let has_subquery = expressions
22112 .iter()
22113 .any(|e| matches!(e, Expression::Select(_)));
22114 let (open, close) = if matches!(
22115 self.config.dialect,
22116 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
22117 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
22118 && has_subquery)
22119 {
22120 ("(", ")")
22121 } else {
22122 ("[", "]")
22123 };
22124 self.write(open);
22125 if should_split {
22126 self.write_newline();
22127 self.indent_level += 1;
22128 for (i, expr) in expressions.iter().enumerate() {
22129 self.write_indent();
22130 self.generate_expression(expr)?;
22131 if i + 1 < expressions.len() {
22132 self.write(",");
22133 }
22134 self.write_newline();
22135 }
22136 self.indent_level -= 1;
22137 self.write_indent();
22138 } else {
22139 for (i, expr) in expressions.iter().enumerate() {
22140 if i > 0 {
22141 self.write(", ");
22142 }
22143 self.generate_expression(expr)?;
22144 }
22145 }
22146 self.write(close);
22147 }
22148 Ok(())
22149 }
22150
22151 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
22152 self.write_keyword("ARRAY_SORT");
22153 self.write("(");
22154 self.generate_expression(&f.this)?;
22155 if let Some(ref comp) = f.comparator {
22156 self.write(", ");
22157 self.generate_expression(comp)?;
22158 }
22159 self.write(")");
22160 Ok(())
22161 }
22162
22163 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
22164 self.write_keyword(name);
22165 self.write("(");
22166 self.generate_expression(&f.this)?;
22167 self.write(", ");
22168 self.generate_expression(&f.separator)?;
22169 if let Some(ref null_rep) = f.null_replacement {
22170 self.write(", ");
22171 self.generate_expression(null_rep)?;
22172 }
22173 self.write(")");
22174 Ok(())
22175 }
22176
22177 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
22178 self.write_keyword("UNNEST");
22179 self.write("(");
22180 self.generate_expression(&f.this)?;
22181 for extra in &f.expressions {
22182 self.write(", ");
22183 self.generate_expression(extra)?;
22184 }
22185 self.write(")");
22186 if f.with_ordinality {
22187 self.write_space();
22188 if self.config.unnest_with_ordinality {
22189 self.write_keyword("WITH ORDINALITY");
22191 } else if f.offset_alias.is_some() {
22192 if let Some(ref alias) = f.alias {
22195 self.write_keyword("AS");
22196 self.write_space();
22197 self.generate_identifier(alias)?;
22198 self.write_space();
22199 }
22200 self.write_keyword("WITH OFFSET");
22201 if let Some(ref offset_alias) = f.offset_alias {
22202 self.write_space();
22203 self.write_keyword("AS");
22204 self.write_space();
22205 self.generate_identifier(offset_alias)?;
22206 }
22207 } else {
22208 self.write_keyword("WITH OFFSET");
22210 if f.alias.is_none() {
22211 self.write(" AS offset");
22212 }
22213 }
22214 }
22215 if let Some(ref alias) = f.alias {
22216 let should_add_alias = if !f.with_ordinality {
22218 true
22219 } else if self.config.unnest_with_ordinality {
22220 true
22222 } else if f.offset_alias.is_some() {
22223 false
22225 } else {
22226 true
22228 };
22229 if should_add_alias {
22230 self.write_space();
22231 self.write_keyword("AS");
22232 self.write_space();
22233 self.generate_identifier(alias)?;
22234 }
22235 }
22236 Ok(())
22237 }
22238
22239 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
22240 self.write_keyword("FILTER");
22241 self.write("(");
22242 self.generate_expression(&f.this)?;
22243 self.write(", ");
22244 self.generate_expression(&f.filter)?;
22245 self.write(")");
22246 Ok(())
22247 }
22248
22249 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
22250 self.write_keyword("TRANSFORM");
22251 self.write("(");
22252 self.generate_expression(&f.this)?;
22253 self.write(", ");
22254 self.generate_expression(&f.transform)?;
22255 self.write(")");
22256 Ok(())
22257 }
22258
22259 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
22260 self.write_keyword(name);
22261 self.write("(");
22262 self.generate_expression(&f.start)?;
22263 self.write(", ");
22264 self.generate_expression(&f.stop)?;
22265 if let Some(ref step) = f.step {
22266 self.write(", ");
22267 self.generate_expression(step)?;
22268 }
22269 self.write(")");
22270 Ok(())
22271 }
22272
22273 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
22276 self.write_keyword("STRUCT");
22277 self.write("(");
22278 for (i, (name, expr)) in f.fields.iter().enumerate() {
22279 if i > 0 {
22280 self.write(", ");
22281 }
22282 if let Some(ref id) = name {
22283 self.generate_identifier(id)?;
22284 self.write(" ");
22285 self.write_keyword("AS");
22286 self.write(" ");
22287 }
22288 self.generate_expression(expr)?;
22289 }
22290 self.write(")");
22291 Ok(())
22292 }
22293
22294 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
22296 let mut names: Vec<Option<String>> = Vec::new();
22299 let mut values: Vec<&Expression> = Vec::new();
22300 let mut all_named = true;
22301
22302 for arg in &func.args {
22303 match arg {
22304 Expression::Alias(a) => {
22305 names.push(Some(a.alias.name.clone()));
22306 values.push(&a.this);
22307 }
22308 _ => {
22309 names.push(None);
22310 values.push(arg);
22311 all_named = false;
22312 }
22313 }
22314 }
22315
22316 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
22317 self.write("{");
22319 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
22320 if i > 0 {
22321 self.write(", ");
22322 }
22323 if let Some(n) = name {
22324 self.write("'");
22325 self.write(n);
22326 self.write("'");
22327 } else {
22328 self.write("'_");
22329 self.write(&i.to_string());
22330 self.write("'");
22331 }
22332 self.write(": ");
22333 self.generate_expression(value)?;
22334 }
22335 self.write("}");
22336 return Ok(());
22337 }
22338
22339 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
22340 self.write_keyword("OBJECT_CONSTRUCT");
22342 self.write("(");
22343 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
22344 if i > 0 {
22345 self.write(", ");
22346 }
22347 if let Some(n) = name {
22348 self.write("'");
22349 self.write(n);
22350 self.write("'");
22351 } else {
22352 self.write("'_");
22353 self.write(&i.to_string());
22354 self.write("'");
22355 }
22356 self.write(", ");
22357 self.generate_expression(value)?;
22358 }
22359 self.write(")");
22360 return Ok(());
22361 }
22362
22363 if matches!(
22364 self.config.dialect,
22365 Some(DialectType::Presto) | Some(DialectType::Trino)
22366 ) {
22367 if all_named && !names.is_empty() {
22368 self.write_keyword("CAST");
22371 self.write("(");
22372 self.write_keyword("ROW");
22373 self.write("(");
22374 for (i, value) in values.iter().enumerate() {
22375 if i > 0 {
22376 self.write(", ");
22377 }
22378 self.generate_expression(value)?;
22379 }
22380 self.write(")");
22381 self.write(" ");
22382 self.write_keyword("AS");
22383 self.write(" ");
22384 self.write_keyword("ROW");
22385 self.write("(");
22386 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
22387 if i > 0 {
22388 self.write(", ");
22389 }
22390 if let Some(n) = name {
22391 self.write(n);
22392 }
22393 self.write(" ");
22394 let type_str = Self::infer_sql_type_for_presto(value);
22395 self.write_keyword(&type_str);
22396 }
22397 self.write(")");
22398 self.write(")");
22399 } else {
22400 self.write_keyword("ROW");
22402 self.write("(");
22403 for (i, value) in values.iter().enumerate() {
22404 if i > 0 {
22405 self.write(", ");
22406 }
22407 self.generate_expression(value)?;
22408 }
22409 self.write(")");
22410 }
22411 return Ok(());
22412 }
22413
22414 self.write_keyword("ROW");
22416 self.write("(");
22417 for (i, value) in values.iter().enumerate() {
22418 if i > 0 {
22419 self.write(", ");
22420 }
22421 self.generate_expression(value)?;
22422 }
22423 self.write(")");
22424 Ok(())
22425 }
22426
22427 fn infer_sql_type_for_presto(expr: &Expression) -> String {
22429 match expr {
22430 Expression::Literal(lit)
22431 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
22432 {
22433 "VARCHAR".to_string()
22434 }
22435 Expression::Literal(lit)
22436 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
22437 {
22438 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
22439 unreachable!()
22440 };
22441 if n.contains('.') {
22442 "DOUBLE".to_string()
22443 } else {
22444 "INTEGER".to_string()
22445 }
22446 }
22447 Expression::Boolean(_) => "BOOLEAN".to_string(),
22448 Expression::Literal(lit)
22449 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
22450 {
22451 "DATE".to_string()
22452 }
22453 Expression::Literal(lit)
22454 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
22455 {
22456 "TIMESTAMP".to_string()
22457 }
22458 Expression::Literal(lit)
22459 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
22460 {
22461 "TIMESTAMP".to_string()
22462 }
22463 Expression::Array(_) | Expression::ArrayFunc(_) => {
22464 "ARRAY(VARCHAR)".to_string()
22466 }
22467 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
22469 Expression::Function(f) => {
22470 if f.name.eq_ignore_ascii_case("STRUCT") {
22471 "ROW".to_string()
22472 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
22473 "DATE".to_string()
22474 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
22475 || f.name.eq_ignore_ascii_case("NOW")
22476 {
22477 "TIMESTAMP".to_string()
22478 } else {
22479 "VARCHAR".to_string()
22480 }
22481 }
22482 _ => "VARCHAR".to_string(),
22483 }
22484 }
22485
22486 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
22487 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
22489 self.write_keyword("STRUCT_EXTRACT");
22490 self.write("(");
22491 self.generate_expression(&f.this)?;
22492 self.write(", ");
22493 self.write("'");
22495 self.write(&f.field.name);
22496 self.write("'");
22497 self.write(")");
22498 return Ok(());
22499 }
22500 self.generate_expression(&f.this)?;
22501 self.write(".");
22502 self.generate_identifier(&f.field)
22503 }
22504
22505 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
22506 if matches!(
22507 self.config.dialect,
22508 Some(DialectType::Spark | DialectType::Databricks)
22509 ) {
22510 self.write_keyword("STRUCT");
22511 self.write("(");
22512 for (i, (name, value)) in f.pairs.iter().enumerate() {
22513 if i > 0 {
22514 self.write(", ");
22515 }
22516 self.generate_expression(value)?;
22517 self.write(" ");
22518 self.write_keyword("AS");
22519 self.write(" ");
22520 if let Expression::Literal(lit) = name {
22521 if let Literal::String(field_name) = lit.as_ref() {
22522 self.generate_identifier(&Identifier::new(field_name))?;
22523 } else {
22524 self.generate_expression(name)?;
22525 }
22526 } else {
22527 self.generate_expression(name)?;
22528 }
22529 }
22530 self.write(")");
22531 return Ok(());
22532 }
22533
22534 self.write_keyword("NAMED_STRUCT");
22535 self.write("(");
22536 for (i, (name, value)) in f.pairs.iter().enumerate() {
22537 if i > 0 {
22538 self.write(", ");
22539 }
22540 self.generate_expression(name)?;
22541 self.write(", ");
22542 self.generate_expression(value)?;
22543 }
22544 self.write(")");
22545 Ok(())
22546 }
22547
22548 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
22551 if f.curly_brace_syntax {
22552 if f.with_map_keyword {
22554 self.write_keyword("MAP");
22555 self.write(" ");
22556 }
22557 self.write("{");
22558 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
22559 if i > 0 {
22560 self.write(", ");
22561 }
22562 self.generate_expression(key)?;
22563 self.write(": ");
22564 self.generate_expression(val)?;
22565 }
22566 self.write("}");
22567 } else {
22568 self.write_keyword("MAP");
22570 self.write("(");
22571 self.write_keyword("ARRAY");
22572 self.write("[");
22573 for (i, key) in f.keys.iter().enumerate() {
22574 if i > 0 {
22575 self.write(", ");
22576 }
22577 self.generate_expression(key)?;
22578 }
22579 self.write("], ");
22580 self.write_keyword("ARRAY");
22581 self.write("[");
22582 for (i, val) in f.values.iter().enumerate() {
22583 if i > 0 {
22584 self.write(", ");
22585 }
22586 self.generate_expression(val)?;
22587 }
22588 self.write("])");
22589 }
22590 Ok(())
22591 }
22592
22593 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
22594 self.write_keyword(name);
22595 self.write("(");
22596 self.generate_expression(&f.this)?;
22597 self.write(", ");
22598 self.generate_expression(&f.transform)?;
22599 self.write(")");
22600 Ok(())
22601 }
22602
22603 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
22606 use crate::dialects::DialectType;
22607
22608 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
22610
22611 if use_arrow {
22612 self.generate_expression(&f.this)?;
22614 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
22615 self.write(" ->> ");
22616 } else {
22617 self.write(" -> ");
22618 }
22619 self.generate_expression(&f.path)?;
22620 return Ok(());
22621 }
22622
22623 if f.hash_arrow_syntax
22625 && matches!(
22626 self.config.dialect,
22627 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22628 )
22629 {
22630 self.generate_expression(&f.this)?;
22631 self.write(" #>> ");
22632 self.generate_expression(&f.path)?;
22633 return Ok(());
22634 }
22635
22636 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
22639 match name {
22640 "JSON_EXTRACT_SCALAR"
22641 | "JSON_EXTRACT_PATH_TEXT"
22642 | "JSON_EXTRACT"
22643 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
22644 _ => name,
22645 }
22646 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
22647 match name {
22648 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
22649 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
22650 _ => name,
22651 }
22652 } else {
22653 name
22654 };
22655
22656 self.write_keyword(func_name);
22657 self.write("(");
22658 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
22660 if let Expression::Cast(ref cast) = f.this {
22661 if matches!(cast.to, crate::expressions::DataType::Json) {
22662 self.generate_expression(&cast.this)?;
22663 } else {
22664 self.generate_expression(&f.this)?;
22665 }
22666 } else {
22667 self.generate_expression(&f.this)?;
22668 }
22669 } else {
22670 self.generate_expression(&f.this)?;
22671 }
22672 if matches!(
22675 self.config.dialect,
22676 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22677 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
22678 {
22679 if let Expression::Literal(ref lit) = f.path {
22680 if let Literal::String(ref s) = lit.as_ref() {
22681 let parts = Self::decompose_json_path(s);
22682 for part in &parts {
22683 self.write(", '");
22684 self.write(part);
22685 self.write("'");
22686 }
22687 }
22688 } else {
22689 self.write(", ");
22690 self.generate_expression(&f.path)?;
22691 }
22692 } else {
22693 self.write(", ");
22694 self.generate_expression(&f.path)?;
22695 }
22696
22697 if let Some(ref wrapper) = f.wrapper_option {
22700 self.write_space();
22701 self.write_keyword(wrapper);
22702 }
22703 if let Some(ref quotes) = f.quotes_option {
22704 self.write_space();
22705 self.write_keyword(quotes);
22706 if f.on_scalar_string {
22707 self.write_space();
22708 self.write_keyword("ON SCALAR STRING");
22709 }
22710 }
22711 if let Some(ref on_err) = f.on_error {
22712 self.write_space();
22713 self.write_keyword(on_err);
22714 }
22715 if let Some(ref ret_type) = f.returning {
22716 self.write_space();
22717 self.write_keyword("RETURNING");
22718 self.write_space();
22719 self.generate_data_type(ret_type)?;
22720 }
22721
22722 self.write(")");
22723 Ok(())
22724 }
22725
22726 fn dialect_supports_json_arrow(&self) -> bool {
22728 use crate::dialects::DialectType;
22729 match self.config.dialect {
22730 Some(DialectType::PostgreSQL) => true,
22732 Some(DialectType::MySQL) => true,
22733 Some(DialectType::DuckDB) => true,
22734 Some(DialectType::CockroachDB) => true,
22735 Some(DialectType::StarRocks) => true,
22736 Some(DialectType::SQLite) => true,
22737 _ => false,
22739 }
22740 }
22741
22742 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
22743 use crate::dialects::DialectType;
22744
22745 if matches!(
22747 self.config.dialect,
22748 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22749 ) && name == "JSON_EXTRACT_PATH"
22750 {
22751 self.generate_expression(&f.this)?;
22752 self.write(" #> ");
22753 if f.paths.len() == 1 {
22754 self.generate_expression(&f.paths[0])?;
22755 } else {
22756 self.write_keyword("ARRAY");
22758 self.write("[");
22759 for (i, path) in f.paths.iter().enumerate() {
22760 if i > 0 {
22761 self.write(", ");
22762 }
22763 self.generate_expression(path)?;
22764 }
22765 self.write("]");
22766 }
22767 return Ok(());
22768 }
22769
22770 self.write_keyword(name);
22771 self.write("(");
22772 self.generate_expression(&f.this)?;
22773 for path in &f.paths {
22774 self.write(", ");
22775 self.generate_expression(path)?;
22776 }
22777 self.write(")");
22778 Ok(())
22779 }
22780
22781 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
22782 use crate::dialects::DialectType;
22783
22784 self.write_keyword("JSON_OBJECT");
22785 self.write("(");
22786 if f.star {
22787 self.write("*");
22788 } else {
22789 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
22793 || matches!(
22794 self.config.dialect,
22795 Some(DialectType::BigQuery)
22796 | Some(DialectType::MySQL)
22797 | Some(DialectType::SQLite)
22798 );
22799
22800 for (i, (key, value)) in f.pairs.iter().enumerate() {
22801 if i > 0 {
22802 self.write(", ");
22803 }
22804 self.generate_expression(key)?;
22805 if use_comma_syntax {
22806 self.write(", ");
22807 } else {
22808 self.write(": ");
22809 }
22810 self.generate_expression(value)?;
22811 }
22812 }
22813 if let Some(null_handling) = f.null_handling {
22814 self.write_space();
22815 match null_handling {
22816 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
22817 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
22818 }
22819 }
22820 if f.with_unique_keys {
22821 self.write_space();
22822 self.write_keyword("WITH UNIQUE KEYS");
22823 }
22824 if let Some(ref ret_type) = f.returning_type {
22825 self.write_space();
22826 self.write_keyword("RETURNING");
22827 self.write_space();
22828 self.generate_data_type(ret_type)?;
22829 if f.format_json {
22830 self.write_space();
22831 self.write_keyword("FORMAT JSON");
22832 }
22833 if let Some(ref enc) = f.encoding {
22834 self.write_space();
22835 self.write_keyword("ENCODING");
22836 self.write_space();
22837 self.write(enc);
22838 }
22839 }
22840 self.write(")");
22841 Ok(())
22842 }
22843
22844 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
22845 self.write_keyword(name);
22846 self.write("(");
22847 self.generate_expression(&f.this)?;
22848 for (path, value) in &f.path_values {
22849 self.write(", ");
22850 self.generate_expression(path)?;
22851 self.write(", ");
22852 self.generate_expression(value)?;
22853 }
22854 self.write(")");
22855 Ok(())
22856 }
22857
22858 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
22859 self.write_keyword("JSON_ARRAYAGG");
22860 self.write("(");
22861 self.generate_expression(&f.this)?;
22862 if let Some(ref order_by) = f.order_by {
22863 self.write_space();
22864 self.write_keyword("ORDER BY");
22865 self.write_space();
22866 for (i, ord) in order_by.iter().enumerate() {
22867 if i > 0 {
22868 self.write(", ");
22869 }
22870 self.generate_ordered(ord)?;
22871 }
22872 }
22873 if let Some(null_handling) = f.null_handling {
22874 self.write_space();
22875 match null_handling {
22876 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
22877 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
22878 }
22879 }
22880 self.write(")");
22881 if let Some(ref filter) = f.filter {
22882 self.write_space();
22883 self.write_keyword("FILTER");
22884 self.write("(");
22885 self.write_keyword("WHERE");
22886 self.write_space();
22887 self.generate_expression(filter)?;
22888 self.write(")");
22889 }
22890 Ok(())
22891 }
22892
22893 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
22894 self.write_keyword("JSON_OBJECTAGG");
22895 self.write("(");
22896 self.generate_expression(&f.key)?;
22897 self.write(": ");
22898 self.generate_expression(&f.value)?;
22899 if let Some(null_handling) = f.null_handling {
22900 self.write_space();
22901 match null_handling {
22902 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
22903 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
22904 }
22905 }
22906 self.write(")");
22907 if let Some(ref filter) = f.filter {
22908 self.write_space();
22909 self.write_keyword("FILTER");
22910 self.write("(");
22911 self.write_keyword("WHERE");
22912 self.write_space();
22913 self.generate_expression(filter)?;
22914 self.write(")");
22915 }
22916 Ok(())
22917 }
22918
22919 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
22922 use crate::dialects::DialectType;
22923
22924 if self.config.dialect == Some(DialectType::Redshift) {
22926 self.write_keyword("CAST");
22927 self.write("(");
22928 self.generate_expression(&f.this)?;
22929 self.write_space();
22930 self.write_keyword("AS");
22931 self.write_space();
22932 self.generate_data_type(&f.to)?;
22933 self.write(")");
22934 return Ok(());
22935 }
22936
22937 self.write_keyword("CONVERT");
22938 self.write("(");
22939 self.generate_data_type(&f.to)?;
22940 self.write(", ");
22941 self.generate_expression(&f.this)?;
22942 if let Some(ref style) = f.style {
22943 self.write(", ");
22944 self.generate_expression(style)?;
22945 }
22946 self.write(")");
22947 Ok(())
22948 }
22949
22950 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
22953 if f.colon {
22954 self.write_keyword("LAMBDA");
22956 self.write_space();
22957 for (i, param) in f.parameters.iter().enumerate() {
22958 if i > 0 {
22959 self.write(", ");
22960 }
22961 self.generate_identifier(param)?;
22962 }
22963 self.write(" : ");
22964 } else {
22965 if f.parameters.len() == 1 {
22967 self.generate_identifier(&f.parameters[0])?;
22968 } else {
22969 self.write("(");
22970 for (i, param) in f.parameters.iter().enumerate() {
22971 if i > 0 {
22972 self.write(", ");
22973 }
22974 self.generate_identifier(param)?;
22975 }
22976 self.write(")");
22977 }
22978 self.write(" -> ");
22979 }
22980 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22981 if let Expression::Lambda(inner) = &f.body {
22982 self.generate_lambda_with_parenthesized_single_param(inner)?;
22983 return Ok(());
22984 }
22985 }
22986
22987 self.generate_expression(&f.body)
22988 }
22989
22990 fn generate_lambda_with_parenthesized_single_param(&mut self, f: &LambdaExpr) -> Result<()> {
22991 if f.colon {
22992 return self.generate_lambda(f);
22993 }
22994
22995 self.write("(");
22996 for (i, param) in f.parameters.iter().enumerate() {
22997 if i > 0 {
22998 self.write(", ");
22999 }
23000 self.generate_identifier(param)?;
23001 }
23002 self.write(") -> ");
23003 self.generate_expression(&f.body)
23004 }
23005
23006 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
23007 self.generate_identifier(&f.name)?;
23008 match f.separator {
23009 NamedArgSeparator::DArrow => self.write(" => "),
23010 NamedArgSeparator::ColonEq => self.write(" := "),
23011 NamedArgSeparator::Eq => self.write(" = "),
23012 }
23013 self.generate_expression(&f.value)
23014 }
23015
23016 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
23017 self.write_keyword(&f.prefix);
23018 self.write(" ");
23019 self.generate_expression(&f.this)
23020 }
23021
23022 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
23023 match f.style {
23024 ParameterStyle::Question => self.write("?"),
23025 ParameterStyle::Dollar => {
23026 if let Some(idx) = f.index {
23027 if matches!(
23028 self.config.dialect,
23029 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23030 ) {
23031 self.write("@P");
23032 self.write(&idx.to_string());
23033 } else {
23034 self.write("$");
23035 self.write(&idx.to_string());
23036 }
23037 } else {
23038 self.write("$");
23039 if let Some(ref name) = f.name {
23040 self.write(name);
23042 }
23043 }
23044 }
23045 ParameterStyle::DollarBrace => {
23046 self.write("${");
23048 if let Some(ref name) = f.name {
23049 self.write(name);
23050 }
23051 if let Some(ref expr) = f.expression {
23052 self.write(":");
23053 self.write(expr);
23054 }
23055 self.write("}");
23056 }
23057 ParameterStyle::Colon => {
23058 self.write(":");
23059 if let Some(idx) = f.index {
23060 self.write(&idx.to_string());
23061 } else if let Some(ref name) = f.name {
23062 self.write(name);
23063 }
23064 }
23065 ParameterStyle::At => {
23066 self.write("@");
23067 if let Some(ref name) = f.name {
23068 if f.string_quoted {
23069 self.write("'");
23070 self.write(name);
23071 self.write("'");
23072 } else if f.quoted {
23073 self.write("\"");
23074 self.write(name);
23075 self.write("\"");
23076 } else {
23077 self.write(name);
23078 }
23079 }
23080 }
23081 ParameterStyle::DoubleAt => {
23082 self.write("@@");
23083 if let Some(ref name) = f.name {
23084 self.write(name);
23085 }
23086 }
23087 ParameterStyle::DoubleDollar => {
23088 self.write("$$");
23089 if let Some(ref name) = f.name {
23090 self.write(name);
23091 }
23092 }
23093 ParameterStyle::Percent => {
23094 if let Some(ref name) = f.name {
23095 self.write("%(");
23097 self.write(name);
23098 self.write(")s");
23099 } else {
23100 self.write("%s");
23102 }
23103 }
23104 ParameterStyle::Brace => {
23105 self.write("{");
23108 if let Some(ref name) = f.name {
23109 self.write(name);
23110 }
23111 if let Some(ref expr) = f.expression {
23112 self.write(": ");
23113 self.write(expr);
23114 }
23115 self.write("}");
23116 }
23117 }
23118 Ok(())
23119 }
23120
23121 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
23122 self.write("?");
23123 if let Some(idx) = f.index {
23124 self.write(&idx.to_string());
23125 }
23126 Ok(())
23127 }
23128
23129 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
23130 if f.is_block {
23131 self.write("/*");
23132 self.write(&f.text);
23133 self.write("*/");
23134 } else {
23135 self.write("--");
23136 self.write(&f.text);
23137 }
23138 Ok(())
23139 }
23140
23141 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
23144 self.generate_expression(&f.this)?;
23145 if f.not {
23146 self.write_space();
23147 self.write_keyword("NOT");
23148 }
23149 self.write_space();
23150 self.write_keyword("SIMILAR TO");
23151 self.write_space();
23152 self.generate_expression(&f.pattern)?;
23153 if let Some(ref escape) = f.escape {
23154 self.write_space();
23155 self.write_keyword("ESCAPE");
23156 self.write_space();
23157 self.generate_expression(escape)?;
23158 }
23159 Ok(())
23160 }
23161
23162 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
23163 self.generate_expression(&f.this)?;
23164 self.write_space();
23165 if let Some(op) = &f.op {
23167 match op {
23168 QuantifiedOp::Eq => self.write("="),
23169 QuantifiedOp::Neq => self.write("<>"),
23170 QuantifiedOp::Lt => self.write("<"),
23171 QuantifiedOp::Lte => self.write("<="),
23172 QuantifiedOp::Gt => self.write(">"),
23173 QuantifiedOp::Gte => self.write(">="),
23174 }
23175 self.write_space();
23176 }
23177 self.write_keyword(name);
23178
23179 if matches!(&f.subquery, Expression::Subquery(_)) {
23181 self.write_space();
23182 self.generate_expression(&f.subquery)?;
23183 } else {
23184 let is_statement = matches!(
23185 &f.subquery,
23186 Expression::Select(_)
23187 | Expression::Union(_)
23188 | Expression::Intersect(_)
23189 | Expression::Except(_)
23190 );
23191 if is_statement
23192 && !self.config.quantified_no_paren_space
23193 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
23194 {
23195 self.write_space();
23196 }
23197 self.write("(");
23198
23199 if self.config.pretty && is_statement {
23200 self.write_newline();
23201 self.indent_level += 1;
23202 self.write_indent();
23203 }
23204 self.generate_expression(&f.subquery)?;
23205 if self.config.pretty && is_statement {
23206 self.write_newline();
23207 self.indent_level -= 1;
23208 self.write_indent();
23209 }
23210 self.write(")");
23211 }
23212 Ok(())
23213 }
23214
23215 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
23216 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
23218 self.generate_expression(this)?;
23219 self.write_space();
23220 self.write_keyword("OVERLAPS");
23221 self.write_space();
23222 self.generate_expression(expr)?;
23223 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
23224 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
23225 {
23226 self.write("(");
23228 self.generate_expression(ls)?;
23229 self.write(", ");
23230 self.generate_expression(le)?;
23231 self.write(")");
23232 self.write_space();
23233 self.write_keyword("OVERLAPS");
23234 self.write_space();
23235 self.write("(");
23236 self.generate_expression(rs)?;
23237 self.write(", ");
23238 self.generate_expression(re)?;
23239 self.write(")");
23240 }
23241 Ok(())
23242 }
23243
23244 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
23247 use crate::dialects::DialectType;
23248
23249 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
23251 self.generate_expression(&cast.this)?;
23252 self.write(" !:> ");
23253 self.generate_data_type(&cast.to)?;
23254 return Ok(());
23255 }
23256
23257 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
23259 self.write_keyword("TRYCAST");
23260 self.write("(");
23261 self.generate_expression(&cast.this)?;
23262 self.write_space();
23263 self.write_keyword("AS");
23264 self.write_space();
23265 self.generate_data_type(&cast.to)?;
23266 self.write(")");
23267 return Ok(());
23268 }
23269
23270 let keyword = if matches!(
23272 self.config.dialect,
23273 Some(DialectType::Hive)
23274 | Some(DialectType::MySQL)
23275 | Some(DialectType::SQLite)
23276 | Some(DialectType::Oracle)
23277 | Some(DialectType::ClickHouse)
23278 | Some(DialectType::Redshift)
23279 | Some(DialectType::PostgreSQL)
23280 | Some(DialectType::StarRocks)
23281 | Some(DialectType::Doris)
23282 ) {
23283 "CAST"
23284 } else {
23285 "TRY_CAST"
23286 };
23287
23288 self.write_keyword(keyword);
23289 self.write("(");
23290 self.generate_expression(&cast.this)?;
23291 self.write_space();
23292 self.write_keyword("AS");
23293 self.write_space();
23294 self.generate_data_type(&cast.to)?;
23295
23296 if let Some(format) = &cast.format {
23298 self.write_space();
23299 self.write_keyword("FORMAT");
23300 self.write_space();
23301 self.generate_expression(format)?;
23302 }
23303
23304 self.write(")");
23305 Ok(())
23306 }
23307
23308 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
23309 self.write_keyword("SAFE_CAST");
23310 self.write("(");
23311 self.generate_expression(&cast.this)?;
23312 self.write_space();
23313 self.write_keyword("AS");
23314 self.write_space();
23315 self.generate_data_type(&cast.to)?;
23316
23317 if let Some(format) = &cast.format {
23319 self.write_space();
23320 self.write_keyword("FORMAT");
23321 self.write_space();
23322 self.generate_expression(format)?;
23323 }
23324
23325 self.write(")");
23326 Ok(())
23327 }
23328
23329 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
23332 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
23336 if needs_parens {
23337 self.write("(");
23338 }
23339 self.generate_expression(&s.this)?;
23340 if needs_parens {
23341 self.write(")");
23342 }
23343 self.write("[");
23344 self.generate_expression(&s.index)?;
23345 self.write("]");
23346 Ok(())
23347 }
23348
23349 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
23350 self.generate_expression(&d.this)?;
23351 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
23354 && matches!(
23355 &d.this,
23356 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
23357 );
23358 if use_colon {
23359 self.write(":");
23360 } else {
23361 self.write(".");
23362 }
23363 self.generate_identifier(&d.field)
23364 }
23365
23366 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
23367 self.generate_expression(&m.this)?;
23368 self.write(".");
23369 if m.method.quoted {
23372 let q = self.config.identifier_quote;
23373 self.write(&format!("{}{}{}", q, m.method.name, q));
23374 } else {
23375 self.write(&m.method.name);
23376 }
23377 self.write("(");
23378 for (i, arg) in m.args.iter().enumerate() {
23379 if i > 0 {
23380 self.write(", ");
23381 }
23382 self.generate_expression(arg)?;
23383 }
23384 self.write(")");
23385 Ok(())
23386 }
23387
23388 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
23389 let needs_parens = matches!(
23392 &s.this,
23393 Expression::JsonExtract(f) if f.arrow_syntax
23394 ) || matches!(
23395 &s.this,
23396 Expression::JsonExtractScalar(f) if f.arrow_syntax
23397 );
23398
23399 if needs_parens {
23400 self.write("(");
23401 }
23402 self.generate_expression(&s.this)?;
23403 if needs_parens {
23404 self.write(")");
23405 }
23406 self.write("[");
23407 if let Some(start) = &s.start {
23408 self.generate_expression(start)?;
23409 }
23410 self.write(":");
23411 if let Some(end) = &s.end {
23412 self.generate_expression(end)?;
23413 }
23414 self.write("]");
23415 Ok(())
23416 }
23417
23418 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
23419 match &op.left {
23423 Expression::Column(col) => {
23424 if let Some(table) = &col.table {
23427 self.generate_identifier(table)?;
23428 self.write(".");
23429 }
23430 self.generate_identifier(&col.name)?;
23431 if col.join_mark && self.config.supports_column_join_marks {
23433 self.write(" (+)");
23434 }
23435 if op.left_comments.is_empty() {
23437 for comment in &col.trailing_comments {
23438 self.write_space();
23439 self.write_formatted_comment(comment);
23440 }
23441 }
23442 }
23443 Expression::Add(inner_op)
23444 | Expression::Sub(inner_op)
23445 | Expression::Mul(inner_op)
23446 | Expression::Div(inner_op)
23447 | Expression::Concat(inner_op) => {
23448 self.generate_binary_op_no_trailing(inner_op, match &op.left {
23450 Expression::Add(_) => "+",
23451 Expression::Sub(_) => "-",
23452 Expression::Mul(_) => "*",
23453 Expression::Div(_) => "/",
23454 Expression::Concat(_) => "||",
23455 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
23456 })?;
23457 }
23458 _ => {
23459 self.generate_expression(&op.left)?;
23460 }
23461 }
23462 for comment in &op.left_comments {
23464 self.write_space();
23465 self.write_formatted_comment(comment);
23466 }
23467 if self.config.pretty
23468 && matches!(self.config.dialect, Some(DialectType::Snowflake))
23469 && (operator == "AND" || operator == "OR")
23470 {
23471 self.write_newline();
23472 self.write_indent();
23473 self.write_keyword(operator);
23474 } else {
23475 self.write_space();
23476 if operator.chars().all(|c| c.is_alphabetic()) {
23477 self.write_keyword(operator);
23478 } else {
23479 self.write(operator);
23480 }
23481 }
23482 for comment in &op.operator_comments {
23484 self.write_space();
23485 self.write_formatted_comment(comment);
23486 }
23487 self.write_space();
23488 self.generate_expression(&op.right)?;
23489 for comment in &op.trailing_comments {
23491 self.write_space();
23492 self.write_formatted_comment(comment);
23493 }
23494 Ok(())
23495 }
23496
23497 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
23498 let keyword = connector.keyword();
23499 let Some(terms) = self.flatten_connector_terms(op, connector) else {
23500 return self.generate_binary_op(op, keyword);
23501 };
23502
23503 let wrap_clickhouse_or_term = |generator: &mut Self, term: &Expression| -> Result<()> {
23504 let should_wrap = matches!(connector, ConnectorOperator::Or)
23505 && matches!(generator.config.dialect, Some(DialectType::ClickHouse))
23506 && matches!(
23507 generator.config.source_dialect,
23508 Some(DialectType::ClickHouse)
23509 )
23510 && matches!(term, Expression::And(_));
23511 if should_wrap {
23512 generator.write("(");
23513 generator.generate_expression(term)?;
23514 generator.write(")");
23515 } else {
23516 generator.generate_expression(term)?;
23517 }
23518 Ok(())
23519 };
23520
23521 wrap_clickhouse_or_term(self, terms[0])?;
23522 for term in terms.iter().skip(1) {
23523 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
23524 self.write_newline();
23525 self.write_indent();
23526 self.write_keyword(keyword);
23527 } else {
23528 self.write_space();
23529 self.write_keyword(keyword);
23530 }
23531 self.write_space();
23532 wrap_clickhouse_or_term(self, term)?;
23533 }
23534
23535 Ok(())
23536 }
23537
23538 fn flatten_connector_terms<'a>(
23539 &self,
23540 root: &'a BinaryOp,
23541 connector: ConnectorOperator,
23542 ) -> Option<Vec<&'a Expression>> {
23543 if !root.left_comments.is_empty()
23544 || !root.operator_comments.is_empty()
23545 || !root.trailing_comments.is_empty()
23546 {
23547 return None;
23548 }
23549
23550 let mut terms = Vec::new();
23551 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
23552
23553 while let Some(expr) = stack.pop() {
23554 match (connector, expr) {
23555 (ConnectorOperator::And, Expression::And(inner))
23556 if inner.left_comments.is_empty()
23557 && inner.operator_comments.is_empty()
23558 && inner.trailing_comments.is_empty() =>
23559 {
23560 stack.push(&inner.right);
23561 stack.push(&inner.left);
23562 }
23563 (ConnectorOperator::Or, Expression::Or(inner))
23564 if inner.left_comments.is_empty()
23565 && inner.operator_comments.is_empty()
23566 && inner.trailing_comments.is_empty() =>
23567 {
23568 stack.push(&inner.right);
23569 stack.push(&inner.left);
23570 }
23571 _ => terms.push(expr),
23572 }
23573 }
23574
23575 if terms.len() > 1 {
23576 Some(terms)
23577 } else {
23578 None
23579 }
23580 }
23581
23582 fn missing_closing_parens_outside_quotes(sql: &str) -> usize {
23583 let mut depth = 0usize;
23584 let mut quote: Option<char> = None;
23585 let mut chars = sql.chars().peekable();
23586
23587 while let Some(ch) = chars.next() {
23588 if let Some(quote_char) = quote {
23589 if ch == '\\' {
23590 chars.next();
23591 } else if ch == quote_char {
23592 if quote_char == '\'' && chars.peek() == Some(&'\'') {
23593 chars.next();
23594 } else {
23595 quote = None;
23596 }
23597 }
23598 continue;
23599 }
23600
23601 match ch {
23602 '\'' | '"' | '`' => quote = Some(ch),
23603 '(' => depth += 1,
23604 ')' => depth = depth.saturating_sub(1),
23605 _ => {}
23606 }
23607 }
23608
23609 depth
23610 }
23611
23612 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
23614 self.generate_like_op_inner(op, operator, false)
23615 }
23616
23617 fn generate_like_op_negated(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
23618 self.generate_like_op_inner(op, operator, true)
23619 }
23620
23621 fn generate_like_op_inner(&mut self, op: &LikeOp, operator: &str, negated: bool) -> Result<()> {
23622 if negated
23623 && matches!(
23624 self.config.dialect,
23625 Some(DialectType::ClickHouse)
23626 | Some(DialectType::DataFusion)
23627 | Some(DialectType::TSQL)
23628 | Some(DialectType::Fabric)
23629 )
23630 {
23631 self.write_keyword("NOT");
23632 self.write_space();
23633 return self.generate_like_op_inner(op, operator, false);
23634 }
23635
23636 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23637 if let Expression::Star(star) = &op.left {
23638 if star
23639 .except
23640 .as_ref()
23641 .is_some_and(|except| !except.is_empty())
23642 {
23643 if let Some(table) = &star.table {
23644 self.generate_identifier(table)?;
23645 self.write(".");
23646 }
23647 self.write("*");
23648 self.write_space();
23649 self.write_keyword(operator);
23650 if let Some(quantifier) = &op.quantifier {
23651 self.write_space();
23652 self.write_keyword(quantifier);
23653 self.write_space();
23654 } else {
23655 self.write_space();
23656 }
23657 self.generate_expression(&op.right)?;
23658 if let Some(escape) = &op.escape {
23659 self.write_space();
23660 self.write_keyword("ESCAPE");
23661 self.write_space();
23662 self.generate_expression(escape)?;
23663 }
23664 if let Some(except) = &star.except {
23665 self.write_space();
23666 self.write_keyword("EXCEPT");
23667 self.write(" (");
23668 for (i, col) in except.iter().enumerate() {
23669 if i > 0 {
23670 self.write(", ");
23671 }
23672 self.generate_identifier(col)?;
23673 }
23674 self.write(")");
23675 }
23676 return Ok(());
23677 }
23678 }
23679 }
23680
23681 self.generate_expression(&op.left)?;
23682 self.write_space();
23683 if negated {
23684 self.write_keyword("NOT");
23685 self.write_space();
23686 }
23687 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
23689 self.write("`ILIKE`");
23690 } else {
23691 self.write_keyword(operator);
23692 }
23693 if let Some(quantifier) = &op.quantifier {
23694 self.write_space();
23695 self.write_keyword(quantifier);
23696 let is_any =
23701 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
23702 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
23703 self.write_space();
23704 }
23705 } else {
23706 self.write_space();
23707 }
23708 self.generate_expression(&op.right)?;
23709 if let Some(escape) = &op.escape {
23710 self.write_space();
23711 self.write_keyword("ESCAPE");
23712 self.write_space();
23713 self.generate_expression(escape)?;
23714 }
23715 Ok(())
23716 }
23717
23718 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
23721 use crate::dialects::DialectType;
23722 self.generate_expression(&op.left)?;
23723 self.write_space();
23724 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
23725 self.write("<=>");
23726 } else {
23727 self.write_keyword("IS NOT DISTINCT FROM");
23728 }
23729 self.write_space();
23730 self.generate_expression(&op.right)?;
23731 Ok(())
23732 }
23733
23734 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
23736 self.generate_expression(&op.left)?;
23737 self.write_space();
23738 self.write_keyword("IS DISTINCT FROM");
23739 self.write_space();
23740 self.generate_expression(&op.right)?;
23741 Ok(())
23742 }
23743
23744 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
23746 match &op.left {
23748 Expression::Column(col) => {
23749 if let Some(table) = &col.table {
23750 self.generate_identifier(table)?;
23751 self.write(".");
23752 }
23753 self.generate_identifier(&col.name)?;
23754 if col.join_mark && self.config.supports_column_join_marks {
23756 self.write(" (+)");
23757 }
23758 }
23759 Expression::Add(inner_op)
23760 | Expression::Sub(inner_op)
23761 | Expression::Mul(inner_op)
23762 | Expression::Div(inner_op)
23763 | Expression::Concat(inner_op) => {
23764 self.generate_binary_op_no_trailing(inner_op, match &op.left {
23765 Expression::Add(_) => "+",
23766 Expression::Sub(_) => "-",
23767 Expression::Mul(_) => "*",
23768 Expression::Div(_) => "/",
23769 Expression::Concat(_) => "||",
23770 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
23771 })?;
23772 }
23773 _ => {
23774 self.generate_expression(&op.left)?;
23775 }
23776 }
23777 for comment in &op.left_comments {
23779 self.write_space();
23780 self.write_formatted_comment(comment);
23781 }
23782 self.write_space();
23783 if operator.chars().all(|c| c.is_alphabetic()) {
23784 self.write_keyword(operator);
23785 } else {
23786 self.write(operator);
23787 }
23788 for comment in &op.operator_comments {
23790 self.write_space();
23791 self.write_formatted_comment(comment);
23792 }
23793 self.write_space();
23794 match &op.right {
23797 Expression::Column(col) => {
23798 if let Some(table) = &col.table {
23799 self.generate_identifier(table)?;
23800 self.write(".");
23801 }
23802 self.generate_identifier(&col.name)?;
23803 if col.join_mark && self.config.supports_column_join_marks {
23805 self.write(" (+)");
23806 }
23807 }
23808 _ => {
23809 self.generate_expression(&op.right)?;
23810 }
23811 }
23812 Ok(())
23814 }
23815
23816 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
23817 if operator.chars().all(|c| c.is_alphabetic()) {
23818 self.write_keyword(operator);
23819 self.write_space();
23820 } else {
23821 self.write(operator);
23822 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
23824 self.write_space();
23825 }
23826 }
23827 self.generate_expression(&op.this)
23828 }
23829
23830 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
23831 let is_generic =
23835 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
23836 let use_prefix_not =
23837 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
23838 if use_prefix_not {
23839 self.write_keyword("NOT");
23840 self.write_space();
23841 }
23842 self.generate_expression(&in_expr.this)?;
23843 if in_expr.global {
23844 self.write_space();
23845 self.write_keyword("GLOBAL");
23846 }
23847 if in_expr.not && !use_prefix_not {
23848 self.write_space();
23849 self.write_keyword("NOT");
23850 }
23851 self.write_space();
23852 self.write_keyword("IN");
23853
23854 if let Some(unnest_expr) = &in_expr.unnest {
23856 self.write_space();
23857 self.write_keyword("UNNEST");
23858 self.write("(");
23859 self.generate_expression(unnest_expr)?;
23860 self.write(")");
23861 return Ok(());
23862 }
23863
23864 if let Some(query) = &in_expr.query {
23865 let is_bare = in_expr.expressions.is_empty()
23868 && !matches!(
23869 query,
23870 Expression::Select(_)
23871 | Expression::Union(_)
23872 | Expression::Intersect(_)
23873 | Expression::Except(_)
23874 | Expression::Subquery(_)
23875 );
23876 if is_bare {
23877 self.write_space();
23879 self.generate_expression(query)?;
23880 } else {
23881 self.write(" (");
23883 let is_statement = matches!(
23884 query,
23885 Expression::Select(_)
23886 | Expression::Union(_)
23887 | Expression::Intersect(_)
23888 | Expression::Except(_)
23889 | Expression::Subquery(_)
23890 );
23891 if self.config.pretty && is_statement {
23892 self.write_newline();
23893 self.indent_level += 1;
23894 self.write_indent();
23895 }
23896 self.generate_expression(query)?;
23897 if self.config.pretty && is_statement {
23898 self.write_newline();
23899 self.indent_level -= 1;
23900 self.write_indent();
23901 }
23902 self.write(")");
23903 }
23904 } else {
23905 let is_duckdb = matches!(
23909 self.config.dialect,
23910 Some(crate::dialects::DialectType::DuckDB)
23911 );
23912 let is_clickhouse = matches!(
23913 self.config.dialect,
23914 Some(crate::dialects::DialectType::ClickHouse)
23915 );
23916 let single_expr = in_expr.expressions.len() == 1;
23917 if is_clickhouse && single_expr {
23918 if let Expression::Array(arr) = &in_expr.expressions[0] {
23919 self.write(" (");
23921 for (i, expr) in arr.expressions.iter().enumerate() {
23922 if i > 0 {
23923 self.write(", ");
23924 }
23925 self.generate_expression(expr)?;
23926 }
23927 self.write(")");
23928 } else if in_expr.is_field {
23929 self.write_space();
23930 self.generate_expression(&in_expr.expressions[0])?;
23931 } else {
23932 self.write(" (");
23933 self.generate_expression(&in_expr.expressions[0])?;
23934 self.write(")");
23935 }
23936 } else {
23937 let is_bare_ref = single_expr
23938 && matches!(
23939 &in_expr.expressions[0],
23940 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
23941 );
23942 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
23943 self.write_space();
23946 self.generate_expression(&in_expr.expressions[0])?;
23947 } else {
23948 self.write(" (");
23950 for (i, expr) in in_expr.expressions.iter().enumerate() {
23951 if i > 0 {
23952 self.write(", ");
23953 }
23954 self.generate_expression(expr)?;
23955 }
23956 self.write(")");
23957 }
23958 }
23959 }
23960
23961 Ok(())
23962 }
23963
23964 fn generate_between(&mut self, between: &Between) -> Result<()> {
23965 let use_prefix_not = between.not
23967 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
23968 if use_prefix_not {
23969 self.write_keyword("NOT");
23970 self.write_space();
23971 }
23972 self.generate_expression(&between.this)?;
23973 if between.not && !use_prefix_not {
23974 self.write_space();
23975 self.write_keyword("NOT");
23976 }
23977 self.write_space();
23978 self.write_keyword("BETWEEN");
23979 if let Some(sym) = between.symmetric {
23981 if sym {
23982 self.write(" SYMMETRIC");
23983 } else {
23984 self.write(" ASYMMETRIC");
23985 }
23986 }
23987 self.write_space();
23988 self.generate_expression(&between.low)?;
23989 self.write_space();
23990 self.write_keyword("AND");
23991 self.write_space();
23992 self.generate_expression(&between.high)
23993 }
23994
23995 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
23996 let use_prefix_not = is_null.not
23998 && (self.config.dialect.is_none()
23999 || self.config.dialect == Some(DialectType::Generic)
24000 || is_null.postfix_form);
24001 if use_prefix_not {
24002 self.write_keyword("NOT");
24004 self.write_space();
24005 self.generate_expression(&is_null.this)?;
24006 self.write_space();
24007 self.write_keyword("IS");
24008 self.write_space();
24009 self.write_keyword("NULL");
24010 } else {
24011 self.generate_expression(&is_null.this)?;
24012 self.write_space();
24013 self.write_keyword("IS");
24014 if is_null.not {
24015 self.write_space();
24016 self.write_keyword("NOT");
24017 }
24018 self.write_space();
24019 self.write_keyword("NULL");
24020 }
24021 Ok(())
24022 }
24023
24024 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
24025 self.generate_expression(&is_true.this)?;
24026 self.write_space();
24027 self.write_keyword("IS");
24028 if is_true.not {
24029 self.write_space();
24030 self.write_keyword("NOT");
24031 }
24032 self.write_space();
24033 self.write_keyword("TRUE");
24034 Ok(())
24035 }
24036
24037 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
24038 self.generate_expression(&is_false.this)?;
24039 self.write_space();
24040 self.write_keyword("IS");
24041 if is_false.not {
24042 self.write_space();
24043 self.write_keyword("NOT");
24044 }
24045 self.write_space();
24046 self.write_keyword("FALSE");
24047 Ok(())
24048 }
24049
24050 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
24051 self.generate_expression(&is_json.this)?;
24052 self.write_space();
24053 self.write_keyword("IS");
24054 if is_json.negated {
24055 self.write_space();
24056 self.write_keyword("NOT");
24057 }
24058 self.write_space();
24059 self.write_keyword("JSON");
24060
24061 if let Some(ref json_type) = is_json.json_type {
24063 self.write_space();
24064 self.write_keyword(json_type);
24065 }
24066
24067 match &is_json.unique_keys {
24069 Some(JsonUniqueKeys::With) => {
24070 self.write_space();
24071 self.write_keyword("WITH UNIQUE KEYS");
24072 }
24073 Some(JsonUniqueKeys::Without) => {
24074 self.write_space();
24075 self.write_keyword("WITHOUT UNIQUE KEYS");
24076 }
24077 Some(JsonUniqueKeys::Shorthand) => {
24078 self.write_space();
24079 self.write_keyword("UNIQUE KEYS");
24080 }
24081 None => {}
24082 }
24083
24084 Ok(())
24085 }
24086
24087 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
24088 self.generate_expression(&is_expr.left)?;
24089 self.write_space();
24090 self.write_keyword("IS");
24091 self.write_space();
24092 self.generate_expression(&is_expr.right)
24093 }
24094
24095 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
24096 if exists.not {
24097 self.write_keyword("NOT");
24098 self.write_space();
24099 }
24100 self.write_keyword("EXISTS");
24101 self.write("(");
24102 let is_statement = matches!(
24103 &exists.this,
24104 Expression::Select(_)
24105 | Expression::Union(_)
24106 | Expression::Intersect(_)
24107 | Expression::Except(_)
24108 );
24109 if self.config.pretty && is_statement {
24110 self.write_newline();
24111 self.indent_level += 1;
24112 self.write_indent();
24113 self.generate_expression(&exists.this)?;
24114 self.write_newline();
24115 self.indent_level -= 1;
24116 self.write_indent();
24117 self.write(")");
24118 } else {
24119 self.generate_expression(&exists.this)?;
24120 self.write(")");
24121 }
24122 Ok(())
24123 }
24124
24125 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
24126 self.generate_expression(&op.left)?;
24127 self.write_space();
24128 self.write_keyword("MEMBER OF");
24129 self.write("(");
24130 self.generate_expression(&op.right)?;
24131 self.write(")");
24132 Ok(())
24133 }
24134
24135 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
24136 if subquery.lateral {
24137 self.write_keyword("LATERAL");
24138 self.write_space();
24139 }
24140
24141 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
24145 matches!(
24146 &p.this,
24147 Expression::Select(_)
24148 | Expression::Union(_)
24149 | Expression::Intersect(_)
24150 | Expression::Except(_)
24151 | Expression::Subquery(_)
24152 )
24153 } else {
24154 false
24155 };
24156
24157 let is_statement = matches!(
24159 &subquery.this,
24160 Expression::Select(_)
24161 | Expression::Union(_)
24162 | Expression::Intersect(_)
24163 | Expression::Except(_)
24164 | Expression::Merge(_)
24165 );
24166
24167 if !skip_outer_parens {
24168 self.write("(");
24169 if self.config.pretty && is_statement {
24170 self.write_newline();
24171 self.indent_level += 1;
24172 self.write_indent();
24173 }
24174 }
24175 self.generate_expression(&subquery.this)?;
24176
24177 if subquery.modifiers_inside {
24179 if let Some(order_by) = &subquery.order_by {
24181 self.write_space();
24182 self.write_keyword("ORDER BY");
24183 self.write_space();
24184 for (i, ord) in order_by.expressions.iter().enumerate() {
24185 if i > 0 {
24186 self.write(", ");
24187 }
24188 self.generate_ordered(ord)?;
24189 }
24190 }
24191
24192 if let Some(limit) = &subquery.limit {
24193 self.write_space();
24194 self.write_keyword("LIMIT");
24195 self.write_space();
24196 self.generate_expression(&limit.this)?;
24197 if limit.percent {
24198 self.write_space();
24199 self.write_keyword("PERCENT");
24200 }
24201 }
24202
24203 if let Some(offset) = &subquery.offset {
24204 self.write_space();
24205 self.write_keyword("OFFSET");
24206 self.write_space();
24207 self.generate_expression(&offset.this)?;
24208 }
24209 }
24210
24211 if !skip_outer_parens {
24212 if self.config.pretty && is_statement {
24213 self.write_newline();
24214 self.indent_level -= 1;
24215 self.write_indent();
24216 }
24217 self.write(")");
24218 }
24219
24220 if !subquery.modifiers_inside {
24222 if let Some(order_by) = &subquery.order_by {
24223 self.write_space();
24224 self.write_keyword("ORDER BY");
24225 self.write_space();
24226 for (i, ord) in order_by.expressions.iter().enumerate() {
24227 if i > 0 {
24228 self.write(", ");
24229 }
24230 self.generate_ordered(ord)?;
24231 }
24232 }
24233
24234 if let Some(limit) = &subquery.limit {
24235 self.write_space();
24236 self.write_keyword("LIMIT");
24237 self.write_space();
24238 self.generate_expression(&limit.this)?;
24239 if limit.percent {
24240 self.write_space();
24241 self.write_keyword("PERCENT");
24242 }
24243 }
24244
24245 if let Some(offset) = &subquery.offset {
24246 self.write_space();
24247 self.write_keyword("OFFSET");
24248 self.write_space();
24249 self.generate_expression(&offset.this)?;
24250 }
24251
24252 if let Some(distribute_by) = &subquery.distribute_by {
24254 self.write_space();
24255 self.write_keyword("DISTRIBUTE BY");
24256 self.write_space();
24257 for (i, expr) in distribute_by.expressions.iter().enumerate() {
24258 if i > 0 {
24259 self.write(", ");
24260 }
24261 self.generate_expression(expr)?;
24262 }
24263 }
24264
24265 if let Some(sort_by) = &subquery.sort_by {
24267 self.write_space();
24268 self.write_keyword("SORT BY");
24269 self.write_space();
24270 for (i, ord) in sort_by.expressions.iter().enumerate() {
24271 if i > 0 {
24272 self.write(", ");
24273 }
24274 self.generate_ordered(ord)?;
24275 }
24276 }
24277
24278 if let Some(cluster_by) = &subquery.cluster_by {
24280 self.write_space();
24281 self.write_keyword("CLUSTER BY");
24282 self.write_space();
24283 for (i, ord) in cluster_by.expressions.iter().enumerate() {
24284 if i > 0 {
24285 self.write(", ");
24286 }
24287 self.generate_ordered(ord)?;
24288 }
24289 }
24290 }
24291
24292 if let Some(alias) = &subquery.alias {
24293 self.write_space();
24294 let skip_as = matches!(self.config.dialect, Some(DialectType::Oracle))
24295 || (matches!(self.config.dialect, Some(DialectType::ClickHouse))
24296 && !subquery.alias_explicit_as);
24297 if !skip_as {
24298 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24299 self.write(subquery.alias_keyword.as_deref().unwrap_or("AS"));
24300 } else {
24301 self.write_keyword("AS");
24302 }
24303 self.write_space();
24304 }
24305 self.generate_identifier(alias)?;
24306 if !subquery.column_aliases.is_empty() {
24307 self.write("(");
24308 for (i, col) in subquery.column_aliases.iter().enumerate() {
24309 if i > 0 {
24310 self.write(", ");
24311 }
24312 self.generate_identifier(col)?;
24313 }
24314 self.write(")");
24315 }
24316 }
24317 for comment in &subquery.trailing_comments {
24319 self.write(" ");
24320 self.write_formatted_comment(comment);
24321 }
24322 Ok(())
24323 }
24324
24325 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
24326 if let Some(ref with) = pivot.with {
24328 self.generate_with(with)?;
24329 self.write_space();
24330 }
24331
24332 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
24333
24334 let is_redshift_unpivot = pivot.unpivot
24338 && pivot.expressions.is_empty()
24339 && pivot.fields.is_empty()
24340 && pivot.using.is_empty()
24341 && pivot.into.is_none()
24342 && !matches!(&pivot.this, Expression::Null(_));
24343
24344 if is_redshift_unpivot {
24345 self.write_keyword("UNPIVOT");
24347 self.write_space();
24348 self.generate_expression(&pivot.this)?;
24349 if let Some(alias) = &pivot.alias {
24351 self.write_space();
24352 self.write_keyword("AS");
24353 self.write_space();
24354 self.write(&alias.name);
24356 }
24357 return Ok(());
24358 }
24359
24360 let is_simplified = !pivot.using.is_empty()
24362 || pivot.into.is_some()
24363 || (pivot.fields.is_empty()
24364 && !pivot.expressions.is_empty()
24365 && !matches!(&pivot.this, Expression::Null(_)));
24366
24367 if is_simplified {
24368 self.write_keyword(direction);
24372 self.write_space();
24373 self.generate_expression(&pivot.this)?;
24374
24375 if !pivot.expressions.is_empty() {
24376 self.write_space();
24377 self.write_keyword("ON");
24378 self.write_space();
24379 for (i, expr) in pivot.expressions.iter().enumerate() {
24380 if i > 0 {
24381 self.write(", ");
24382 }
24383 self.generate_expression(expr)?;
24384 }
24385 }
24386
24387 if let Some(into) = &pivot.into {
24389 self.write_space();
24390 self.write_keyword("INTO");
24391 self.write_space();
24392 self.generate_expression(into)?;
24393 }
24394
24395 if !pivot.using.is_empty() {
24397 self.write_space();
24398 self.write_keyword("USING");
24399 self.write_space();
24400 for (i, expr) in pivot.using.iter().enumerate() {
24401 if i > 0 {
24402 self.write(", ");
24403 }
24404 self.generate_expression(expr)?;
24405 }
24406 }
24407
24408 if let Some(group) = &pivot.group {
24410 self.write_space();
24411 self.generate_expression(group)?;
24412 }
24413 } else {
24414 if !matches!(&pivot.this, Expression::Null(_)) {
24419 self.generate_expression(&pivot.this)?;
24420 self.write_space();
24421 }
24422 self.write_keyword(direction);
24423 self.write("(");
24424
24425 for (i, expr) in pivot.expressions.iter().enumerate() {
24427 if i > 0 {
24428 self.write(", ");
24429 }
24430 self.generate_expression(expr)?;
24431 }
24432
24433 if !pivot.fields.is_empty() {
24435 if !pivot.expressions.is_empty() {
24436 self.write_space();
24437 }
24438 self.write_keyword("FOR");
24439 self.write_space();
24440 for (i, field) in pivot.fields.iter().enumerate() {
24441 if i > 0 {
24442 self.write_space();
24443 }
24444 self.generate_expression(field)?;
24446 }
24447 }
24448
24449 if let Some(default_val) = &pivot.default_on_null {
24451 self.write_space();
24452 self.write_keyword("DEFAULT ON NULL");
24453 self.write(" (");
24454 self.generate_expression(default_val)?;
24455 self.write(")");
24456 }
24457
24458 if let Some(group) = &pivot.group {
24460 self.write_space();
24461 self.generate_expression(group)?;
24462 }
24463
24464 self.write(")");
24465 }
24466
24467 if let Some(alias) = &pivot.alias {
24469 self.write_space();
24470 self.write_keyword("AS");
24471 self.write_space();
24472 self.generate_identifier(alias)?;
24473 self.generate_alias_column_list(&pivot.alias_columns)?;
24474 }
24475
24476 Ok(())
24477 }
24478
24479 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
24480 self.generate_expression(&unpivot.this)?;
24481 self.write_space();
24482 self.write_keyword("UNPIVOT");
24483 if let Some(include) = unpivot.include_nulls {
24485 self.write_space();
24486 if include {
24487 self.write_keyword("INCLUDE NULLS");
24488 } else {
24489 self.write_keyword("EXCLUDE NULLS");
24490 }
24491 self.write_space();
24492 }
24493 self.write("(");
24494 if unpivot.value_column_parenthesized {
24495 self.write("(");
24496 }
24497 self.generate_identifier(&unpivot.value_column)?;
24498 for extra_col in &unpivot.extra_value_columns {
24500 self.write(", ");
24501 self.generate_identifier(extra_col)?;
24502 }
24503 if unpivot.value_column_parenthesized {
24504 self.write(")");
24505 }
24506 self.write_space();
24507 self.write_keyword("FOR");
24508 self.write_space();
24509 self.generate_identifier(&unpivot.name_column)?;
24510 self.write_space();
24511 self.write_keyword("IN");
24512 self.write(" (");
24513 for (i, col) in unpivot.columns.iter().enumerate() {
24514 if i > 0 {
24515 self.write(", ");
24516 }
24517 self.generate_expression(col)?;
24518 }
24519 self.write("))");
24520 if let Some(alias) = &unpivot.alias {
24521 self.write_space();
24522 self.write_keyword("AS");
24523 self.write_space();
24524 self.generate_identifier(alias)?;
24525 self.generate_alias_column_list(&unpivot.alias_columns)?;
24526 }
24527 Ok(())
24528 }
24529
24530 fn generate_alias_column_list(&mut self, columns: &[Identifier]) -> Result<()> {
24531 if columns.is_empty() {
24532 return Ok(());
24533 }
24534
24535 self.write("(");
24536 for (i, column) in columns.iter().enumerate() {
24537 if i > 0 {
24538 self.write(", ");
24539 }
24540 self.generate_identifier(column)?;
24541 }
24542 self.write(")");
24543 Ok(())
24544 }
24545
24546 fn generate_values(&mut self, values: &Values) -> Result<()> {
24547 self.write_keyword("VALUES");
24548 for (i, row) in values.expressions.iter().enumerate() {
24549 if i > 0 {
24550 self.write(",");
24551 }
24552 self.write(" (");
24553 for (j, expr) in row.expressions.iter().enumerate() {
24554 if j > 0 {
24555 self.write(", ");
24556 }
24557 self.generate_expression(expr)?;
24558 }
24559 self.write(")");
24560 }
24561 if let Some(alias) = &values.alias {
24562 self.write_space();
24563 self.write_keyword("AS");
24564 self.write_space();
24565 self.generate_identifier(alias)?;
24566 if !values.column_aliases.is_empty() {
24567 self.write("(");
24568 for (i, col) in values.column_aliases.iter().enumerate() {
24569 if i > 0 {
24570 self.write(", ");
24571 }
24572 self.generate_identifier(col)?;
24573 }
24574 self.write(")");
24575 }
24576 }
24577 Ok(())
24578 }
24579
24580 fn generate_array(&mut self, arr: &Array) -> Result<()> {
24581 let needs_inheritance = matches!(
24583 self.config.dialect,
24584 Some(DialectType::DuckDB)
24585 | Some(DialectType::Spark)
24586 | Some(DialectType::Databricks)
24587 | Some(DialectType::Hive)
24588 | Some(DialectType::Snowflake)
24589 | Some(DialectType::Presto)
24590 | Some(DialectType::Trino)
24591 );
24592 let propagated: Vec<Expression>;
24593 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
24594 propagated = Self::inherit_struct_field_names(&arr.expressions);
24595 &propagated
24596 } else {
24597 &arr.expressions
24598 };
24599
24600 let use_parens =
24603 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
24604 if !self.config.array_bracket_only {
24605 self.write_keyword("ARRAY");
24606 }
24607 if use_parens {
24608 self.write("(");
24609 } else {
24610 self.write("[");
24611 }
24612 for (i, expr) in expressions.iter().enumerate() {
24613 if i > 0 {
24614 self.write(", ");
24615 }
24616 self.generate_expression(expr)?;
24617 }
24618 if use_parens {
24619 self.write(")");
24620 } else {
24621 self.write("]");
24622 }
24623 Ok(())
24624 }
24625
24626 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
24627 if tuple.expressions.len() == 2 {
24630 if let Expression::TableAlias(_) = &tuple.expressions[1] {
24631 self.generate_expression(&tuple.expressions[0])?;
24633 self.write_space();
24634 self.write_keyword("AS");
24635 self.write_space();
24636 self.generate_expression(&tuple.expressions[1])?;
24637 return Ok(());
24638 }
24639 }
24640
24641 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
24644 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
24645 for expr in &tuple.expressions {
24646 expr_strings.push(self.generate_to_string(expr)?);
24647 }
24648 self.too_wide(&expr_strings)
24649 } else {
24650 false
24651 };
24652
24653 if expand_tuple {
24654 self.write("(");
24655 self.write_newline();
24656 self.indent_level += 1;
24657 for (i, expr) in tuple.expressions.iter().enumerate() {
24658 if i > 0 {
24659 self.write(",");
24660 self.write_newline();
24661 }
24662 self.write_indent();
24663 self.generate_expression(expr)?;
24664 }
24665 self.indent_level -= 1;
24666 self.write_newline();
24667 self.write_indent();
24668 self.write(")");
24669 } else {
24670 self.write("(");
24671 for (i, expr) in tuple.expressions.iter().enumerate() {
24672 if i > 0 {
24673 self.write(", ");
24674 }
24675 self.generate_expression(expr)?;
24676 }
24677 self.write(")");
24678 }
24679 Ok(())
24680 }
24681
24682 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
24683 self.generate_expression(&pipe.this)?;
24684 self.write(" |> ");
24685 self.generate_expression(&pipe.expression)?;
24686 Ok(())
24687 }
24688
24689 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
24690 let unsupported_tsql_null_ordering = ordered.nulls_first.is_some()
24691 && !self.config.null_ordering_supported
24692 && matches!(
24693 self.config.dialect,
24694 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24695 );
24696 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
24697 let emulate_tsql_null_ordering = if let Some(nulls_first) = ordered.nulls_first {
24698 let target_default_nulls_first = !ordered.desc;
24699
24700 unsupported_tsql_null_ordering
24701 && nulls_first != target_default_nulls_first
24702 && !random_ordering
24703 } else {
24704 false
24705 };
24706
24707 if emulate_tsql_null_ordering {
24708 if Self::is_integer_ordering_literal(&ordered.this) {
24709 let nulls_order = if ordered.nulls_first == Some(true) {
24710 "NULLS FIRST"
24711 } else {
24712 "NULLS LAST"
24713 };
24714 self.unsupported(format!(
24715 "'{nulls_order}' translation not supported with positional ordering"
24716 ))?;
24717 } else {
24718 self.write_keyword("CASE WHEN");
24719 self.write_space();
24720 self.generate_expression(&ordered.this)?;
24721 self.write_space();
24722 self.write_keyword("IS NULL THEN 1 ELSE 0 END");
24723 if ordered.nulls_first == Some(true) {
24724 self.write_space();
24725 self.write_keyword("DESC");
24726 }
24727 self.write(", ");
24728 }
24729 }
24730
24731 self.generate_expression(&ordered.this)?;
24732 if ordered.desc {
24733 self.write_space();
24734 self.write_keyword("DESC");
24735 } else if ordered.explicit_asc {
24736 self.write_space();
24737 self.write_keyword("ASC");
24738 }
24739 if let Some(nulls_first) = ordered.nulls_first {
24740 if !unsupported_tsql_null_ordering
24741 && (self.config.null_ordering_supported
24742 || !matches!(self.config.dialect, Some(DialectType::Fabric)))
24743 {
24744 let is_asc = !ordered.desc;
24758 let is_nulls_are_large = matches!(
24759 self.config.dialect,
24760 Some(DialectType::Oracle)
24761 | Some(DialectType::PostgreSQL)
24762 | Some(DialectType::Redshift)
24763 | Some(DialectType::Snowflake)
24764 );
24765 let is_nulls_are_last = matches!(
24766 self.config.dialect,
24767 Some(DialectType::Dremio)
24768 | Some(DialectType::DuckDB)
24769 | Some(DialectType::Presto)
24770 | Some(DialectType::Trino)
24771 | Some(DialectType::Athena)
24772 | Some(DialectType::ClickHouse)
24773 | Some(DialectType::Drill)
24774 | Some(DialectType::Exasol)
24775 );
24776
24777 let is_default_nulls = if is_nulls_are_large {
24779 (is_asc && !nulls_first) || (!is_asc && nulls_first)
24781 } else if is_nulls_are_last {
24782 !nulls_first
24784 } else {
24785 false
24786 };
24787
24788 if !is_default_nulls {
24789 self.write_space();
24790 self.write_keyword("NULLS");
24791 self.write_space();
24792 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
24793 }
24794 }
24795 }
24796 if let Some(ref with_fill) = ordered.with_fill {
24798 self.write_space();
24799 self.generate_with_fill(with_fill)?;
24800 }
24801 Ok(())
24802 }
24803
24804 fn is_integer_ordering_literal(expr: &Expression) -> bool {
24805 matches!(
24806 expr,
24807 Expression::Literal(lit)
24808 if matches!(lit.as_ref(), Literal::Number(n) if n.parse::<u64>().is_ok())
24809 )
24810 }
24811
24812 fn write_clickhouse_type(&mut self, type_str: &str) {
24814 if self.clickhouse_nullable_depth < 0 {
24815 self.write(type_str);
24817 } else {
24818 self.write(&format!("Nullable({})", type_str));
24819 }
24820 }
24821
24822 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
24823 use crate::dialects::DialectType;
24824
24825 match dt {
24826 DataType::Boolean => {
24827 match self.config.dialect {
24829 Some(DialectType::TSQL) => self.write_keyword("BIT"),
24830 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
24832 self.write_keyword("NUMBER(1)")
24834 }
24835 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
24837 }
24838 }
24839 DataType::TinyInt { length } => {
24840 match self.config.dialect {
24844 Some(DialectType::PostgreSQL)
24845 | Some(DialectType::Redshift)
24846 | Some(DialectType::Oracle)
24847 | Some(DialectType::Exasol) => {
24848 self.write_keyword("SMALLINT");
24849 }
24850 Some(DialectType::Teradata) => {
24851 self.write_keyword("BYTEINT");
24853 }
24854 Some(DialectType::Dremio) => {
24855 self.write_keyword("INT");
24857 }
24858 Some(DialectType::ClickHouse) => {
24859 self.write_clickhouse_type("Int8");
24860 }
24861 _ => {
24862 self.write_keyword("TINYINT");
24863 }
24864 }
24865 if let Some(n) = length {
24866 if !matches!(
24867 self.config.dialect,
24868 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
24869 ) {
24870 self.write(&format!("({})", n));
24871 }
24872 }
24873 }
24874 DataType::SmallInt { length } => {
24875 match self.config.dialect {
24877 Some(DialectType::Dremio) => {
24878 self.write_keyword("INT");
24879 }
24880 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
24881 self.write_keyword("INTEGER");
24882 }
24883 Some(DialectType::BigQuery) => {
24884 self.write_keyword("INT64");
24885 }
24886 Some(DialectType::ClickHouse) => {
24887 self.write_clickhouse_type("Int16");
24888 }
24889 _ => {
24890 self.write_keyword("SMALLINT");
24891 if let Some(n) = length {
24892 self.write(&format!("({})", n));
24893 }
24894 }
24895 }
24896 }
24897 DataType::Int {
24898 length,
24899 integer_spelling: _,
24900 } => {
24901 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
24903 self.write_keyword("INT64");
24904 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24905 self.write_clickhouse_type("Int32");
24906 } else {
24907 let use_integer = match self.config.dialect {
24909 Some(DialectType::TSQL)
24910 | Some(DialectType::Fabric)
24911 | Some(DialectType::Presto)
24912 | Some(DialectType::Trino)
24913 | Some(DialectType::SQLite)
24914 | Some(DialectType::Redshift) => true,
24915 _ => false,
24916 };
24917 if use_integer {
24918 self.write_keyword("INTEGER");
24919 } else {
24920 self.write_keyword("INT");
24921 }
24922 if let Some(n) = length {
24923 self.write(&format!("({})", n));
24924 }
24925 }
24926 }
24927 DataType::BigInt { length } => {
24928 match self.config.dialect {
24930 Some(DialectType::Oracle) => {
24931 self.write_keyword("INT");
24933 }
24934 Some(DialectType::ClickHouse) => {
24935 self.write_clickhouse_type("Int64");
24936 }
24937 _ => {
24938 self.write_keyword("BIGINT");
24939 if let Some(n) = length {
24940 self.write(&format!("({})", n));
24941 }
24942 }
24943 }
24944 }
24945 DataType::Float {
24946 precision,
24947 scale,
24948 real_spelling,
24949 } => {
24950 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24954 self.write_clickhouse_type("Float32");
24955 } else if *real_spelling
24956 && !matches!(
24957 self.config.dialect,
24958 Some(DialectType::Spark)
24959 | Some(DialectType::Databricks)
24960 | Some(DialectType::Hive)
24961 | Some(DialectType::Snowflake)
24962 | Some(DialectType::MySQL)
24963 | Some(DialectType::BigQuery)
24964 )
24965 {
24966 self.write_keyword("REAL")
24967 } else {
24968 match self.config.dialect {
24969 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
24970 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
24971 _ => self.write_keyword("FLOAT"),
24972 }
24973 }
24974 if !matches!(
24977 self.config.dialect,
24978 Some(DialectType::Spark)
24979 | Some(DialectType::Databricks)
24980 | Some(DialectType::Hive)
24981 | Some(DialectType::Presto)
24982 | Some(DialectType::Trino)
24983 ) {
24984 if let Some(p) = precision {
24985 self.write(&format!("({}", p));
24986 if let Some(s) = scale {
24987 self.write(&format!(", {})", s));
24988 } else {
24989 self.write(")");
24990 }
24991 }
24992 }
24993 }
24994 DataType::Double { precision, scale } => {
24995 match self.config.dialect {
24997 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24998 self.write_keyword("FLOAT")
24999 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
25001 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
25002 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
25003 Some(DialectType::SQLite) => self.write_keyword("REAL"),
25004 Some(DialectType::PostgreSQL)
25005 | Some(DialectType::Redshift)
25006 | Some(DialectType::Teradata)
25007 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
25008 _ => self.write_keyword("DOUBLE"),
25009 }
25010 if let Some(p) = precision {
25012 self.write(&format!("({}", p));
25013 if let Some(s) = scale {
25014 self.write(&format!(", {})", s));
25015 } else {
25016 self.write(")");
25017 }
25018 }
25019 }
25020 DataType::Decimal { precision, scale } => {
25021 match self.config.dialect {
25023 Some(DialectType::ClickHouse) => {
25024 self.write("Decimal");
25025 if let Some(p) = precision {
25026 self.write(&format!("({}", p));
25027 if let Some(s) = scale {
25028 self.write(&format!(", {}", s));
25029 }
25030 self.write(")");
25031 }
25032 }
25033 Some(DialectType::Oracle) => {
25034 self.write_keyword("NUMBER");
25036 if let Some(p) = precision {
25037 self.write(&format!("({}", p));
25038 if let Some(s) = scale {
25039 self.write(&format!(", {}", s));
25040 }
25041 self.write(")");
25042 }
25043 }
25044 Some(DialectType::BigQuery) => {
25045 self.write_keyword("NUMERIC");
25047 if let Some(p) = precision {
25048 self.write(&format!("({}", p));
25049 if let Some(s) = scale {
25050 self.write(&format!(", {}", s));
25051 }
25052 self.write(")");
25053 }
25054 }
25055 _ => {
25056 self.write_keyword("DECIMAL");
25057 if let Some(p) = precision {
25058 self.write(&format!("({}", p));
25059 if let Some(s) = scale {
25060 self.write(&format!(", {}", s));
25061 }
25062 self.write(")");
25063 }
25064 }
25065 }
25066 }
25067 DataType::Char { length } => {
25068 match self.config.dialect {
25070 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25071 self.write_keyword("TEXT");
25073 }
25074 Some(DialectType::Hive)
25075 | Some(DialectType::Spark)
25076 | Some(DialectType::Databricks) => {
25077 if length.is_some()
25080 && !matches!(self.config.dialect, Some(DialectType::Hive))
25081 {
25082 self.write_keyword("CHAR");
25083 if let Some(n) = length {
25084 self.write(&format!("({})", n));
25085 }
25086 } else {
25087 self.write_keyword("STRING");
25088 }
25089 }
25090 Some(DialectType::Dremio) => {
25091 self.write_keyword("VARCHAR");
25093 if let Some(n) = length {
25094 self.write(&format!("({})", n));
25095 }
25096 }
25097 _ => {
25098 self.write_keyword("CHAR");
25099 if let Some(n) = length {
25100 self.write(&format!("({})", n));
25101 }
25102 }
25103 }
25104 }
25105 DataType::VarChar {
25106 length,
25107 parenthesized_length,
25108 } => {
25109 match self.config.dialect {
25111 Some(DialectType::Oracle) => {
25112 self.write_keyword("VARCHAR2");
25113 if let Some(n) = length {
25114 self.write(&format!("({})", n));
25115 }
25116 }
25117 Some(DialectType::DuckDB) => {
25118 self.write_keyword("TEXT");
25120 if let Some(n) = length {
25121 self.write(&format!("({})", n));
25122 }
25123 }
25124 Some(DialectType::SQLite) => {
25125 self.write_keyword("TEXT");
25127 if let Some(n) = length {
25128 self.write(&format!("({})", n));
25129 }
25130 }
25131 Some(DialectType::MySQL) if length.is_none() => {
25132 self.write_keyword("TEXT");
25134 }
25135 Some(DialectType::Hive)
25136 | Some(DialectType::Spark)
25137 | Some(DialectType::Databricks)
25138 if length.is_none() =>
25139 {
25140 self.write_keyword("STRING");
25142 }
25143 _ => {
25144 self.write_keyword("VARCHAR");
25145 if let Some(n) = length {
25146 if *parenthesized_length {
25148 self.write(&format!("(({}))", n));
25149 } else {
25150 self.write(&format!("({})", n));
25151 }
25152 }
25153 }
25154 }
25155 }
25156 DataType::Text => {
25157 match self.config.dialect {
25159 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
25160 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25161 self.write_keyword("VARCHAR(MAX)")
25162 }
25163 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
25164 Some(DialectType::Snowflake)
25165 | Some(DialectType::Dremio)
25166 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
25167 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
25168 Some(DialectType::Presto)
25169 | Some(DialectType::Trino)
25170 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
25171 Some(DialectType::Spark)
25172 | Some(DialectType::Databricks)
25173 | Some(DialectType::Hive) => self.write_keyword("STRING"),
25174 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
25175 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
25176 self.write_keyword("STRING")
25177 }
25178 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
25179 _ => self.write_keyword("TEXT"),
25180 }
25181 }
25182 DataType::TextWithLength { length } => {
25183 match self.config.dialect {
25185 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
25186 Some(DialectType::Hive)
25187 | Some(DialectType::Spark)
25188 | Some(DialectType::Databricks) => {
25189 self.write(&format!("VARCHAR({})", length));
25190 }
25191 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
25192 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
25193 Some(DialectType::Snowflake)
25194 | Some(DialectType::Presto)
25195 | Some(DialectType::Trino)
25196 | Some(DialectType::Athena)
25197 | Some(DialectType::Drill)
25198 | Some(DialectType::Dremio) => {
25199 self.write(&format!("VARCHAR({})", length));
25200 }
25201 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25202 self.write(&format!("VARCHAR({})", length))
25203 }
25204 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
25205 self.write(&format!("STRING({})", length))
25206 }
25207 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
25208 _ => self.write(&format!("TEXT({})", length)),
25209 }
25210 }
25211 DataType::String { length } => {
25212 match self.config.dialect {
25214 Some(DialectType::ClickHouse) => {
25215 self.write("String");
25217 if let Some(n) = length {
25218 self.write(&format!("({})", n));
25219 }
25220 }
25221 Some(DialectType::BigQuery)
25222 | Some(DialectType::Hive)
25223 | Some(DialectType::Spark)
25224 | Some(DialectType::Databricks)
25225 | Some(DialectType::StarRocks)
25226 | Some(DialectType::Doris) => {
25227 self.write_keyword("STRING");
25228 if let Some(n) = length {
25229 self.write(&format!("({})", n));
25230 }
25231 }
25232 Some(DialectType::PostgreSQL) => {
25233 if let Some(n) = length {
25235 self.write_keyword("VARCHAR");
25236 self.write(&format!("({})", n));
25237 } else {
25238 self.write_keyword("TEXT");
25239 }
25240 }
25241 Some(DialectType::Redshift) => {
25242 if let Some(n) = length {
25244 self.write_keyword("VARCHAR");
25245 self.write(&format!("({})", n));
25246 } else {
25247 self.write_keyword("VARCHAR(MAX)");
25248 }
25249 }
25250 Some(DialectType::MySQL) => {
25251 if let Some(n) = length {
25253 self.write_keyword("VARCHAR");
25254 self.write(&format!("({})", n));
25255 } else {
25256 self.write_keyword("TEXT");
25257 }
25258 }
25259 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25260 if let Some(n) = length {
25262 self.write_keyword("VARCHAR");
25263 self.write(&format!("({})", n));
25264 } else {
25265 self.write_keyword("VARCHAR(MAX)");
25266 }
25267 }
25268 Some(DialectType::Oracle) => {
25269 self.write_keyword("CLOB");
25271 }
25272 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
25273 self.write_keyword("TEXT");
25275 if let Some(n) = length {
25276 self.write(&format!("({})", n));
25277 }
25278 }
25279 Some(DialectType::Presto)
25280 | Some(DialectType::Trino)
25281 | Some(DialectType::Drill)
25282 | Some(DialectType::Dremio) => {
25283 self.write_keyword("VARCHAR");
25285 if let Some(n) = length {
25286 self.write(&format!("({})", n));
25287 }
25288 }
25289 Some(DialectType::Snowflake) => {
25290 self.write_keyword("STRING");
25293 if let Some(n) = length {
25294 self.write(&format!("({})", n));
25295 }
25296 }
25297 _ => {
25298 self.write_keyword("STRING");
25300 if let Some(n) = length {
25301 self.write(&format!("({})", n));
25302 }
25303 }
25304 }
25305 }
25306 DataType::Binary { length } => {
25307 match self.config.dialect {
25309 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25310 self.write_keyword("BYTEA");
25311 if let Some(n) = length {
25312 self.write(&format!("({})", n));
25313 }
25314 }
25315 Some(DialectType::Redshift) => {
25316 self.write_keyword("VARBYTE");
25317 if let Some(n) = length {
25318 self.write(&format!("({})", n));
25319 }
25320 }
25321 Some(DialectType::DuckDB)
25322 | Some(DialectType::SQLite)
25323 | Some(DialectType::Oracle) => {
25324 self.write_keyword("BLOB");
25326 if let Some(n) = length {
25327 self.write(&format!("({})", n));
25328 }
25329 }
25330 Some(DialectType::Presto)
25331 | Some(DialectType::Trino)
25332 | Some(DialectType::Athena)
25333 | Some(DialectType::Drill)
25334 | Some(DialectType::Dremio) => {
25335 self.write_keyword("VARBINARY");
25337 if let Some(n) = length {
25338 self.write(&format!("({})", n));
25339 }
25340 }
25341 Some(DialectType::ClickHouse) => {
25342 if self.clickhouse_nullable_depth < 0 {
25344 self.write("BINARY");
25345 } else {
25346 self.write("Nullable(BINARY");
25347 }
25348 if let Some(n) = length {
25349 self.write(&format!("({})", n));
25350 }
25351 if self.clickhouse_nullable_depth >= 0 {
25352 self.write(")");
25353 }
25354 }
25355 _ => {
25356 self.write_keyword("BINARY");
25357 if let Some(n) = length {
25358 self.write(&format!("({})", n));
25359 }
25360 }
25361 }
25362 }
25363 DataType::VarBinary { length } => {
25364 match self.config.dialect {
25366 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25367 self.write_keyword("BYTEA");
25368 if let Some(n) = length {
25369 self.write(&format!("({})", n));
25370 }
25371 }
25372 Some(DialectType::Redshift) => {
25373 self.write_keyword("VARBYTE");
25374 if let Some(n) = length {
25375 self.write(&format!("({})", n));
25376 }
25377 }
25378 Some(DialectType::DuckDB)
25379 | Some(DialectType::SQLite)
25380 | Some(DialectType::Oracle) => {
25381 self.write_keyword("BLOB");
25383 if let Some(n) = length {
25384 self.write(&format!("({})", n));
25385 }
25386 }
25387 Some(DialectType::Exasol) => {
25388 self.write_keyword("VARCHAR");
25390 }
25391 Some(DialectType::Spark)
25392 | Some(DialectType::Hive)
25393 | Some(DialectType::Databricks) => {
25394 self.write_keyword("BINARY");
25396 if let Some(n) = length {
25397 self.write(&format!("({})", n));
25398 }
25399 }
25400 Some(DialectType::ClickHouse) => {
25401 self.write_clickhouse_type("String");
25403 }
25404 _ => {
25405 self.write_keyword("VARBINARY");
25406 if let Some(n) = length {
25407 self.write(&format!("({})", n));
25408 }
25409 }
25410 }
25411 }
25412 DataType::Blob => {
25413 match self.config.dialect {
25415 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
25416 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
25417 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25418 self.write_keyword("VARBINARY")
25419 }
25420 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
25421 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
25422 Some(DialectType::Presto)
25423 | Some(DialectType::Trino)
25424 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
25425 Some(DialectType::DuckDB) => {
25426 self.write_keyword("VARBINARY");
25429 }
25430 Some(DialectType::Spark)
25431 | Some(DialectType::Databricks)
25432 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
25433 Some(DialectType::ClickHouse) => {
25434 self.write("Nullable(String)");
25438 }
25439 _ => self.write_keyword("BLOB"),
25440 }
25441 }
25442 DataType::Bit { length } => {
25443 match self.config.dialect {
25445 Some(DialectType::Dremio)
25446 | Some(DialectType::Spark)
25447 | Some(DialectType::Databricks)
25448 | Some(DialectType::Hive)
25449 | Some(DialectType::Snowflake)
25450 | Some(DialectType::BigQuery)
25451 | Some(DialectType::Presto)
25452 | Some(DialectType::Trino)
25453 | Some(DialectType::ClickHouse)
25454 | Some(DialectType::Redshift) => {
25455 self.write_keyword("BOOLEAN");
25457 }
25458 _ => {
25459 self.write_keyword("BIT");
25460 if let Some(n) = length {
25461 self.write(&format!("({})", n));
25462 }
25463 }
25464 }
25465 }
25466 DataType::VarBit { length } => {
25467 self.write_keyword("VARBIT");
25468 if let Some(n) = length {
25469 self.write(&format!("({})", n));
25470 }
25471 }
25472 DataType::Date => self.write_keyword("DATE"),
25473 DataType::Time {
25474 precision,
25475 timezone,
25476 } => {
25477 if *timezone {
25478 match self.config.dialect {
25480 Some(DialectType::DuckDB) => {
25481 self.write_keyword("TIMETZ");
25483 }
25484 Some(DialectType::PostgreSQL) => {
25485 self.write_keyword("TIMETZ");
25487 if let Some(p) = precision {
25488 self.write(&format!("({})", p));
25489 }
25490 }
25491 _ => {
25492 self.write_keyword("TIME");
25494 if let Some(p) = precision {
25495 self.write(&format!("({})", p));
25496 }
25497 self.write_keyword(" WITH TIME ZONE");
25498 }
25499 }
25500 } else {
25501 if matches!(
25503 self.config.dialect,
25504 Some(DialectType::Spark)
25505 | Some(DialectType::Databricks)
25506 | Some(DialectType::Hive)
25507 ) {
25508 self.write_keyword("TIMESTAMP");
25509 } else {
25510 self.write_keyword("TIME");
25511 if let Some(p) = precision {
25512 self.write(&format!("({})", p));
25513 }
25514 }
25515 }
25516 }
25517 DataType::Timestamp {
25518 precision,
25519 timezone,
25520 } => {
25521 match self.config.dialect {
25523 Some(DialectType::Snowflake) if *timezone => {
25524 self.write_keyword("TIMESTAMPTZ");
25525 if let Some(p) = precision {
25526 self.write(&format!("({})", p));
25527 }
25528 }
25529 Some(DialectType::ClickHouse) => {
25530 self.write("DateTime");
25531 if let Some(p) = precision {
25532 self.write(&format!("({})", p));
25533 }
25534 }
25535 Some(DialectType::TSQL) => {
25536 if *timezone {
25537 self.write_keyword("DATETIMEOFFSET");
25538 } else {
25539 self.write_keyword("DATETIME2");
25540 }
25541 if let Some(p) = precision {
25542 self.write(&format!("({})", p));
25543 }
25544 }
25545 Some(DialectType::MySQL) => {
25546 self.write_keyword("TIMESTAMP");
25548 if let Some(p) = precision {
25549 self.write(&format!("({})", p));
25550 }
25551 }
25552 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
25553 self.write_keyword("DATETIME");
25555 if let Some(p) = precision {
25556 self.write(&format!("({})", p));
25557 }
25558 }
25559 Some(DialectType::BigQuery) => {
25560 if *timezone {
25562 self.write_keyword("TIMESTAMP");
25563 } else {
25564 self.write_keyword("DATETIME");
25565 }
25566 }
25567 Some(DialectType::DuckDB) => {
25568 if *timezone {
25570 self.write_keyword("TIMESTAMPTZ");
25571 } else {
25572 self.write_keyword("TIMESTAMP");
25573 if let Some(p) = precision {
25574 self.write(&format!("({})", p));
25575 }
25576 }
25577 }
25578 _ => {
25579 if *timezone && !self.config.tz_to_with_time_zone {
25580 self.write_keyword("TIMESTAMPTZ");
25582 if let Some(p) = precision {
25583 self.write(&format!("({})", p));
25584 }
25585 } else {
25586 self.write_keyword("TIMESTAMP");
25587 if let Some(p) = precision {
25588 self.write(&format!("({})", p));
25589 }
25590 if *timezone {
25591 self.write_space();
25592 self.write_keyword("WITH TIME ZONE");
25593 }
25594 }
25595 }
25596 }
25597 }
25598 DataType::Interval { unit, to } => {
25599 self.write_keyword("INTERVAL");
25600 if let Some(u) = unit {
25601 self.write_space();
25602 self.write_keyword(u);
25603 }
25604 if let Some(t) = to {
25606 self.write_space();
25607 self.write_keyword("TO");
25608 self.write_space();
25609 self.write_keyword(t);
25610 }
25611 }
25612 DataType::Json => {
25613 match self.config.dialect {
25615 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
25618 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
25619 _ => self.write_keyword("JSON"),
25620 }
25621 }
25622 DataType::JsonB => {
25623 match self.config.dialect {
25625 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
25626 Some(DialectType::Doris) => self.write_keyword("JSONB"),
25627 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
25628 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
25629 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
25632 }
25633 DataType::Uuid => {
25634 match self.config.dialect {
25636 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
25637 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
25638 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
25639 Some(DialectType::BigQuery)
25640 | Some(DialectType::Spark)
25641 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
25642 _ => self.write_keyword("UUID"),
25643 }
25644 }
25645 DataType::Array {
25646 element_type,
25647 dimension,
25648 } => {
25649 match self.config.dialect {
25651 Some(DialectType::PostgreSQL)
25652 | Some(DialectType::Redshift)
25653 | Some(DialectType::DuckDB) => {
25654 self.generate_data_type(element_type)?;
25656 if let Some(dim) = dimension {
25657 self.write(&format!("[{}]", dim));
25658 } else {
25659 self.write("[]");
25660 }
25661 }
25662 Some(DialectType::BigQuery) => {
25663 self.write_keyword("ARRAY<");
25664 self.generate_data_type(element_type)?;
25665 self.write(">");
25666 }
25667 Some(DialectType::Snowflake)
25668 | Some(DialectType::Presto)
25669 | Some(DialectType::Trino)
25670 | Some(DialectType::ClickHouse) => {
25671 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25673 self.write("Array(");
25674 } else {
25675 self.write_keyword("ARRAY(");
25676 }
25677 self.generate_data_type(element_type)?;
25678 self.write(")");
25679 }
25680 Some(DialectType::TSQL)
25681 | Some(DialectType::MySQL)
25682 | Some(DialectType::Oracle) => {
25683 match self.config.dialect {
25686 Some(DialectType::MySQL) => self.write_keyword("JSON"),
25687 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
25688 _ => self.write_keyword("JSON"),
25689 }
25690 }
25691 _ => {
25692 self.write_keyword("ARRAY<");
25694 self.generate_data_type(element_type)?;
25695 self.write(">");
25696 }
25697 }
25698 }
25699 DataType::List { element_type } => {
25700 self.generate_data_type(element_type)?;
25702 self.write_keyword(" LIST");
25703 }
25704 DataType::Map {
25705 key_type,
25706 value_type,
25707 } => {
25708 match self.config.dialect {
25710 Some(DialectType::Materialize) => {
25711 self.write_keyword("MAP[");
25713 self.generate_data_type(key_type)?;
25714 self.write(" => ");
25715 self.generate_data_type(value_type)?;
25716 self.write("]");
25717 }
25718 Some(DialectType::Snowflake)
25719 | Some(DialectType::RisingWave)
25720 | Some(DialectType::DuckDB)
25721 | Some(DialectType::Presto)
25722 | Some(DialectType::Trino)
25723 | Some(DialectType::Athena) => {
25724 self.write_keyword("MAP(");
25725 self.generate_data_type(key_type)?;
25726 self.write(", ");
25727 self.generate_data_type(value_type)?;
25728 self.write(")");
25729 }
25730 Some(DialectType::ClickHouse) => {
25731 self.write("Map(");
25734 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
25736 self.clickhouse_nullable_depth = 0;
25737 self.write(", ");
25738 self.generate_data_type(value_type)?;
25739 self.write(")");
25740 }
25741 _ => {
25742 self.write_keyword("MAP<");
25743 self.generate_data_type(key_type)?;
25744 self.write(", ");
25745 self.generate_data_type(value_type)?;
25746 self.write(">");
25747 }
25748 }
25749 }
25750 DataType::Vector {
25751 element_type,
25752 dimension,
25753 } => {
25754 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
25755 self.write_keyword("VECTOR(");
25757 if let Some(dim) = dimension {
25758 self.write(&dim.to_string());
25759 }
25760 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
25762 DataType::TinyInt { .. } => Some("I8"),
25763 DataType::SmallInt { .. } => Some("I16"),
25764 DataType::Int { .. } => Some("I32"),
25765 DataType::BigInt { .. } => Some("I64"),
25766 DataType::Float { .. } => Some("F32"),
25767 DataType::Double { .. } => Some("F64"),
25768 _ => None,
25769 });
25770 if let Some(alias) = type_alias {
25771 if dimension.is_some() {
25772 self.write(", ");
25773 }
25774 self.write(alias);
25775 }
25776 self.write(")");
25777 } else {
25778 self.write_keyword("VECTOR(");
25780 if let Some(ref et) = element_type {
25781 self.generate_data_type(et)?;
25782 if dimension.is_some() {
25783 self.write(", ");
25784 }
25785 }
25786 if let Some(dim) = dimension {
25787 self.write(&dim.to_string());
25788 }
25789 self.write(")");
25790 }
25791 }
25792 DataType::Object { fields, modifier } => {
25793 self.write_keyword("OBJECT(");
25794 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
25795 if i > 0 {
25796 self.write(", ");
25797 }
25798 self.write(name);
25799 self.write(" ");
25800 self.generate_data_type(dt)?;
25801 if *not_null {
25802 self.write_keyword(" NOT NULL");
25803 }
25804 }
25805 self.write(")");
25806 if let Some(mod_str) = modifier {
25807 self.write(" ");
25808 self.write_keyword(mod_str);
25809 }
25810 }
25811 DataType::Struct { fields, nested } => {
25812 match self.config.dialect {
25814 Some(DialectType::Snowflake) => {
25815 self.write_keyword("OBJECT(");
25817 for (i, field) in fields.iter().enumerate() {
25818 if i > 0 {
25819 self.write(", ");
25820 }
25821 if !field.name.is_empty() {
25822 self.write(&field.name);
25823 self.write(" ");
25824 }
25825 self.generate_data_type(&field.data_type)?;
25826 }
25827 self.write(")");
25828 }
25829 Some(DialectType::Presto) | Some(DialectType::Trino) => {
25830 self.write_keyword("ROW(");
25832 for (i, field) in fields.iter().enumerate() {
25833 if i > 0 {
25834 self.write(", ");
25835 }
25836 if !field.name.is_empty() {
25837 self.write(&field.name);
25838 self.write(" ");
25839 }
25840 self.generate_data_type(&field.data_type)?;
25841 }
25842 self.write(")");
25843 }
25844 Some(DialectType::DuckDB) => {
25845 self.write_keyword("STRUCT(");
25847 for (i, field) in fields.iter().enumerate() {
25848 if i > 0 {
25849 self.write(", ");
25850 }
25851 if !field.name.is_empty() {
25852 self.write(&field.name);
25853 self.write(" ");
25854 }
25855 self.generate_data_type(&field.data_type)?;
25856 }
25857 self.write(")");
25858 }
25859 Some(DialectType::ClickHouse) => {
25860 self.write("Tuple(");
25862 for (i, field) in fields.iter().enumerate() {
25863 if i > 0 {
25864 self.write(", ");
25865 }
25866 if !field.name.is_empty() {
25867 self.write(&field.name);
25868 self.write(" ");
25869 }
25870 self.generate_data_type(&field.data_type)?;
25871 }
25872 self.write(")");
25873 }
25874 Some(DialectType::SingleStore) => {
25875 self.write_keyword("RECORD(");
25877 for (i, field) in fields.iter().enumerate() {
25878 if i > 0 {
25879 self.write(", ");
25880 }
25881 if !field.name.is_empty() {
25882 self.write(&field.name);
25883 self.write(" ");
25884 }
25885 self.generate_data_type(&field.data_type)?;
25886 }
25887 self.write(")");
25888 }
25889 _ => {
25890 let force_angle_brackets = matches!(
25892 self.config.dialect,
25893 Some(DialectType::Hive)
25894 | Some(DialectType::Spark)
25895 | Some(DialectType::Databricks)
25896 );
25897 if *nested && !force_angle_brackets {
25898 self.write_keyword("STRUCT(");
25899 for (i, field) in fields.iter().enumerate() {
25900 if i > 0 {
25901 self.write(", ");
25902 }
25903 if !field.name.is_empty() {
25904 self.write(&field.name);
25905 self.write(" ");
25906 }
25907 self.generate_data_type(&field.data_type)?;
25908 }
25909 self.write(")");
25910 } else {
25911 self.write_keyword("STRUCT<");
25912 for (i, field) in fields.iter().enumerate() {
25913 if i > 0 {
25914 self.write(", ");
25915 }
25916 if !field.name.is_empty() {
25917 self.write(&field.name);
25919 self.write(self.config.struct_field_sep);
25920 }
25921 self.generate_data_type(&field.data_type)?;
25923 if let Some(comment) = &field.comment {
25925 self.write(" COMMENT '");
25926 self.write(comment);
25927 self.write("'");
25928 }
25929 if !field.options.is_empty() {
25931 self.write(" ");
25932 self.generate_options_clause(&field.options)?;
25933 }
25934 }
25935 self.write(">");
25936 }
25937 }
25938 }
25939 }
25940 DataType::Enum {
25941 values,
25942 assignments,
25943 } => {
25944 if self.config.dialect == Some(DialectType::ClickHouse) {
25947 self.write("Enum(");
25948 } else {
25949 self.write_keyword("ENUM(");
25950 }
25951 for (i, val) in values.iter().enumerate() {
25952 if i > 0 {
25953 self.write(", ");
25954 }
25955 self.write("'");
25956 self.write(val);
25957 self.write("'");
25958 if let Some(Some(assignment)) = assignments.get(i) {
25959 self.write(" = ");
25960 self.write(assignment);
25961 }
25962 }
25963 self.write(")");
25964 }
25965 DataType::Set { values } => {
25966 self.write_keyword("SET(");
25968 for (i, val) in values.iter().enumerate() {
25969 if i > 0 {
25970 self.write(", ");
25971 }
25972 self.write("'");
25973 self.write(val);
25974 self.write("'");
25975 }
25976 self.write(")");
25977 }
25978 DataType::Union { fields } => {
25979 self.write_keyword("UNION(");
25981 for (i, (name, dt)) in fields.iter().enumerate() {
25982 if i > 0 {
25983 self.write(", ");
25984 }
25985 if !name.is_empty() {
25986 self.write(name);
25987 self.write(" ");
25988 }
25989 self.generate_data_type(dt)?;
25990 }
25991 self.write(")");
25992 }
25993 DataType::Nullable { inner } => {
25994 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25996 self.write("Nullable(");
25997 let saved_depth = self.clickhouse_nullable_depth;
25999 self.clickhouse_nullable_depth = -1;
26000 self.generate_data_type(inner)?;
26001 self.clickhouse_nullable_depth = saved_depth;
26002 self.write(")");
26003 } else {
26004 match inner.as_ref() {
26006 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
26007 self.generate_data_type(&DataType::Timestamp {
26008 precision: None,
26009 timezone: false,
26010 })?;
26011 }
26012 _ => {
26013 self.generate_data_type(inner)?;
26014 }
26015 }
26016 }
26017 }
26018 DataType::Custom { name } => {
26019 let name_upper = name.to_ascii_uppercase();
26021 match self.config.dialect {
26022 Some(DialectType::ClickHouse) => {
26023 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
26024 (name_upper[..idx].to_string(), &name[idx..])
26025 } else {
26026 (name_upper.clone(), "")
26027 };
26028 let mapped = match base_upper.as_str() {
26029 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
26030 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
26031 "DATETIME64" => "DateTime64",
26032 "DATE32" => "Date32",
26033 "INT" => "Int32",
26034 "MEDIUMINT" => "Int32",
26035 "INT8" => "Int8",
26036 "INT16" => "Int16",
26037 "INT32" => "Int32",
26038 "INT64" => "Int64",
26039 "INT128" => "Int128",
26040 "INT256" => "Int256",
26041 "UINT8" => "UInt8",
26042 "UINT16" => "UInt16",
26043 "UINT32" => "UInt32",
26044 "UINT64" => "UInt64",
26045 "UINT128" => "UInt128",
26046 "UINT256" => "UInt256",
26047 "FLOAT32" => "Float32",
26048 "FLOAT64" => "Float64",
26049 "DECIMAL32" => "Decimal32",
26050 "DECIMAL64" => "Decimal64",
26051 "DECIMAL128" => "Decimal128",
26052 "DECIMAL256" => "Decimal256",
26053 "ENUM" => "Enum",
26054 "ENUM8" => "Enum8",
26055 "ENUM16" => "Enum16",
26056 "FIXEDSTRING" => "FixedString",
26057 "NESTED" => "Nested",
26058 "LOWCARDINALITY" => "LowCardinality",
26059 "NULLABLE" => "Nullable",
26060 "IPV4" => "IPv4",
26061 "IPV6" => "IPv6",
26062 "POINT" => "Point",
26063 "RING" => "Ring",
26064 "LINESTRING" => "LineString",
26065 "MULTILINESTRING" => "MultiLineString",
26066 "POLYGON" => "Polygon",
26067 "MULTIPOLYGON" => "MultiPolygon",
26068 "AGGREGATEFUNCTION" => "AggregateFunction",
26069 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
26070 "DYNAMIC" => "Dynamic",
26071 _ => "",
26072 };
26073 if mapped.is_empty() {
26074 self.write(name);
26075 } else {
26076 self.write(mapped);
26077 if matches!(base_upper.as_str(), "ENUM8" | "ENUM16")
26078 && !suffix.is_empty()
26079 {
26080 let escaped_suffix = suffix
26081 .replace('\\', "\\\\")
26082 .replace('\t', "\\t")
26083 .replace('\n', "\\n")
26084 .replace('\r', "\\r");
26085 self.write(&escaped_suffix);
26086 } else {
26087 self.write(suffix);
26088 }
26089 }
26090 }
26091 Some(DialectType::MySQL)
26092 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
26093 {
26094 self.write_keyword("TIMESTAMP");
26096 }
26097 Some(DialectType::Snowflake) => {
26098 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
26099 (name_upper[..idx].to_string(), &name[idx..])
26100 } else {
26101 (name_upper.clone(), "")
26102 };
26103
26104 match base_upper.as_str() {
26105 "TIMESTAMPNTZ" | "TIMESTAMP_NTZ" => {
26106 self.write_keyword("TIMESTAMPNTZ");
26107 self.write(suffix);
26108 }
26109 "TIMESTAMPLTZ" | "TIMESTAMP_LTZ" => {
26110 self.write_keyword("TIMESTAMPLTZ");
26111 self.write(suffix);
26112 }
26113 "TIMESTAMPTZ" | "TIMESTAMP_TZ" => {
26114 self.write_keyword("TIMESTAMPTZ");
26115 self.write(suffix);
26116 }
26117 _ => self.write(name),
26118 }
26119 }
26120 Some(DialectType::Fabric) => {
26121 let (base_upper, args_str) = if let Some(idx) = name.find('(') {
26122 (name_upper[..idx].to_string(), Some(&name[idx..]))
26123 } else {
26124 (name_upper.clone(), None)
26125 };
26126
26127 match base_upper.as_str() {
26128 "NVARCHAR" => {
26129 self.write_keyword("VARCHAR");
26130 if let Some(args) = args_str {
26131 self.write(args);
26132 }
26133 }
26134 "NCHAR" => {
26135 self.write_keyword("CHAR");
26136 if let Some(args) = args_str {
26137 self.write(args);
26138 }
26139 }
26140 _ => self.write(name),
26141 }
26142 }
26143 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
26144 self.write_keyword("SQL_VARIANT");
26145 }
26146 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
26147 self.write_keyword("DECIMAL(38, 5)");
26148 }
26149 Some(DialectType::Exasol) => {
26150 match name_upper.as_str() {
26152 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
26154 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
26156 "MEDIUMINT" => self.write_keyword("INT"),
26158 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
26160 self.write_keyword("DECIMAL")
26161 }
26162 "DATETIME" => self.write_keyword("TIMESTAMP"),
26164 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
26165 _ => self.write(name),
26166 }
26167 }
26168 Some(DialectType::Dremio) => {
26169 match name_upper.as_str() {
26171 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
26172 "ARRAY" => self.write_keyword("LIST"),
26173 "NCHAR" => self.write_keyword("VARCHAR"),
26174 _ => self.write(name),
26175 }
26176 }
26177 _ => {
26179 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
26181 (name_upper[..idx].to_string(), Some(&name[idx..]))
26182 } else {
26183 (name_upper.clone(), None)
26184 };
26185
26186 match base_upper.as_str() {
26187 "INT64"
26188 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26189 {
26190 self.write_keyword("BIGINT");
26191 }
26192 "FLOAT64"
26193 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26194 {
26195 self.write_keyword("DOUBLE");
26196 }
26197 "BOOL"
26198 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26199 {
26200 self.write_keyword("BOOLEAN");
26201 }
26202 "BYTES"
26203 if matches!(
26204 self.config.dialect,
26205 Some(DialectType::Spark)
26206 | Some(DialectType::Hive)
26207 | Some(DialectType::Databricks)
26208 ) =>
26209 {
26210 self.write_keyword("BINARY");
26211 }
26212 "BYTES"
26213 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26214 {
26215 self.write_keyword("VARBINARY");
26216 }
26217 "DATETIME2" | "SMALLDATETIME"
26219 if !matches!(
26220 self.config.dialect,
26221 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26222 ) =>
26223 {
26224 if matches!(
26226 self.config.dialect,
26227 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
26228 ) {
26229 self.write_keyword("TIMESTAMP");
26230 if let Some(args) = _args_str {
26231 self.write(args);
26232 }
26233 } else {
26234 self.write_keyword("TIMESTAMP");
26235 }
26236 }
26237 "DATETIMEOFFSET"
26239 if !matches!(
26240 self.config.dialect,
26241 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26242 ) =>
26243 {
26244 if matches!(
26245 self.config.dialect,
26246 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
26247 ) {
26248 self.write_keyword("TIMESTAMPTZ");
26249 if let Some(args) = _args_str {
26250 self.write(args);
26251 }
26252 } else {
26253 self.write_keyword("TIMESTAMPTZ");
26254 }
26255 }
26256 "UNIQUEIDENTIFIER"
26258 if !matches!(
26259 self.config.dialect,
26260 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26261 ) =>
26262 {
26263 match self.config.dialect {
26264 Some(DialectType::Spark)
26265 | Some(DialectType::Databricks)
26266 | Some(DialectType::Hive) => self.write_keyword("STRING"),
26267 _ => self.write_keyword("UUID"),
26268 }
26269 }
26270 "BIT"
26272 if !matches!(
26273 self.config.dialect,
26274 Some(DialectType::TSQL)
26275 | Some(DialectType::Fabric)
26276 | Some(DialectType::PostgreSQL)
26277 | Some(DialectType::MySQL)
26278 | Some(DialectType::DuckDB)
26279 ) =>
26280 {
26281 self.write_keyword("BOOLEAN");
26282 }
26283 "NVARCHAR"
26285 if !matches!(
26286 self.config.dialect,
26287 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26288 ) =>
26289 {
26290 match self.config.dialect {
26291 Some(DialectType::Oracle) => {
26292 self.write_keyword("NVARCHAR2");
26294 if let Some(args) = _args_str {
26295 self.write(args);
26296 }
26297 }
26298 Some(DialectType::BigQuery) => {
26299 self.write_keyword("STRING");
26301 }
26302 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
26303 self.write_keyword("TEXT");
26304 if let Some(args) = _args_str {
26305 self.write(args);
26306 }
26307 }
26308 Some(DialectType::Hive) => {
26309 self.write_keyword("STRING");
26311 }
26312 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
26313 if _args_str.is_some() {
26314 self.write_keyword("VARCHAR");
26315 self.write(_args_str.unwrap());
26316 } else {
26317 self.write_keyword("STRING");
26318 }
26319 }
26320 _ => {
26321 self.write_keyword("VARCHAR");
26322 if let Some(args) = _args_str {
26323 self.write(args);
26324 }
26325 }
26326 }
26327 }
26328 "NCHAR"
26330 if !matches!(
26331 self.config.dialect,
26332 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26333 ) =>
26334 {
26335 match self.config.dialect {
26336 Some(DialectType::Oracle) => {
26337 self.write_keyword("NCHAR");
26339 if let Some(args) = _args_str {
26340 self.write(args);
26341 }
26342 }
26343 Some(DialectType::BigQuery) => {
26344 self.write_keyword("STRING");
26346 }
26347 Some(DialectType::Hive) => {
26348 self.write_keyword("STRING");
26350 }
26351 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
26352 self.write_keyword("TEXT");
26353 if let Some(args) = _args_str {
26354 self.write(args);
26355 }
26356 }
26357 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
26358 if _args_str.is_some() {
26359 self.write_keyword("CHAR");
26360 self.write(_args_str.unwrap());
26361 } else {
26362 self.write_keyword("STRING");
26363 }
26364 }
26365 _ => {
26366 self.write_keyword("CHAR");
26367 if let Some(args) = _args_str {
26368 self.write(args);
26369 }
26370 }
26371 }
26372 }
26373 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
26376 Some(DialectType::MySQL)
26377 | Some(DialectType::SingleStore)
26378 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
26379 Some(DialectType::Spark)
26380 | Some(DialectType::Databricks)
26381 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
26382 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
26383 Some(DialectType::Presto)
26384 | Some(DialectType::Trino)
26385 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
26386 Some(DialectType::Snowflake)
26387 | Some(DialectType::Redshift)
26388 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
26389 _ => self.write_keyword("TEXT"),
26390 },
26391 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
26394 Some(DialectType::MySQL)
26395 | Some(DialectType::SingleStore)
26396 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
26397 Some(DialectType::Spark)
26398 | Some(DialectType::Databricks)
26399 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
26400 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
26401 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
26402 Some(DialectType::Presto)
26403 | Some(DialectType::Trino)
26404 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
26405 Some(DialectType::Snowflake)
26406 | Some(DialectType::Redshift)
26407 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
26408 _ => self.write_keyword("BLOB"),
26409 },
26410 "LONGVARCHAR" => match self.config.dialect {
26412 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
26413 _ => self.write_keyword("VARCHAR"),
26414 },
26415 "DATETIME" => {
26417 match self.config.dialect {
26418 Some(DialectType::MySQL)
26419 | Some(DialectType::Doris)
26420 | Some(DialectType::StarRocks)
26421 | Some(DialectType::TSQL)
26422 | Some(DialectType::Fabric)
26423 | Some(DialectType::BigQuery)
26424 | Some(DialectType::SQLite)
26425 | Some(DialectType::Snowflake) => {
26426 self.write_keyword("DATETIME");
26427 if let Some(args) = _args_str {
26428 self.write(args);
26429 }
26430 }
26431 Some(_) => {
26432 self.write_keyword("TIMESTAMP");
26434 if let Some(args) = _args_str {
26435 self.write(args);
26436 }
26437 }
26438 None => {
26439 self.write(name);
26441 }
26442 }
26443 }
26444 "VARCHAR2"
26446 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
26447 {
26448 match self.config.dialect {
26449 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
26450 self.write_keyword("TEXT");
26451 }
26452 Some(DialectType::Hive)
26453 | Some(DialectType::Spark)
26454 | Some(DialectType::Databricks)
26455 | Some(DialectType::BigQuery)
26456 | Some(DialectType::ClickHouse)
26457 | Some(DialectType::StarRocks)
26458 | Some(DialectType::Doris) => {
26459 self.write_keyword("STRING");
26460 }
26461 _ => {
26462 self.write_keyword("VARCHAR");
26463 if let Some(args) = _args_str {
26464 self.write(args);
26465 }
26466 }
26467 }
26468 }
26469 "NVARCHAR2"
26470 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
26471 {
26472 match self.config.dialect {
26473 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
26474 self.write_keyword("TEXT");
26475 }
26476 Some(DialectType::Hive)
26477 | Some(DialectType::Spark)
26478 | Some(DialectType::Databricks)
26479 | Some(DialectType::BigQuery)
26480 | Some(DialectType::ClickHouse)
26481 | Some(DialectType::StarRocks)
26482 | Some(DialectType::Doris) => {
26483 self.write_keyword("STRING");
26484 }
26485 _ => {
26486 self.write_keyword("VARCHAR");
26487 if let Some(args) = _args_str {
26488 self.write(args);
26489 }
26490 }
26491 }
26492 }
26493 _ => self.write(name),
26494 }
26495 }
26496 }
26497 }
26498 DataType::Geometry { subtype, srid } => {
26499 match self.config.dialect {
26501 Some(DialectType::MySQL) => {
26502 if let Some(sub) = subtype {
26504 self.write_keyword(sub);
26505 if let Some(s) = srid {
26506 self.write(" SRID ");
26507 self.write(&s.to_string());
26508 }
26509 } else {
26510 self.write_keyword("GEOMETRY");
26511 }
26512 }
26513 Some(DialectType::BigQuery) => {
26514 self.write_keyword("GEOGRAPHY");
26516 }
26517 Some(DialectType::Teradata) => {
26518 self.write_keyword("ST_GEOMETRY");
26520 if subtype.is_some() || srid.is_some() {
26521 self.write("(");
26522 if let Some(sub) = subtype {
26523 self.write_keyword(sub);
26524 }
26525 if let Some(s) = srid {
26526 if subtype.is_some() {
26527 self.write(", ");
26528 }
26529 self.write(&s.to_string());
26530 }
26531 self.write(")");
26532 }
26533 }
26534 _ => {
26535 self.write_keyword("GEOMETRY");
26537 if subtype.is_some() || srid.is_some() {
26538 self.write("(");
26539 if let Some(sub) = subtype {
26540 self.write_keyword(sub);
26541 }
26542 if let Some(s) = srid {
26543 if subtype.is_some() {
26544 self.write(", ");
26545 }
26546 self.write(&s.to_string());
26547 }
26548 self.write(")");
26549 }
26550 }
26551 }
26552 }
26553 DataType::Geography { subtype, srid } => {
26554 match self.config.dialect {
26556 Some(DialectType::MySQL) => {
26557 if let Some(sub) = subtype {
26559 self.write_keyword(sub);
26560 } else {
26561 self.write_keyword("GEOMETRY");
26562 }
26563 let effective_srid = srid.unwrap_or(4326);
26565 self.write(" SRID ");
26566 self.write(&effective_srid.to_string());
26567 }
26568 Some(DialectType::BigQuery) => {
26569 self.write_keyword("GEOGRAPHY");
26571 }
26572 Some(DialectType::Snowflake) => {
26573 self.write_keyword("GEOGRAPHY");
26575 }
26576 _ => {
26577 self.write_keyword("GEOGRAPHY");
26579 if subtype.is_some() || srid.is_some() {
26580 self.write("(");
26581 if let Some(sub) = subtype {
26582 self.write_keyword(sub);
26583 }
26584 if let Some(s) = srid {
26585 if subtype.is_some() {
26586 self.write(", ");
26587 }
26588 self.write(&s.to_string());
26589 }
26590 self.write(")");
26591 }
26592 }
26593 }
26594 }
26595 DataType::CharacterSet { name } => {
26596 self.write_keyword("CHAR CHARACTER SET ");
26598 self.write(name);
26599 }
26600 _ => self.write("UNKNOWN"),
26601 }
26602 Ok(())
26603 }
26604
26605 #[inline]
26608 fn write(&mut self, s: &str) {
26609 self.output.push_str(s);
26610 }
26611
26612 #[inline]
26613 fn write_space(&mut self) {
26614 self.output.push(' ');
26615 }
26616
26617 #[inline]
26618 fn write_keyword(&mut self, keyword: &str) {
26619 if self.config.uppercase_keywords {
26620 self.output.push_str(keyword);
26621 } else {
26622 for b in keyword.bytes() {
26623 self.output.push(b.to_ascii_lowercase() as char);
26624 }
26625 }
26626 }
26627
26628 fn write_func_name(&mut self, name: &str) {
26630 let normalized = self.normalize_func_name(name);
26631 self.output.push_str(normalized.as_ref());
26632 }
26633
26634 fn convert_strptime_to_exasol_format(format: &str) -> String {
26638 let mut result = String::new();
26639 let chars: Vec<char> = format.chars().collect();
26640 let mut i = 0;
26641 while i < chars.len() {
26642 if chars[i] == '%' && i + 1 < chars.len() {
26643 let spec = chars[i + 1];
26644 let exasol_spec = match spec {
26645 'Y' => "YYYY",
26646 'y' => "YY",
26647 'm' => "MM",
26648 'd' => "DD",
26649 'H' => "HH",
26650 'M' => "MI",
26651 'S' => "SS",
26652 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
26664 result.push('%');
26666 result.push(spec);
26667 i += 2;
26668 continue;
26669 }
26670 };
26671 result.push_str(exasol_spec);
26672 i += 2;
26673 } else {
26674 result.push(chars[i]);
26675 i += 1;
26676 }
26677 }
26678 result
26679 }
26680
26681 fn convert_strptime_to_postgres_format(format: &str) -> String {
26685 let mut result = String::new();
26686 let chars: Vec<char> = format.chars().collect();
26687 let mut i = 0;
26688 while i < chars.len() {
26689 if chars[i] == '%' && i + 1 < chars.len() {
26690 if chars[i + 1] == '-' && i + 2 < chars.len() {
26692 let spec = chars[i + 2];
26693 let pg_spec = match spec {
26694 'd' => "FMDD",
26695 'm' => "FMMM",
26696 'H' => "FMHH24",
26697 'M' => "FMMI",
26698 'S' => "FMSS",
26699 _ => {
26700 result.push('%');
26701 result.push('-');
26702 result.push(spec);
26703 i += 3;
26704 continue;
26705 }
26706 };
26707 result.push_str(pg_spec);
26708 i += 3;
26709 continue;
26710 }
26711 let spec = chars[i + 1];
26712 let pg_spec = match spec {
26713 'Y' => "YYYY",
26714 'y' => "YY",
26715 'm' => "MM",
26716 'd' => "DD",
26717 'H' => "HH24",
26718 'I' => "HH12",
26719 'M' => "MI",
26720 'S' => "SS",
26721 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
26732 result.push('%');
26734 result.push(spec);
26735 i += 2;
26736 continue;
26737 }
26738 };
26739 result.push_str(pg_spec);
26740 i += 2;
26741 } else {
26742 result.push(chars[i]);
26743 i += 1;
26744 }
26745 }
26746 result
26747 }
26748
26749 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
26751 if self.config.limit_only_literals {
26752 if let Some(value) = Self::try_evaluate_constant(expr) {
26753 self.write(&value.to_string());
26754 return Ok(());
26755 }
26756 }
26757 self.generate_expression(expr)
26758 }
26759
26760 fn is_noop_limit_expr(expr: &Expression) -> bool {
26761 match expr {
26762 Expression::Null(_) => true,
26763 Expression::Identifier(identifier) => identifier.name.eq_ignore_ascii_case("ALL"),
26764 Expression::Column(column) => {
26765 column.table.is_none() && column.name.name.eq_ignore_ascii_case("ALL")
26766 }
26767 Expression::Var(var) => var.this.eq_ignore_ascii_case("ALL"),
26768 Expression::Paren(paren) => Self::is_noop_limit_expr(&paren.this),
26769 _ => false,
26770 }
26771 }
26772
26773 fn write_formatted_comment(&mut self, comment: &str) {
26777 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
26780 &comment[2..comment.len() - 2]
26783 } else if comment.starts_with("--") {
26784 &comment[2..]
26787 } else {
26788 comment
26790 };
26791 if content.trim().is_empty() {
26793 return;
26794 }
26795 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
26798 let content = &sanitized;
26799 self.output.push_str("/*");
26801 if !content.starts_with(' ') {
26802 self.output.push(' ');
26803 }
26804 self.output.push_str(content);
26805 if !content.ends_with(' ') {
26806 self.output.push(' ');
26807 }
26808 self.output.push_str("*/");
26809 }
26810
26811 fn escape_block_for_single_quote(&self, block: &str) -> String {
26814 let escape_backslash = matches!(
26815 self.config.dialect,
26816 Some(crate::dialects::DialectType::Snowflake)
26817 );
26818 let mut escaped = String::with_capacity(block.len() + 4);
26819 for ch in block.chars() {
26820 if ch == '\'' {
26821 escaped.push('\\');
26822 escaped.push('\'');
26823 } else if escape_backslash && ch == '\\' {
26824 escaped.push('\\');
26825 escaped.push('\\');
26826 } else {
26827 escaped.push(ch);
26828 }
26829 }
26830 escaped
26831 }
26832
26833 fn write_newline(&mut self) {
26834 self.output.push('\n');
26835 }
26836
26837 fn write_indent(&mut self) {
26838 for _ in 0..self.indent_level {
26839 self.output.push_str(self.config.indent);
26840 }
26841 }
26842
26843 fn too_wide(&self, args: &[String]) -> bool {
26849 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
26850 }
26851
26852 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
26855 let config = GeneratorConfig {
26856 pretty: false,
26857 dialect: self.config.dialect,
26858 ..Default::default()
26859 };
26860 let mut gen = Generator::with_config(config);
26861 gen.generate_expression(expr)?;
26862 Ok(gen.output)
26863 }
26864
26865 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
26868 if self.config.pretty {
26869 self.write_newline();
26870 self.write_indent();
26871 self.write_keyword(keyword);
26872 self.write_newline();
26873 self.indent_level += 1;
26874 self.write_indent();
26875 self.generate_expression(condition)?;
26876 self.indent_level -= 1;
26877 } else {
26878 self.write_space();
26879 self.write_keyword(keyword);
26880 self.write_space();
26881 self.generate_expression(condition)?;
26882 }
26883 Ok(())
26884 }
26885
26886 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
26889 if exprs.is_empty() {
26890 return Ok(());
26891 }
26892
26893 if self.config.pretty {
26894 self.write_newline();
26895 self.write_indent();
26896 self.write_keyword(keyword);
26897 self.write_newline();
26898 self.indent_level += 1;
26899 for (i, expr) in exprs.iter().enumerate() {
26900 if i > 0 {
26901 self.write(",");
26902 self.write_newline();
26903 }
26904 self.write_indent();
26905 self.generate_expression(expr)?;
26906 }
26907 self.indent_level -= 1;
26908 } else {
26909 self.write_space();
26910 self.write_keyword(keyword);
26911 self.write_space();
26912 for (i, expr) in exprs.iter().enumerate() {
26913 if i > 0 {
26914 self.write(", ");
26915 }
26916 self.generate_expression(expr)?;
26917 }
26918 }
26919 Ok(())
26920 }
26921
26922 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
26924 if orderings.is_empty() {
26925 return Ok(());
26926 }
26927
26928 if self.config.pretty {
26929 self.write_newline();
26930 self.write_indent();
26931 self.write_keyword(keyword);
26932 self.write_newline();
26933 self.indent_level += 1;
26934 for (i, ordered) in orderings.iter().enumerate() {
26935 if i > 0 {
26936 self.write(",");
26937 self.write_newline();
26938 }
26939 self.write_indent();
26940 self.generate_ordered(ordered)?;
26941 }
26942 self.indent_level -= 1;
26943 } else {
26944 self.write_space();
26945 self.write_keyword(keyword);
26946 self.write_space();
26947 for (i, ordered) in orderings.iter().enumerate() {
26948 if i > 0 {
26949 self.write(", ");
26950 }
26951 self.generate_ordered(ordered)?;
26952 }
26953 }
26954 Ok(())
26955 }
26956
26957 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
26959 if windows.is_empty() {
26960 return Ok(());
26961 }
26962
26963 if self.config.pretty {
26964 self.write_newline();
26965 self.write_indent();
26966 self.write_keyword("WINDOW");
26967 self.write_newline();
26968 self.indent_level += 1;
26969 for (i, named_window) in windows.iter().enumerate() {
26970 if i > 0 {
26971 self.write(",");
26972 self.write_newline();
26973 }
26974 self.write_indent();
26975 self.generate_identifier(&named_window.name)?;
26976 self.write_space();
26977 self.write_keyword("AS");
26978 self.write(" (");
26979 self.generate_over(&named_window.spec)?;
26980 self.write(")");
26981 }
26982 self.indent_level -= 1;
26983 } else {
26984 self.write_space();
26985 self.write_keyword("WINDOW");
26986 self.write_space();
26987 for (i, named_window) in windows.iter().enumerate() {
26988 if i > 0 {
26989 self.write(", ");
26990 }
26991 self.generate_identifier(&named_window.name)?;
26992 self.write_space();
26993 self.write_keyword("AS");
26994 self.write(" (");
26995 self.generate_over(&named_window.spec)?;
26996 self.write(")");
26997 }
26998 }
26999 Ok(())
27000 }
27001
27002 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
27004 self.write_keyword("AI_AGG");
27006 self.write("(");
27007 self.generate_expression(&e.this)?;
27008 self.write(", ");
27009 self.generate_expression(&e.expression)?;
27010 self.write(")");
27011 Ok(())
27012 }
27013
27014 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
27015 self.write_keyword("AI_CLASSIFY");
27017 self.write("(");
27018 self.generate_expression(&e.this)?;
27019 if let Some(categories) = &e.categories {
27020 self.write(", ");
27021 self.generate_expression(categories)?;
27022 }
27023 if let Some(config) = &e.config {
27024 self.write(", ");
27025 self.generate_expression(config)?;
27026 }
27027 self.write(")");
27028 Ok(())
27029 }
27030
27031 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
27032 self.write_keyword("ADD");
27034 self.write_space();
27035 if e.exists {
27036 self.write_keyword("IF NOT EXISTS");
27037 self.write_space();
27038 }
27039 self.generate_expression(&e.this)?;
27040 if let Some(location) = &e.location {
27041 self.write_space();
27042 self.generate_expression(location)?;
27043 }
27044 Ok(())
27045 }
27046
27047 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
27048 self.write_keyword("ALGORITHM");
27050 self.write("=");
27051 self.generate_expression(&e.this)?;
27052 Ok(())
27053 }
27054
27055 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
27056 self.generate_expression(&e.this)?;
27058 self.write_space();
27059 self.write_keyword("AS");
27060 self.write(" (");
27061 for (i, expr) in e.expressions.iter().enumerate() {
27062 if i > 0 {
27063 self.write(", ");
27064 }
27065 self.generate_expression(expr)?;
27066 }
27067 self.write(")");
27068 Ok(())
27069 }
27070
27071 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
27072 self.write_keyword("ALLOWED_VALUES");
27074 self.write_space();
27075 for (i, expr) in e.expressions.iter().enumerate() {
27076 if i > 0 {
27077 self.write(", ");
27078 }
27079 self.generate_expression(expr)?;
27080 }
27081 Ok(())
27082 }
27083
27084 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
27085 self.write_keyword("ALTER COLUMN");
27087 self.write_space();
27088 self.generate_expression(&e.this)?;
27089
27090 if let Some(dtype) = &e.dtype {
27091 self.write_space();
27092 self.write_keyword("SET DATA TYPE");
27093 self.write_space();
27094 self.generate_expression(dtype)?;
27095 if let Some(collate) = &e.collate {
27096 self.write_space();
27097 self.write_keyword("COLLATE");
27098 self.write_space();
27099 self.generate_expression(collate)?;
27100 }
27101 if let Some(using) = &e.using {
27102 self.write_space();
27103 self.write_keyword("USING");
27104 self.write_space();
27105 self.generate_expression(using)?;
27106 }
27107 } else if let Some(default) = &e.default {
27108 self.write_space();
27109 self.write_keyword("SET DEFAULT");
27110 self.write_space();
27111 self.generate_expression(default)?;
27112 } else if let Some(comment) = &e.comment {
27113 self.write_space();
27114 self.write_keyword("COMMENT");
27115 self.write_space();
27116 self.generate_expression(comment)?;
27117 } else if let Some(drop) = &e.drop {
27118 self.write_space();
27119 self.write_keyword("DROP");
27120 self.write_space();
27121 self.generate_expression(drop)?;
27122 } else if let Some(visible) = &e.visible {
27123 self.write_space();
27124 self.generate_expression(visible)?;
27125 } else if let Some(rename_to) = &e.rename_to {
27126 self.write_space();
27127 self.write_keyword("RENAME TO");
27128 self.write_space();
27129 self.generate_expression(rename_to)?;
27130 } else if let Some(allow_null) = &e.allow_null {
27131 self.write_space();
27132 self.generate_expression(allow_null)?;
27133 }
27134 Ok(())
27135 }
27136
27137 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
27138 self.write_keyword("ALTER SESSION");
27140 self.write_space();
27141 if e.unset.is_some() {
27142 self.write_keyword("UNSET");
27143 } else {
27144 self.write_keyword("SET");
27145 }
27146 self.write_space();
27147 for (i, expr) in e.expressions.iter().enumerate() {
27148 if i > 0 {
27149 self.write(", ");
27150 }
27151 self.generate_expression(expr)?;
27152 }
27153 Ok(())
27154 }
27155
27156 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
27157 self.write_keyword("SET");
27159
27160 if let Some(opt) = &e.option {
27162 self.write_space();
27163 self.generate_expression(opt)?;
27164 }
27165
27166 if !e.expressions.is_empty() {
27169 let is_properties = e
27171 .expressions
27172 .iter()
27173 .any(|expr| matches!(expr, Expression::Eq(_)));
27174 if is_properties && e.option.is_none() {
27175 self.write_space();
27176 self.write_keyword("PROPERTIES");
27177 }
27178 self.write_space();
27179 for (i, expr) in e.expressions.iter().enumerate() {
27180 if i > 0 {
27181 self.write(", ");
27182 }
27183 self.generate_expression(expr)?;
27184 }
27185 }
27186
27187 if let Some(file_format) = &e.file_format {
27189 self.write(" ");
27190 self.write_keyword("STAGE_FILE_FORMAT");
27191 self.write(" = (");
27192 self.generate_space_separated_properties(file_format)?;
27193 self.write(")");
27194 }
27195
27196 if let Some(copy_options) = &e.copy_options {
27198 self.write(" ");
27199 self.write_keyword("STAGE_COPY_OPTIONS");
27200 self.write(" = (");
27201 self.generate_space_separated_properties(copy_options)?;
27202 self.write(")");
27203 }
27204
27205 if let Some(tag) = &e.tag {
27207 self.write(" ");
27208 self.write_keyword("TAG");
27209 self.write(" ");
27210 self.generate_expression(tag)?;
27211 }
27212
27213 Ok(())
27214 }
27215
27216 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
27218 match expr {
27219 Expression::Tuple(t) => {
27220 for (i, prop) in t.expressions.iter().enumerate() {
27221 if i > 0 {
27222 self.write(" ");
27223 }
27224 self.generate_expression(prop)?;
27225 }
27226 }
27227 _ => {
27228 self.generate_expression(expr)?;
27229 }
27230 }
27231 Ok(())
27232 }
27233
27234 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
27235 self.write_keyword("ALTER");
27237 if e.compound.is_some() {
27238 self.write_space();
27239 self.write_keyword("COMPOUND");
27240 }
27241 self.write_space();
27242 self.write_keyword("SORTKEY");
27243 self.write_space();
27244 if let Some(this) = &e.this {
27245 self.generate_expression(this)?;
27246 } else if !e.expressions.is_empty() {
27247 self.write("(");
27248 for (i, expr) in e.expressions.iter().enumerate() {
27249 if i > 0 {
27250 self.write(", ");
27251 }
27252 self.generate_expression(expr)?;
27253 }
27254 self.write(")");
27255 }
27256 Ok(())
27257 }
27258
27259 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
27260 self.write_keyword("ANALYZE");
27262 if !e.options.is_empty() {
27263 self.write_space();
27264 for (i, opt) in e.options.iter().enumerate() {
27265 if i > 0 {
27266 self.write_space();
27267 }
27268 if let Expression::Identifier(id) = opt {
27270 self.write_keyword(&id.name);
27271 } else {
27272 self.generate_expression(opt)?;
27273 }
27274 }
27275 }
27276 if let Some(kind) = &e.kind {
27277 self.write_space();
27278 self.write_keyword(kind);
27279 }
27280 if let Some(this) = &e.this {
27281 self.write_space();
27282 self.generate_expression(this)?;
27283 }
27284 if !e.columns.is_empty() {
27286 self.write("(");
27287 for (i, col) in e.columns.iter().enumerate() {
27288 if i > 0 {
27289 self.write(", ");
27290 }
27291 self.write(col);
27292 }
27293 self.write(")");
27294 }
27295 if let Some(partition) = &e.partition {
27296 self.write_space();
27297 self.generate_expression(partition)?;
27298 }
27299 if let Some(mode) = &e.mode {
27300 self.write_space();
27301 self.generate_expression(mode)?;
27302 }
27303 if let Some(expression) = &e.expression {
27304 self.write_space();
27305 self.generate_expression(expression)?;
27306 }
27307 if !e.properties.is_empty() {
27308 self.write_space();
27309 self.write_keyword(self.config.with_properties_prefix);
27310 self.write(" (");
27311 for (i, prop) in e.properties.iter().enumerate() {
27312 if i > 0 {
27313 self.write(", ");
27314 }
27315 self.generate_expression(prop)?;
27316 }
27317 self.write(")");
27318 }
27319 Ok(())
27320 }
27321
27322 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
27323 self.write_keyword("DELETE");
27325 if let Some(kind) = &e.kind {
27326 self.write_space();
27327 self.write_keyword(kind);
27328 }
27329 self.write_space();
27330 self.write_keyword("STATISTICS");
27331 Ok(())
27332 }
27333
27334 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
27335 if let Expression::Identifier(id) = e.this.as_ref() {
27338 self.write_keyword(&id.name);
27339 } else {
27340 self.generate_expression(&e.this)?;
27341 }
27342 self.write_space();
27343 self.write_keyword("HISTOGRAM ON");
27344 self.write_space();
27345 for (i, expr) in e.expressions.iter().enumerate() {
27346 if i > 0 {
27347 self.write(", ");
27348 }
27349 self.generate_expression(expr)?;
27350 }
27351 if let Some(expression) = &e.expression {
27352 self.write_space();
27353 self.generate_expression(expression)?;
27354 }
27355 if let Some(update_options) = &e.update_options {
27356 self.write_space();
27357 self.generate_expression(update_options)?;
27358 self.write_space();
27359 self.write_keyword("UPDATE");
27360 }
27361 Ok(())
27362 }
27363
27364 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
27365 self.write_keyword("LIST CHAINED ROWS");
27367 if let Some(expression) = &e.expression {
27368 self.write_space();
27369 self.write_keyword("INTO");
27370 self.write_space();
27371 self.generate_expression(expression)?;
27372 }
27373 Ok(())
27374 }
27375
27376 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
27377 self.write_keyword("SAMPLE");
27379 self.write_space();
27380 if let Some(sample) = &e.sample {
27381 self.generate_expression(sample)?;
27382 self.write_space();
27383 }
27384 self.write_keyword(&e.kind);
27385 Ok(())
27386 }
27387
27388 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
27389 self.write_keyword(&e.kind);
27391 if let Some(option) = &e.option {
27392 self.write_space();
27393 self.generate_expression(option)?;
27394 }
27395 self.write_space();
27396 self.write_keyword("STATISTICS");
27397 if let Some(this) = &e.this {
27398 self.write_space();
27399 self.generate_expression(this)?;
27400 }
27401 if !e.expressions.is_empty() {
27402 self.write_space();
27403 for (i, expr) in e.expressions.iter().enumerate() {
27404 if i > 0 {
27405 self.write(", ");
27406 }
27407 self.generate_expression(expr)?;
27408 }
27409 }
27410 Ok(())
27411 }
27412
27413 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
27414 self.write_keyword("VALIDATE");
27416 self.write_space();
27417 self.write_keyword(&e.kind);
27418 if let Some(this) = &e.this {
27419 self.write_space();
27420 if let Expression::Identifier(id) = this.as_ref() {
27422 self.write_keyword(&id.name);
27423 } else {
27424 self.generate_expression(this)?;
27425 }
27426 }
27427 if let Some(expression) = &e.expression {
27428 self.write_space();
27429 self.write_keyword("INTO");
27430 self.write_space();
27431 self.generate_expression(expression)?;
27432 }
27433 Ok(())
27434 }
27435
27436 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
27437 self.write_keyword("WITH");
27439 self.write_space();
27440 for (i, expr) in e.expressions.iter().enumerate() {
27441 if i > 0 {
27442 self.write(", ");
27443 }
27444 self.generate_expression(expr)?;
27445 }
27446 Ok(())
27447 }
27448
27449 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
27450 self.generate_expression(&e.this)?;
27453 self.write("(");
27454 for (i, arg) in e.expressions.iter().enumerate() {
27455 if i > 0 {
27456 self.write(", ");
27457 }
27458 self.generate_expression(arg)?;
27459 }
27460 self.write(")");
27461 Ok(())
27462 }
27463
27464 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
27465 self.generate_expression(&e.this)?;
27467 self.write("(");
27468 for (i, arg) in e.expressions.iter().enumerate() {
27469 if i > 0 {
27470 self.write(", ");
27471 }
27472 self.generate_expression(arg)?;
27473 }
27474 self.write(")");
27475 Ok(())
27476 }
27477
27478 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
27479 self.generate_expression(&e.this)?;
27481 self.write_space();
27482 self.write_keyword("APPLY");
27483 self.write("(");
27484 self.generate_expression(&e.expression)?;
27485 self.write(")");
27486 Ok(())
27487 }
27488
27489 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
27490 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
27492 self.write("(");
27493 self.generate_expression(&e.this)?;
27494 if let Some(percentile) = &e.percentile {
27495 self.write(", ");
27496 self.generate_expression(percentile)?;
27497 }
27498 self.write(")");
27499 Ok(())
27500 }
27501
27502 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
27503 self.write_keyword("APPROX_QUANTILE");
27505 self.write("(");
27506 self.generate_expression(&e.this)?;
27507 if let Some(quantile) = &e.quantile {
27508 self.write(", ");
27509 self.generate_expression(quantile)?;
27510 }
27511 if let Some(accuracy) = &e.accuracy {
27512 self.write(", ");
27513 self.generate_expression(accuracy)?;
27514 }
27515 if let Some(weight) = &e.weight {
27516 self.write(", ");
27517 self.generate_expression(weight)?;
27518 }
27519 self.write(")");
27520 Ok(())
27521 }
27522
27523 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
27524 self.write_keyword("APPROX_QUANTILES");
27526 self.write("(");
27527 self.generate_expression(&e.this)?;
27528 if let Some(expression) = &e.expression {
27529 self.write(", ");
27530 self.generate_expression(expression)?;
27531 }
27532 self.write(")");
27533 Ok(())
27534 }
27535
27536 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
27537 self.write_keyword("APPROX_TOP_K");
27539 self.write("(");
27540 self.generate_expression(&e.this)?;
27541 if let Some(expression) = &e.expression {
27542 self.write(", ");
27543 self.generate_expression(expression)?;
27544 }
27545 if let Some(counters) = &e.counters {
27546 self.write(", ");
27547 self.generate_expression(counters)?;
27548 }
27549 self.write(")");
27550 Ok(())
27551 }
27552
27553 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
27554 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
27556 self.write("(");
27557 self.generate_expression(&e.this)?;
27558 if let Some(expression) = &e.expression {
27559 self.write(", ");
27560 self.generate_expression(expression)?;
27561 }
27562 self.write(")");
27563 Ok(())
27564 }
27565
27566 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
27567 self.write_keyword("APPROX_TOP_K_COMBINE");
27569 self.write("(");
27570 self.generate_expression(&e.this)?;
27571 if let Some(expression) = &e.expression {
27572 self.write(", ");
27573 self.generate_expression(expression)?;
27574 }
27575 self.write(")");
27576 Ok(())
27577 }
27578
27579 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
27580 self.write_keyword("APPROX_TOP_K_ESTIMATE");
27582 self.write("(");
27583 self.generate_expression(&e.this)?;
27584 if let Some(expression) = &e.expression {
27585 self.write(", ");
27586 self.generate_expression(expression)?;
27587 }
27588 self.write(")");
27589 Ok(())
27590 }
27591
27592 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
27593 self.write_keyword("APPROX_TOP_SUM");
27595 self.write("(");
27596 self.generate_expression(&e.this)?;
27597 self.write(", ");
27598 self.generate_expression(&e.expression)?;
27599 if let Some(count) = &e.count {
27600 self.write(", ");
27601 self.generate_expression(count)?;
27602 }
27603 self.write(")");
27604 Ok(())
27605 }
27606
27607 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
27608 self.write_keyword("ARG_MAX");
27610 self.write("(");
27611 self.generate_expression(&e.this)?;
27612 self.write(", ");
27613 self.generate_expression(&e.expression)?;
27614 if let Some(count) = &e.count {
27615 self.write(", ");
27616 self.generate_expression(count)?;
27617 }
27618 self.write(")");
27619 Ok(())
27620 }
27621
27622 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
27623 self.write_keyword("ARG_MIN");
27625 self.write("(");
27626 self.generate_expression(&e.this)?;
27627 self.write(", ");
27628 self.generate_expression(&e.expression)?;
27629 if let Some(count) = &e.count {
27630 self.write(", ");
27631 self.generate_expression(count)?;
27632 }
27633 self.write(")");
27634 Ok(())
27635 }
27636
27637 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
27638 self.write_keyword("ARRAY_ALL");
27640 self.write("(");
27641 self.generate_expression(&e.this)?;
27642 self.write(", ");
27643 self.generate_expression(&e.expression)?;
27644 self.write(")");
27645 Ok(())
27646 }
27647
27648 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
27649 self.write_keyword("ARRAY_ANY");
27651 self.write("(");
27652 self.generate_expression(&e.this)?;
27653 self.write(", ");
27654 self.generate_expression(&e.expression)?;
27655 self.write(")");
27656 Ok(())
27657 }
27658
27659 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
27660 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
27662 self.write("(");
27663 for (i, expr) in e.expressions.iter().enumerate() {
27664 if i > 0 {
27665 self.write(", ");
27666 }
27667 self.generate_expression(expr)?;
27668 }
27669 self.write(")");
27670 Ok(())
27671 }
27672
27673 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
27674 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
27676 self.write("arraySum");
27677 } else {
27678 self.write_keyword("ARRAY_SUM");
27679 }
27680 self.write("(");
27681 self.generate_expression(&e.this)?;
27682 if let Some(expression) = &e.expression {
27683 self.write(", ");
27684 self.generate_expression(expression)?;
27685 }
27686 self.write(")");
27687 Ok(())
27688 }
27689
27690 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
27691 self.generate_expression(&e.this)?;
27693 self.write_space();
27694 self.write_keyword("AT");
27695 self.write_space();
27696 self.generate_expression(&e.expression)?;
27697 Ok(())
27698 }
27699
27700 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
27701 self.write_keyword("ATTACH");
27703 if e.exists {
27704 self.write_space();
27705 self.write_keyword("IF NOT EXISTS");
27706 }
27707 self.write_space();
27708 self.generate_expression(&e.this)?;
27709 if !e.expressions.is_empty() {
27710 self.write(" (");
27711 for (i, expr) in e.expressions.iter().enumerate() {
27712 if i > 0 {
27713 self.write(", ");
27714 }
27715 self.generate_expression(expr)?;
27716 }
27717 self.write(")");
27718 }
27719 Ok(())
27720 }
27721
27722 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
27723 self.generate_expression(&e.this)?;
27726 if let Some(expression) = &e.expression {
27727 self.write_space();
27728 self.generate_expression(expression)?;
27729 }
27730 Ok(())
27731 }
27732
27733 fn generate_auto_increment_keyword(
27737 &mut self,
27738 col: &crate::expressions::ColumnDef,
27739 ) -> Result<()> {
27740 use crate::dialects::DialectType;
27741 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
27742 self.write_keyword("IDENTITY");
27743 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27744 self.write("(");
27745 if let Some(ref start) = col.auto_increment_start {
27746 self.generate_expression(start)?;
27747 } else {
27748 self.write("0");
27749 }
27750 self.write(", ");
27751 if let Some(ref inc) = col.auto_increment_increment {
27752 self.generate_expression(inc)?;
27753 } else {
27754 self.write("1");
27755 }
27756 self.write(")");
27757 }
27758 } else if matches!(
27759 self.config.dialect,
27760 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
27761 ) {
27762 self.write_keyword("AUTOINCREMENT");
27763 if let Some(ref start) = col.auto_increment_start {
27764 self.write_space();
27765 self.write_keyword("START");
27766 self.write_space();
27767 self.generate_expression(start)?;
27768 }
27769 if let Some(ref inc) = col.auto_increment_increment {
27770 self.write_space();
27771 self.write_keyword("INCREMENT");
27772 self.write_space();
27773 self.generate_expression(inc)?;
27774 }
27775 if let Some(order) = col.auto_increment_order {
27776 self.write_space();
27777 if order {
27778 self.write_keyword("ORDER");
27779 } else {
27780 self.write_keyword("NOORDER");
27781 }
27782 }
27783 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
27784 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
27785 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27786 self.write(" (");
27787 let mut first = true;
27788 if let Some(ref start) = col.auto_increment_start {
27789 self.write_keyword("START WITH");
27790 self.write_space();
27791 self.generate_expression(start)?;
27792 first = false;
27793 }
27794 if let Some(ref inc) = col.auto_increment_increment {
27795 if !first {
27796 self.write_space();
27797 }
27798 self.write_keyword("INCREMENT BY");
27799 self.write_space();
27800 self.generate_expression(inc)?;
27801 }
27802 self.write(")");
27803 }
27804 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
27805 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27808 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
27809 } else {
27810 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
27811 }
27812 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27813 self.write(" (");
27814 let mut first = true;
27815 if let Some(ref start) = col.auto_increment_start {
27816 self.write_keyword("START WITH");
27817 self.write_space();
27818 self.generate_expression(start)?;
27819 first = false;
27820 }
27821 if let Some(ref inc) = col.auto_increment_increment {
27822 if !first {
27823 self.write_space();
27824 }
27825 self.write_keyword("INCREMENT BY");
27826 self.write_space();
27827 self.generate_expression(inc)?;
27828 }
27829 self.write(")");
27830 }
27831 } else if matches!(
27832 self.config.dialect,
27833 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27834 ) {
27835 self.write_keyword("IDENTITY");
27836 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27837 self.write("(");
27838 if let Some(ref start) = col.auto_increment_start {
27839 self.generate_expression(start)?;
27840 } else {
27841 self.write("0");
27842 }
27843 self.write(", ");
27844 if let Some(ref inc) = col.auto_increment_increment {
27845 self.generate_expression(inc)?;
27846 } else {
27847 self.write("1");
27848 }
27849 self.write(")");
27850 }
27851 } else {
27852 self.write_keyword("AUTO_INCREMENT");
27853 if let Some(ref start) = col.auto_increment_start {
27854 self.write_space();
27855 self.write_keyword("START");
27856 self.write_space();
27857 self.generate_expression(start)?;
27858 }
27859 if let Some(ref inc) = col.auto_increment_increment {
27860 self.write_space();
27861 self.write_keyword("INCREMENT");
27862 self.write_space();
27863 self.generate_expression(inc)?;
27864 }
27865 if let Some(order) = col.auto_increment_order {
27866 self.write_space();
27867 if order {
27868 self.write_keyword("ORDER");
27869 } else {
27870 self.write_keyword("NOORDER");
27871 }
27872 }
27873 }
27874 Ok(())
27875 }
27876
27877 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
27878 self.write_keyword("AUTO_INCREMENT");
27880 self.write("=");
27881 self.generate_expression(&e.this)?;
27882 Ok(())
27883 }
27884
27885 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
27886 self.write_keyword("AUTO_REFRESH");
27888 self.write("=");
27889 self.generate_expression(&e.this)?;
27890 Ok(())
27891 }
27892
27893 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
27894 self.write_keyword("BACKUP");
27896 self.write_space();
27897 self.generate_expression(&e.this)?;
27898 Ok(())
27899 }
27900
27901 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
27902 self.write_keyword("BASE64_DECODE_BINARY");
27904 self.write("(");
27905 self.generate_expression(&e.this)?;
27906 if let Some(alphabet) = &e.alphabet {
27907 self.write(", ");
27908 self.generate_expression(alphabet)?;
27909 }
27910 self.write(")");
27911 Ok(())
27912 }
27913
27914 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
27915 self.write_keyword("BASE64_DECODE_STRING");
27917 self.write("(");
27918 self.generate_expression(&e.this)?;
27919 if let Some(alphabet) = &e.alphabet {
27920 self.write(", ");
27921 self.generate_expression(alphabet)?;
27922 }
27923 self.write(")");
27924 Ok(())
27925 }
27926
27927 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
27928 self.write_keyword("BASE64_ENCODE");
27930 self.write("(");
27931 self.generate_expression(&e.this)?;
27932 if let Some(max_line_length) = &e.max_line_length {
27933 self.write(", ");
27934 self.generate_expression(max_line_length)?;
27935 }
27936 if let Some(alphabet) = &e.alphabet {
27937 self.write(", ");
27938 self.generate_expression(alphabet)?;
27939 }
27940 self.write(")");
27941 Ok(())
27942 }
27943
27944 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
27945 self.write_keyword("BLOCKCOMPRESSION");
27947 self.write("=");
27948 if let Some(autotemp) = &e.autotemp {
27949 self.write_keyword("AUTOTEMP");
27950 self.write("(");
27951 self.generate_expression(autotemp)?;
27952 self.write(")");
27953 }
27954 if let Some(always) = &e.always {
27955 self.generate_expression(always)?;
27956 }
27957 if let Some(default) = &e.default {
27958 self.generate_expression(default)?;
27959 }
27960 if let Some(manual) = &e.manual {
27961 self.generate_expression(manual)?;
27962 }
27963 if let Some(never) = &e.never {
27964 self.generate_expression(never)?;
27965 }
27966 Ok(())
27967 }
27968
27969 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
27970 self.write("((");
27972 self.generate_expression(&e.this)?;
27973 self.write(") ");
27974 self.write_keyword("AND");
27975 self.write(" (");
27976 self.generate_expression(&e.expression)?;
27977 self.write("))");
27978 Ok(())
27979 }
27980
27981 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
27982 self.write("((");
27984 self.generate_expression(&e.this)?;
27985 self.write(") ");
27986 self.write_keyword("OR");
27987 self.write(" (");
27988 self.generate_expression(&e.expression)?;
27989 self.write("))");
27990 Ok(())
27991 }
27992
27993 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
27994 self.write_keyword("BUILD");
27996 self.write_space();
27997 self.generate_expression(&e.this)?;
27998 Ok(())
27999 }
28000
28001 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
28002 self.generate_expression(&e.this)?;
28004 Ok(())
28005 }
28006
28007 fn generate_case_specific_column_constraint(
28008 &mut self,
28009 e: &CaseSpecificColumnConstraint,
28010 ) -> Result<()> {
28011 if e.not_.is_some() {
28013 self.write_keyword("NOT");
28014 self.write_space();
28015 }
28016 self.write_keyword("CASESPECIFIC");
28017 Ok(())
28018 }
28019
28020 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
28021 self.write_keyword("CAST");
28023 self.write("(");
28024 self.generate_expression(&e.this)?;
28025 if self.config.dialect == Some(DialectType::ClickHouse) {
28026 self.write(", ");
28028 } else {
28029 self.write_space();
28030 self.write_keyword("AS");
28031 self.write_space();
28032 }
28033 if let Some(to) = &e.to {
28034 self.generate_expression(to)?;
28035 }
28036 self.write(")");
28037 Ok(())
28038 }
28039
28040 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
28041 self.write_keyword("CHANGES");
28044 self.write(" (");
28045 if let Some(information) = &e.information {
28046 self.write_keyword("INFORMATION");
28047 self.write(" => ");
28048 self.generate_expression(information)?;
28049 }
28050 self.write(")");
28051 if let Some(at_before) = &e.at_before {
28053 self.write(" ");
28054 self.generate_expression(at_before)?;
28055 }
28056 if let Some(end) = &e.end {
28057 self.write(" ");
28058 self.generate_expression(end)?;
28059 }
28060 Ok(())
28061 }
28062
28063 fn generate_character_set_column_constraint(
28064 &mut self,
28065 e: &CharacterSetColumnConstraint,
28066 ) -> Result<()> {
28067 self.write_keyword("CHARACTER SET");
28069 self.write_space();
28070 self.generate_expression(&e.this)?;
28071 Ok(())
28072 }
28073
28074 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
28075 if e.default.is_some() {
28077 self.write_keyword("DEFAULT");
28078 self.write_space();
28079 }
28080 self.write_keyword("CHARACTER SET");
28081 self.write("=");
28082 self.generate_expression(&e.this)?;
28083 Ok(())
28084 }
28085
28086 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
28087 self.write_keyword("CHECK");
28089 self.write(" (");
28090 self.generate_expression(&e.this)?;
28091 self.write(")");
28092 if e.enforced.is_some() {
28093 self.write_space();
28094 self.write_keyword("ENFORCED");
28095 }
28096 Ok(())
28097 }
28098
28099 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
28100 self.write_keyword("ASSUME");
28102 self.write(" (");
28103 self.generate_expression(&e.this)?;
28104 self.write(")");
28105 Ok(())
28106 }
28107
28108 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
28109 self.write_keyword("CHECK_JSON");
28111 self.write("(");
28112 self.generate_expression(&e.this)?;
28113 self.write(")");
28114 Ok(())
28115 }
28116
28117 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
28118 self.write_keyword("CHECK_XML");
28120 self.write("(");
28121 self.generate_expression(&e.this)?;
28122 self.write(")");
28123 Ok(())
28124 }
28125
28126 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
28127 self.write_keyword("CHECKSUM");
28129 self.write("=");
28130 if e.on.is_some() {
28131 self.write_keyword("ON");
28132 } else if e.default.is_some() {
28133 self.write_keyword("DEFAULT");
28134 } else {
28135 self.write_keyword("OFF");
28136 }
28137 Ok(())
28138 }
28139
28140 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
28141 if e.shallow.is_some() {
28143 self.write_keyword("SHALLOW");
28144 self.write_space();
28145 }
28146 if e.copy.is_some() {
28147 self.write_keyword("COPY");
28148 } else {
28149 self.write_keyword("CLONE");
28150 }
28151 self.write_space();
28152 self.generate_expression(&e.this)?;
28153 Ok(())
28154 }
28155
28156 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
28157 self.write_keyword("CLUSTER BY");
28159 self.write(" (");
28160 for (i, ord) in e.expressions.iter().enumerate() {
28161 if i > 0 {
28162 self.write(", ");
28163 }
28164 self.generate_ordered(ord)?;
28165 }
28166 self.write(")");
28167 Ok(())
28168 }
28169
28170 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
28171 self.write_keyword("CLUSTER BY");
28173 self.write_space();
28174 for (i, col) in e.columns.iter().enumerate() {
28175 if i > 0 {
28176 self.write(", ");
28177 }
28178 self.generate_identifier(col)?;
28179 }
28180 Ok(())
28181 }
28182
28183 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
28184 self.write_keyword("CLUSTERED BY");
28186 self.write(" (");
28187 for (i, expr) in e.expressions.iter().enumerate() {
28188 if i > 0 {
28189 self.write(", ");
28190 }
28191 self.generate_expression(expr)?;
28192 }
28193 self.write(")");
28194 if let Some(sorted_by) = &e.sorted_by {
28195 self.write_space();
28196 self.write_keyword("SORTED BY");
28197 self.write(" (");
28198 if let Expression::Tuple(t) = sorted_by.as_ref() {
28200 for (i, expr) in t.expressions.iter().enumerate() {
28201 if i > 0 {
28202 self.write(", ");
28203 }
28204 self.generate_expression(expr)?;
28205 }
28206 } else {
28207 self.generate_expression(sorted_by)?;
28208 }
28209 self.write(")");
28210 }
28211 if let Some(buckets) = &e.buckets {
28212 self.write_space();
28213 self.write_keyword("INTO");
28214 self.write_space();
28215 self.generate_expression(buckets)?;
28216 self.write_space();
28217 self.write_keyword("BUCKETS");
28218 }
28219 Ok(())
28220 }
28221
28222 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
28223 if e.default.is_some() {
28227 self.write_keyword("DEFAULT");
28228 self.write_space();
28229 }
28230 self.write_keyword("COLLATE");
28231 match self.config.dialect {
28233 Some(DialectType::BigQuery) => self.write_space(),
28234 _ => self.write("="),
28235 }
28236 self.generate_expression(&e.this)?;
28237 Ok(())
28238 }
28239
28240 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
28241 match e {
28243 ColumnConstraint::NotNull => {
28244 self.write_keyword("NOT NULL");
28245 }
28246 ColumnConstraint::Null => {
28247 self.write_keyword("NULL");
28248 }
28249 ColumnConstraint::Unique => {
28250 self.write_keyword("UNIQUE");
28251 }
28252 ColumnConstraint::PrimaryKey => {
28253 self.write_keyword("PRIMARY KEY");
28254 }
28255 ColumnConstraint::Default(expr) => {
28256 self.write_keyword("DEFAULT");
28257 self.write_space();
28258 self.generate_expression(expr)?;
28259 }
28260 ColumnConstraint::Check(expr) => {
28261 self.write_keyword("CHECK");
28262 self.write(" (");
28263 self.generate_expression(expr)?;
28264 self.write(")");
28265 }
28266 ColumnConstraint::References(fk_ref) => {
28267 if fk_ref.has_foreign_key_keywords {
28268 self.write_keyword("FOREIGN KEY");
28269 self.write_space();
28270 }
28271 self.write_keyword("REFERENCES");
28272 self.write_space();
28273 self.generate_table(&fk_ref.table)?;
28274 if !fk_ref.columns.is_empty() {
28275 self.write(" (");
28276 for (i, col) in fk_ref.columns.iter().enumerate() {
28277 if i > 0 {
28278 self.write(", ");
28279 }
28280 self.generate_identifier(col)?;
28281 }
28282 self.write(")");
28283 }
28284 }
28285 ColumnConstraint::GeneratedAsIdentity(gen) => {
28286 self.write_keyword("GENERATED");
28287 self.write_space();
28288 if gen.always {
28289 self.write_keyword("ALWAYS");
28290 } else {
28291 self.write_keyword("BY DEFAULT");
28292 if gen.on_null {
28293 self.write_space();
28294 self.write_keyword("ON NULL");
28295 }
28296 }
28297 self.write_space();
28298 self.write_keyword("AS IDENTITY");
28299 }
28300 ColumnConstraint::Collate(collation) => {
28301 self.write_keyword("COLLATE");
28302 self.write_space();
28303 self.generate_identifier(collation)?;
28304 }
28305 ColumnConstraint::Comment(comment) => {
28306 self.write_keyword("COMMENT");
28307 self.write(" '");
28308 self.write(comment);
28309 self.write("'");
28310 }
28311 ColumnConstraint::ComputedColumn(cc) => {
28312 self.generate_computed_column_inline(cc)?;
28313 }
28314 ColumnConstraint::GeneratedAsRow(gar) => {
28315 self.generate_generated_as_row_inline(gar)?;
28316 }
28317 ColumnConstraint::Tags(tags) => {
28318 self.write_keyword("TAG");
28319 self.write(" (");
28320 for (i, expr) in tags.expressions.iter().enumerate() {
28321 if i > 0 {
28322 self.write(", ");
28323 }
28324 self.generate_expression(expr)?;
28325 }
28326 self.write(")");
28327 }
28328 ColumnConstraint::Path(path_expr) => {
28329 self.write_keyword("PATH");
28330 self.write_space();
28331 self.generate_expression(path_expr)?;
28332 }
28333 }
28334 Ok(())
28335 }
28336
28337 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
28338 match e {
28340 ColumnPosition::First => {
28341 self.write_keyword("FIRST");
28342 }
28343 ColumnPosition::After(ident) => {
28344 self.write_keyword("AFTER");
28345 self.write_space();
28346 self.generate_identifier(ident)?;
28347 }
28348 }
28349 Ok(())
28350 }
28351
28352 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
28353 self.generate_expression(&e.this)?;
28355 self.write("(");
28356 self.generate_expression(&e.expression)?;
28357 self.write(")");
28358 Ok(())
28359 }
28360
28361 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
28362 if let Some(ref unpack) = e.unpack {
28365 if let Expression::Boolean(b) = unpack.as_ref() {
28366 if b.value {
28367 self.write("*");
28368 }
28369 }
28370 }
28371 self.write_keyword("COLUMNS");
28372 self.write("(");
28373 self.generate_expression(&e.this)?;
28374 self.write(")");
28375 Ok(())
28376 }
28377
28378 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
28379 self.generate_expression(&e.this)?;
28381 self.write("(");
28382 for (i, expr) in e.expressions.iter().enumerate() {
28383 if i > 0 {
28384 self.write(", ");
28385 }
28386 self.generate_expression(expr)?;
28387 }
28388 self.write(")");
28389 Ok(())
28390 }
28391
28392 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
28393 self.generate_expression(&e.this)?;
28395 self.write("(");
28396 for (i, param) in e.params.iter().enumerate() {
28397 if i > 0 {
28398 self.write(", ");
28399 }
28400 self.generate_expression(param)?;
28401 }
28402 self.write(")(");
28403 for (i, expr) in e.expressions.iter().enumerate() {
28404 if i > 0 {
28405 self.write(", ");
28406 }
28407 self.generate_expression(expr)?;
28408 }
28409 self.write(")");
28410 Ok(())
28411 }
28412
28413 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
28414 self.write_keyword("COMMIT");
28416
28417 if e.this.is_none()
28419 && matches!(
28420 self.config.dialect,
28421 Some(DialectType::TSQL) | Some(DialectType::Fabric)
28422 )
28423 {
28424 self.write_space();
28425 self.write_keyword("TRANSACTION");
28426 }
28427
28428 if let Some(this) = &e.this {
28430 let is_transaction_marker = matches!(
28432 this.as_ref(),
28433 Expression::Identifier(id) if id.name == "TRANSACTION"
28434 );
28435
28436 self.write_space();
28437 self.write_keyword("TRANSACTION");
28438
28439 if !is_transaction_marker {
28441 self.write_space();
28442 self.generate_expression(this)?;
28443 }
28444 }
28445
28446 if let Some(durability) = &e.durability {
28448 self.write_space();
28449 self.write_keyword("WITH");
28450 self.write(" (");
28451 self.write_keyword("DELAYED_DURABILITY");
28452 self.write(" = ");
28453 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
28454 self.write_keyword("ON");
28455 } else {
28456 self.write_keyword("OFF");
28457 }
28458 self.write(")");
28459 }
28460
28461 if let Some(chain) = &e.chain {
28463 self.write_space();
28464 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
28465 self.write_keyword("AND NO CHAIN");
28466 } else {
28467 self.write_keyword("AND CHAIN");
28468 }
28469 }
28470 Ok(())
28471 }
28472
28473 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
28474 self.write("[");
28476 self.generate_expression(&e.this)?;
28477 self.write_space();
28478 self.write_keyword("FOR");
28479 self.write_space();
28480 self.generate_expression(&e.expression)?;
28481 if let Some(pos) = &e.position {
28483 self.write(", ");
28484 self.generate_expression(pos)?;
28485 }
28486 if let Some(iterator) = &e.iterator {
28487 self.write_space();
28488 self.write_keyword("IN");
28489 self.write_space();
28490 self.generate_expression(iterator)?;
28491 }
28492 if let Some(condition) = &e.condition {
28493 self.write_space();
28494 self.write_keyword("IF");
28495 self.write_space();
28496 self.generate_expression(condition)?;
28497 }
28498 self.write("]");
28499 Ok(())
28500 }
28501
28502 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
28503 self.write_keyword("COMPRESS");
28505 self.write("(");
28506 self.generate_expression(&e.this)?;
28507 if let Some(method) = &e.method {
28508 self.write(", '");
28509 self.write(method);
28510 self.write("'");
28511 }
28512 self.write(")");
28513 Ok(())
28514 }
28515
28516 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
28517 self.write_keyword("COMPRESS");
28519 if let Some(this) = &e.this {
28520 self.write_space();
28521 self.generate_expression(this)?;
28522 }
28523 Ok(())
28524 }
28525
28526 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
28527 self.write_keyword("AS");
28529 self.write_space();
28530 self.generate_expression(&e.this)?;
28531 if e.not_null.is_some() {
28532 self.write_space();
28533 self.write_keyword("PERSISTED NOT NULL");
28534 } else if e.persisted.is_some() {
28535 self.write_space();
28536 self.write_keyword("PERSISTED");
28537 }
28538 Ok(())
28539 }
28540
28541 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
28545 let computed_expr = if matches!(
28546 self.config.dialect,
28547 Some(DialectType::TSQL) | Some(DialectType::Fabric)
28548 ) {
28549 match &*cc.expression {
28550 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
28551 {
28552 let wrapped = Expression::Cast(Box::new(Cast {
28553 this: y.this.clone(),
28554 to: DataType::Date,
28555 trailing_comments: Vec::new(),
28556 double_colon_syntax: false,
28557 format: None,
28558 default: None,
28559 inferred_type: None,
28560 }));
28561 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
28562 }
28563 Expression::Function(f)
28564 if f.name.eq_ignore_ascii_case("YEAR")
28565 && f.args.len() == 1
28566 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
28567 {
28568 let wrapped = Expression::Cast(Box::new(Cast {
28569 this: f.args[0].clone(),
28570 to: DataType::Date,
28571 trailing_comments: Vec::new(),
28572 double_colon_syntax: false,
28573 format: None,
28574 default: None,
28575 inferred_type: None,
28576 }));
28577 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
28578 }
28579 _ => *cc.expression.clone(),
28580 }
28581 } else {
28582 *cc.expression.clone()
28583 };
28584
28585 match cc.persistence_kind.as_deref() {
28586 Some("STORED") | Some("VIRTUAL") => {
28587 self.write_keyword("GENERATED ALWAYS AS");
28589 self.write(" (");
28590 self.generate_expression(&computed_expr)?;
28591 self.write(")");
28592 self.write_space();
28593 if cc.persisted {
28594 self.write_keyword("STORED");
28595 } else {
28596 self.write_keyword("VIRTUAL");
28597 }
28598 }
28599 Some("PERSISTED") => {
28600 self.write_keyword("AS");
28602 self.write(" (");
28603 self.generate_expression(&computed_expr)?;
28604 self.write(")");
28605 self.write_space();
28606 self.write_keyword("PERSISTED");
28607 if let Some(ref dt) = cc.data_type {
28609 self.write_space();
28610 self.generate_data_type(dt)?;
28611 }
28612 if cc.not_null {
28613 self.write_space();
28614 self.write_keyword("NOT NULL");
28615 }
28616 }
28617 _ => {
28618 if matches!(
28621 self.config.dialect,
28622 Some(DialectType::Spark)
28623 | Some(DialectType::Databricks)
28624 | Some(DialectType::Hive)
28625 ) {
28626 self.write_keyword("GENERATED ALWAYS AS");
28627 self.write(" (");
28628 self.generate_expression(&computed_expr)?;
28629 self.write(")");
28630 } else if matches!(
28631 self.config.dialect,
28632 Some(DialectType::TSQL) | Some(DialectType::Fabric)
28633 ) {
28634 self.write_keyword("AS");
28635 let omit_parens = matches!(computed_expr, Expression::Year(_))
28636 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
28637 if omit_parens {
28638 self.write_space();
28639 self.generate_expression(&computed_expr)?;
28640 } else {
28641 self.write(" (");
28642 self.generate_expression(&computed_expr)?;
28643 self.write(")");
28644 }
28645 } else {
28646 self.write_keyword("AS");
28647 self.write(" (");
28648 self.generate_expression(&computed_expr)?;
28649 self.write(")");
28650 }
28651 }
28652 }
28653 Ok(())
28654 }
28655
28656 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
28659 self.write_keyword("GENERATED ALWAYS AS ROW ");
28660 if gar.start {
28661 self.write_keyword("START");
28662 } else {
28663 self.write_keyword("END");
28664 }
28665 if gar.hidden {
28666 self.write_space();
28667 self.write_keyword("HIDDEN");
28668 }
28669 Ok(())
28670 }
28671
28672 fn generate_system_versioning_content(
28674 &mut self,
28675 e: &WithSystemVersioningProperty,
28676 ) -> Result<()> {
28677 let mut parts = Vec::new();
28678
28679 if let Some(this) = &e.this {
28680 let mut s = String::from("HISTORY_TABLE=");
28681 let mut gen = Generator::with_arc_config(self.config.clone());
28682 gen.generate_expression(this)?;
28683 s.push_str(&gen.output);
28684 parts.push(s);
28685 }
28686
28687 if let Some(data_consistency) = &e.data_consistency {
28688 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
28689 let mut gen = Generator::with_arc_config(self.config.clone());
28690 gen.generate_expression(data_consistency)?;
28691 s.push_str(&gen.output);
28692 parts.push(s);
28693 }
28694
28695 if let Some(retention_period) = &e.retention_period {
28696 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
28697 let mut gen = Generator::with_arc_config(self.config.clone());
28698 gen.generate_expression(retention_period)?;
28699 s.push_str(&gen.output);
28700 parts.push(s);
28701 }
28702
28703 self.write_keyword("SYSTEM_VERSIONING");
28704 self.write("=");
28705
28706 if !parts.is_empty() {
28707 self.write_keyword("ON");
28708 self.write("(");
28709 self.write(&parts.join(", "));
28710 self.write(")");
28711 } else if e.on.is_some() {
28712 self.write_keyword("ON");
28713 } else {
28714 self.write_keyword("OFF");
28715 }
28716
28717 Ok(())
28718 }
28719
28720 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
28721 if e.else_.is_some() {
28724 self.write_keyword("ELSE");
28725 self.write_space();
28726 } else if let Some(expression) = &e.expression {
28727 self.write_keyword("WHEN");
28728 self.write_space();
28729 self.generate_expression(expression)?;
28730 self.write_space();
28731 self.write_keyword("THEN");
28732 self.write_space();
28733 }
28734
28735 if let Expression::Insert(insert) = e.this.as_ref() {
28738 self.write_keyword("INTO");
28739 self.write_space();
28740 self.generate_table(&insert.table)?;
28741
28742 if !insert.columns.is_empty() {
28744 self.write(" (");
28745 for (i, col) in insert.columns.iter().enumerate() {
28746 if i > 0 {
28747 self.write(", ");
28748 }
28749 self.generate_identifier(col)?;
28750 }
28751 self.write(")");
28752 }
28753
28754 if !insert.values.is_empty() {
28756 self.write_space();
28757 self.write_keyword("VALUES");
28758 for (row_idx, row) in insert.values.iter().enumerate() {
28759 if row_idx > 0 {
28760 self.write(", ");
28761 }
28762 self.write(" (");
28763 for (i, val) in row.iter().enumerate() {
28764 if i > 0 {
28765 self.write(", ");
28766 }
28767 self.generate_expression(val)?;
28768 }
28769 self.write(")");
28770 }
28771 }
28772 } else {
28773 self.generate_expression(&e.this)?;
28775 }
28776 Ok(())
28777 }
28778
28779 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
28780 self.write_keyword("CONSTRAINT");
28782 self.write_space();
28783 self.generate_expression(&e.this)?;
28784 if !e.expressions.is_empty() {
28785 self.write_space();
28786 for (i, expr) in e.expressions.iter().enumerate() {
28787 if i > 0 {
28788 self.write_space();
28789 }
28790 self.generate_expression(expr)?;
28791 }
28792 }
28793 Ok(())
28794 }
28795
28796 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
28797 self.write_keyword("CONVERT_TIMEZONE");
28799 self.write("(");
28800 let mut first = true;
28801 if let Some(source_tz) = &e.source_tz {
28802 self.generate_expression(source_tz)?;
28803 first = false;
28804 }
28805 if let Some(target_tz) = &e.target_tz {
28806 if !first {
28807 self.write(", ");
28808 }
28809 self.generate_expression(target_tz)?;
28810 first = false;
28811 }
28812 if let Some(timestamp) = &e.timestamp {
28813 if !first {
28814 self.write(", ");
28815 }
28816 self.generate_expression(timestamp)?;
28817 }
28818 self.write(")");
28819 Ok(())
28820 }
28821
28822 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
28823 self.write_keyword("CONVERT");
28825 self.write("(");
28826 self.generate_expression(&e.this)?;
28827 if let Some(dest) = &e.dest {
28828 self.write_space();
28829 self.write_keyword("USING");
28830 self.write_space();
28831 self.generate_expression(dest)?;
28832 }
28833 self.write(")");
28834 Ok(())
28835 }
28836
28837 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
28838 self.write_keyword("COPY");
28839 if e.is_into {
28840 self.write_space();
28841 self.write_keyword("INTO");
28842 }
28843 self.write_space();
28844
28845 if let Expression::Literal(lit) = &e.this {
28847 if let Literal::String(s) = lit.as_ref() {
28848 if s.starts_with('@') {
28849 self.write(s);
28850 } else {
28851 self.generate_expression(&e.this)?;
28852 }
28853 }
28854 } else {
28855 self.generate_expression(&e.this)?;
28856 }
28857
28858 if e.kind {
28860 if self.config.pretty {
28862 self.write_newline();
28863 } else {
28864 self.write_space();
28865 }
28866 self.write_keyword("FROM");
28867 self.write_space();
28868 } else if !e.files.is_empty() {
28869 if self.config.pretty {
28871 self.write_newline();
28872 } else {
28873 self.write_space();
28874 }
28875 self.write_keyword("TO");
28876 self.write_space();
28877 }
28878
28879 for (i, file) in e.files.iter().enumerate() {
28881 if i > 0 {
28882 self.write_space();
28883 }
28884 if let Expression::Literal(lit) = file {
28886 if let Literal::String(s) = lit.as_ref() {
28887 if s.starts_with('@') {
28888 self.write(s);
28889 } else {
28890 self.generate_expression(file)?;
28891 }
28892 }
28893 } else if let Expression::Identifier(id) = file {
28894 if id.quoted {
28896 self.write("`");
28897 self.write(&id.name);
28898 self.write("`");
28899 } else {
28900 self.generate_expression(file)?;
28901 }
28902 } else {
28903 self.generate_expression(file)?;
28904 }
28905 }
28906
28907 if !e.with_wrapped {
28909 if let Some(ref creds) = e.credentials {
28910 if let Some(ref storage) = creds.storage {
28911 if self.config.pretty {
28912 self.write_newline();
28913 } else {
28914 self.write_space();
28915 }
28916 self.write_keyword("STORAGE_INTEGRATION");
28917 self.write(" = ");
28918 self.write(storage);
28919 }
28920 if creds.credentials.is_empty() {
28921 if self.config.pretty {
28923 self.write_newline();
28924 } else {
28925 self.write_space();
28926 }
28927 self.write_keyword("CREDENTIALS");
28928 self.write(" = ()");
28929 } else {
28930 if self.config.pretty {
28931 self.write_newline();
28932 } else {
28933 self.write_space();
28934 }
28935 self.write_keyword("CREDENTIALS");
28936 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
28939 self.write(" '");
28941 self.write(&creds.credentials[0].1);
28942 self.write("'");
28943 } else {
28944 self.write(" = (");
28946 for (i, (k, v)) in creds.credentials.iter().enumerate() {
28947 if i > 0 {
28948 self.write_space();
28949 }
28950 self.write(k);
28951 self.write("='");
28952 self.write(v);
28953 self.write("'");
28954 }
28955 self.write(")");
28956 }
28957 }
28958 if let Some(ref encryption) = creds.encryption {
28959 self.write_space();
28960 self.write_keyword("ENCRYPTION");
28961 self.write(" = ");
28962 self.write(encryption);
28963 }
28964 }
28965 }
28966
28967 if !e.params.is_empty() {
28969 if e.with_wrapped {
28970 self.write_space();
28972 self.write_keyword("WITH");
28973 self.write(" (");
28974 for (i, param) in e.params.iter().enumerate() {
28975 if i > 0 {
28976 self.write(", ");
28977 }
28978 self.generate_copy_param_with_format(param)?;
28979 }
28980 self.write(")");
28981 } else {
28982 for param in &e.params {
28986 if self.config.pretty {
28987 self.write_newline();
28988 } else {
28989 self.write_space();
28990 }
28991 self.write(¶m.name);
28993 if let Some(ref value) = param.value {
28994 if param.eq {
28996 self.write(" = ");
28997 } else {
28998 self.write(" ");
28999 }
29000 if !param.values.is_empty() {
29001 self.write("(");
29002 for (i, v) in param.values.iter().enumerate() {
29003 if i > 0 {
29004 self.write_space();
29005 }
29006 self.generate_copy_nested_param(v)?;
29007 }
29008 self.write(")");
29009 } else {
29010 self.generate_copy_param_value(value)?;
29012 }
29013 } else if !param.values.is_empty() {
29014 if param.eq {
29016 self.write(" = (");
29017 } else {
29018 self.write(" (");
29019 }
29020 let is_key_value_pairs = param
29025 .values
29026 .first()
29027 .map_or(false, |v| matches!(v, Expression::Eq(_)));
29028 let sep = if is_key_value_pairs && param.eq {
29029 " "
29030 } else {
29031 ", "
29032 };
29033 for (i, v) in param.values.iter().enumerate() {
29034 if i > 0 {
29035 self.write(sep);
29036 }
29037 self.generate_copy_nested_param(v)?;
29038 }
29039 self.write(")");
29040 }
29041 }
29042 }
29043 }
29044
29045 Ok(())
29046 }
29047
29048 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
29051 self.write_keyword(¶m.name);
29052 if !param.values.is_empty() {
29053 self.write(" = (");
29055 for (i, v) in param.values.iter().enumerate() {
29056 if i > 0 {
29057 self.write(", ");
29058 }
29059 self.generate_copy_nested_param(v)?;
29060 }
29061 self.write(")");
29062 } else if let Some(ref value) = param.value {
29063 if param.eq {
29064 self.write(" = ");
29065 } else {
29066 self.write(" ");
29067 }
29068 self.generate_expression(value)?;
29069 }
29070 Ok(())
29071 }
29072
29073 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
29075 match expr {
29076 Expression::Eq(eq) => {
29077 match &eq.left {
29079 Expression::Column(c) => self.write(&c.name.name),
29080 _ => self.generate_expression(&eq.left)?,
29081 }
29082 self.write("=");
29083 match &eq.right {
29085 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
29086 let Literal::String(s) = lit.as_ref() else {
29087 unreachable!()
29088 };
29089 self.write("'");
29090 self.write(s);
29091 self.write("'");
29092 }
29093 Expression::Tuple(t) => {
29094 self.write("(");
29096 if self.config.pretty {
29097 self.write_newline();
29098 self.indent_level += 1;
29099 for (i, item) in t.expressions.iter().enumerate() {
29100 if i > 0 {
29101 self.write(", ");
29102 }
29103 self.write_indent();
29104 self.generate_expression(item)?;
29105 }
29106 self.write_newline();
29107 self.indent_level -= 1;
29108 } else {
29109 for (i, item) in t.expressions.iter().enumerate() {
29110 if i > 0 {
29111 self.write(", ");
29112 }
29113 self.generate_expression(item)?;
29114 }
29115 }
29116 self.write(")");
29117 }
29118 _ => self.generate_expression(&eq.right)?,
29119 }
29120 Ok(())
29121 }
29122 Expression::Column(c) => {
29123 self.write(&c.name.name);
29125 Ok(())
29126 }
29127 _ => self.generate_expression(expr),
29128 }
29129 }
29130
29131 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
29134 match expr {
29135 Expression::Column(c) => {
29136 if c.name.quoted {
29138 self.write("\"");
29139 self.write(&c.name.name);
29140 self.write("\"");
29141 } else {
29142 self.write(&c.name.name);
29143 }
29144 Ok(())
29145 }
29146 Expression::Identifier(id) => {
29147 if id.quoted {
29149 self.write("\"");
29150 self.write(&id.name);
29151 self.write("\"");
29152 } else {
29153 self.write(&id.name);
29154 }
29155 Ok(())
29156 }
29157 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
29158 let Literal::String(s) = lit.as_ref() else {
29159 unreachable!()
29160 };
29161 self.write("'");
29163 self.write(s);
29164 self.write("'");
29165 Ok(())
29166 }
29167 _ => self.generate_expression(expr),
29168 }
29169 }
29170
29171 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
29172 self.write_keyword(&e.name);
29173 if let Some(ref value) = e.value {
29174 if e.eq {
29175 self.write(" = ");
29176 } else {
29177 self.write(" ");
29178 }
29179 self.generate_expression(value)?;
29180 }
29181 if !e.values.is_empty() {
29182 if e.eq {
29183 self.write(" = ");
29184 } else {
29185 self.write(" ");
29186 }
29187 self.write("(");
29188 for (i, v) in e.values.iter().enumerate() {
29189 if i > 0 {
29190 self.write(", ");
29191 }
29192 self.generate_expression(v)?;
29193 }
29194 self.write(")");
29195 }
29196 Ok(())
29197 }
29198
29199 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
29200 self.write_keyword("CORR");
29202 self.write("(");
29203 self.generate_expression(&e.this)?;
29204 self.write(", ");
29205 self.generate_expression(&e.expression)?;
29206 self.write(")");
29207 Ok(())
29208 }
29209
29210 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
29211 self.write_keyword("COSINE_DISTANCE");
29213 self.write("(");
29214 self.generate_expression(&e.this)?;
29215 self.write(", ");
29216 self.generate_expression(&e.expression)?;
29217 self.write(")");
29218 Ok(())
29219 }
29220
29221 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
29222 self.write_keyword("COVAR_POP");
29224 self.write("(");
29225 self.generate_expression(&e.this)?;
29226 self.write(", ");
29227 self.generate_expression(&e.expression)?;
29228 self.write(")");
29229 Ok(())
29230 }
29231
29232 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
29233 self.write_keyword("COVAR_SAMP");
29235 self.write("(");
29236 self.generate_expression(&e.this)?;
29237 self.write(", ");
29238 self.generate_expression(&e.expression)?;
29239 self.write(")");
29240 Ok(())
29241 }
29242
29243 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
29244 self.write_keyword("CREDENTIALS");
29246 self.write(" (");
29247 for (i, (key, value)) in e.credentials.iter().enumerate() {
29248 if i > 0 {
29249 self.write(", ");
29250 }
29251 self.write(key);
29252 self.write("='");
29253 self.write(value);
29254 self.write("'");
29255 }
29256 self.write(")");
29257 Ok(())
29258 }
29259
29260 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
29261 self.write_keyword("CREDENTIALS");
29263 self.write("=(");
29264 for (i, expr) in e.expressions.iter().enumerate() {
29265 if i > 0 {
29266 self.write(", ");
29267 }
29268 self.generate_expression(expr)?;
29269 }
29270 self.write(")");
29271 Ok(())
29272 }
29273
29274 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
29275 use crate::dialects::DialectType;
29276
29277 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
29280 self.generate_expression(&e.this)?;
29281 self.write_space();
29282 self.write_keyword("AS");
29283 self.write_space();
29284 self.generate_identifier(&e.alias)?;
29285 return Ok(());
29286 }
29287 self.write(&e.alias.name);
29288
29289 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
29291
29292 if !e.columns.is_empty() && !skip_cte_columns {
29293 self.write("(");
29294 for (i, col) in e.columns.iter().enumerate() {
29295 if i > 0 {
29296 self.write(", ");
29297 }
29298 self.write(&col.name);
29299 }
29300 self.write(")");
29301 }
29302 if !e.key_expressions.is_empty() {
29304 self.write_space();
29305 self.write_keyword("USING KEY");
29306 self.write(" (");
29307 for (i, key) in e.key_expressions.iter().enumerate() {
29308 if i > 0 {
29309 self.write(", ");
29310 }
29311 self.write(&key.name);
29312 }
29313 self.write(")");
29314 }
29315 self.write_space();
29316 self.write_keyword("AS");
29317 self.write_space();
29318 if let Some(materialized) = e.materialized {
29319 if materialized {
29320 self.write_keyword("MATERIALIZED");
29321 } else {
29322 self.write_keyword("NOT MATERIALIZED");
29323 }
29324 self.write_space();
29325 }
29326 self.write("(");
29327 self.generate_expression(&e.this)?;
29328 self.write(")");
29329 Ok(())
29330 }
29331
29332 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
29333 if e.expressions.is_empty() {
29335 self.write_keyword("WITH CUBE");
29336 } else {
29337 self.write_keyword("CUBE");
29338 self.write("(");
29339 for (i, expr) in e.expressions.iter().enumerate() {
29340 if i > 0 {
29341 self.write(", ");
29342 }
29343 self.generate_expression(expr)?;
29344 }
29345 self.write(")");
29346 }
29347 Ok(())
29348 }
29349
29350 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
29351 self.write_keyword("CURRENT_DATETIME");
29353 if let Some(this) = &e.this {
29354 self.write("(");
29355 self.generate_expression(this)?;
29356 self.write(")");
29357 }
29358 Ok(())
29359 }
29360
29361 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
29362 self.write_keyword("CURRENT_SCHEMA");
29364 Ok(())
29365 }
29366
29367 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
29368 self.write_keyword("CURRENT_SCHEMAS");
29370 self.write("(");
29371 if !matches!(
29373 self.config.dialect,
29374 Some(crate::dialects::DialectType::Snowflake)
29375 ) {
29376 if let Some(this) = &e.this {
29377 self.generate_expression(this)?;
29378 }
29379 }
29380 self.write(")");
29381 Ok(())
29382 }
29383
29384 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
29385 self.write_keyword("CURRENT_USER");
29387 let needs_parens = e.this.is_some()
29389 || matches!(
29390 self.config.dialect,
29391 Some(DialectType::Snowflake)
29392 | Some(DialectType::Spark)
29393 | Some(DialectType::Hive)
29394 | Some(DialectType::DuckDB)
29395 | Some(DialectType::BigQuery)
29396 | Some(DialectType::MySQL)
29397 | Some(DialectType::Databricks)
29398 );
29399 if needs_parens {
29400 self.write("()");
29401 }
29402 Ok(())
29403 }
29404
29405 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
29406 if self.config.dialect == Some(DialectType::Solr) {
29408 self.generate_expression(&e.this)?;
29409 self.write(" ");
29410 self.write_keyword("OR");
29411 self.write(" ");
29412 self.generate_expression(&e.expression)?;
29413 } else if self.config.dialect == Some(DialectType::MySQL) {
29414 self.generate_mysql_concat_from_dpipe(e)?;
29415 } else {
29416 self.generate_expression(&e.this)?;
29418 self.write(" || ");
29419 self.generate_expression(&e.expression)?;
29420 }
29421 Ok(())
29422 }
29423
29424 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
29425 self.write_keyword("DATABLOCKSIZE");
29427 self.write("=");
29428 if let Some(size) = e.size {
29429 self.write(&size.to_string());
29430 if let Some(units) = &e.units {
29431 self.write_space();
29432 self.generate_expression(units)?;
29433 }
29434 } else if e.minimum.is_some() {
29435 self.write_keyword("MINIMUM");
29436 } else if e.maximum.is_some() {
29437 self.write_keyword("MAXIMUM");
29438 } else if e.default.is_some() {
29439 self.write_keyword("DEFAULT");
29440 }
29441 Ok(())
29442 }
29443
29444 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
29445 self.write_keyword("DATA_DELETION");
29447 self.write("=");
29448
29449 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
29450 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
29451
29452 if is_on {
29453 self.write_keyword("ON");
29454 if has_options {
29455 self.write("(");
29456 let mut first = true;
29457 if let Some(filter_column) = &e.filter_column {
29458 self.write_keyword("FILTER_COLUMN");
29459 self.write("=");
29460 self.generate_expression(filter_column)?;
29461 first = false;
29462 }
29463 if let Some(retention_period) = &e.retention_period {
29464 if !first {
29465 self.write(", ");
29466 }
29467 self.write_keyword("RETENTION_PERIOD");
29468 self.write("=");
29469 self.generate_expression(retention_period)?;
29470 }
29471 self.write(")");
29472 }
29473 } else {
29474 self.write_keyword("OFF");
29475 }
29476 Ok(())
29477 }
29478
29479 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
29483 use crate::dialects::DialectType;
29484 use crate::expressions::Literal;
29485
29486 match self.config.dialect {
29487 Some(DialectType::Exasol) => {
29489 self.write_keyword("TO_DATE");
29490 self.write("(");
29491 match &e.this {
29493 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
29494 let Literal::String(s) = lit.as_ref() else {
29495 unreachable!()
29496 };
29497 self.write("'");
29498 self.write(s);
29499 self.write("'");
29500 }
29501 _ => {
29502 self.generate_expression(&e.this)?;
29503 }
29504 }
29505 self.write(")");
29506 }
29507 _ => {
29509 self.write_keyword("DATE");
29510 self.write("(");
29511 self.generate_expression(&e.this)?;
29512 self.write(")");
29513 }
29514 }
29515 Ok(())
29516 }
29517
29518 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
29519 self.write_keyword("DATE_BIN");
29521 self.write("(");
29522 self.generate_expression(&e.this)?;
29523 self.write(", ");
29524 self.generate_expression(&e.expression)?;
29525 if let Some(origin) = &e.origin {
29526 self.write(", ");
29527 self.generate_expression(origin)?;
29528 }
29529 self.write(")");
29530 Ok(())
29531 }
29532
29533 fn generate_date_format_column_constraint(
29534 &mut self,
29535 e: &DateFormatColumnConstraint,
29536 ) -> Result<()> {
29537 self.write_keyword("FORMAT");
29539 self.write_space();
29540 self.generate_expression(&e.this)?;
29541 Ok(())
29542 }
29543
29544 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
29545 self.write_keyword("DATE_FROM_PARTS");
29547 self.write("(");
29548 let mut first = true;
29549 if let Some(year) = &e.year {
29550 self.generate_expression(year)?;
29551 first = false;
29552 }
29553 if let Some(month) = &e.month {
29554 if !first {
29555 self.write(", ");
29556 }
29557 self.generate_expression(month)?;
29558 first = false;
29559 }
29560 if let Some(day) = &e.day {
29561 if !first {
29562 self.write(", ");
29563 }
29564 self.generate_expression(day)?;
29565 }
29566 self.write(")");
29567 Ok(())
29568 }
29569
29570 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
29571 self.write_keyword("DATETIME");
29573 self.write("(");
29574 self.generate_expression(&e.this)?;
29575 if let Some(expr) = &e.expression {
29576 self.write(", ");
29577 self.generate_expression(expr)?;
29578 }
29579 self.write(")");
29580 Ok(())
29581 }
29582
29583 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
29584 self.write_keyword("DATETIME_ADD");
29586 self.write("(");
29587 self.generate_expression(&e.this)?;
29588 self.write(", ");
29589 self.generate_expression(&e.expression)?;
29590 if let Some(unit) = &e.unit {
29591 self.write(", ");
29592 self.write_keyword(unit);
29593 }
29594 self.write(")");
29595 Ok(())
29596 }
29597
29598 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
29599 self.write_keyword("DATETIME_DIFF");
29601 self.write("(");
29602 self.generate_expression(&e.this)?;
29603 self.write(", ");
29604 self.generate_expression(&e.expression)?;
29605 if let Some(unit) = &e.unit {
29606 self.write(", ");
29607 self.write_keyword(unit);
29608 }
29609 self.write(")");
29610 Ok(())
29611 }
29612
29613 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
29614 self.write_keyword("DATETIME_SUB");
29616 self.write("(");
29617 self.generate_expression(&e.this)?;
29618 self.write(", ");
29619 self.generate_expression(&e.expression)?;
29620 if let Some(unit) = &e.unit {
29621 self.write(", ");
29622 self.write_keyword(unit);
29623 }
29624 self.write(")");
29625 Ok(())
29626 }
29627
29628 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
29629 self.write_keyword("DATETIME_TRUNC");
29631 self.write("(");
29632 self.generate_expression(&e.this)?;
29633 self.write(", ");
29634 self.write_keyword(&e.unit);
29635 if let Some(zone) = &e.zone {
29636 self.write(", ");
29637 self.generate_expression(zone)?;
29638 }
29639 self.write(")");
29640 Ok(())
29641 }
29642
29643 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
29644 self.write_keyword("DAYNAME");
29646 self.write("(");
29647 self.generate_expression(&e.this)?;
29648 self.write(")");
29649 Ok(())
29650 }
29651
29652 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
29653 self.write_keyword("DECLARE");
29655 self.write_space();
29656 if e.replace {
29657 self.write_keyword("OR");
29658 self.write_space();
29659 self.write_keyword("REPLACE");
29660 self.write_space();
29661 }
29662 for (i, expr) in e.expressions.iter().enumerate() {
29663 if i > 0 {
29664 self.write(", ");
29665 }
29666 self.generate_expression(expr)?;
29667 }
29668 Ok(())
29669 }
29670
29671 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
29672 use crate::dialects::DialectType;
29673
29674 self.generate_expression(&e.this)?;
29676 for name in &e.additional_names {
29678 self.write(", ");
29679 self.generate_expression(name)?;
29680 }
29681 if let Some(kind) = &e.kind {
29682 self.write_space();
29683 match self.config.dialect {
29687 Some(DialectType::BigQuery) => {
29688 self.write(kind);
29689 }
29690 Some(DialectType::TSQL) => {
29691 let is_complex_table = kind.starts_with("TABLE")
29695 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
29696 if is_complex_table {
29697 self.write(kind);
29698 } else if kind == "INT" {
29699 self.write("INTEGER");
29700 } else if kind.starts_with("TABLE") {
29701 let normalized = kind
29703 .replace(" INT ", " INTEGER ")
29704 .replace(" INT,", " INTEGER,")
29705 .replace(" INT)", " INTEGER)")
29706 .replace("(INT ", "(INTEGER ");
29707 self.write(&normalized);
29708 } else {
29709 self.write(kind);
29710 }
29711 }
29712 _ => {
29713 if e.has_as {
29714 self.write_keyword("AS");
29715 self.write_space();
29716 }
29717 self.write(kind);
29718 }
29719 }
29720 }
29721 if let Some(default) = &e.default {
29722 match self.config.dialect {
29724 Some(DialectType::BigQuery) => {
29725 self.write_space();
29726 self.write_keyword("DEFAULT");
29727 self.write_space();
29728 }
29729 _ => {
29730 self.write(" = ");
29731 }
29732 }
29733 self.generate_expression(default)?;
29734 }
29735 Ok(())
29736 }
29737
29738 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
29739 self.write_keyword("DECODE");
29741 self.write("(");
29742 for (i, expr) in e.expressions.iter().enumerate() {
29743 if i > 0 {
29744 self.write(", ");
29745 }
29746 self.generate_expression(expr)?;
29747 }
29748 self.write(")");
29749 Ok(())
29750 }
29751
29752 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
29753 self.write_keyword("DECOMPRESS");
29755 self.write("(");
29756 self.generate_expression(&e.this)?;
29757 self.write(", '");
29758 self.write(&e.method);
29759 self.write("')");
29760 Ok(())
29761 }
29762
29763 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
29764 self.write_keyword("DECOMPRESS");
29766 self.write("(");
29767 self.generate_expression(&e.this)?;
29768 self.write(", '");
29769 self.write(&e.method);
29770 self.write("')");
29771 Ok(())
29772 }
29773
29774 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
29775 self.write_keyword("DECRYPT");
29777 self.write("(");
29778 self.generate_expression(&e.this)?;
29779 if let Some(passphrase) = &e.passphrase {
29780 self.write(", ");
29781 self.generate_expression(passphrase)?;
29782 }
29783 if let Some(aad) = &e.aad {
29784 self.write(", ");
29785 self.generate_expression(aad)?;
29786 }
29787 if let Some(method) = &e.encryption_method {
29788 self.write(", ");
29789 self.generate_expression(method)?;
29790 }
29791 self.write(")");
29792 Ok(())
29793 }
29794
29795 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
29796 self.write_keyword("DECRYPT_RAW");
29798 self.write("(");
29799 self.generate_expression(&e.this)?;
29800 if let Some(key) = &e.key {
29801 self.write(", ");
29802 self.generate_expression(key)?;
29803 }
29804 if let Some(iv) = &e.iv {
29805 self.write(", ");
29806 self.generate_expression(iv)?;
29807 }
29808 if let Some(aad) = &e.aad {
29809 self.write(", ");
29810 self.generate_expression(aad)?;
29811 }
29812 if let Some(method) = &e.encryption_method {
29813 self.write(", ");
29814 self.generate_expression(method)?;
29815 }
29816 self.write(")");
29817 Ok(())
29818 }
29819
29820 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
29821 self.write_keyword("DEFINER");
29823 self.write(" = ");
29824 self.generate_expression(&e.this)?;
29825 Ok(())
29826 }
29827
29828 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
29829 self.write_keyword("DETACH");
29831 if e.exists {
29832 self.write_keyword(" DATABASE IF EXISTS");
29833 }
29834 self.write_space();
29835 self.generate_expression(&e.this)?;
29836 Ok(())
29837 }
29838
29839 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
29840 let property_name = match e.this.as_ref() {
29841 Expression::Identifier(id) => id.name.as_str(),
29842 Expression::Var(v) => v.this.as_str(),
29843 _ => "DICTIONARY",
29844 };
29845 self.write_keyword(property_name);
29846 self.write("(");
29847 self.write(&e.kind);
29848 if let Some(settings) = &e.settings {
29849 self.write("(");
29850 if let Expression::Tuple(t) = settings.as_ref() {
29851 if self.config.pretty && !t.expressions.is_empty() {
29852 self.write_newline();
29853 self.indent_level += 1;
29854 for (i, pair) in t.expressions.iter().enumerate() {
29855 if i > 0 {
29856 self.write(",");
29857 self.write_newline();
29858 }
29859 self.write_indent();
29860 if let Expression::Tuple(pair_tuple) = pair {
29861 if let Some(k) = pair_tuple.expressions.first() {
29862 self.generate_expression(k)?;
29863 }
29864 if let Some(v) = pair_tuple.expressions.get(1) {
29865 self.write(" ");
29866 self.generate_expression(v)?;
29867 }
29868 } else {
29869 self.generate_expression(pair)?;
29870 }
29871 }
29872 self.indent_level -= 1;
29873 self.write_newline();
29874 self.write_indent();
29875 } else {
29876 for (i, pair) in t.expressions.iter().enumerate() {
29877 if i > 0 {
29878 self.write(" ");
29880 }
29881 if let Expression::Tuple(pair_tuple) = pair {
29882 if let Some(k) = pair_tuple.expressions.first() {
29883 self.generate_expression(k)?;
29884 }
29885 if let Some(v) = pair_tuple.expressions.get(1) {
29886 self.write(" ");
29887 self.generate_expression(v)?;
29888 }
29889 } else {
29890 self.generate_expression(pair)?;
29891 }
29892 }
29893 }
29894 } else {
29895 self.generate_expression(settings)?;
29896 }
29897 self.write(")");
29898 } else {
29899 self.write("()");
29901 }
29902 self.write(")");
29903 Ok(())
29904 }
29905
29906 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
29907 let property_name = match e.this.as_ref() {
29908 Expression::Identifier(id) => id.name.as_str(),
29909 Expression::Var(v) => v.this.as_str(),
29910 _ => "RANGE",
29911 };
29912 self.write_keyword(property_name);
29913 self.write("(");
29914 if let Some(min) = &e.min {
29915 self.write_keyword("MIN");
29916 self.write_space();
29917 self.generate_expression(min)?;
29918 }
29919 if let Some(max) = &e.max {
29920 self.write_space();
29921 self.write_keyword("MAX");
29922 self.write_space();
29923 self.generate_expression(max)?;
29924 }
29925 self.write(")");
29926 Ok(())
29927 }
29928
29929 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
29930 if e.local.is_some() {
29932 self.write_keyword("LOCAL ");
29933 }
29934 self.write_keyword("DIRECTORY");
29935 self.write_space();
29936 self.generate_expression(&e.this)?;
29937 if let Some(row_format) = &e.row_format {
29938 self.write_space();
29939 self.generate_expression(row_format)?;
29940 }
29941 Ok(())
29942 }
29943
29944 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
29945 self.write_keyword("DISTKEY");
29947 self.write("(");
29948 self.generate_expression(&e.this)?;
29949 self.write(")");
29950 Ok(())
29951 }
29952
29953 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
29954 self.write_keyword("DISTSTYLE");
29956 self.write_space();
29957 self.generate_expression(&e.this)?;
29958 Ok(())
29959 }
29960
29961 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
29962 self.write_keyword("DISTRIBUTE BY");
29964 self.write_space();
29965 for (i, expr) in e.expressions.iter().enumerate() {
29966 if i > 0 {
29967 self.write(", ");
29968 }
29969 self.generate_expression(expr)?;
29970 }
29971 Ok(())
29972 }
29973
29974 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
29975 self.write_keyword("DISTRIBUTED BY");
29977 self.write_space();
29978 self.write(&e.kind);
29979 if !e.expressions.is_empty() {
29980 self.write(" (");
29981 for (i, expr) in e.expressions.iter().enumerate() {
29982 if i > 0 {
29983 self.write(", ");
29984 }
29985 self.generate_expression(expr)?;
29986 }
29987 self.write(")");
29988 }
29989 if let Some(buckets) = &e.buckets {
29990 self.write_space();
29991 self.write_keyword("BUCKETS");
29992 self.write_space();
29993 self.generate_expression(buckets)?;
29994 }
29995 if let Some(order) = &e.order {
29996 self.write_space();
29997 self.generate_expression(order)?;
29998 }
29999 Ok(())
30000 }
30001
30002 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
30003 self.write_keyword("DOT_PRODUCT");
30005 self.write("(");
30006 self.generate_expression(&e.this)?;
30007 self.write(", ");
30008 self.generate_expression(&e.expression)?;
30009 self.write(")");
30010 Ok(())
30011 }
30012
30013 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
30014 self.write_keyword("DROP");
30016 if e.exists {
30017 self.write_keyword(" IF EXISTS ");
30018 } else {
30019 self.write_space();
30020 }
30021 for (i, expr) in e.expressions.iter().enumerate() {
30022 if i > 0 {
30023 self.write(", ");
30024 }
30025 self.generate_expression(expr)?;
30026 }
30027 Ok(())
30028 }
30029
30030 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
30031 self.write_keyword("DUPLICATE KEY");
30033 self.write(" (");
30034 for (i, expr) in e.expressions.iter().enumerate() {
30035 if i > 0 {
30036 self.write(", ");
30037 }
30038 self.generate_expression(expr)?;
30039 }
30040 self.write(")");
30041 Ok(())
30042 }
30043
30044 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
30045 self.write_keyword("ELT");
30047 self.write("(");
30048 self.generate_expression(&e.this)?;
30049 for expr in &e.expressions {
30050 self.write(", ");
30051 self.generate_expression(expr)?;
30052 }
30053 self.write(")");
30054 Ok(())
30055 }
30056
30057 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
30058 self.write_keyword("ENCODE");
30060 self.write("(");
30061 self.generate_expression(&e.this)?;
30062 if let Some(charset) = &e.charset {
30063 self.write(", ");
30064 self.generate_expression(charset)?;
30065 }
30066 self.write(")");
30067 Ok(())
30068 }
30069
30070 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
30071 if e.key.is_some() {
30073 self.write_keyword("KEY ");
30074 }
30075 self.write_keyword("ENCODE");
30076 self.write_space();
30077 self.generate_expression(&e.this)?;
30078 if !e.properties.is_empty() {
30079 self.write(" (");
30080 for (i, prop) in e.properties.iter().enumerate() {
30081 if i > 0 {
30082 self.write(", ");
30083 }
30084 self.generate_expression(prop)?;
30085 }
30086 self.write(")");
30087 }
30088 Ok(())
30089 }
30090
30091 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
30092 self.write_keyword("ENCRYPT");
30094 self.write("(");
30095 self.generate_expression(&e.this)?;
30096 if let Some(passphrase) = &e.passphrase {
30097 self.write(", ");
30098 self.generate_expression(passphrase)?;
30099 }
30100 if let Some(aad) = &e.aad {
30101 self.write(", ");
30102 self.generate_expression(aad)?;
30103 }
30104 if let Some(method) = &e.encryption_method {
30105 self.write(", ");
30106 self.generate_expression(method)?;
30107 }
30108 self.write(")");
30109 Ok(())
30110 }
30111
30112 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
30113 self.write_keyword("ENCRYPT_RAW");
30115 self.write("(");
30116 self.generate_expression(&e.this)?;
30117 if let Some(key) = &e.key {
30118 self.write(", ");
30119 self.generate_expression(key)?;
30120 }
30121 if let Some(iv) = &e.iv {
30122 self.write(", ");
30123 self.generate_expression(iv)?;
30124 }
30125 if let Some(aad) = &e.aad {
30126 self.write(", ");
30127 self.generate_expression(aad)?;
30128 }
30129 if let Some(method) = &e.encryption_method {
30130 self.write(", ");
30131 self.generate_expression(method)?;
30132 }
30133 self.write(")");
30134 Ok(())
30135 }
30136
30137 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
30138 self.write_keyword("ENGINE");
30140 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
30141 self.write("=");
30142 } else {
30143 self.write(" = ");
30144 }
30145 self.generate_expression(&e.this)?;
30146 Ok(())
30147 }
30148
30149 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
30150 self.write_keyword("ENVIRONMENT");
30152 self.write(" (");
30153 for (i, expr) in e.expressions.iter().enumerate() {
30154 if i > 0 {
30155 self.write(", ");
30156 }
30157 self.generate_expression(expr)?;
30158 }
30159 self.write(")");
30160 Ok(())
30161 }
30162
30163 fn generate_ephemeral_column_constraint(
30164 &mut self,
30165 e: &EphemeralColumnConstraint,
30166 ) -> Result<()> {
30167 self.write_keyword("EPHEMERAL");
30169 if let Some(this) = &e.this {
30170 self.write_space();
30171 self.generate_expression(this)?;
30172 }
30173 Ok(())
30174 }
30175
30176 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
30177 self.write_keyword("EQUAL_NULL");
30179 self.write("(");
30180 self.generate_expression(&e.this)?;
30181 self.write(", ");
30182 self.generate_expression(&e.expression)?;
30183 self.write(")");
30184 Ok(())
30185 }
30186
30187 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
30188 use crate::dialects::DialectType;
30189
30190 match self.config.dialect {
30192 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
30193 self.generate_expression(&e.this)?;
30194 self.write(" <-> ");
30195 self.generate_expression(&e.expression)?;
30196 }
30197 _ => {
30198 self.write_keyword("EUCLIDEAN_DISTANCE");
30200 self.write("(");
30201 self.generate_expression(&e.this)?;
30202 self.write(", ");
30203 self.generate_expression(&e.expression)?;
30204 self.write(")");
30205 }
30206 }
30207 Ok(())
30208 }
30209
30210 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
30211 self.write_keyword("EXECUTE AS");
30213 self.write_space();
30214 self.generate_expression(&e.this)?;
30215 Ok(())
30216 }
30217
30218 fn generate_export(&mut self, e: &Export) -> Result<()> {
30219 self.write_keyword("EXPORT DATA");
30221 if let Some(connection) = &e.connection {
30222 self.write_space();
30223 self.write_keyword("WITH CONNECTION");
30224 self.write_space();
30225 self.generate_expression(connection)?;
30226 }
30227 if !e.options.is_empty() {
30228 self.write_space();
30229 self.generate_options_clause(&e.options)?;
30230 }
30231 self.write_space();
30232 self.write_keyword("AS");
30233 self.write_space();
30234 self.generate_expression(&e.this)?;
30235 Ok(())
30236 }
30237
30238 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
30239 self.write_keyword("EXTERNAL");
30241 if let Some(this) = &e.this {
30242 self.write_space();
30243 self.generate_expression(this)?;
30244 }
30245 Ok(())
30246 }
30247
30248 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
30249 if e.no.is_some() {
30251 self.write_keyword("NO ");
30252 }
30253 self.write_keyword("FALLBACK");
30254 if e.protection.is_some() {
30255 self.write_keyword(" PROTECTION");
30256 }
30257 Ok(())
30258 }
30259
30260 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
30261 self.write_keyword("FARM_FINGERPRINT");
30263 self.write("(");
30264 for (i, expr) in e.expressions.iter().enumerate() {
30265 if i > 0 {
30266 self.write(", ");
30267 }
30268 self.generate_expression(expr)?;
30269 }
30270 self.write(")");
30271 Ok(())
30272 }
30273
30274 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
30275 self.write_keyword("FEATURES_AT_TIME");
30277 self.write("(");
30278 self.generate_expression(&e.this)?;
30279 if let Some(time) = &e.time {
30280 self.write(", ");
30281 self.generate_expression(time)?;
30282 }
30283 if let Some(num_rows) = &e.num_rows {
30284 self.write(", ");
30285 self.generate_expression(num_rows)?;
30286 }
30287 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
30288 self.write(", ");
30289 self.generate_expression(ignore_nulls)?;
30290 }
30291 self.write(")");
30292 Ok(())
30293 }
30294
30295 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
30296 let use_limit = !e.percent
30298 && !e.with_ties
30299 && e.count.is_some()
30300 && matches!(
30301 self.config.dialect,
30302 Some(DialectType::Spark)
30303 | Some(DialectType::Hive)
30304 | Some(DialectType::DuckDB)
30305 | Some(DialectType::SQLite)
30306 | Some(DialectType::MySQL)
30307 | Some(DialectType::BigQuery)
30308 | Some(DialectType::Databricks)
30309 | Some(DialectType::StarRocks)
30310 | Some(DialectType::Doris)
30311 | Some(DialectType::Athena)
30312 | Some(DialectType::ClickHouse)
30313 );
30314
30315 if use_limit {
30316 self.write_keyword("LIMIT");
30317 self.write_space();
30318 self.generate_expression(e.count.as_ref().unwrap())?;
30319 return Ok(());
30320 }
30321
30322 self.write_keyword("FETCH");
30324 if !e.direction.is_empty() {
30325 self.write_space();
30326 self.write_keyword(&e.direction);
30327 }
30328 if let Some(count) = &e.count {
30329 self.write_space();
30330 self.generate_expression(count)?;
30331 }
30332 if e.percent {
30334 self.write_keyword(" PERCENT");
30335 }
30336 if e.rows {
30337 self.write_keyword(" ROWS");
30338 }
30339 if e.with_ties {
30340 self.write_keyword(" WITH TIES");
30341 } else if e.rows {
30342 self.write_keyword(" ONLY");
30343 } else {
30344 self.write_keyword(" ROWS ONLY");
30345 }
30346 Ok(())
30347 }
30348
30349 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
30350 if e.hive_format.is_some() {
30354 self.write_keyword("STORED AS");
30356 self.write_space();
30357 if let Some(this) = &e.this {
30358 if let Expression::Identifier(id) = this.as_ref() {
30360 self.write_keyword(&id.name.to_ascii_uppercase());
30361 } else {
30362 self.generate_expression(this)?;
30363 }
30364 }
30365 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
30366 self.write_keyword("STORED AS");
30368 self.write_space();
30369 if let Some(this) = &e.this {
30370 if let Expression::Identifier(id) = this.as_ref() {
30371 self.write_keyword(&id.name.to_ascii_uppercase());
30372 } else {
30373 self.generate_expression(this)?;
30374 }
30375 }
30376 } else if matches!(
30377 self.config.dialect,
30378 Some(DialectType::Spark) | Some(DialectType::Databricks)
30379 ) {
30380 self.write_keyword("USING");
30382 self.write_space();
30383 if let Some(this) = &e.this {
30384 self.generate_expression(this)?;
30385 }
30386 } else {
30387 self.write_keyword("FILE_FORMAT");
30389 self.write(" = ");
30390 if let Some(this) = &e.this {
30391 self.generate_expression(this)?;
30392 } else if !e.expressions.is_empty() {
30393 self.write("(");
30394 for (i, expr) in e.expressions.iter().enumerate() {
30395 if i > 0 {
30396 self.write(", ");
30397 }
30398 self.generate_expression(expr)?;
30399 }
30400 self.write(")");
30401 }
30402 }
30403 Ok(())
30404 }
30405
30406 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
30407 self.generate_expression(&e.this)?;
30409 self.write_space();
30410 self.write_keyword("FILTER");
30411 self.write("(");
30412 self.write_keyword("WHERE");
30413 self.write_space();
30414 self.generate_expression(&e.expression)?;
30415 self.write(")");
30416 Ok(())
30417 }
30418
30419 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
30420 self.write_keyword("FLOAT64");
30422 self.write("(");
30423 self.generate_expression(&e.this)?;
30424 if let Some(expr) = &e.expression {
30425 self.write(", ");
30426 self.generate_expression(expr)?;
30427 }
30428 self.write(")");
30429 Ok(())
30430 }
30431
30432 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
30433 self.write_keyword("FOR");
30435 self.write_space();
30436 self.generate_expression(&e.this)?;
30437 self.write_space();
30438 self.write_keyword("DO");
30439 self.write_space();
30440 self.generate_expression(&e.expression)?;
30441 Ok(())
30442 }
30443
30444 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
30445 self.write_keyword("FOREIGN KEY");
30447 if !e.expressions.is_empty() {
30448 self.write(" (");
30449 for (i, expr) in e.expressions.iter().enumerate() {
30450 if i > 0 {
30451 self.write(", ");
30452 }
30453 self.generate_expression(expr)?;
30454 }
30455 self.write(")");
30456 }
30457 if let Some(reference) = &e.reference {
30458 self.write_space();
30459 self.generate_expression(reference)?;
30460 }
30461 if let Some(delete) = &e.delete {
30462 self.write_space();
30463 self.write_keyword("ON DELETE");
30464 self.write_space();
30465 self.generate_expression(delete)?;
30466 }
30467 if let Some(update) = &e.update {
30468 self.write_space();
30469 self.write_keyword("ON UPDATE");
30470 self.write_space();
30471 self.generate_expression(update)?;
30472 }
30473 if !e.options.is_empty() {
30474 self.write_space();
30475 for (i, opt) in e.options.iter().enumerate() {
30476 if i > 0 {
30477 self.write_space();
30478 }
30479 self.generate_expression(opt)?;
30480 }
30481 }
30482 Ok(())
30483 }
30484
30485 fn generate_format(&mut self, e: &Format) -> Result<()> {
30486 self.write_keyword("FORMAT");
30488 self.write("(");
30489 self.generate_expression(&e.this)?;
30490 for expr in &e.expressions {
30491 self.write(", ");
30492 self.generate_expression(expr)?;
30493 }
30494 self.write(")");
30495 Ok(())
30496 }
30497
30498 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
30499 self.generate_expression(&e.this)?;
30501 self.write(" (");
30502 self.write_keyword("FORMAT");
30503 self.write(" '");
30504 self.write(&e.format);
30505 self.write("')");
30506 Ok(())
30507 }
30508
30509 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
30510 self.write_keyword("FREESPACE");
30512 self.write("=");
30513 self.generate_expression(&e.this)?;
30514 if e.percent.is_some() {
30515 self.write_keyword(" PERCENT");
30516 }
30517 Ok(())
30518 }
30519
30520 fn generate_from(&mut self, e: &From) -> Result<()> {
30521 self.write_keyword("FROM");
30523 self.write_space();
30524
30525 use crate::dialects::DialectType;
30529 let has_tablesample = e
30530 .expressions
30531 .iter()
30532 .any(|expr| matches!(expr, Expression::TableSample(_)));
30533 let is_cross_join_dialect = matches!(
30534 self.config.dialect,
30535 Some(DialectType::BigQuery)
30536 | Some(DialectType::Hive)
30537 | Some(DialectType::Spark)
30538 | Some(DialectType::Databricks)
30539 | Some(DialectType::SQLite)
30540 | Some(DialectType::ClickHouse)
30541 );
30542 let source_is_same_as_target2 = self.config.source_dialect.is_some()
30543 && self.config.source_dialect == self.config.dialect;
30544 let source_is_cross_join_dialect2 = matches!(
30545 self.config.source_dialect,
30546 Some(DialectType::BigQuery)
30547 | Some(DialectType::Hive)
30548 | Some(DialectType::Spark)
30549 | Some(DialectType::Databricks)
30550 | Some(DialectType::SQLite)
30551 | Some(DialectType::ClickHouse)
30552 );
30553 let use_cross_join = !has_tablesample
30554 && is_cross_join_dialect
30555 && (source_is_same_as_target2
30556 || source_is_cross_join_dialect2
30557 || self.config.source_dialect.is_none());
30558
30559 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
30561
30562 for (i, expr) in e.expressions.iter().enumerate() {
30563 if i > 0 {
30564 if use_cross_join {
30565 self.write(" CROSS JOIN ");
30566 } else {
30567 self.write(", ");
30568 }
30569 }
30570 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
30571 self.write("(");
30572 self.generate_expression(expr)?;
30573 self.write(")");
30574 } else {
30575 self.generate_expression(expr)?;
30576 }
30577 let leading = Self::extract_table_leading_comments(expr);
30580 for comment in &leading {
30581 self.write_space();
30582 self.write_formatted_comment(comment);
30583 }
30584 }
30585 Ok(())
30586 }
30587
30588 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
30590 match expr {
30591 Expression::Table(t) => t.leading_comments.clone(),
30592 Expression::Pivot(p) => {
30593 if let Expression::Table(t) = &p.this {
30594 t.leading_comments.clone()
30595 } else {
30596 Vec::new()
30597 }
30598 }
30599 _ => Vec::new(),
30600 }
30601 }
30602
30603 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
30604 self.write_keyword("FROM_BASE");
30606 self.write("(");
30607 self.generate_expression(&e.this)?;
30608 self.write(", ");
30609 self.generate_expression(&e.expression)?;
30610 self.write(")");
30611 Ok(())
30612 }
30613
30614 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
30615 self.generate_expression(&e.this)?;
30617 if let Some(zone) = &e.zone {
30618 self.write_space();
30619 self.write_keyword("AT TIME ZONE");
30620 self.write_space();
30621 self.generate_expression(zone)?;
30622 self.write_space();
30623 self.write_keyword("AT TIME ZONE");
30624 self.write(" 'UTC'");
30625 }
30626 Ok(())
30627 }
30628
30629 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
30630 self.write_keyword("GAP_FILL");
30632 self.write("(");
30633 self.generate_expression(&e.this)?;
30634 if let Some(ts_column) = &e.ts_column {
30635 self.write(", ");
30636 self.generate_expression(ts_column)?;
30637 }
30638 if let Some(bucket_width) = &e.bucket_width {
30639 self.write(", ");
30640 self.generate_expression(bucket_width)?;
30641 }
30642 if let Some(partitioning_columns) = &e.partitioning_columns {
30643 self.write(", ");
30644 self.generate_expression(partitioning_columns)?;
30645 }
30646 if let Some(value_columns) = &e.value_columns {
30647 self.write(", ");
30648 self.generate_expression(value_columns)?;
30649 }
30650 self.write(")");
30651 Ok(())
30652 }
30653
30654 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
30655 self.write_keyword("GENERATE_DATE_ARRAY");
30657 self.write("(");
30658 let mut first = true;
30659 if let Some(start) = &e.start {
30660 self.generate_expression(start)?;
30661 first = false;
30662 }
30663 if let Some(end) = &e.end {
30664 if !first {
30665 self.write(", ");
30666 }
30667 self.generate_expression(end)?;
30668 first = false;
30669 }
30670 if let Some(step) = &e.step {
30671 if !first {
30672 self.write(", ");
30673 }
30674 self.generate_expression(step)?;
30675 }
30676 self.write(")");
30677 Ok(())
30678 }
30679
30680 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
30681 self.write_keyword("ML.GENERATE_EMBEDDING");
30683 self.write("(");
30684 self.generate_expression(&e.this)?;
30685 self.write(", ");
30686 self.generate_expression(&e.expression)?;
30687 if let Some(params) = &e.params_struct {
30688 self.write(", ");
30689 self.generate_expression(params)?;
30690 }
30691 self.write(")");
30692 Ok(())
30693 }
30694
30695 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
30696 let fn_name = match self.config.dialect {
30698 Some(DialectType::Presto)
30699 | Some(DialectType::Trino)
30700 | Some(DialectType::Athena)
30701 | Some(DialectType::Spark)
30702 | Some(DialectType::Databricks)
30703 | Some(DialectType::Hive) => "SEQUENCE",
30704 _ => "GENERATE_SERIES",
30705 };
30706 self.write_keyword(fn_name);
30707 self.write("(");
30708 let mut first = true;
30709 if let Some(start) = &e.start {
30710 self.generate_expression(start)?;
30711 first = false;
30712 }
30713 if let Some(end) = &e.end {
30714 if !first {
30715 self.write(", ");
30716 }
30717 self.generate_expression(end)?;
30718 first = false;
30719 }
30720 if let Some(step) = &e.step {
30721 if !first {
30722 self.write(", ");
30723 }
30724 if matches!(
30727 self.config.dialect,
30728 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
30729 ) {
30730 if let Some(converted) = self.convert_week_interval_to_day(step) {
30731 self.generate_expression(&converted)?;
30732 } else {
30733 self.generate_expression(step)?;
30734 }
30735 } else {
30736 self.generate_expression(step)?;
30737 }
30738 }
30739 self.write(")");
30740 Ok(())
30741 }
30742
30743 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
30746 use crate::expressions::*;
30747 if let Expression::Interval(ref iv) = expr {
30748 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
30750 unit: IntervalUnit::Week,
30751 ..
30752 }) = &iv.unit
30753 {
30754 let count = match &iv.this {
30756 Some(Expression::Literal(lit)) => match lit.as_ref() {
30757 Literal::String(s) | Literal::Number(s) => s.clone(),
30758 _ => return None,
30759 },
30760 _ => return None,
30761 };
30762 (true, count)
30763 } else if iv.unit.is_none() {
30764 if let Some(Expression::Literal(lit)) = &iv.this {
30766 if let Literal::String(s) = lit.as_ref() {
30767 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
30768 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
30769 (true, parts[0].to_string())
30770 } else {
30771 (false, String::new())
30772 }
30773 } else {
30774 (false, String::new())
30775 }
30776 } else {
30777 (false, String::new())
30778 }
30779 } else {
30780 (false, String::new())
30781 };
30782
30783 if is_week {
30784 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
30786 let day_interval = Expression::Interval(Box::new(Interval {
30787 this: Some(Expression::Literal(Box::new(Literal::String(
30788 "7".to_string(),
30789 )))),
30790 unit: Some(IntervalUnitSpec::Simple {
30791 unit: IntervalUnit::Day,
30792 use_plural: false,
30793 }),
30794 }));
30795 let mul = Expression::Mul(Box::new(BinaryOp {
30796 left: count_expr,
30797 right: day_interval,
30798 left_comments: vec![],
30799 operator_comments: vec![],
30800 trailing_comments: vec![],
30801 inferred_type: None,
30802 }));
30803 return Some(Expression::Paren(Box::new(Paren {
30804 this: mul,
30805 trailing_comments: vec![],
30806 })));
30807 }
30808 }
30809 None
30810 }
30811
30812 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
30813 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
30815 self.write("(");
30816 let mut first = true;
30817 if let Some(start) = &e.start {
30818 self.generate_expression(start)?;
30819 first = false;
30820 }
30821 if let Some(end) = &e.end {
30822 if !first {
30823 self.write(", ");
30824 }
30825 self.generate_expression(end)?;
30826 first = false;
30827 }
30828 if let Some(step) = &e.step {
30829 if !first {
30830 self.write(", ");
30831 }
30832 self.generate_expression(step)?;
30833 }
30834 self.write(")");
30835 Ok(())
30836 }
30837
30838 fn generate_generated_as_identity_column_constraint(
30839 &mut self,
30840 e: &GeneratedAsIdentityColumnConstraint,
30841 ) -> Result<()> {
30842 use crate::dialects::DialectType;
30843
30844 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
30846 self.write_keyword("AUTOINCREMENT");
30847 if let Some(start) = &e.start {
30848 self.write_keyword(" START ");
30849 self.generate_expression(start)?;
30850 }
30851 if let Some(increment) = &e.increment {
30852 self.write_keyword(" INCREMENT ");
30853 self.generate_expression(increment)?;
30854 }
30855 return Ok(());
30856 }
30857
30858 self.write_keyword("GENERATED");
30860 if let Some(this) = &e.this {
30861 if let Expression::Boolean(b) = this.as_ref() {
30863 if b.value {
30864 self.write_keyword(" ALWAYS");
30865 } else {
30866 self.write_keyword(" BY DEFAULT");
30867 if e.on_null.is_some() {
30868 self.write_keyword(" ON NULL");
30869 }
30870 }
30871 } else {
30872 self.write_keyword(" ALWAYS");
30873 }
30874 }
30875 self.write_keyword(" AS IDENTITY");
30876 let has_options = e.start.is_some()
30878 || e.increment.is_some()
30879 || e.minvalue.is_some()
30880 || e.maxvalue.is_some();
30881 if has_options {
30882 self.write(" (");
30883 let mut first = true;
30884 if let Some(start) = &e.start {
30885 self.write_keyword("START WITH ");
30886 self.generate_expression(start)?;
30887 first = false;
30888 }
30889 if let Some(increment) = &e.increment {
30890 if !first {
30891 self.write(" ");
30892 }
30893 self.write_keyword("INCREMENT BY ");
30894 self.generate_expression(increment)?;
30895 first = false;
30896 }
30897 if let Some(minvalue) = &e.minvalue {
30898 if !first {
30899 self.write(" ");
30900 }
30901 self.write_keyword("MINVALUE ");
30902 self.generate_expression(minvalue)?;
30903 first = false;
30904 }
30905 if let Some(maxvalue) = &e.maxvalue {
30906 if !first {
30907 self.write(" ");
30908 }
30909 self.write_keyword("MAXVALUE ");
30910 self.generate_expression(maxvalue)?;
30911 }
30912 self.write(")");
30913 }
30914 Ok(())
30915 }
30916
30917 fn generate_generated_as_row_column_constraint(
30918 &mut self,
30919 e: &GeneratedAsRowColumnConstraint,
30920 ) -> Result<()> {
30921 self.write_keyword("GENERATED ALWAYS AS ROW ");
30923 if e.start.is_some() {
30924 self.write_keyword("START");
30925 } else {
30926 self.write_keyword("END");
30927 }
30928 if e.hidden.is_some() {
30929 self.write_keyword(" HIDDEN");
30930 }
30931 Ok(())
30932 }
30933
30934 fn generate_get(&mut self, e: &Get) -> Result<()> {
30935 self.write_keyword("GET");
30937 self.write_space();
30938 self.generate_expression(&e.this)?;
30939 if let Some(target) = &e.target {
30940 self.write_space();
30941 self.generate_expression(target)?;
30942 }
30943 for prop in &e.properties {
30944 self.write_space();
30945 self.generate_expression(prop)?;
30946 }
30947 Ok(())
30948 }
30949
30950 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
30951 self.generate_expression(&e.this)?;
30953 self.write("[");
30954 self.generate_expression(&e.expression)?;
30955 self.write("]");
30956 Ok(())
30957 }
30958
30959 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
30960 self.write_keyword("GETBIT");
30962 self.write("(");
30963 self.generate_expression(&e.this)?;
30964 self.write(", ");
30965 self.generate_expression(&e.expression)?;
30966 self.write(")");
30967 Ok(())
30968 }
30969
30970 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
30971 if e.is_role {
30973 self.write_keyword("ROLE");
30974 self.write_space();
30975 } else if e.is_group {
30976 self.write_keyword("GROUP");
30977 self.write_space();
30978 } else if e.is_share {
30979 self.write_keyword("SHARE");
30980 self.write_space();
30981 }
30982 self.write(&e.name.name);
30983 Ok(())
30984 }
30985
30986 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
30987 self.generate_expression(&e.this)?;
30989 if !e.expressions.is_empty() {
30990 self.write("(");
30991 for (i, expr) in e.expressions.iter().enumerate() {
30992 if i > 0 {
30993 self.write(", ");
30994 }
30995 self.generate_expression(expr)?;
30996 }
30997 self.write(")");
30998 }
30999 Ok(())
31000 }
31001
31002 fn generate_group(&mut self, e: &Group) -> Result<()> {
31003 self.write_keyword("GROUP BY");
31005 match e.all {
31007 Some(true) => {
31008 self.write_space();
31009 self.write_keyword("ALL");
31010 }
31011 Some(false) => {
31012 self.write_space();
31013 self.write_keyword("DISTINCT");
31014 }
31015 None => {}
31016 }
31017 if !e.expressions.is_empty() {
31018 self.write_space();
31019 for (i, expr) in e.expressions.iter().enumerate() {
31020 if i > 0 {
31021 self.write(", ");
31022 }
31023 self.generate_expression(expr)?;
31024 }
31025 }
31026 if let Some(cube) = &e.cube {
31028 if !e.expressions.is_empty() {
31029 self.write(", ");
31030 } else {
31031 self.write_space();
31032 }
31033 self.generate_expression(cube)?;
31034 }
31035 if let Some(rollup) = &e.rollup {
31036 if !e.expressions.is_empty() || e.cube.is_some() {
31037 self.write(", ");
31038 } else {
31039 self.write_space();
31040 }
31041 self.generate_expression(rollup)?;
31042 }
31043 if let Some(grouping_sets) = &e.grouping_sets {
31044 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
31045 self.write(", ");
31046 } else {
31047 self.write_space();
31048 }
31049 self.generate_expression(grouping_sets)?;
31050 }
31051 if let Some(totals) = &e.totals {
31052 self.write_space();
31053 self.write_keyword("WITH TOTALS");
31054 self.generate_expression(totals)?;
31055 }
31056 Ok(())
31057 }
31058
31059 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
31060 self.write_keyword("GROUP BY");
31062 match e.all {
31064 Some(true) => {
31065 self.write_space();
31066 self.write_keyword("ALL");
31067 }
31068 Some(false) => {
31069 self.write_space();
31070 self.write_keyword("DISTINCT");
31071 }
31072 None => {}
31073 }
31074
31075 let mut trailing_cube = false;
31078 let mut trailing_rollup = false;
31079 let mut regular_expressions: Vec<&Expression> = Vec::new();
31080
31081 for expr in &e.expressions {
31082 match expr {
31083 Expression::Cube(c) if c.expressions.is_empty() => {
31084 trailing_cube = true;
31085 }
31086 Expression::Rollup(r) if r.expressions.is_empty() => {
31087 trailing_rollup = true;
31088 }
31089 _ => {
31090 regular_expressions.push(expr);
31091 }
31092 }
31093 }
31094
31095 if self.config.pretty {
31097 self.write_newline();
31098 self.indent_level += 1;
31099 for (i, expr) in regular_expressions.iter().enumerate() {
31100 if i > 0 {
31101 self.write(",");
31102 self.write_newline();
31103 }
31104 self.write_indent();
31105 self.generate_expression(expr)?;
31106 }
31107 self.indent_level -= 1;
31108 } else {
31109 self.write_space();
31110 for (i, expr) in regular_expressions.iter().enumerate() {
31111 if i > 0 {
31112 self.write(", ");
31113 }
31114 self.generate_expression(expr)?;
31115 }
31116 }
31117
31118 if trailing_cube {
31120 self.write_space();
31121 self.write_keyword("WITH CUBE");
31122 } else if trailing_rollup {
31123 self.write_space();
31124 self.write_keyword("WITH ROLLUP");
31125 }
31126
31127 if e.totals {
31129 self.write_space();
31130 self.write_keyword("WITH TOTALS");
31131 }
31132
31133 Ok(())
31134 }
31135
31136 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
31137 let function_name = if e.expressions.len() > 1
31138 && matches!(
31139 self.config.dialect,
31140 Some(DialectType::TSQL | DialectType::Fabric)
31141 ) {
31142 "GROUPING_ID"
31143 } else {
31144 "GROUPING"
31145 };
31146 self.write_keyword(function_name);
31147 self.write("(");
31148 for (i, expr) in e.expressions.iter().enumerate() {
31149 if i > 0 {
31150 self.write(", ");
31151 }
31152 self.generate_expression(expr)?;
31153 }
31154 self.write(")");
31155 Ok(())
31156 }
31157
31158 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
31159 self.write_keyword("GROUPING_ID");
31161 self.write("(");
31162 for (i, expr) in e.expressions.iter().enumerate() {
31163 if i > 0 {
31164 self.write(", ");
31165 }
31166 self.generate_expression(expr)?;
31167 }
31168 self.write(")");
31169 Ok(())
31170 }
31171
31172 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
31173 self.write_keyword("GROUPING SETS");
31175 self.write(" (");
31176 for (i, expr) in e.expressions.iter().enumerate() {
31177 if i > 0 {
31178 self.write(", ");
31179 }
31180 self.generate_expression(expr)?;
31181 }
31182 self.write(")");
31183 Ok(())
31184 }
31185
31186 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
31187 self.write_keyword("HASH_AGG");
31189 self.write("(");
31190 self.generate_expression(&e.this)?;
31191 for expr in &e.expressions {
31192 self.write(", ");
31193 self.generate_expression(expr)?;
31194 }
31195 self.write(")");
31196 Ok(())
31197 }
31198
31199 fn generate_having(&mut self, e: &Having) -> Result<()> {
31200 self.write_keyword("HAVING");
31202 self.write_space();
31203 self.generate_expression(&e.this)?;
31204 Ok(())
31205 }
31206
31207 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
31208 self.generate_expression(&e.this)?;
31210 self.write_space();
31211 self.write_keyword("HAVING");
31212 self.write_space();
31213 if e.max.is_some() {
31214 self.write_keyword("MAX");
31215 } else {
31216 self.write_keyword("MIN");
31217 }
31218 self.write_space();
31219 self.generate_expression(&e.expression)?;
31220 Ok(())
31221 }
31222
31223 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
31224 use crate::dialects::DialectType;
31225 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
31227 if let Expression::Literal(ref lit) = *e.this {
31229 if let Literal::String(ref s) = lit.as_ref() {
31230 return self.generate_string_literal(s);
31231 }
31232 }
31233 }
31234 if matches!(
31236 self.config.dialect,
31237 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31238 ) {
31239 self.write("$");
31240 if let Some(tag) = &e.tag {
31241 self.generate_expression(tag)?;
31242 }
31243 self.write("$");
31244 self.generate_expression(&e.this)?;
31245 self.write("$");
31246 if let Some(tag) = &e.tag {
31247 self.generate_expression(tag)?;
31248 }
31249 self.write("$");
31250 return Ok(());
31251 }
31252 self.write("$");
31254 if let Some(tag) = &e.tag {
31255 self.generate_expression(tag)?;
31256 }
31257 self.write("$");
31258 self.generate_expression(&e.this)?;
31259 self.write("$");
31260 if let Some(tag) = &e.tag {
31261 self.generate_expression(tag)?;
31262 }
31263 self.write("$");
31264 Ok(())
31265 }
31266
31267 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
31268 self.write_keyword("HEX_ENCODE");
31270 self.write("(");
31271 self.generate_expression(&e.this)?;
31272 self.write(")");
31273 Ok(())
31274 }
31275
31276 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
31277 match e.this.as_ref() {
31280 Expression::Identifier(id) => self.write(&id.name),
31281 other => self.generate_expression(other)?,
31282 }
31283 self.write(" (");
31284 self.write(&e.kind);
31285 self.write(" => ");
31286 self.generate_expression(&e.expression)?;
31287 self.write(")");
31288 Ok(())
31289 }
31290
31291 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
31292 self.write_keyword("HLL");
31294 self.write("(");
31295 self.generate_expression(&e.this)?;
31296 for expr in &e.expressions {
31297 self.write(", ");
31298 self.generate_expression(expr)?;
31299 }
31300 self.write(")");
31301 Ok(())
31302 }
31303
31304 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
31305 if e.input_.is_some() && e.output.is_some() {
31307 self.write_keyword("IN OUT");
31308 } else if e.input_.is_some() {
31309 self.write_keyword("IN");
31310 } else if e.output.is_some() {
31311 self.write_keyword("OUT");
31312 }
31313 Ok(())
31314 }
31315
31316 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
31317 self.write_keyword("INCLUDE");
31319 self.write_space();
31320 self.generate_expression(&e.this)?;
31321 if let Some(column_def) = &e.column_def {
31322 self.write_space();
31323 self.generate_expression(column_def)?;
31324 }
31325 if let Some(alias) = &e.alias {
31326 self.write_space();
31327 self.write_keyword("AS");
31328 self.write_space();
31329 self.write(alias);
31330 }
31331 Ok(())
31332 }
31333
31334 fn generate_index(&mut self, e: &Index) -> Result<()> {
31335 if e.unique {
31337 self.write_keyword("UNIQUE");
31338 self.write_space();
31339 }
31340 if e.primary.is_some() {
31341 self.write_keyword("PRIMARY");
31342 self.write_space();
31343 }
31344 if e.amp.is_some() {
31345 self.write_keyword("AMP");
31346 self.write_space();
31347 }
31348 if e.table.is_none() {
31349 self.write_keyword("INDEX");
31350 self.write_space();
31351 }
31352 if let Some(name) = &e.this {
31353 self.generate_expression(name)?;
31354 self.write_space();
31355 }
31356 if let Some(table) = &e.table {
31357 self.write_keyword("ON");
31358 self.write_space();
31359 self.generate_expression(table)?;
31360 }
31361 if !e.params.is_empty() {
31362 self.write("(");
31363 for (i, param) in e.params.iter().enumerate() {
31364 if i > 0 {
31365 self.write(", ");
31366 }
31367 self.generate_expression(param)?;
31368 }
31369 self.write(")");
31370 }
31371 Ok(())
31372 }
31373
31374 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
31375 if let Some(kind) = &e.kind {
31377 self.write(kind);
31378 self.write_space();
31379 }
31380 self.write_keyword("INDEX");
31381 if let Some(this) = &e.this {
31382 self.write_space();
31383 self.generate_expression(this)?;
31384 }
31385 if let Some(index_type) = &e.index_type {
31386 self.write_space();
31387 self.write_keyword("USING");
31388 self.write_space();
31389 self.generate_expression(index_type)?;
31390 }
31391 if !e.expressions.is_empty() {
31392 self.write(" (");
31393 for (i, expr) in e.expressions.iter().enumerate() {
31394 if i > 0 {
31395 self.write(", ");
31396 }
31397 self.generate_expression(expr)?;
31398 }
31399 self.write(")");
31400 }
31401 for opt in &e.options {
31402 self.write_space();
31403 self.generate_expression(opt)?;
31404 }
31405 Ok(())
31406 }
31407
31408 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
31409 if let Some(key_block_size) = &e.key_block_size {
31411 self.write_keyword("KEY_BLOCK_SIZE");
31412 self.write(" = ");
31413 self.generate_expression(key_block_size)?;
31414 } else if let Some(using) = &e.using {
31415 self.write_keyword("USING");
31416 self.write_space();
31417 self.generate_expression(using)?;
31418 } else if let Some(parser) = &e.parser {
31419 self.write_keyword("WITH PARSER");
31420 self.write_space();
31421 self.generate_expression(parser)?;
31422 } else if let Some(comment) = &e.comment {
31423 self.write_keyword("COMMENT");
31424 self.write_space();
31425 self.generate_expression(comment)?;
31426 } else if let Some(visible) = &e.visible {
31427 self.generate_expression(visible)?;
31428 } else if let Some(engine_attr) = &e.engine_attr {
31429 self.write_keyword("ENGINE_ATTRIBUTE");
31430 self.write(" = ");
31431 self.generate_expression(engine_attr)?;
31432 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
31433 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
31434 self.write(" = ");
31435 self.generate_expression(secondary_engine_attr)?;
31436 }
31437 Ok(())
31438 }
31439
31440 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
31441 if let Some(using) = &e.using {
31443 self.write_keyword("USING");
31444 self.write_space();
31445 self.generate_expression(using)?;
31446 }
31447 if !e.columns.is_empty() {
31448 self.write("(");
31449 for (i, col) in e.columns.iter().enumerate() {
31450 if i > 0 {
31451 self.write(", ");
31452 }
31453 self.generate_expression(col)?;
31454 }
31455 self.write(")");
31456 }
31457 if let Some(partition_by) = &e.partition_by {
31458 self.write_space();
31459 self.write_keyword("PARTITION BY");
31460 self.write_space();
31461 self.generate_expression(partition_by)?;
31462 }
31463 if let Some(where_) = &e.where_ {
31464 self.write_space();
31465 self.generate_expression(where_)?;
31466 }
31467 if let Some(include) = &e.include {
31468 self.write_space();
31469 self.write_keyword("INCLUDE");
31470 self.write(" (");
31471 self.generate_expression(include)?;
31472 self.write(")");
31473 }
31474 if let Some(with_storage) = &e.with_storage {
31475 self.write_space();
31476 self.write_keyword("WITH");
31477 self.write(" (");
31478 self.generate_expression(with_storage)?;
31479 self.write(")");
31480 }
31481 if let Some(tablespace) = &e.tablespace {
31482 self.write_space();
31483 self.write_keyword("USING INDEX TABLESPACE");
31484 self.write_space();
31485 self.generate_expression(tablespace)?;
31486 }
31487 Ok(())
31488 }
31489
31490 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
31491 if let Expression::Identifier(id) = &*e.this {
31495 self.write_keyword(&id.name);
31496 } else {
31497 self.generate_expression(&e.this)?;
31498 }
31499 self.write_space();
31500 self.write_keyword("INDEX");
31501 if let Some(target) = &e.target {
31502 self.write_space();
31503 self.write_keyword("FOR");
31504 self.write_space();
31505 if let Expression::Identifier(id) = &**target {
31506 self.write_keyword(&id.name);
31507 } else {
31508 self.generate_expression(target)?;
31509 }
31510 }
31511 self.write(" (");
31513 for (i, expr) in e.expressions.iter().enumerate() {
31514 if i > 0 {
31515 self.write(", ");
31516 }
31517 self.generate_expression(expr)?;
31518 }
31519 self.write(")");
31520 Ok(())
31521 }
31522
31523 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
31524 self.write_keyword("INHERITS");
31526 self.write(" (");
31527 for (i, expr) in e.expressions.iter().enumerate() {
31528 if i > 0 {
31529 self.write(", ");
31530 }
31531 self.generate_expression(expr)?;
31532 }
31533 self.write(")");
31534 Ok(())
31535 }
31536
31537 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
31538 self.write_keyword("INPUT");
31540 self.write("(");
31541 self.generate_expression(&e.this)?;
31542 self.write(")");
31543 Ok(())
31544 }
31545
31546 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
31547 if let Some(input_format) = &e.input_format {
31549 self.write_keyword("INPUTFORMAT");
31550 self.write_space();
31551 self.generate_expression(input_format)?;
31552 }
31553 if let Some(output_format) = &e.output_format {
31554 if e.input_format.is_some() {
31555 self.write(" ");
31556 }
31557 self.write_keyword("OUTPUTFORMAT");
31558 self.write_space();
31559 self.generate_expression(output_format)?;
31560 }
31561 Ok(())
31562 }
31563
31564 fn generate_install(&mut self, e: &Install) -> Result<()> {
31565 if e.force.is_some() {
31567 self.write_keyword("FORCE");
31568 self.write_space();
31569 }
31570 self.write_keyword("INSTALL");
31571 self.write_space();
31572 self.generate_expression(&e.this)?;
31573 if let Some(from) = &e.from_ {
31574 self.write_space();
31575 self.write_keyword("FROM");
31576 self.write_space();
31577 self.generate_expression(from)?;
31578 }
31579 Ok(())
31580 }
31581
31582 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
31583 self.write_keyword("INTERVAL");
31585 self.write_space();
31586 self.generate_expression(&e.expression)?;
31588 if let Some(unit) = &e.unit {
31589 self.write_space();
31590 self.write(unit);
31591 }
31592 Ok(())
31593 }
31594
31595 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
31596 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
31598 self.write_space();
31599 self.write_keyword("TO");
31600 self.write_space();
31601 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
31602 Ok(())
31603 }
31604
31605 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
31606 self.write_keyword("INTO");
31608 if e.temporary {
31609 self.write_keyword(" TEMPORARY");
31610 }
31611 if e.unlogged.is_some() {
31612 self.write_keyword(" UNLOGGED");
31613 }
31614 if let Some(this) = &e.this {
31615 self.write_space();
31616 self.generate_expression(this)?;
31617 }
31618 if !e.expressions.is_empty() {
31619 self.write(" (");
31620 for (i, expr) in e.expressions.iter().enumerate() {
31621 if i > 0 {
31622 self.write(", ");
31623 }
31624 self.generate_expression(expr)?;
31625 }
31626 self.write(")");
31627 }
31628 Ok(())
31629 }
31630
31631 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
31632 self.generate_expression(&e.this)?;
31634 self.write_space();
31635 self.generate_expression(&e.expression)?;
31636 Ok(())
31637 }
31638
31639 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
31640 self.write_keyword("WITH");
31642 if e.no.is_some() {
31643 self.write_keyword(" NO");
31644 }
31645 if e.concurrent.is_some() {
31646 self.write_keyword(" CONCURRENT");
31647 }
31648 self.write_keyword(" ISOLATED LOADING");
31649 if let Some(target) = &e.target {
31650 self.write_space();
31651 self.generate_expression(target)?;
31652 }
31653 Ok(())
31654 }
31655
31656 fn generate_json(&mut self, e: &JSON) -> Result<()> {
31657 self.write_keyword("JSON");
31659 if let Some(this) = &e.this {
31660 self.write_space();
31661 self.generate_expression(this)?;
31662 }
31663 if let Some(with_) = &e.with_ {
31664 if let Expression::Boolean(b) = with_.as_ref() {
31666 if b.value {
31667 self.write_keyword(" WITH");
31668 } else {
31669 self.write_keyword(" WITHOUT");
31670 }
31671 }
31672 }
31673 if e.unique {
31674 self.write_keyword(" UNIQUE KEYS");
31675 }
31676 Ok(())
31677 }
31678
31679 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
31680 self.write_keyword("JSON_ARRAY");
31682 self.write("(");
31683 for (i, expr) in e.expressions.iter().enumerate() {
31684 if i > 0 {
31685 self.write(", ");
31686 }
31687 self.generate_expression(expr)?;
31688 }
31689 if let Some(null_handling) = &e.null_handling {
31690 self.write_space();
31691 self.generate_expression(null_handling)?;
31692 }
31693 if let Some(return_type) = &e.return_type {
31694 self.write_space();
31695 self.write_keyword("RETURNING");
31696 self.write_space();
31697 self.generate_expression(return_type)?;
31698 }
31699 if e.strict.is_some() {
31700 self.write_space();
31701 self.write_keyword("STRICT");
31702 }
31703 self.write(")");
31704 Ok(())
31705 }
31706
31707 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
31708 self.write_keyword("JSON_ARRAYAGG");
31710 self.write("(");
31711 self.generate_expression(&e.this)?;
31712 if let Some(order) = &e.order {
31713 self.write_space();
31714 if let Expression::OrderBy(ob) = order.as_ref() {
31716 self.write_keyword("ORDER BY");
31717 self.write_space();
31718 for (i, ord) in ob.expressions.iter().enumerate() {
31719 if i > 0 {
31720 self.write(", ");
31721 }
31722 self.generate_ordered(ord)?;
31723 }
31724 } else {
31725 self.generate_expression(order)?;
31727 }
31728 }
31729 if let Some(null_handling) = &e.null_handling {
31730 self.write_space();
31731 self.generate_expression(null_handling)?;
31732 }
31733 if let Some(return_type) = &e.return_type {
31734 self.write_space();
31735 self.write_keyword("RETURNING");
31736 self.write_space();
31737 self.generate_expression(return_type)?;
31738 }
31739 if e.strict.is_some() {
31740 self.write_space();
31741 self.write_keyword("STRICT");
31742 }
31743 self.write(")");
31744 Ok(())
31745 }
31746
31747 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
31748 self.write_keyword("JSON_OBJECTAGG");
31750 self.write("(");
31751 for (i, expr) in e.expressions.iter().enumerate() {
31752 if i > 0 {
31753 self.write(", ");
31754 }
31755 self.generate_expression(expr)?;
31756 }
31757 if let Some(null_handling) = &e.null_handling {
31758 self.write_space();
31759 self.generate_expression(null_handling)?;
31760 }
31761 if let Some(unique_keys) = &e.unique_keys {
31762 self.write_space();
31763 if let Expression::Boolean(b) = unique_keys.as_ref() {
31764 if b.value {
31765 self.write_keyword("WITH UNIQUE KEYS");
31766 } else {
31767 self.write_keyword("WITHOUT UNIQUE KEYS");
31768 }
31769 }
31770 }
31771 if let Some(return_type) = &e.return_type {
31772 self.write_space();
31773 self.write_keyword("RETURNING");
31774 self.write_space();
31775 self.generate_expression(return_type)?;
31776 }
31777 self.write(")");
31778 Ok(())
31779 }
31780
31781 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
31782 self.write_keyword("JSON_ARRAY_APPEND");
31784 self.write("(");
31785 self.generate_expression(&e.this)?;
31786 for expr in &e.expressions {
31787 self.write(", ");
31788 self.generate_expression(expr)?;
31789 }
31790 self.write(")");
31791 Ok(())
31792 }
31793
31794 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
31795 self.write_keyword("JSON_ARRAY_CONTAINS");
31797 self.write("(");
31798 self.generate_expression(&e.this)?;
31799 self.write(", ");
31800 self.generate_expression(&e.expression)?;
31801 self.write(")");
31802 Ok(())
31803 }
31804
31805 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
31806 self.write_keyword("JSON_ARRAY_INSERT");
31808 self.write("(");
31809 self.generate_expression(&e.this)?;
31810 for expr in &e.expressions {
31811 self.write(", ");
31812 self.generate_expression(expr)?;
31813 }
31814 self.write(")");
31815 Ok(())
31816 }
31817
31818 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
31819 self.write_keyword("JSONB_EXISTS");
31821 self.write("(");
31822 self.generate_expression(&e.this)?;
31823 if let Some(path) = &e.path {
31824 self.write(", ");
31825 self.generate_expression(path)?;
31826 }
31827 self.write(")");
31828 Ok(())
31829 }
31830
31831 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
31832 self.write_keyword("JSONB_EXTRACT_SCALAR");
31834 self.write("(");
31835 self.generate_expression(&e.this)?;
31836 self.write(", ");
31837 self.generate_expression(&e.expression)?;
31838 self.write(")");
31839 Ok(())
31840 }
31841
31842 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
31843 self.write_keyword("JSONB_OBJECT_AGG");
31845 self.write("(");
31846 self.generate_expression(&e.this)?;
31847 self.write(", ");
31848 self.generate_expression(&e.expression)?;
31849 self.write(")");
31850 Ok(())
31851 }
31852
31853 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
31854 if let Some(nested_schema) = &e.nested_schema {
31856 self.write_keyword("NESTED");
31857 if let Some(path) = &e.path {
31858 self.write_space();
31859 self.write_keyword("PATH");
31860 self.write_space();
31861 self.generate_expression(path)?;
31862 }
31863 self.write_space();
31864 self.generate_expression(nested_schema)?;
31865 } else {
31866 if let Some(this) = &e.this {
31867 self.generate_expression(this)?;
31868 }
31869 if let Some(kind) = &e.kind {
31870 self.write_space();
31871 self.write(kind);
31872 }
31873 if e.format_json {
31874 self.write_space();
31875 self.write_keyword("FORMAT JSON");
31876 }
31877 if let Some(path) = &e.path {
31878 self.write_space();
31879 self.write_keyword("PATH");
31880 self.write_space();
31881 self.generate_expression(path)?;
31882 }
31883 if e.ordinality.is_some() {
31884 self.write_keyword(" FOR ORDINALITY");
31885 }
31886 }
31887 Ok(())
31888 }
31889
31890 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
31891 self.write_keyword("JSON_EXISTS");
31893 self.write("(");
31894 self.generate_expression(&e.this)?;
31895 if let Some(path) = &e.path {
31896 self.write(", ");
31897 self.generate_expression(path)?;
31898 }
31899 if let Some(passing) = &e.passing {
31900 self.write_space();
31901 self.write_keyword("PASSING");
31902 self.write_space();
31903 self.generate_expression(passing)?;
31904 }
31905 if let Some(on_condition) = &e.on_condition {
31906 self.write_space();
31907 self.generate_expression(on_condition)?;
31908 }
31909 self.write(")");
31910 Ok(())
31911 }
31912
31913 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
31914 self.generate_expression(&e.this)?;
31915 self.write(".:");
31916 if Self::data_type_has_nested_expressions(&e.to) {
31920 let saved = std::mem::take(&mut self.output);
31922 self.generate_data_type(&e.to)?;
31923 let type_sql = std::mem::replace(&mut self.output, saved);
31924 self.write("\"");
31925 self.write(&type_sql);
31926 self.write("\"");
31927 } else {
31928 self.generate_data_type(&e.to)?;
31929 }
31930 Ok(())
31931 }
31932
31933 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
31936 matches!(
31937 dt,
31938 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
31939 )
31940 }
31941
31942 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
31943 self.write_keyword("JSON_EXTRACT_ARRAY");
31945 self.write("(");
31946 self.generate_expression(&e.this)?;
31947 if let Some(expr) = &e.expression {
31948 self.write(", ");
31949 self.generate_expression(expr)?;
31950 }
31951 self.write(")");
31952 Ok(())
31953 }
31954
31955 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
31956 if let Some(option) = &e.option {
31958 self.generate_expression(option)?;
31959 self.write_space();
31960 }
31961 self.write_keyword("QUOTES");
31962 if e.scalar.is_some() {
31963 self.write_keyword(" SCALAR_ONLY");
31964 }
31965 Ok(())
31966 }
31967
31968 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
31969 self.write_keyword("JSON_EXTRACT_SCALAR");
31971 self.write("(");
31972 self.generate_expression(&e.this)?;
31973 self.write(", ");
31974 self.generate_expression(&e.expression)?;
31975 self.write(")");
31976 Ok(())
31977 }
31978
31979 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
31980 if e.variant_extract.is_some() {
31984 use crate::dialects::DialectType;
31985 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
31986 self.generate_expression(&e.this)?;
31990 self.write(":");
31991 match e.expression.as_ref() {
31992 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
31993 let Literal::String(s) = lit.as_ref() else {
31994 unreachable!()
31995 };
31996 self.write_databricks_json_path(s);
31997 }
31998 _ => {
31999 self.generate_expression(&e.expression)?;
32001 }
32002 }
32003 } else {
32004 self.write_keyword("GET_PATH");
32006 self.write("(");
32007 self.generate_expression(&e.this)?;
32008 self.write(", ");
32009 self.generate_expression(&e.expression)?;
32010 self.write(")");
32011 }
32012 } else {
32013 self.write_keyword("JSON_EXTRACT");
32014 self.write("(");
32015 self.generate_expression(&e.this)?;
32016 self.write(", ");
32017 self.generate_expression(&e.expression)?;
32018 for expr in &e.expressions {
32019 self.write(", ");
32020 self.generate_expression(expr)?;
32021 }
32022 self.write(")");
32023 }
32024 Ok(())
32025 }
32026
32027 fn write_databricks_json_path(&mut self, path: &str) {
32031 if path.starts_with("[\"") || path.starts_with("['") {
32034 self.write(path);
32035 return;
32036 }
32037 let mut first = true;
32041 for segment in path.split('.') {
32042 if !first {
32043 self.write(".");
32044 }
32045 first = false;
32046 if let Some(bracket_pos) = segment.find('[') {
32048 let key = &segment[..bracket_pos];
32049 let subscript = &segment[bracket_pos..];
32050 if key.is_empty() {
32051 self.write(segment);
32053 } else if Self::is_safe_json_path_key(key) {
32054 self.write(key);
32055 self.write(subscript);
32056 } else {
32057 self.write("[\"");
32058 self.write(key);
32059 self.write("\"]");
32060 self.write(subscript);
32061 }
32062 } else if Self::is_safe_json_path_key(segment) {
32063 self.write(segment);
32064 } else {
32065 self.write("[\"");
32066 self.write(segment);
32067 self.write("\"]");
32068 }
32069 }
32070 }
32071
32072 fn is_safe_json_path_key(key: &str) -> bool {
32075 if key.is_empty() {
32076 return false;
32077 }
32078 let mut chars = key.chars();
32079 let first = chars.next().unwrap();
32080 if first != '_' && !first.is_ascii_alphabetic() {
32081 return false;
32082 }
32083 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
32084 }
32085
32086 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
32087 if let Some(this) = &e.this {
32090 self.generate_expression(this)?;
32091 self.write_space();
32092 }
32093 self.write_keyword("FORMAT JSON");
32094 Ok(())
32095 }
32096
32097 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
32098 self.generate_expression(&e.this)?;
32100 self.write(": ");
32101 self.generate_expression(&e.expression)?;
32102 Ok(())
32103 }
32104
32105 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
32106 self.write_keyword("JSON_KEYS");
32108 self.write("(");
32109 self.generate_expression(&e.this)?;
32110 if let Some(expr) = &e.expression {
32111 self.write(", ");
32112 self.generate_expression(expr)?;
32113 }
32114 for expr in &e.expressions {
32115 self.write(", ");
32116 self.generate_expression(expr)?;
32117 }
32118 self.write(")");
32119 Ok(())
32120 }
32121
32122 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
32123 self.write_keyword("JSON_KEYS");
32125 self.write("(");
32126 self.generate_expression(&e.this)?;
32127 if let Some(expr) = &e.expression {
32128 self.write(", ");
32129 self.generate_expression(expr)?;
32130 }
32131 self.write(")");
32132 Ok(())
32133 }
32134
32135 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
32136 let mut path_str = String::new();
32139 for expr in &e.expressions {
32140 match expr {
32141 Expression::JSONPathRoot(_) => {
32142 path_str.push('$');
32143 }
32144 Expression::JSONPathKey(k) => {
32145 if let Expression::Literal(lit) = k.this.as_ref() {
32147 if let crate::expressions::Literal::String(s) = lit.as_ref() {
32148 path_str.push('.');
32149 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
32151 if needs_quoting {
32152 path_str.push('"');
32153 path_str.push_str(s);
32154 path_str.push('"');
32155 } else {
32156 path_str.push_str(s);
32157 }
32158 }
32159 }
32160 }
32161 Expression::JSONPathSubscript(s) => {
32162 if let Expression::Literal(lit) = s.this.as_ref() {
32164 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
32165 path_str.push('[');
32166 path_str.push_str(n);
32167 path_str.push(']');
32168 }
32169 }
32170 }
32171 _ => {
32172 let mut temp_gen = Self::with_arc_config(self.config.clone());
32174 temp_gen.generate_expression(expr)?;
32175 path_str.push_str(&temp_gen.output);
32176 }
32177 }
32178 }
32179 self.write("'");
32181 self.write(&path_str);
32182 self.write("'");
32183 Ok(())
32184 }
32185
32186 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
32187 self.write("?(");
32189 self.generate_expression(&e.this)?;
32190 self.write(")");
32191 Ok(())
32192 }
32193
32194 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
32195 self.write(".");
32197 self.generate_expression(&e.this)?;
32198 Ok(())
32199 }
32200
32201 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
32202 self.write("..");
32204 if let Some(this) = &e.this {
32205 self.generate_expression(this)?;
32206 }
32207 Ok(())
32208 }
32209
32210 fn generate_json_path_root(&mut self) -> Result<()> {
32211 self.write("$");
32213 Ok(())
32214 }
32215
32216 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
32217 self.write("(");
32219 self.generate_expression(&e.this)?;
32220 self.write(")");
32221 Ok(())
32222 }
32223
32224 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
32225 self.generate_expression(&e.this)?;
32227 Ok(())
32228 }
32229
32230 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
32231 self.write("[");
32233 if let Some(start) = &e.start {
32234 self.generate_expression(start)?;
32235 }
32236 self.write(":");
32237 if let Some(end) = &e.end {
32238 self.generate_expression(end)?;
32239 }
32240 if let Some(step) = &e.step {
32241 self.write(":");
32242 self.generate_expression(step)?;
32243 }
32244 self.write("]");
32245 Ok(())
32246 }
32247
32248 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
32249 self.write("[");
32251 self.generate_expression(&e.this)?;
32252 self.write("]");
32253 Ok(())
32254 }
32255
32256 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
32257 self.write("[");
32259 for (i, expr) in e.expressions.iter().enumerate() {
32260 if i > 0 {
32261 self.write(", ");
32262 }
32263 self.generate_expression(expr)?;
32264 }
32265 self.write("]");
32266 Ok(())
32267 }
32268
32269 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
32270 self.write_keyword("JSON_REMOVE");
32272 self.write("(");
32273 self.generate_expression(&e.this)?;
32274 for expr in &e.expressions {
32275 self.write(", ");
32276 self.generate_expression(expr)?;
32277 }
32278 self.write(")");
32279 Ok(())
32280 }
32281
32282 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
32283 self.write_keyword("COLUMNS");
32286 self.write("(");
32287
32288 if self.config.pretty && !e.expressions.is_empty() {
32289 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
32291 for expr in &e.expressions {
32292 let mut temp_gen = Generator::with_arc_config(self.config.clone());
32293 temp_gen.generate_expression(expr)?;
32294 expr_strings.push(temp_gen.output);
32295 }
32296
32297 if self.too_wide(&expr_strings) {
32299 self.write_newline();
32301 self.indent_level += 1;
32302 for (i, expr_str) in expr_strings.iter().enumerate() {
32303 if i > 0 {
32304 self.write(",");
32305 self.write_newline();
32306 }
32307 self.write_indent();
32308 self.write(expr_str);
32309 }
32310 self.write_newline();
32311 self.indent_level -= 1;
32312 self.write_indent();
32313 } else {
32314 for (i, expr_str) in expr_strings.iter().enumerate() {
32316 if i > 0 {
32317 self.write(", ");
32318 }
32319 self.write(expr_str);
32320 }
32321 }
32322 } else {
32323 for (i, expr) in e.expressions.iter().enumerate() {
32325 if i > 0 {
32326 self.write(", ");
32327 }
32328 self.generate_expression(expr)?;
32329 }
32330 }
32331 self.write(")");
32332 Ok(())
32333 }
32334
32335 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
32336 self.write_keyword("JSON_SET");
32338 self.write("(");
32339 self.generate_expression(&e.this)?;
32340 for expr in &e.expressions {
32341 self.write(", ");
32342 self.generate_expression(expr)?;
32343 }
32344 self.write(")");
32345 Ok(())
32346 }
32347
32348 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
32349 self.write_keyword("JSON_STRIP_NULLS");
32351 self.write("(");
32352 self.generate_expression(&e.this)?;
32353 if let Some(expr) = &e.expression {
32354 self.write(", ");
32355 self.generate_expression(expr)?;
32356 }
32357 self.write(")");
32358 Ok(())
32359 }
32360
32361 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
32362 self.write_keyword("JSON_TABLE");
32364 self.write("(");
32365 self.generate_expression(&e.this)?;
32366 if let Some(path) = &e.path {
32367 self.write(", ");
32368 self.generate_expression(path)?;
32369 }
32370 if let Some(error_handling) = &e.error_handling {
32371 self.write_space();
32372 self.generate_expression(error_handling)?;
32373 }
32374 if let Some(empty_handling) = &e.empty_handling {
32375 self.write_space();
32376 self.generate_expression(empty_handling)?;
32377 }
32378 if let Some(schema) = &e.schema {
32379 self.write_space();
32380 self.generate_expression(schema)?;
32381 }
32382 self.write(")");
32383 Ok(())
32384 }
32385
32386 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
32387 self.write_keyword("JSON_TYPE");
32389 self.write("(");
32390 self.generate_expression(&e.this)?;
32391 self.write(")");
32392 Ok(())
32393 }
32394
32395 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
32396 self.write_keyword("JSON_VALUE");
32398 self.write("(");
32399 self.generate_expression(&e.this)?;
32400 if let Some(path) = &e.path {
32401 self.write(", ");
32402 self.generate_expression(path)?;
32403 }
32404 if let Some(returning) = &e.returning {
32405 self.write_space();
32406 self.write_keyword("RETURNING");
32407 self.write_space();
32408 self.generate_expression(returning)?;
32409 }
32410 if let Some(on_condition) = &e.on_condition {
32411 self.write_space();
32412 self.generate_expression(on_condition)?;
32413 }
32414 self.write(")");
32415 Ok(())
32416 }
32417
32418 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
32419 self.write_keyword("JSON_VALUE_ARRAY");
32421 self.write("(");
32422 self.generate_expression(&e.this)?;
32423 self.write(")");
32424 Ok(())
32425 }
32426
32427 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
32428 self.write_keyword("JAROWINKLER_SIMILARITY");
32430 self.write("(");
32431 self.generate_expression(&e.this)?;
32432 self.write(", ");
32433 self.generate_expression(&e.expression)?;
32434 self.write(")");
32435 Ok(())
32436 }
32437
32438 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
32439 self.generate_expression(&e.this)?;
32441 self.write("(");
32442 for (i, expr) in e.expressions.iter().enumerate() {
32443 if i > 0 {
32444 self.write(", ");
32445 }
32446 self.generate_expression(expr)?;
32447 }
32448 self.write(")");
32449 Ok(())
32450 }
32451
32452 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
32453 if e.no.is_some() {
32455 self.write_keyword("NO ");
32456 }
32457 if let Some(local) = &e.local {
32458 self.generate_expression(local)?;
32459 self.write_space();
32460 }
32461 if e.dual.is_some() {
32462 self.write_keyword("DUAL ");
32463 }
32464 if e.before.is_some() {
32465 self.write_keyword("BEFORE ");
32466 }
32467 if e.after.is_some() {
32468 self.write_keyword("AFTER ");
32469 }
32470 self.write_keyword("JOURNAL");
32471 Ok(())
32472 }
32473
32474 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
32475 self.write_keyword("LANGUAGE");
32477 self.write_space();
32478 self.generate_expression(&e.this)?;
32479 Ok(())
32480 }
32481
32482 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
32483 if e.view.is_some() {
32485 self.write_keyword("LATERAL VIEW");
32487 if e.outer.is_some() {
32488 self.write_space();
32489 self.write_keyword("OUTER");
32490 }
32491 self.write_space();
32492 self.generate_expression(&e.this)?;
32493 if let Some(alias) = &e.alias {
32494 self.write_space();
32495 self.write(alias);
32496 }
32497 } else {
32498 self.write_keyword("LATERAL");
32500 self.write_space();
32501 self.generate_expression(&e.this)?;
32502 if e.ordinality.is_some() {
32503 self.write_space();
32504 self.write_keyword("WITH ORDINALITY");
32505 }
32506 if let Some(alias) = &e.alias {
32507 self.write_space();
32508 self.write_keyword("AS");
32509 self.write_space();
32510 self.write(alias);
32511 if !e.column_aliases.is_empty() {
32512 self.write("(");
32513 for (i, col) in e.column_aliases.iter().enumerate() {
32514 if i > 0 {
32515 self.write(", ");
32516 }
32517 self.write(col);
32518 }
32519 self.write(")");
32520 }
32521 }
32522 }
32523 Ok(())
32524 }
32525
32526 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
32527 self.write_keyword("LIKE");
32529 self.write_space();
32530 self.generate_expression(&e.this)?;
32531 for expr in &e.expressions {
32532 self.write_space();
32533 self.generate_expression(expr)?;
32534 }
32535 Ok(())
32536 }
32537
32538 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
32539 self.write_keyword("LIMIT");
32540 self.write_space();
32541 self.write_limit_expr(&e.this)?;
32542 if e.percent {
32543 self.write_space();
32544 self.write_keyword("PERCENT");
32545 }
32546 for comment in &e.comments {
32548 self.write(" ");
32549 self.write_formatted_comment(comment);
32550 }
32551 Ok(())
32552 }
32553
32554 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
32555 if e.percent.is_some() {
32557 self.write_keyword(" PERCENT");
32558 }
32559 if e.rows.is_some() {
32560 self.write_keyword(" ROWS");
32561 }
32562 if e.with_ties.is_some() {
32563 self.write_keyword(" WITH TIES");
32564 } else if e.rows.is_some() {
32565 self.write_keyword(" ONLY");
32566 }
32567 Ok(())
32568 }
32569
32570 fn generate_list(&mut self, e: &List) -> Result<()> {
32571 use crate::dialects::DialectType;
32572 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
32573
32574 if e.expressions.len() == 1 {
32576 if let Expression::Select(_) = &e.expressions[0] {
32577 self.write_keyword("LIST");
32578 self.write("(");
32579 self.generate_expression(&e.expressions[0])?;
32580 self.write(")");
32581 return Ok(());
32582 }
32583 }
32584
32585 if is_materialize {
32587 self.write_keyword("LIST");
32588 self.write("[");
32589 for (i, expr) in e.expressions.iter().enumerate() {
32590 if i > 0 {
32591 self.write(", ");
32592 }
32593 self.generate_expression(expr)?;
32594 }
32595 self.write("]");
32596 } else {
32597 self.write_keyword("LIST");
32599 self.write("(");
32600 for (i, expr) in e.expressions.iter().enumerate() {
32601 if i > 0 {
32602 self.write(", ");
32603 }
32604 self.generate_expression(expr)?;
32605 }
32606 self.write(")");
32607 }
32608 Ok(())
32609 }
32610
32611 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
32612 if let Expression::Select(_) = &*e.this {
32614 self.write_keyword("MAP");
32615 self.write("(");
32616 self.generate_expression(&e.this)?;
32617 self.write(")");
32618 return Ok(());
32619 }
32620
32621 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
32622
32623 self.write_keyword("MAP");
32625 if is_duckdb {
32626 self.write(" {");
32627 } else {
32628 self.write("[");
32629 }
32630 if let Expression::Struct(s) = &*e.this {
32631 for (i, (_, expr)) in s.fields.iter().enumerate() {
32632 if i > 0 {
32633 self.write(", ");
32634 }
32635 if let Expression::PropertyEQ(op) = expr {
32636 self.generate_expression(&op.left)?;
32637 if is_duckdb {
32638 self.write(": ");
32639 } else {
32640 self.write(" => ");
32641 }
32642 self.generate_expression(&op.right)?;
32643 } else {
32644 self.generate_expression(expr)?;
32645 }
32646 }
32647 }
32648 if is_duckdb {
32649 self.write("}");
32650 } else {
32651 self.write("]");
32652 }
32653 Ok(())
32654 }
32655
32656 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
32657 self.write_keyword("LOCALTIME");
32659 if let Some(precision) = &e.this {
32660 self.write("(");
32661 self.generate_expression(precision)?;
32662 self.write(")");
32663 }
32664 Ok(())
32665 }
32666
32667 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
32668 self.write_keyword("LOCALTIMESTAMP");
32670 if let Some(precision) = &e.this {
32671 self.write("(");
32672 self.generate_expression(precision)?;
32673 self.write(")");
32674 }
32675 Ok(())
32676 }
32677
32678 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
32679 self.write_keyword("LOCATION");
32681 self.write_space();
32682 self.generate_expression(&e.this)?;
32683 Ok(())
32684 }
32685
32686 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
32687 if e.update.is_some() {
32689 if e.key.is_some() {
32690 self.write_keyword("FOR NO KEY UPDATE");
32691 } else {
32692 self.write_keyword("FOR UPDATE");
32693 }
32694 } else {
32695 if e.key.is_some() {
32696 self.write_keyword("FOR KEY SHARE");
32697 } else {
32698 self.write_keyword("FOR SHARE");
32699 }
32700 }
32701 if !e.expressions.is_empty() {
32702 self.write_keyword(" OF ");
32703 for (i, expr) in e.expressions.iter().enumerate() {
32704 if i > 0 {
32705 self.write(", ");
32706 }
32707 self.generate_expression(expr)?;
32708 }
32709 }
32710 if let Some(wait) = &e.wait {
32715 match wait.as_ref() {
32716 Expression::Boolean(b) => {
32717 if b.value {
32718 self.write_keyword(" NOWAIT");
32719 } else {
32720 self.write_keyword(" SKIP LOCKED");
32721 }
32722 }
32723 _ => {
32724 self.write_keyword(" WAIT ");
32726 self.generate_expression(wait)?;
32727 }
32728 }
32729 }
32730 Ok(())
32731 }
32732
32733 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
32734 self.write_keyword("LOCK");
32736 self.write_space();
32737 self.generate_expression(&e.this)?;
32738 Ok(())
32739 }
32740
32741 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
32742 self.write_keyword("LOCKING");
32744 self.write_space();
32745 self.write(&e.kind);
32746 if let Some(this) = &e.this {
32747 self.write_space();
32748 self.generate_expression(this)?;
32749 }
32750 if let Some(for_or_in) = &e.for_or_in {
32751 self.write_space();
32752 self.generate_expression(for_or_in)?;
32753 }
32754 if let Some(lock_type) = &e.lock_type {
32755 self.write_space();
32756 self.generate_expression(lock_type)?;
32757 }
32758 if e.override_.is_some() {
32759 self.write_keyword(" OVERRIDE");
32760 }
32761 Ok(())
32762 }
32763
32764 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
32765 self.generate_expression(&e.this)?;
32767 self.write_space();
32768 self.generate_expression(&e.expression)?;
32769 Ok(())
32770 }
32771
32772 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
32773 if e.no.is_some() {
32775 self.write_keyword("NO ");
32776 }
32777 self.write_keyword("LOG");
32778 Ok(())
32779 }
32780
32781 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
32782 self.write_keyword("MD5");
32784 self.write("(");
32785 self.generate_expression(&e.this)?;
32786 for expr in &e.expressions {
32787 self.write(", ");
32788 self.generate_expression(expr)?;
32789 }
32790 self.write(")");
32791 Ok(())
32792 }
32793
32794 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
32795 self.write_keyword("ML.FORECAST");
32797 self.write("(");
32798 self.generate_expression(&e.this)?;
32799 if let Some(expression) = &e.expression {
32800 self.write(", ");
32801 self.generate_expression(expression)?;
32802 }
32803 if let Some(params) = &e.params_struct {
32804 self.write(", ");
32805 self.generate_expression(params)?;
32806 }
32807 self.write(")");
32808 Ok(())
32809 }
32810
32811 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
32812 self.write_keyword("ML.TRANSLATE");
32814 self.write("(");
32815 self.generate_expression(&e.this)?;
32816 self.write(", ");
32817 self.generate_expression(&e.expression)?;
32818 if let Some(params) = &e.params_struct {
32819 self.write(", ");
32820 self.generate_expression(params)?;
32821 }
32822 self.write(")");
32823 Ok(())
32824 }
32825
32826 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
32827 self.write_keyword("MAKE_INTERVAL");
32829 self.write("(");
32830 let mut first = true;
32831 if let Some(year) = &e.year {
32832 self.write("years => ");
32833 self.generate_expression(year)?;
32834 first = false;
32835 }
32836 if let Some(month) = &e.month {
32837 if !first {
32838 self.write(", ");
32839 }
32840 self.write("months => ");
32841 self.generate_expression(month)?;
32842 first = false;
32843 }
32844 if let Some(week) = &e.week {
32845 if !first {
32846 self.write(", ");
32847 }
32848 self.write("weeks => ");
32849 self.generate_expression(week)?;
32850 first = false;
32851 }
32852 if let Some(day) = &e.day {
32853 if !first {
32854 self.write(", ");
32855 }
32856 self.write("days => ");
32857 self.generate_expression(day)?;
32858 first = false;
32859 }
32860 if let Some(hour) = &e.hour {
32861 if !first {
32862 self.write(", ");
32863 }
32864 self.write("hours => ");
32865 self.generate_expression(hour)?;
32866 first = false;
32867 }
32868 if let Some(minute) = &e.minute {
32869 if !first {
32870 self.write(", ");
32871 }
32872 self.write("mins => ");
32873 self.generate_expression(minute)?;
32874 first = false;
32875 }
32876 if let Some(second) = &e.second {
32877 if !first {
32878 self.write(", ");
32879 }
32880 self.write("secs => ");
32881 self.generate_expression(second)?;
32882 }
32883 self.write(")");
32884 Ok(())
32885 }
32886
32887 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
32888 self.write_keyword("MANHATTAN_DISTANCE");
32890 self.write("(");
32891 self.generate_expression(&e.this)?;
32892 self.write(", ");
32893 self.generate_expression(&e.expression)?;
32894 self.write(")");
32895 Ok(())
32896 }
32897
32898 fn generate_map(&mut self, e: &Map) -> Result<()> {
32899 self.write_keyword("MAP");
32901 self.write("(");
32902 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
32903 if i > 0 {
32904 self.write(", ");
32905 }
32906 self.generate_expression(key)?;
32907 self.write(", ");
32908 self.generate_expression(value)?;
32909 }
32910 self.write(")");
32911 Ok(())
32912 }
32913
32914 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
32915 self.write_keyword("MAP_CAT");
32917 self.write("(");
32918 self.generate_expression(&e.this)?;
32919 self.write(", ");
32920 self.generate_expression(&e.expression)?;
32921 self.write(")");
32922 Ok(())
32923 }
32924
32925 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
32926 self.write_keyword("MAP_DELETE");
32928 self.write("(");
32929 self.generate_expression(&e.this)?;
32930 for expr in &e.expressions {
32931 self.write(", ");
32932 self.generate_expression(expr)?;
32933 }
32934 self.write(")");
32935 Ok(())
32936 }
32937
32938 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
32939 self.write_keyword("MAP_INSERT");
32941 self.write("(");
32942 self.generate_expression(&e.this)?;
32943 if let Some(key) = &e.key {
32944 self.write(", ");
32945 self.generate_expression(key)?;
32946 }
32947 if let Some(value) = &e.value {
32948 self.write(", ");
32949 self.generate_expression(value)?;
32950 }
32951 if let Some(update_flag) = &e.update_flag {
32952 self.write(", ");
32953 self.generate_expression(update_flag)?;
32954 }
32955 self.write(")");
32956 Ok(())
32957 }
32958
32959 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
32960 self.write_keyword("MAP_PICK");
32962 self.write("(");
32963 self.generate_expression(&e.this)?;
32964 for expr in &e.expressions {
32965 self.write(", ");
32966 self.generate_expression(expr)?;
32967 }
32968 self.write(")");
32969 Ok(())
32970 }
32971
32972 fn generate_masking_policy_column_constraint(
32973 &mut self,
32974 e: &MaskingPolicyColumnConstraint,
32975 ) -> Result<()> {
32976 self.write_keyword("MASKING POLICY");
32978 self.write_space();
32979 self.generate_expression(&e.this)?;
32980 if !e.expressions.is_empty() {
32981 self.write_keyword(" USING");
32982 self.write(" (");
32983 for (i, expr) in e.expressions.iter().enumerate() {
32984 if i > 0 {
32985 self.write(", ");
32986 }
32987 self.generate_expression(expr)?;
32988 }
32989 self.write(")");
32990 }
32991 Ok(())
32992 }
32993
32994 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
32995 if matches!(
32996 self.config.dialect,
32997 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
32998 ) {
32999 if e.expressions.len() > 1 {
33000 self.write("(");
33001 }
33002 for (i, expr) in e.expressions.iter().enumerate() {
33003 if i > 0 {
33004 self.write_keyword(" OR ");
33005 }
33006 self.generate_expression(expr)?;
33007 self.write_space();
33008 self.write("@@");
33009 self.write_space();
33010 self.generate_expression(&e.this)?;
33011 }
33012 if e.expressions.len() > 1 {
33013 self.write(")");
33014 }
33015 return Ok(());
33016 }
33017
33018 self.write_keyword("MATCH");
33020 self.write("(");
33021 for (i, expr) in e.expressions.iter().enumerate() {
33022 if i > 0 {
33023 self.write(", ");
33024 }
33025 self.generate_expression(expr)?;
33026 }
33027 self.write(")");
33028 self.write_keyword(" AGAINST");
33029 self.write("(");
33030 self.generate_expression(&e.this)?;
33031 if let Some(modifier) = &e.modifier {
33032 self.write_space();
33033 self.generate_expression(modifier)?;
33034 }
33035 self.write(")");
33036 Ok(())
33037 }
33038
33039 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
33040 if let Some(window_frame) = &e.window_frame {
33042 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
33043 self.write_space();
33044 }
33045 self.generate_expression(&e.this)?;
33046 Ok(())
33047 }
33048
33049 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
33050 self.write_keyword("MATERIALIZED");
33052 if let Some(this) = &e.this {
33053 self.write_space();
33054 self.generate_expression(this)?;
33055 }
33056 Ok(())
33057 }
33058
33059 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
33060 if let Some(with_) = &e.with_ {
33063 if let Expression::With(with_clause) = with_.as_ref() {
33064 self.generate_with(with_clause)?;
33065 self.write_space();
33066 } else {
33067 self.generate_expression(with_)?;
33068 self.write_space();
33069 }
33070 }
33071 self.write_keyword("MERGE INTO");
33072 self.write_space();
33073 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
33074 if let Expression::Alias(alias) = e.this.as_ref() {
33075 self.generate_expression(&alias.this)?;
33076 self.write_space();
33077 self.generate_identifier(&alias.alias)?;
33078 } else {
33079 self.generate_expression(&e.this)?;
33080 }
33081 } else {
33082 self.generate_expression(&e.this)?;
33083 }
33084
33085 if self.config.pretty {
33087 self.write_newline();
33088 self.write_indent();
33089 } else {
33090 self.write_space();
33091 }
33092 self.write_keyword("USING");
33093 self.write_space();
33094 self.generate_expression(&e.using)?;
33095
33096 if let Some(on) = &e.on {
33098 if self.config.pretty {
33099 self.write_newline();
33100 self.write_indent();
33101 } else {
33102 self.write_space();
33103 }
33104 self.write_keyword("ON");
33105 self.write_space();
33106 self.generate_expression(on)?;
33107 }
33108 if let Some(using_cond) = &e.using_cond {
33110 self.write_space();
33111 self.write_keyword("USING");
33112 self.write_space();
33113 self.write("(");
33114 if let Expression::Tuple(tuple) = using_cond.as_ref() {
33116 for (i, col) in tuple.expressions.iter().enumerate() {
33117 if i > 0 {
33118 self.write(", ");
33119 }
33120 self.generate_expression(col)?;
33121 }
33122 } else {
33123 self.generate_expression(using_cond)?;
33124 }
33125 self.write(")");
33126 }
33127 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
33129 if matches!(
33130 self.config.dialect,
33131 Some(crate::DialectType::PostgreSQL)
33132 | Some(crate::DialectType::Redshift)
33133 | Some(crate::DialectType::Trino)
33134 | Some(crate::DialectType::Presto)
33135 | Some(crate::DialectType::Athena)
33136 ) {
33137 let mut names = Vec::new();
33138 match e.this.as_ref() {
33139 Expression::Alias(a) => {
33140 if let Expression::Table(t) = &a.this {
33142 names.push(t.name.name.clone());
33143 } else if let Expression::Identifier(id) = &a.this {
33144 names.push(id.name.clone());
33145 }
33146 names.push(a.alias.name.clone());
33147 }
33148 Expression::Table(t) => {
33149 names.push(t.name.name.clone());
33150 }
33151 Expression::Identifier(id) => {
33152 names.push(id.name.clone());
33153 }
33154 _ => {}
33155 }
33156 self.merge_strip_qualifiers = names;
33157 }
33158
33159 if let Some(whens) = &e.whens {
33161 if self.config.pretty {
33162 self.write_newline();
33163 self.write_indent();
33164 } else {
33165 self.write_space();
33166 }
33167 self.generate_expression(whens)?;
33168 }
33169
33170 self.merge_strip_qualifiers = saved_merge_strip;
33172
33173 if let Some(returning) = &e.returning {
33175 if self.config.pretty {
33176 self.write_newline();
33177 self.write_indent();
33178 } else {
33179 self.write_space();
33180 }
33181 self.generate_expression(returning)?;
33182 }
33183 Ok(())
33184 }
33185
33186 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
33187 if e.no.is_some() {
33189 self.write_keyword("NO MERGEBLOCKRATIO");
33190 } else if e.default.is_some() {
33191 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
33192 } else {
33193 self.write_keyword("MERGEBLOCKRATIO");
33194 self.write("=");
33195 if let Some(this) = &e.this {
33196 self.generate_expression(this)?;
33197 }
33198 if e.percent.is_some() {
33199 self.write_keyword(" PERCENT");
33200 }
33201 }
33202 Ok(())
33203 }
33204
33205 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
33206 self.write_keyword("TTL");
33208 let pretty_clickhouse = self.config.pretty
33209 && matches!(
33210 self.config.dialect,
33211 Some(crate::dialects::DialectType::ClickHouse)
33212 );
33213
33214 if pretty_clickhouse {
33215 self.write_newline();
33216 self.indent_level += 1;
33217 for (i, expr) in e.expressions.iter().enumerate() {
33218 if i > 0 {
33219 self.write(",");
33220 self.write_newline();
33221 }
33222 self.write_indent();
33223 self.generate_expression(expr)?;
33224 }
33225 self.indent_level -= 1;
33226 } else {
33227 self.write_space();
33228 for (i, expr) in e.expressions.iter().enumerate() {
33229 if i > 0 {
33230 self.write(", ");
33231 }
33232 self.generate_expression(expr)?;
33233 }
33234 }
33235
33236 if let Some(where_) = &e.where_ {
33237 if pretty_clickhouse {
33238 self.write_newline();
33239 if let Expression::Where(w) = where_.as_ref() {
33240 self.write_indent();
33241 self.write_keyword("WHERE");
33242 self.write_newline();
33243 self.indent_level += 1;
33244 self.write_indent();
33245 self.generate_expression(&w.this)?;
33246 self.indent_level -= 1;
33247 } else {
33248 self.write_indent();
33249 self.generate_expression(where_)?;
33250 }
33251 } else {
33252 self.write_space();
33253 self.generate_expression(where_)?;
33254 }
33255 }
33256 if let Some(group) = &e.group {
33257 if pretty_clickhouse {
33258 self.write_newline();
33259 if let Expression::Group(g) = group.as_ref() {
33260 self.write_indent();
33261 self.write_keyword("GROUP BY");
33262 self.write_newline();
33263 self.indent_level += 1;
33264 for (i, expr) in g.expressions.iter().enumerate() {
33265 if i > 0 {
33266 self.write(",");
33267 self.write_newline();
33268 }
33269 self.write_indent();
33270 self.generate_expression(expr)?;
33271 }
33272 self.indent_level -= 1;
33273 } else {
33274 self.write_indent();
33275 self.generate_expression(group)?;
33276 }
33277 } else {
33278 self.write_space();
33279 self.generate_expression(group)?;
33280 }
33281 }
33282 if let Some(aggregates) = &e.aggregates {
33283 if pretty_clickhouse {
33284 self.write_newline();
33285 self.write_indent();
33286 self.write_keyword("SET");
33287 self.write_newline();
33288 self.indent_level += 1;
33289 if let Expression::Tuple(t) = aggregates.as_ref() {
33290 for (i, agg) in t.expressions.iter().enumerate() {
33291 if i > 0 {
33292 self.write(",");
33293 self.write_newline();
33294 }
33295 self.write_indent();
33296 self.generate_expression(agg)?;
33297 }
33298 } else {
33299 self.write_indent();
33300 self.generate_expression(aggregates)?;
33301 }
33302 self.indent_level -= 1;
33303 } else {
33304 self.write_space();
33305 self.write_keyword("SET");
33306 self.write_space();
33307 if let Expression::Tuple(t) = aggregates.as_ref() {
33308 for (i, agg) in t.expressions.iter().enumerate() {
33309 if i > 0 {
33310 self.write(", ");
33311 }
33312 self.generate_expression(agg)?;
33313 }
33314 } else {
33315 self.generate_expression(aggregates)?;
33316 }
33317 }
33318 }
33319 Ok(())
33320 }
33321
33322 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
33323 self.generate_expression(&e.this)?;
33325 if e.delete.is_some() {
33326 self.write_keyword(" DELETE");
33327 }
33328 if let Some(recompress) = &e.recompress {
33329 self.write_keyword(" RECOMPRESS ");
33330 self.generate_expression(recompress)?;
33331 }
33332 if let Some(to_disk) = &e.to_disk {
33333 self.write_keyword(" TO DISK ");
33334 self.generate_expression(to_disk)?;
33335 }
33336 if let Some(to_volume) = &e.to_volume {
33337 self.write_keyword(" TO VOLUME ");
33338 self.generate_expression(to_volume)?;
33339 }
33340 Ok(())
33341 }
33342
33343 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
33344 self.write_keyword("MINHASH");
33346 self.write("(");
33347 self.generate_expression(&e.this)?;
33348 for expr in &e.expressions {
33349 self.write(", ");
33350 self.generate_expression(expr)?;
33351 }
33352 self.write(")");
33353 Ok(())
33354 }
33355
33356 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
33357 self.generate_expression(&e.this)?;
33359 self.write("!");
33360 self.generate_expression(&e.expression)?;
33361 Ok(())
33362 }
33363
33364 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
33365 self.write_keyword("MONTHNAME");
33367 self.write("(");
33368 self.generate_expression(&e.this)?;
33369 self.write(")");
33370 Ok(())
33371 }
33372
33373 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
33374 for comment in &e.leading_comments {
33376 self.write_formatted_comment(comment);
33377 if self.config.pretty {
33378 self.write_newline();
33379 self.write_indent();
33380 } else {
33381 self.write_space();
33382 }
33383 }
33384 self.write_keyword("INSERT");
33386 if e.overwrite {
33387 self.write_space();
33388 self.write_keyword("OVERWRITE");
33389 }
33390 self.write_space();
33391 self.write(&e.kind);
33392 if self.config.pretty {
33393 self.indent_level += 1;
33394 for expr in &e.expressions {
33395 self.write_newline();
33396 self.write_indent();
33397 self.generate_expression(expr)?;
33398 }
33399 self.indent_level -= 1;
33400 } else {
33401 for expr in &e.expressions {
33402 self.write_space();
33403 self.generate_expression(expr)?;
33404 }
33405 }
33406 if let Some(source) = &e.source {
33407 if self.config.pretty {
33408 self.write_newline();
33409 self.write_indent();
33410 } else {
33411 self.write_space();
33412 }
33413 self.generate_expression(source)?;
33414 }
33415 Ok(())
33416 }
33417
33418 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
33419 self.write_keyword("NEXT VALUE FOR");
33421 self.write_space();
33422 self.generate_expression(&e.this)?;
33423 if let Some(order) = &e.order {
33424 self.write_space();
33425 self.write_keyword("OVER");
33426 self.write(" (");
33427 self.generate_expression(order)?;
33428 self.write(")");
33429 }
33430 Ok(())
33431 }
33432
33433 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
33434 self.write_keyword("NORMAL");
33436 self.write("(");
33437 self.generate_expression(&e.this)?;
33438 if let Some(stddev) = &e.stddev {
33439 self.write(", ");
33440 self.generate_expression(stddev)?;
33441 }
33442 if let Some(gen) = &e.gen {
33443 self.write(", ");
33444 self.generate_expression(gen)?;
33445 }
33446 self.write(")");
33447 Ok(())
33448 }
33449
33450 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
33451 if e.is_casefold.is_some() {
33453 self.write_keyword("NORMALIZE_AND_CASEFOLD");
33454 } else {
33455 self.write_keyword("NORMALIZE");
33456 }
33457 self.write("(");
33458 self.generate_expression(&e.this)?;
33459 if let Some(form) = &e.form {
33460 self.write(", ");
33461 self.generate_expression(form)?;
33462 }
33463 self.write(")");
33464 Ok(())
33465 }
33466
33467 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
33468 if e.allow_null.is_none() {
33470 self.write_keyword("NOT ");
33471 }
33472 self.write_keyword("NULL");
33473 Ok(())
33474 }
33475
33476 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
33477 self.write_keyword("NULLIF");
33479 self.write("(");
33480 self.generate_expression(&e.this)?;
33481 self.write(", ");
33482 self.generate_expression(&e.expression)?;
33483 self.write(")");
33484 Ok(())
33485 }
33486
33487 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
33488 self.write_keyword("FORMAT");
33490 self.write("(");
33491 self.generate_expression(&e.this)?;
33492 self.write(", '");
33493 self.write(&e.format);
33494 self.write("'");
33495 if let Some(culture) = &e.culture {
33496 self.write(", ");
33497 self.generate_expression(culture)?;
33498 }
33499 self.write(")");
33500 Ok(())
33501 }
33502
33503 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
33504 self.write_keyword("OBJECT_AGG");
33506 self.write("(");
33507 self.generate_expression(&e.this)?;
33508 self.write(", ");
33509 self.generate_expression(&e.expression)?;
33510 self.write(")");
33511 Ok(())
33512 }
33513
33514 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
33515 self.generate_expression(&e.this)?;
33517 Ok(())
33518 }
33519
33520 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
33521 self.write_keyword("OBJECT_INSERT");
33523 self.write("(");
33524 self.generate_expression(&e.this)?;
33525 if let Some(key) = &e.key {
33526 self.write(", ");
33527 self.generate_expression(key)?;
33528 }
33529 if let Some(value) = &e.value {
33530 self.write(", ");
33531 self.generate_expression(value)?;
33532 }
33533 if let Some(update_flag) = &e.update_flag {
33534 self.write(", ");
33535 self.generate_expression(update_flag)?;
33536 }
33537 self.write(")");
33538 Ok(())
33539 }
33540
33541 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
33542 self.write_keyword("OFFSET");
33544 self.write_space();
33545 self.generate_expression(&e.this)?;
33546 if e.rows == Some(true)
33548 && matches!(
33549 self.config.dialect,
33550 Some(crate::dialects::DialectType::TSQL)
33551 | Some(crate::dialects::DialectType::Oracle)
33552 )
33553 {
33554 self.write_space();
33555 self.write_keyword("ROWS");
33556 }
33557 Ok(())
33558 }
33559
33560 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
33561 self.write_keyword("QUALIFY");
33563 self.write_space();
33564 self.generate_expression(&e.this)?;
33565 Ok(())
33566 }
33567
33568 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
33569 self.write_keyword("ON CLUSTER");
33571 self.write_space();
33572 self.generate_expression(&e.this)?;
33573 Ok(())
33574 }
33575
33576 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
33577 self.write_keyword("ON COMMIT");
33579 if e.delete.is_some() {
33580 self.write_keyword(" DELETE ROWS");
33581 } else {
33582 self.write_keyword(" PRESERVE ROWS");
33583 }
33584 Ok(())
33585 }
33586
33587 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
33588 if let Some(empty) = &e.empty {
33590 self.generate_expression(empty)?;
33591 self.write_keyword(" ON EMPTY");
33592 }
33593 if let Some(error) = &e.error {
33594 if e.empty.is_some() {
33595 self.write_space();
33596 }
33597 self.generate_expression(error)?;
33598 self.write_keyword(" ON ERROR");
33599 }
33600 if let Some(null) = &e.null {
33601 if e.empty.is_some() || e.error.is_some() {
33602 self.write_space();
33603 }
33604 self.generate_expression(null)?;
33605 self.write_keyword(" ON NULL");
33606 }
33607 Ok(())
33608 }
33609
33610 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
33611 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
33613 return Ok(());
33614 }
33615 if e.duplicate.is_some() {
33617 self.write_keyword("ON DUPLICATE KEY UPDATE");
33619 for (i, expr) in e.expressions.iter().enumerate() {
33620 if i > 0 {
33621 self.write(",");
33622 }
33623 self.write_space();
33624 self.generate_expression(expr)?;
33625 }
33626 return Ok(());
33627 } else {
33628 self.write_keyword("ON CONFLICT");
33629 }
33630 if let Some(constraint) = &e.constraint {
33631 self.write_keyword(" ON CONSTRAINT ");
33632 self.generate_expression(constraint)?;
33633 }
33634 if let Some(conflict_keys) = &e.conflict_keys {
33635 if let Expression::Tuple(t) = conflict_keys.as_ref() {
33637 self.write("(");
33638 for (i, expr) in t.expressions.iter().enumerate() {
33639 if i > 0 {
33640 self.write(", ");
33641 }
33642 self.generate_expression(expr)?;
33643 }
33644 self.write(")");
33645 } else {
33646 self.write("(");
33647 self.generate_expression(conflict_keys)?;
33648 self.write(")");
33649 }
33650 }
33651 if let Some(index_predicate) = &e.index_predicate {
33652 self.write_keyword(" WHERE ");
33653 self.generate_expression(index_predicate)?;
33654 }
33655 if let Some(action) = &e.action {
33656 if let Expression::Identifier(id) = action.as_ref() {
33658 if id.name.eq_ignore_ascii_case("NOTHING") {
33659 self.write_keyword(" DO NOTHING");
33660 } else {
33661 self.write_keyword(" DO ");
33662 self.generate_expression(action)?;
33663 }
33664 } else if let Expression::Tuple(t) = action.as_ref() {
33665 self.write_keyword(" DO UPDATE SET ");
33667 for (i, expr) in t.expressions.iter().enumerate() {
33668 if i > 0 {
33669 self.write(", ");
33670 }
33671 self.generate_expression(expr)?;
33672 }
33673 } else {
33674 self.write_keyword(" DO ");
33675 self.generate_expression(action)?;
33676 }
33677 }
33678 if let Some(where_) = &e.where_ {
33680 self.write_keyword(" WHERE ");
33681 self.generate_expression(where_)?;
33682 }
33683 Ok(())
33684 }
33685
33686 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
33687 self.write_keyword("ON");
33689 self.write_space();
33690 self.generate_expression(&e.this)?;
33691 Ok(())
33692 }
33693
33694 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
33695 self.generate_expression(&e.this)?;
33697 self.write_space();
33698 self.generate_expression(&e.expression)?;
33699 Ok(())
33700 }
33701
33702 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
33703 self.write_keyword("OPENJSON");
33705 self.write("(");
33706 self.generate_expression(&e.this)?;
33707 if let Some(path) = &e.path {
33708 self.write(", ");
33709 self.generate_expression(path)?;
33710 }
33711 self.write(")");
33712 if !e.expressions.is_empty() {
33713 self.write_keyword(" WITH");
33714 if self.config.pretty {
33715 self.write(" (\n");
33716 self.indent_level += 2;
33717 for (i, expr) in e.expressions.iter().enumerate() {
33718 if i > 0 {
33719 self.write(",\n");
33720 }
33721 self.write_indent();
33722 self.generate_expression(expr)?;
33723 }
33724 self.write("\n");
33725 self.indent_level -= 2;
33726 self.write(")");
33727 } else {
33728 self.write(" (");
33729 for (i, expr) in e.expressions.iter().enumerate() {
33730 if i > 0 {
33731 self.write(", ");
33732 }
33733 self.generate_expression(expr)?;
33734 }
33735 self.write(")");
33736 }
33737 }
33738 Ok(())
33739 }
33740
33741 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
33742 self.generate_expression(&e.this)?;
33744 self.write_space();
33745 if let Some(ref dt) = e.data_type {
33747 self.generate_data_type(dt)?;
33748 } else if !e.kind.is_empty() {
33749 self.write(&e.kind);
33750 }
33751 if let Some(path) = &e.path {
33752 self.write_space();
33753 self.generate_expression(path)?;
33754 }
33755 if e.as_json.is_some() {
33756 self.write_keyword(" AS JSON");
33757 }
33758 Ok(())
33759 }
33760
33761 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
33762 self.generate_expression(&e.this)?;
33764 self.write_space();
33765 if let Some(op) = &e.operator {
33766 self.write_keyword("OPERATOR");
33767 self.write("(");
33768 self.generate_expression(op)?;
33769 self.write(")");
33770 }
33771 for comment in &e.comments {
33773 self.write_space();
33774 self.write_formatted_comment(comment);
33775 }
33776 self.write_space();
33777 self.generate_expression(&e.expression)?;
33778 Ok(())
33779 }
33780
33781 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
33782 self.write_keyword("ORDER BY");
33784 let pretty_clickhouse_single_paren = self.config.pretty
33785 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
33786 && e.expressions.len() == 1
33787 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
33788 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
33789 && e.expressions.len() == 1
33790 && matches!(e.expressions[0].this, Expression::Tuple(_))
33791 && !e.expressions[0].desc
33792 && e.expressions[0].nulls_first.is_none();
33793
33794 if pretty_clickhouse_single_paren {
33795 self.write_space();
33796 if let Expression::Paren(p) = &e.expressions[0].this {
33797 self.write("(");
33798 self.write_newline();
33799 self.indent_level += 1;
33800 self.write_indent();
33801 self.generate_expression(&p.this)?;
33802 self.indent_level -= 1;
33803 self.write_newline();
33804 self.write(")");
33805 }
33806 return Ok(());
33807 }
33808
33809 if clickhouse_single_tuple {
33810 self.write_space();
33811 if let Expression::Tuple(t) = &e.expressions[0].this {
33812 self.write("(");
33813 for (i, expr) in t.expressions.iter().enumerate() {
33814 if i > 0 {
33815 self.write(", ");
33816 }
33817 self.generate_expression(expr)?;
33818 }
33819 self.write(")");
33820 }
33821 return Ok(());
33822 }
33823
33824 self.write_space();
33825 for (i, ordered) in e.expressions.iter().enumerate() {
33826 if i > 0 {
33827 self.write(", ");
33828 }
33829 self.generate_expression(&ordered.this)?;
33830 if ordered.desc {
33831 self.write_space();
33832 self.write_keyword("DESC");
33833 } else if ordered.explicit_asc {
33834 self.write_space();
33835 self.write_keyword("ASC");
33836 }
33837 if let Some(nulls_first) = ordered.nulls_first {
33838 let skip_nulls_last =
33840 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
33841 if !skip_nulls_last {
33842 self.write_space();
33843 self.write_keyword("NULLS");
33844 self.write_space();
33845 if nulls_first {
33846 self.write_keyword("FIRST");
33847 } else {
33848 self.write_keyword("LAST");
33849 }
33850 }
33851 }
33852 }
33853 Ok(())
33854 }
33855
33856 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
33857 self.write_keyword("OUTPUT");
33859 self.write("(");
33860 if self.config.pretty {
33861 self.indent_level += 1;
33862 self.write_newline();
33863 self.write_indent();
33864 self.generate_expression(&e.this)?;
33865 self.indent_level -= 1;
33866 self.write_newline();
33867 } else {
33868 self.generate_expression(&e.this)?;
33869 }
33870 self.write(")");
33871 Ok(())
33872 }
33873
33874 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
33875 self.write_keyword("TRUNCATE");
33877 if let Some(this) = &e.this {
33878 self.write_space();
33879 self.generate_expression(this)?;
33880 }
33881 if e.with_count.is_some() {
33882 self.write_keyword(" WITH COUNT");
33883 } else {
33884 self.write_keyword(" WITHOUT COUNT");
33885 }
33886 Ok(())
33887 }
33888
33889 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
33890 self.generate_expression(&e.this)?;
33892 self.write("(");
33893 for (i, expr) in e.expressions.iter().enumerate() {
33894 if i > 0 {
33895 self.write(", ");
33896 }
33897 self.generate_expression(expr)?;
33898 }
33899 self.write(")(");
33900 for (i, param) in e.params.iter().enumerate() {
33901 if i > 0 {
33902 self.write(", ");
33903 }
33904 self.generate_expression(param)?;
33905 }
33906 self.write(")");
33907 Ok(())
33908 }
33909
33910 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
33911 self.write_keyword("PARSE_DATETIME");
33913 self.write("(");
33914 if let Some(format) = &e.format {
33915 self.write("'");
33916 self.write(format);
33917 self.write("', ");
33918 }
33919 self.generate_expression(&e.this)?;
33920 if let Some(zone) = &e.zone {
33921 self.write(", ");
33922 self.generate_expression(zone)?;
33923 }
33924 self.write(")");
33925 Ok(())
33926 }
33927
33928 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
33929 self.write_keyword("PARSE_IP");
33931 self.write("(");
33932 self.generate_expression(&e.this)?;
33933 if let Some(type_) = &e.type_ {
33934 self.write(", ");
33935 self.generate_expression(type_)?;
33936 }
33937 if let Some(permissive) = &e.permissive {
33938 self.write(", ");
33939 self.generate_expression(permissive)?;
33940 }
33941 self.write(")");
33942 Ok(())
33943 }
33944
33945 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
33946 self.write_keyword("PARSE_JSON");
33948 self.write("(");
33949 self.generate_expression(&e.this)?;
33950 if let Some(expression) = &e.expression {
33951 self.write(", ");
33952 self.generate_expression(expression)?;
33953 }
33954 self.write(")");
33955 Ok(())
33956 }
33957
33958 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
33959 self.write_keyword("PARSE_TIME");
33961 self.write("(");
33962 self.write(&format!("'{}'", e.format));
33963 self.write(", ");
33964 self.generate_expression(&e.this)?;
33965 self.write(")");
33966 Ok(())
33967 }
33968
33969 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
33970 self.write_keyword("PARSE_URL");
33972 self.write("(");
33973 self.generate_expression(&e.this)?;
33974 if let Some(part) = &e.part_to_extract {
33975 self.write(", ");
33976 self.generate_expression(part)?;
33977 }
33978 if let Some(key) = &e.key {
33979 self.write(", ");
33980 self.generate_expression(key)?;
33981 }
33982 if let Some(permissive) = &e.permissive {
33983 self.write(", ");
33984 self.generate_expression(permissive)?;
33985 }
33986 self.write(")");
33987 Ok(())
33988 }
33989
33990 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
33991 if e.subpartition {
33993 self.write_keyword("SUBPARTITION");
33994 } else {
33995 self.write_keyword("PARTITION");
33996 }
33997 self.write("(");
33998 for (i, expr) in e.expressions.iter().enumerate() {
33999 if i > 0 {
34000 self.write(", ");
34001 }
34002 self.generate_expression(expr)?;
34003 }
34004 self.write(")");
34005 Ok(())
34006 }
34007
34008 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
34009 if let Some(this) = &e.this {
34011 if let Some(expression) = &e.expression {
34012 self.write_keyword("WITH");
34014 self.write(" (");
34015 self.write_keyword("MODULUS");
34016 self.write_space();
34017 self.generate_expression(this)?;
34018 self.write(", ");
34019 self.write_keyword("REMAINDER");
34020 self.write_space();
34021 self.generate_expression(expression)?;
34022 self.write(")");
34023 } else {
34024 self.write_keyword("IN");
34026 self.write(" (");
34027 self.generate_partition_bound_values(this)?;
34028 self.write(")");
34029 }
34030 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
34031 self.write_keyword("FROM");
34033 self.write(" (");
34034 self.generate_partition_bound_values(from)?;
34035 self.write(") ");
34036 self.write_keyword("TO");
34037 self.write(" (");
34038 self.generate_partition_bound_values(to)?;
34039 self.write(")");
34040 }
34041 Ok(())
34042 }
34043
34044 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
34047 if let Expression::Tuple(t) = expr {
34048 for (i, e) in t.expressions.iter().enumerate() {
34049 if i > 0 {
34050 self.write(", ");
34051 }
34052 self.generate_expression(e)?;
34053 }
34054 Ok(())
34055 } else {
34056 self.generate_expression(expr)
34057 }
34058 }
34059
34060 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
34061 self.write_keyword("PARTITION BY LIST");
34063 if let Some(partition_exprs) = &e.partition_expressions {
34064 self.write(" (");
34065 self.generate_doris_partition_expressions(partition_exprs)?;
34067 self.write(")");
34068 }
34069 if let Some(create_exprs) = &e.create_expressions {
34070 self.write(" (");
34071 self.generate_doris_partition_definitions(create_exprs)?;
34073 self.write(")");
34074 }
34075 Ok(())
34076 }
34077
34078 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
34079 self.write_keyword("PARTITION BY RANGE");
34081 if let Some(partition_exprs) = &e.partition_expressions {
34082 self.write(" (");
34083 self.generate_doris_partition_expressions(partition_exprs)?;
34085 self.write(")");
34086 }
34087 if let Some(create_exprs) = &e.create_expressions {
34088 self.write(" (");
34089 self.generate_doris_partition_definitions(create_exprs)?;
34091 self.write(")");
34092 }
34093 Ok(())
34094 }
34095
34096 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
34098 if let Expression::Tuple(t) = expr {
34099 for (i, e) in t.expressions.iter().enumerate() {
34100 if i > 0 {
34101 self.write(", ");
34102 }
34103 self.generate_expression(e)?;
34104 }
34105 } else {
34106 self.generate_expression(expr)?;
34107 }
34108 Ok(())
34109 }
34110
34111 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
34113 match expr {
34114 Expression::Tuple(t) => {
34115 for (i, part) in t.expressions.iter().enumerate() {
34117 if i > 0 {
34118 self.write(", ");
34119 }
34120 if let Expression::Partition(p) = part {
34122 for (j, inner) in p.expressions.iter().enumerate() {
34123 if j > 0 {
34124 self.write(", ");
34125 }
34126 self.generate_expression(inner)?;
34127 }
34128 } else {
34129 self.generate_expression(part)?;
34130 }
34131 }
34132 }
34133 Expression::PartitionByRangePropertyDynamic(_) => {
34134 self.generate_expression(expr)?;
34136 }
34137 _ => {
34138 self.generate_expression(expr)?;
34139 }
34140 }
34141 Ok(())
34142 }
34143
34144 fn generate_partition_by_range_property_dynamic(
34145 &mut self,
34146 e: &PartitionByRangePropertyDynamic,
34147 ) -> Result<()> {
34148 if e.use_start_end {
34149 if let Some(start) = &e.start {
34151 self.write_keyword("START");
34152 self.write(" (");
34153 self.generate_expression(start)?;
34154 self.write(")");
34155 }
34156 if let Some(end) = &e.end {
34157 self.write_space();
34158 self.write_keyword("END");
34159 self.write(" (");
34160 self.generate_expression(end)?;
34161 self.write(")");
34162 }
34163 if let Some(every) = &e.every {
34164 self.write_space();
34165 self.write_keyword("EVERY");
34166 self.write(" (");
34167 self.generate_doris_interval(every)?;
34169 self.write(")");
34170 }
34171 } else {
34172 if let Some(start) = &e.start {
34174 self.write_keyword("FROM");
34175 self.write(" (");
34176 self.generate_expression(start)?;
34177 self.write(")");
34178 }
34179 if let Some(end) = &e.end {
34180 self.write_space();
34181 self.write_keyword("TO");
34182 self.write(" (");
34183 self.generate_expression(end)?;
34184 self.write(")");
34185 }
34186 if let Some(every) = &e.every {
34187 self.write_space();
34188 self.generate_doris_interval(every)?;
34190 }
34191 }
34192 Ok(())
34193 }
34194
34195 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
34197 if let Expression::Interval(interval) = expr {
34198 self.write_keyword("INTERVAL");
34199 if let Some(ref value) = interval.this {
34200 self.write_space();
34201 match value {
34205 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()) => {
34206 if let Literal::String(s) = lit.as_ref() {
34207 self.write(s);
34208 }
34209 }
34210 _ => {
34211 self.generate_expression(value)?;
34212 }
34213 }
34214 }
34215 if let Some(ref unit_spec) = interval.unit {
34216 self.write_space();
34217 self.write_interval_unit_spec(unit_spec)?;
34218 }
34219 Ok(())
34220 } else {
34221 self.generate_expression(expr)
34222 }
34223 }
34224
34225 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
34226 self.write_keyword("TRUNCATE");
34228 self.write("(");
34229 self.generate_expression(&e.expression)?;
34230 self.write(", ");
34231 self.generate_expression(&e.this)?;
34232 self.write(")");
34233 Ok(())
34234 }
34235
34236 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
34237 self.write_keyword("PARTITION");
34239 self.write_space();
34240 self.generate_expression(&e.this)?;
34241 self.write_space();
34242 self.write_keyword("VALUES IN");
34243 self.write(" (");
34244 for (i, expr) in e.expressions.iter().enumerate() {
34245 if i > 0 {
34246 self.write(", ");
34247 }
34248 self.generate_expression(expr)?;
34249 }
34250 self.write(")");
34251 Ok(())
34252 }
34253
34254 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
34255 if e.expressions.is_empty() && e.expression.is_some() {
34258 self.generate_expression(&e.this)?;
34260 self.write_space();
34261 self.write_keyword("TO");
34262 self.write_space();
34263 self.generate_expression(e.expression.as_ref().unwrap())?;
34264 return Ok(());
34265 }
34266
34267 self.write_keyword("PARTITION");
34269 self.write_space();
34270 self.generate_expression(&e.this)?;
34271 self.write_space();
34272
34273 if e.expressions.len() == 1 {
34275 self.write_keyword("VALUES LESS THAN");
34277 self.write(" (");
34278 self.generate_expression(&e.expressions[0])?;
34279 self.write(")");
34280 } else if !e.expressions.is_empty() {
34281 self.write_keyword("VALUES");
34283 self.write(" [");
34284 for (i, expr) in e.expressions.iter().enumerate() {
34285 if i > 0 {
34286 self.write(", ");
34287 }
34288 if let Expression::Tuple(t) = expr {
34290 self.write("(");
34291 for (j, inner) in t.expressions.iter().enumerate() {
34292 if j > 0 {
34293 self.write(", ");
34294 }
34295 self.generate_expression(inner)?;
34296 }
34297 self.write(")");
34298 } else {
34299 self.write("(");
34300 self.generate_expression(expr)?;
34301 self.write(")");
34302 }
34303 }
34304 self.write(")");
34305 }
34306 Ok(())
34307 }
34308
34309 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
34310 self.write_keyword("BUCKET");
34312 self.write("(");
34313 self.generate_expression(&e.this)?;
34314 self.write(", ");
34315 self.generate_expression(&e.expression)?;
34316 self.write(")");
34317 Ok(())
34318 }
34319
34320 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
34321 self.write_keyword("PARTITION BY");
34323 self.write_space();
34324 for (i, expr) in e.expressions.iter().enumerate() {
34325 if i > 0 {
34326 self.write(", ");
34327 }
34328 self.generate_expression(expr)?;
34329 }
34330 Ok(())
34331 }
34332
34333 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
34334 if matches!(
34336 self.config.dialect,
34337 Some(crate::dialects::DialectType::Teradata)
34338 | Some(crate::dialects::DialectType::ClickHouse)
34339 ) {
34340 self.write_keyword("PARTITION BY");
34341 } else {
34342 self.write_keyword("PARTITIONED BY");
34343 }
34344 self.write_space();
34345 if self.config.pretty {
34347 if let Expression::Tuple(ref tuple) = *e.this {
34348 self.write("(");
34349 self.write_newline();
34350 self.indent_level += 1;
34351 for (i, expr) in tuple.expressions.iter().enumerate() {
34352 if i > 0 {
34353 self.write(",");
34354 self.write_newline();
34355 }
34356 self.write_indent();
34357 self.generate_expression(expr)?;
34358 }
34359 self.indent_level -= 1;
34360 self.write_newline();
34361 self.write(")");
34362 } else {
34363 self.generate_expression(&e.this)?;
34364 }
34365 } else {
34366 self.generate_expression(&e.this)?;
34367 }
34368 Ok(())
34369 }
34370
34371 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
34372 self.write_keyword("PARTITION OF");
34374 self.write_space();
34375 self.generate_expression(&e.this)?;
34376 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
34378 self.write_space();
34379 self.write_keyword("FOR VALUES");
34380 self.write_space();
34381 self.generate_expression(&e.expression)?;
34382 } else {
34383 self.write_space();
34384 self.write_keyword("DEFAULT");
34385 }
34386 Ok(())
34387 }
34388
34389 fn generate_period_for_system_time_constraint(
34390 &mut self,
34391 e: &PeriodForSystemTimeConstraint,
34392 ) -> Result<()> {
34393 self.write_keyword("PERIOD FOR SYSTEM_TIME");
34395 self.write(" (");
34396 self.generate_expression(&e.this)?;
34397 self.write(", ");
34398 self.generate_expression(&e.expression)?;
34399 self.write(")");
34400 Ok(())
34401 }
34402
34403 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
34404 self.generate_expression(&e.this)?;
34407 self.write_space();
34408 self.write_keyword("AS");
34409 self.write_space();
34410 if self.config.unpivot_aliases_are_identifiers {
34412 match &e.alias {
34413 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
34414 let Literal::String(s) = lit.as_ref() else {
34415 unreachable!()
34416 };
34417 self.generate_identifier(&Identifier::new(s.clone()))?;
34419 }
34420 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
34421 let Literal::Number(n) = lit.as_ref() else {
34422 unreachable!()
34423 };
34424 let mut id = Identifier::new(n.clone());
34426 id.quoted = true;
34427 self.generate_identifier(&id)?;
34428 }
34429 other => {
34430 self.generate_expression(other)?;
34431 }
34432 }
34433 } else {
34434 self.generate_expression(&e.alias)?;
34435 }
34436 Ok(())
34437 }
34438
34439 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
34440 self.write_keyword("ANY");
34442 if let Some(this) = &e.this {
34443 self.write_space();
34444 self.generate_expression(this)?;
34445 }
34446 Ok(())
34447 }
34448
34449 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
34450 self.write_keyword("ML.PREDICT");
34452 self.write("(");
34453 self.write_keyword("MODEL");
34454 self.write_space();
34455 self.generate_expression(&e.this)?;
34456 self.write(", ");
34457 self.generate_expression(&e.expression)?;
34458 if let Some(params) = &e.params_struct {
34459 self.write(", ");
34460 self.generate_expression(params)?;
34461 }
34462 self.write(")");
34463 Ok(())
34464 }
34465
34466 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
34467 self.write_keyword("PREVIOUS_DAY");
34469 self.write("(");
34470 self.generate_expression(&e.this)?;
34471 self.write(", ");
34472 self.generate_expression(&e.expression)?;
34473 self.write(")");
34474 Ok(())
34475 }
34476
34477 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
34478 self.write_keyword("PRIMARY KEY");
34480 if let Some(name) = &e.this {
34481 self.write_space();
34482 self.generate_expression(name)?;
34483 }
34484 if !e.expressions.is_empty() {
34485 self.write(" (");
34486 for (i, expr) in e.expressions.iter().enumerate() {
34487 if i > 0 {
34488 self.write(", ");
34489 }
34490 self.generate_expression(expr)?;
34491 }
34492 self.write(")");
34493 }
34494 if let Some(include) = &e.include {
34495 self.write_space();
34496 self.generate_expression(include)?;
34497 }
34498 if !e.options.is_empty() {
34499 self.write_space();
34500 for (i, opt) in e.options.iter().enumerate() {
34501 if i > 0 {
34502 self.write_space();
34503 }
34504 self.generate_expression(opt)?;
34505 }
34506 }
34507 Ok(())
34508 }
34509
34510 fn generate_primary_key_column_constraint(
34511 &mut self,
34512 _e: &PrimaryKeyColumnConstraint,
34513 ) -> Result<()> {
34514 self.write_keyword("PRIMARY KEY");
34516 Ok(())
34517 }
34518
34519 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
34520 self.write_keyword("PATH");
34522 self.write_space();
34523 self.generate_expression(&e.this)?;
34524 Ok(())
34525 }
34526
34527 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
34528 self.write_keyword("PROJECTION");
34530 self.write_space();
34531 self.generate_expression(&e.this)?;
34532 self.write(" (");
34533 self.generate_expression(&e.expression)?;
34534 self.write(")");
34535 Ok(())
34536 }
34537
34538 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
34539 for (i, prop) in e.expressions.iter().enumerate() {
34541 if i > 0 {
34542 self.write(", ");
34543 }
34544 self.generate_expression(prop)?;
34545 }
34546 Ok(())
34547 }
34548
34549 fn generate_property(&mut self, e: &Property) -> Result<()> {
34550 self.generate_expression(&e.this)?;
34552 if let Some(value) = &e.value {
34553 self.write("=");
34554 self.generate_expression(value)?;
34555 }
34556 Ok(())
34557 }
34558
34559 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
34560 self.write_keyword("OPTIONS");
34561 if e.entries.is_empty() {
34562 self.write(" ()");
34563 return Ok(());
34564 }
34565
34566 if self.config.pretty {
34567 self.write(" (");
34568 self.write_newline();
34569 self.indent_level += 1;
34570 for (i, entry) in e.entries.iter().enumerate() {
34571 if i > 0 {
34572 self.write(",");
34573 self.write_newline();
34574 }
34575 self.write_indent();
34576 self.generate_identifier(&entry.key)?;
34577 self.write("=");
34578 self.generate_expression(&entry.value)?;
34579 }
34580 self.indent_level -= 1;
34581 self.write_newline();
34582 self.write(")");
34583 } else {
34584 self.write(" (");
34585 for (i, entry) in e.entries.iter().enumerate() {
34586 if i > 0 {
34587 self.write(", ");
34588 }
34589 self.generate_identifier(&entry.key)?;
34590 self.write("=");
34591 self.generate_expression(&entry.value)?;
34592 }
34593 self.write(")");
34594 }
34595 Ok(())
34596 }
34597
34598 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
34600 self.write_keyword("OPTIONS");
34601 self.write(" (");
34602 for (i, opt) in options.iter().enumerate() {
34603 if i > 0 {
34604 self.write(", ");
34605 }
34606 self.generate_option_expression(opt)?;
34607 }
34608 self.write(")");
34609 Ok(())
34610 }
34611
34612 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
34614 self.write_keyword("PROPERTIES");
34615 self.write(" (");
34616 for (i, prop) in properties.iter().enumerate() {
34617 if i > 0 {
34618 self.write(", ");
34619 }
34620 self.generate_option_expression(prop)?;
34621 }
34622 self.write(")");
34623 Ok(())
34624 }
34625
34626 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
34628 self.write_keyword("ENVIRONMENT");
34629 self.write(" (");
34630 for (i, env_item) in environment.iter().enumerate() {
34631 if i > 0 {
34632 self.write(", ");
34633 }
34634 self.generate_environment_expression(env_item)?;
34635 }
34636 self.write(")");
34637 Ok(())
34638 }
34639
34640 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
34642 match expr {
34643 Expression::Eq(eq) => {
34644 self.generate_expression(&eq.left)?;
34646 self.write(" = ");
34647 self.generate_expression(&eq.right)?;
34648 Ok(())
34649 }
34650 _ => self.generate_expression(expr),
34651 }
34652 }
34653
34654 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
34656 self.write_keyword("TBLPROPERTIES");
34657 if self.config.pretty {
34658 self.write(" (");
34659 self.write_newline();
34660 self.indent_level += 1;
34661 for (i, opt) in options.iter().enumerate() {
34662 if i > 0 {
34663 self.write(",");
34664 self.write_newline();
34665 }
34666 self.write_indent();
34667 self.generate_option_expression(opt)?;
34668 }
34669 self.indent_level -= 1;
34670 self.write_newline();
34671 self.write(")");
34672 } else {
34673 self.write(" (");
34674 for (i, opt) in options.iter().enumerate() {
34675 if i > 0 {
34676 self.write(", ");
34677 }
34678 self.generate_option_expression(opt)?;
34679 }
34680 self.write(")");
34681 }
34682 Ok(())
34683 }
34684
34685 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
34687 match expr {
34688 Expression::Eq(eq) => {
34689 self.generate_expression(&eq.left)?;
34691 self.write("=");
34692 self.generate_expression(&eq.right)?;
34693 Ok(())
34694 }
34695 _ => self.generate_expression(expr),
34696 }
34697 }
34698
34699 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
34700 self.generate_expression(&e.this)?;
34702 Ok(())
34703 }
34704
34705 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
34706 self.write_keyword("PUT");
34708 self.write_space();
34709
34710 if e.source_quoted {
34712 self.write("'");
34713 self.write(&e.source);
34714 self.write("'");
34715 } else {
34716 self.write(&e.source);
34717 }
34718
34719 self.write_space();
34720
34721 if let Expression::Literal(lit) = &e.target {
34723 if let Literal::String(s) = lit.as_ref() {
34724 self.write(s);
34725 }
34726 } else {
34727 self.generate_expression(&e.target)?;
34728 }
34729
34730 for param in &e.params {
34732 self.write_space();
34733 self.write(¶m.name);
34734 if let Some(ref value) = param.value {
34735 self.write("=");
34736 self.generate_expression(value)?;
34737 }
34738 }
34739
34740 Ok(())
34741 }
34742
34743 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
34744 self.write_keyword("QUANTILE");
34746 self.write("(");
34747 self.generate_expression(&e.this)?;
34748 if let Some(quantile) = &e.quantile {
34749 self.write(", ");
34750 self.generate_expression(quantile)?;
34751 }
34752 self.write(")");
34753 Ok(())
34754 }
34755
34756 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
34757 if matches!(
34759 self.config.dialect,
34760 Some(crate::dialects::DialectType::Teradata)
34761 ) {
34762 self.write_keyword("SET");
34763 self.write_space();
34764 }
34765 self.write_keyword("QUERY_BAND");
34766 self.write(" = ");
34767 self.generate_expression(&e.this)?;
34768 if e.update.is_some() {
34769 self.write_space();
34770 self.write_keyword("UPDATE");
34771 }
34772 if let Some(scope) = &e.scope {
34773 self.write_space();
34774 self.write_keyword("FOR");
34775 self.write_space();
34776 self.generate_expression(scope)?;
34777 }
34778 Ok(())
34779 }
34780
34781 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
34782 self.generate_expression(&e.this)?;
34784 if let Some(expression) = &e.expression {
34785 self.write(" = ");
34786 self.generate_expression(expression)?;
34787 }
34788 Ok(())
34789 }
34790
34791 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
34792 self.write_keyword("TRANSFORM");
34794 self.write("(");
34795 for (i, expr) in e.expressions.iter().enumerate() {
34796 if i > 0 {
34797 self.write(", ");
34798 }
34799 self.generate_expression(expr)?;
34800 }
34801 self.write(")");
34802 if let Some(row_format_before) = &e.row_format_before {
34803 self.write_space();
34804 self.generate_expression(row_format_before)?;
34805 }
34806 if let Some(record_writer) = &e.record_writer {
34807 self.write_space();
34808 self.write_keyword("RECORDWRITER");
34809 self.write_space();
34810 self.generate_expression(record_writer)?;
34811 }
34812 if let Some(command_script) = &e.command_script {
34813 self.write_space();
34814 self.write_keyword("USING");
34815 self.write_space();
34816 self.generate_expression(command_script)?;
34817 }
34818 if let Some(schema) = &e.schema {
34819 self.write_space();
34820 self.write_keyword("AS");
34821 self.write_space();
34822 self.generate_expression(schema)?;
34823 }
34824 if let Some(row_format_after) = &e.row_format_after {
34825 self.write_space();
34826 self.generate_expression(row_format_after)?;
34827 }
34828 if let Some(record_reader) = &e.record_reader {
34829 self.write_space();
34830 self.write_keyword("RECORDREADER");
34831 self.write_space();
34832 self.generate_expression(record_reader)?;
34833 }
34834 Ok(())
34835 }
34836
34837 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
34838 self.write_keyword("RANDN");
34840 self.write("(");
34841 if let Some(this) = &e.this {
34842 self.generate_expression(this)?;
34843 }
34844 self.write(")");
34845 Ok(())
34846 }
34847
34848 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
34849 self.write_keyword("RANDSTR");
34851 self.write("(");
34852 self.generate_expression(&e.this)?;
34853 if let Some(generator) = &e.generator {
34854 self.write(", ");
34855 self.generate_expression(generator)?;
34856 }
34857 self.write(")");
34858 Ok(())
34859 }
34860
34861 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
34862 self.write_keyword("RANGE_BUCKET");
34864 self.write("(");
34865 self.generate_expression(&e.this)?;
34866 self.write(", ");
34867 self.generate_expression(&e.expression)?;
34868 self.write(")");
34869 Ok(())
34870 }
34871
34872 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
34873 self.write_keyword("RANGE_N");
34875 self.write("(");
34876 self.generate_expression(&e.this)?;
34877 self.write_space();
34878 self.write_keyword("BETWEEN");
34879 self.write_space();
34880 for (i, expr) in e.expressions.iter().enumerate() {
34881 if i > 0 {
34882 self.write(", ");
34883 }
34884 self.generate_expression(expr)?;
34885 }
34886 if let Some(each) = &e.each {
34887 self.write_space();
34888 self.write_keyword("EACH");
34889 self.write_space();
34890 self.generate_expression(each)?;
34891 }
34892 self.write(")");
34893 Ok(())
34894 }
34895
34896 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
34897 self.write_keyword("READ_CSV");
34899 self.write("(");
34900 self.generate_expression(&e.this)?;
34901 for expr in &e.expressions {
34902 self.write(", ");
34903 self.generate_expression(expr)?;
34904 }
34905 self.write(")");
34906 Ok(())
34907 }
34908
34909 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
34910 self.write_keyword("READ_PARQUET");
34912 self.write("(");
34913 for (i, expr) in e.expressions.iter().enumerate() {
34914 if i > 0 {
34915 self.write(", ");
34916 }
34917 self.generate_expression(expr)?;
34918 }
34919 self.write(")");
34920 Ok(())
34921 }
34922
34923 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
34924 if e.kind == "CYCLE" {
34927 self.write_keyword("CYCLE");
34928 } else {
34929 self.write_keyword("SEARCH");
34930 self.write_space();
34931 self.write(&e.kind);
34932 self.write_space();
34933 self.write_keyword("FIRST BY");
34934 }
34935 self.write_space();
34936 self.generate_expression(&e.this)?;
34937 self.write_space();
34938 self.write_keyword("SET");
34939 self.write_space();
34940 self.generate_expression(&e.expression)?;
34941 if let Some(using) = &e.using {
34942 self.write_space();
34943 self.write_keyword("USING");
34944 self.write_space();
34945 self.generate_expression(using)?;
34946 }
34947 Ok(())
34948 }
34949
34950 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
34951 self.write_keyword("REDUCE");
34953 self.write("(");
34954 self.generate_expression(&e.this)?;
34955 if let Some(initial) = &e.initial {
34956 self.write(", ");
34957 self.generate_expression(initial)?;
34958 }
34959 if let Some(merge) = &e.merge {
34960 self.write(", ");
34961 self.generate_expression(merge)?;
34962 }
34963 if let Some(finish) = &e.finish {
34964 self.write(", ");
34965 self.generate_expression(finish)?;
34966 }
34967 self.write(")");
34968 Ok(())
34969 }
34970
34971 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
34972 self.write_keyword("REFERENCES");
34974 self.write_space();
34975 self.generate_expression(&e.this)?;
34976 if !e.expressions.is_empty() {
34977 self.write(" (");
34978 for (i, expr) in e.expressions.iter().enumerate() {
34979 if i > 0 {
34980 self.write(", ");
34981 }
34982 self.generate_expression(expr)?;
34983 }
34984 self.write(")");
34985 }
34986 for opt in &e.options {
34987 self.write_space();
34988 self.generate_expression(opt)?;
34989 }
34990 Ok(())
34991 }
34992
34993 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
34994 self.write_keyword("REFRESH");
34996 if !e.kind.is_empty() {
34997 self.write_space();
34998 self.write_keyword(&e.kind);
34999 }
35000 self.write_space();
35001 self.generate_expression(&e.this)?;
35002 Ok(())
35003 }
35004
35005 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
35006 self.write_keyword("REFRESH");
35008 self.write_space();
35009 self.write_keyword(&e.method);
35010
35011 if let Some(ref kind) = e.kind {
35012 self.write_space();
35013 self.write_keyword("ON");
35014 self.write_space();
35015 self.write_keyword(kind);
35016
35017 if let Some(ref every) = e.every {
35019 self.write_space();
35020 self.write_keyword("EVERY");
35021 self.write_space();
35022 self.generate_expression(every)?;
35023 if let Some(ref unit) = e.unit {
35024 self.write_space();
35025 self.write_keyword(unit);
35026 }
35027 }
35028
35029 if let Some(ref starts) = e.starts {
35031 self.write_space();
35032 self.write_keyword("STARTS");
35033 self.write_space();
35034 self.generate_expression(starts)?;
35035 }
35036 }
35037 Ok(())
35038 }
35039
35040 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
35041 self.write_keyword("REGEXP_COUNT");
35043 self.write("(");
35044 self.generate_expression(&e.this)?;
35045 self.write(", ");
35046 self.generate_expression(&e.expression)?;
35047 if let Some(position) = &e.position {
35048 self.write(", ");
35049 self.generate_expression(position)?;
35050 }
35051 if let Some(parameters) = &e.parameters {
35052 self.write(", ");
35053 self.generate_expression(parameters)?;
35054 }
35055 self.write(")");
35056 Ok(())
35057 }
35058
35059 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
35060 self.write_keyword("REGEXP_EXTRACT_ALL");
35062 self.write("(");
35063 self.generate_expression(&e.this)?;
35064 self.write(", ");
35065 self.generate_expression(&e.expression)?;
35066 if let Some(group) = &e.group {
35067 self.write(", ");
35068 self.generate_expression(group)?;
35069 }
35070 self.write(")");
35071 Ok(())
35072 }
35073
35074 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
35075 self.write_keyword("REGEXP_FULL_MATCH");
35077 self.write("(");
35078 self.generate_expression(&e.this)?;
35079 self.write(", ");
35080 self.generate_expression(&e.expression)?;
35081 self.write(")");
35082 Ok(())
35083 }
35084
35085 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
35086 use crate::dialects::DialectType;
35087 if matches!(
35089 self.config.dialect,
35090 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
35091 ) && e.flag.is_none()
35092 {
35093 self.generate_expression(&e.this)?;
35094 self.write(" ~* ");
35095 self.generate_expression(&e.expression)?;
35096 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && e.flag.is_none() {
35097 self.write("match(");
35101 self.generate_expression(&e.this)?;
35102 self.write(", ");
35103 if let Expression::Literal(lit) = e.expression.as_ref() {
35104 if let Literal::String(s) = lit.as_ref() {
35105 let insensitive =
35106 Expression::Literal(Box::new(Literal::String(format!("(?i){s}"))));
35107 self.generate_expression(&insensitive)?;
35108 self.write(")");
35109 return Ok(());
35110 }
35111 }
35112 self.write("concat('(?i)', ");
35113 self.generate_expression(&e.expression)?;
35114 self.write("))");
35115 return Ok(());
35116 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35117 self.write_keyword("REGEXP_LIKE");
35119 self.write("(");
35120 self.generate_expression(&e.this)?;
35121 self.write(", ");
35122 self.generate_expression(&e.expression)?;
35123 self.write(", ");
35124 if let Some(flag) = &e.flag {
35125 self.generate_expression(flag)?;
35126 } else {
35127 self.write("'i'");
35128 }
35129 self.write(")");
35130 } else {
35131 self.generate_expression(&e.this)?;
35133 self.write_space();
35134 self.write_keyword("REGEXP_ILIKE");
35135 self.write_space();
35136 self.generate_expression(&e.expression)?;
35137 if let Some(flag) = &e.flag {
35138 self.write(", ");
35139 self.generate_expression(flag)?;
35140 }
35141 }
35142 Ok(())
35143 }
35144
35145 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
35146 self.write_keyword("REGEXP_INSTR");
35148 self.write("(");
35149 self.generate_expression(&e.this)?;
35150 self.write(", ");
35151 self.generate_expression(&e.expression)?;
35152 if let Some(position) = &e.position {
35153 self.write(", ");
35154 self.generate_expression(position)?;
35155 }
35156 if let Some(occurrence) = &e.occurrence {
35157 self.write(", ");
35158 self.generate_expression(occurrence)?;
35159 }
35160 if let Some(option) = &e.option {
35161 self.write(", ");
35162 self.generate_expression(option)?;
35163 }
35164 if let Some(parameters) = &e.parameters {
35165 self.write(", ");
35166 self.generate_expression(parameters)?;
35167 }
35168 if let Some(group) = &e.group {
35169 self.write(", ");
35170 self.generate_expression(group)?;
35171 }
35172 self.write(")");
35173 Ok(())
35174 }
35175
35176 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
35177 self.write_keyword("REGEXP_SPLIT");
35179 self.write("(");
35180 self.generate_expression(&e.this)?;
35181 self.write(", ");
35182 self.generate_expression(&e.expression)?;
35183 if let Some(limit) = &e.limit {
35184 self.write(", ");
35185 self.generate_expression(limit)?;
35186 }
35187 self.write(")");
35188 Ok(())
35189 }
35190
35191 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
35192 self.write_keyword("REGR_AVGX");
35194 self.write("(");
35195 self.generate_expression(&e.this)?;
35196 self.write(", ");
35197 self.generate_expression(&e.expression)?;
35198 self.write(")");
35199 Ok(())
35200 }
35201
35202 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
35203 self.write_keyword("REGR_AVGY");
35205 self.write("(");
35206 self.generate_expression(&e.this)?;
35207 self.write(", ");
35208 self.generate_expression(&e.expression)?;
35209 self.write(")");
35210 Ok(())
35211 }
35212
35213 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
35214 self.write_keyword("REGR_COUNT");
35216 self.write("(");
35217 self.generate_expression(&e.this)?;
35218 self.write(", ");
35219 self.generate_expression(&e.expression)?;
35220 self.write(")");
35221 Ok(())
35222 }
35223
35224 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
35225 self.write_keyword("REGR_INTERCEPT");
35227 self.write("(");
35228 self.generate_expression(&e.this)?;
35229 self.write(", ");
35230 self.generate_expression(&e.expression)?;
35231 self.write(")");
35232 Ok(())
35233 }
35234
35235 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
35236 self.write_keyword("REGR_R2");
35238 self.write("(");
35239 self.generate_expression(&e.this)?;
35240 self.write(", ");
35241 self.generate_expression(&e.expression)?;
35242 self.write(")");
35243 Ok(())
35244 }
35245
35246 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
35247 self.write_keyword("REGR_SLOPE");
35249 self.write("(");
35250 self.generate_expression(&e.this)?;
35251 self.write(", ");
35252 self.generate_expression(&e.expression)?;
35253 self.write(")");
35254 Ok(())
35255 }
35256
35257 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
35258 self.write_keyword("REGR_SXX");
35260 self.write("(");
35261 self.generate_expression(&e.this)?;
35262 self.write(", ");
35263 self.generate_expression(&e.expression)?;
35264 self.write(")");
35265 Ok(())
35266 }
35267
35268 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
35269 self.write_keyword("REGR_SXY");
35271 self.write("(");
35272 self.generate_expression(&e.this)?;
35273 self.write(", ");
35274 self.generate_expression(&e.expression)?;
35275 self.write(")");
35276 Ok(())
35277 }
35278
35279 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
35280 self.write_keyword("REGR_SYY");
35282 self.write("(");
35283 self.generate_expression(&e.this)?;
35284 self.write(", ");
35285 self.generate_expression(&e.expression)?;
35286 self.write(")");
35287 Ok(())
35288 }
35289
35290 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
35291 self.write_keyword("REGR_VALX");
35293 self.write("(");
35294 self.generate_expression(&e.this)?;
35295 self.write(", ");
35296 self.generate_expression(&e.expression)?;
35297 self.write(")");
35298 Ok(())
35299 }
35300
35301 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
35302 self.write_keyword("REGR_VALY");
35304 self.write("(");
35305 self.generate_expression(&e.this)?;
35306 self.write(", ");
35307 self.generate_expression(&e.expression)?;
35308 self.write(")");
35309 Ok(())
35310 }
35311
35312 fn generate_remote_with_connection_model_property(
35313 &mut self,
35314 e: &RemoteWithConnectionModelProperty,
35315 ) -> Result<()> {
35316 self.write_keyword("REMOTE WITH CONNECTION");
35318 self.write_space();
35319 self.generate_expression(&e.this)?;
35320 Ok(())
35321 }
35322
35323 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
35324 self.write_keyword("RENAME COLUMN");
35326 if e.exists {
35327 self.write_space();
35328 self.write_keyword("IF EXISTS");
35329 }
35330 self.write_space();
35331 self.generate_expression(&e.this)?;
35332 if let Some(to) = &e.to {
35333 self.write_space();
35334 self.write_keyword("TO");
35335 self.write_space();
35336 self.generate_expression(to)?;
35337 }
35338 Ok(())
35339 }
35340
35341 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
35342 self.write_keyword("REPLACE PARTITION");
35344 self.write_space();
35345 self.generate_expression(&e.expression)?;
35346 if let Some(source) = &e.source {
35347 self.write_space();
35348 self.write_keyword("FROM");
35349 self.write_space();
35350 self.generate_expression(source)?;
35351 }
35352 Ok(())
35353 }
35354
35355 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
35356 let keyword = match self.config.dialect {
35359 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
35360 _ => "RETURNING",
35361 };
35362 self.write_keyword(keyword);
35363 self.write_space();
35364 for (i, expr) in e.expressions.iter().enumerate() {
35365 if i > 0 {
35366 self.write(", ");
35367 }
35368 self.generate_expression(expr)?;
35369 }
35370 if let Some(into) = &e.into {
35371 self.write_space();
35372 self.write_keyword("INTO");
35373 self.write_space();
35374 self.generate_expression(into)?;
35375 }
35376 Ok(())
35377 }
35378
35379 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
35380 self.write_space();
35382 self.write_keyword("OUTPUT");
35383 self.write_space();
35384 for (i, expr) in output.columns.iter().enumerate() {
35385 if i > 0 {
35386 self.write(", ");
35387 }
35388 self.generate_expression(expr)?;
35389 }
35390 if let Some(into_table) = &output.into_table {
35391 self.write_space();
35392 self.write_keyword("INTO");
35393 self.write_space();
35394 self.generate_expression(into_table)?;
35395 }
35396 Ok(())
35397 }
35398
35399 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
35400 self.write_keyword("RETURNS");
35402 if e.is_table.is_some() {
35403 self.write_space();
35404 self.write_keyword("TABLE");
35405 }
35406 if let Some(table) = &e.table {
35407 self.write_space();
35408 self.generate_expression(table)?;
35409 } else if let Some(this) = &e.this {
35410 self.write_space();
35411 self.generate_expression(this)?;
35412 }
35413 if e.null.is_some() {
35414 self.write_space();
35415 self.write_keyword("NULL ON NULL INPUT");
35416 }
35417 Ok(())
35418 }
35419
35420 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
35421 self.write_keyword("ROLLBACK");
35423
35424 if e.this.is_none()
35426 && matches!(
35427 self.config.dialect,
35428 Some(DialectType::TSQL) | Some(DialectType::Fabric)
35429 )
35430 {
35431 self.write_space();
35432 self.write_keyword("TRANSACTION");
35433 }
35434
35435 if let Some(this) = &e.this {
35437 let is_transaction_marker = matches!(
35439 this.as_ref(),
35440 Expression::Identifier(id) if id.name == "TRANSACTION"
35441 );
35442
35443 self.write_space();
35444 self.write_keyword("TRANSACTION");
35445
35446 if !is_transaction_marker {
35448 self.write_space();
35449 self.generate_expression(this)?;
35450 }
35451 }
35452
35453 if let Some(savepoint) = &e.savepoint {
35455 self.write_space();
35456 self.write_keyword("TO");
35457 self.write_space();
35458 self.generate_expression(savepoint)?;
35459 }
35460 Ok(())
35461 }
35462
35463 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
35464 if e.expressions.is_empty() {
35466 self.write_keyword("WITH ROLLUP");
35467 } else {
35468 self.write_keyword("ROLLUP");
35469 self.write("(");
35470 for (i, expr) in e.expressions.iter().enumerate() {
35471 if i > 0 {
35472 self.write(", ");
35473 }
35474 self.generate_expression(expr)?;
35475 }
35476 self.write(")");
35477 }
35478 Ok(())
35479 }
35480
35481 fn generate_row_format_delimited_property(
35482 &mut self,
35483 e: &RowFormatDelimitedProperty,
35484 ) -> Result<()> {
35485 self.write_keyword("ROW FORMAT DELIMITED");
35487 if let Some(fields) = &e.fields {
35488 self.write_space();
35489 self.write_keyword("FIELDS TERMINATED BY");
35490 self.write_space();
35491 self.generate_expression(fields)?;
35492 }
35493 if let Some(escaped) = &e.escaped {
35494 self.write_space();
35495 self.write_keyword("ESCAPED BY");
35496 self.write_space();
35497 self.generate_expression(escaped)?;
35498 }
35499 if let Some(items) = &e.collection_items {
35500 self.write_space();
35501 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
35502 self.write_space();
35503 self.generate_expression(items)?;
35504 }
35505 if let Some(keys) = &e.map_keys {
35506 self.write_space();
35507 self.write_keyword("MAP KEYS TERMINATED BY");
35508 self.write_space();
35509 self.generate_expression(keys)?;
35510 }
35511 if let Some(lines) = &e.lines {
35512 self.write_space();
35513 self.write_keyword("LINES TERMINATED BY");
35514 self.write_space();
35515 self.generate_expression(lines)?;
35516 }
35517 if let Some(null) = &e.null {
35518 self.write_space();
35519 self.write_keyword("NULL DEFINED AS");
35520 self.write_space();
35521 self.generate_expression(null)?;
35522 }
35523 if let Some(serde) = &e.serde {
35524 self.write_space();
35525 self.generate_expression(serde)?;
35526 }
35527 Ok(())
35528 }
35529
35530 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
35531 self.write_keyword("ROW FORMAT");
35533 self.write_space();
35534 self.generate_expression(&e.this)?;
35535 Ok(())
35536 }
35537
35538 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
35539 self.write_keyword("ROW FORMAT SERDE");
35541 self.write_space();
35542 self.generate_expression(&e.this)?;
35543 if let Some(props) = &e.serde_properties {
35544 self.write_space();
35545 self.generate_expression(props)?;
35547 }
35548 Ok(())
35549 }
35550
35551 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
35552 self.write_keyword("SHA2");
35554 self.write("(");
35555 self.generate_expression(&e.this)?;
35556 if let Some(length) = e.length {
35557 self.write(", ");
35558 self.write(&length.to_string());
35559 }
35560 self.write(")");
35561 Ok(())
35562 }
35563
35564 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
35565 self.write_keyword("SHA2_DIGEST");
35567 self.write("(");
35568 self.generate_expression(&e.this)?;
35569 if let Some(length) = e.length {
35570 self.write(", ");
35571 self.write(&length.to_string());
35572 }
35573 self.write(")");
35574 Ok(())
35575 }
35576
35577 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
35578 let name = if matches!(
35579 self.config.dialect,
35580 Some(crate::dialects::DialectType::Spark)
35581 | Some(crate::dialects::DialectType::Databricks)
35582 ) {
35583 "TRY_ADD"
35584 } else {
35585 "SAFE_ADD"
35586 };
35587 self.write_keyword(name);
35588 self.write("(");
35589 self.generate_expression(&e.this)?;
35590 self.write(", ");
35591 self.generate_expression(&e.expression)?;
35592 self.write(")");
35593 Ok(())
35594 }
35595
35596 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
35597 self.write_keyword("SAFE_DIVIDE");
35599 self.write("(");
35600 self.generate_expression(&e.this)?;
35601 self.write(", ");
35602 self.generate_expression(&e.expression)?;
35603 self.write(")");
35604 Ok(())
35605 }
35606
35607 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
35608 let name = if matches!(
35609 self.config.dialect,
35610 Some(crate::dialects::DialectType::Spark)
35611 | Some(crate::dialects::DialectType::Databricks)
35612 ) {
35613 "TRY_MULTIPLY"
35614 } else {
35615 "SAFE_MULTIPLY"
35616 };
35617 self.write_keyword(name);
35618 self.write("(");
35619 self.generate_expression(&e.this)?;
35620 self.write(", ");
35621 self.generate_expression(&e.expression)?;
35622 self.write(")");
35623 Ok(())
35624 }
35625
35626 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
35627 let name = if matches!(
35628 self.config.dialect,
35629 Some(crate::dialects::DialectType::Spark)
35630 | Some(crate::dialects::DialectType::Databricks)
35631 ) {
35632 "TRY_SUBTRACT"
35633 } else {
35634 "SAFE_SUBTRACT"
35635 };
35636 self.write_keyword(name);
35637 self.write("(");
35638 self.generate_expression(&e.this)?;
35639 self.write(", ");
35640 self.generate_expression(&e.expression)?;
35641 self.write(")");
35642 Ok(())
35643 }
35644
35645 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
35648 if matches!(sample.method, SampleMethod::Bucket) {
35650 self.write(" (");
35651 self.write_keyword("BUCKET");
35652 self.write_space();
35653 if let Some(ref num) = sample.bucket_numerator {
35654 self.generate_expression(num)?;
35655 }
35656 self.write_space();
35657 self.write_keyword("OUT OF");
35658 self.write_space();
35659 if let Some(ref denom) = sample.bucket_denominator {
35660 self.generate_expression(denom)?;
35661 }
35662 if let Some(ref field) = sample.bucket_field {
35663 self.write_space();
35664 self.write_keyword("ON");
35665 self.write_space();
35666 self.generate_expression(field)?;
35667 }
35668 self.write(")");
35669 return Ok(());
35670 }
35671
35672 let is_snowflake = matches!(
35674 self.config.dialect,
35675 Some(crate::dialects::DialectType::Snowflake)
35676 );
35677 let is_postgres = matches!(
35678 self.config.dialect,
35679 Some(crate::dialects::DialectType::PostgreSQL)
35680 | Some(crate::dialects::DialectType::Redshift)
35681 );
35682 let is_databricks = matches!(
35684 self.config.dialect,
35685 Some(crate::dialects::DialectType::Databricks)
35686 );
35687 let is_spark = matches!(
35688 self.config.dialect,
35689 Some(crate::dialects::DialectType::Spark)
35690 );
35691 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
35692 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
35694 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
35695 self.write_space();
35696 if !sample.explicit_method && (is_snowflake || force_method) {
35697 self.write_keyword("BERNOULLI");
35699 } else {
35700 match sample.method {
35701 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
35702 SampleMethod::System => self.write_keyword("SYSTEM"),
35703 SampleMethod::Block => self.write_keyword("BLOCK"),
35704 SampleMethod::Row => self.write_keyword("ROW"),
35705 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
35706 SampleMethod::Percent => self.write_keyword("SYSTEM"),
35707 SampleMethod::Bucket => {} }
35709 }
35710 }
35711
35712 let emit_size_no_parens = !self.config.tablesample_requires_parens;
35714 if emit_size_no_parens {
35715 self.write_space();
35716 match &sample.size {
35717 Expression::Tuple(tuple) => {
35718 for (i, expr) in tuple.expressions.iter().enumerate() {
35719 if i > 0 {
35720 self.write(", ");
35721 }
35722 self.generate_expression(expr)?;
35723 }
35724 }
35725 expr => self.generate_expression(expr)?,
35726 }
35727 } else {
35728 self.write(" (");
35729 self.generate_expression(&sample.size)?;
35730 }
35731
35732 let is_rows_method = matches!(
35734 sample.method,
35735 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
35736 );
35737 let is_percent = matches!(
35738 sample.method,
35739 SampleMethod::Percent
35740 | SampleMethod::System
35741 | SampleMethod::Bernoulli
35742 | SampleMethod::Block
35743 );
35744
35745 let is_presto = matches!(
35749 self.config.dialect,
35750 Some(crate::dialects::DialectType::Presto)
35751 | Some(crate::dialects::DialectType::Trino)
35752 | Some(crate::dialects::DialectType::Athena)
35753 );
35754 let should_output_unit = if is_databricks || is_spark {
35755 is_percent || is_rows_method || sample.unit_after_size
35757 } else if is_snowflake || is_postgres || is_presto {
35758 sample.unit_after_size
35759 } else {
35760 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
35761 };
35762
35763 if should_output_unit {
35764 self.write_space();
35765 if sample.is_percent {
35766 self.write_keyword("PERCENT");
35767 } else if is_rows_method && !sample.unit_after_size {
35768 self.write_keyword("ROWS");
35769 } else if sample.unit_after_size {
35770 match sample.method {
35771 SampleMethod::Percent
35772 | SampleMethod::System
35773 | SampleMethod::Bernoulli
35774 | SampleMethod::Block => {
35775 self.write_keyword("PERCENT");
35776 }
35777 SampleMethod::Row | SampleMethod::Reservoir => {
35778 self.write_keyword("ROWS");
35779 }
35780 _ => self.write_keyword("ROWS"),
35781 }
35782 } else {
35783 self.write_keyword("PERCENT");
35784 }
35785 }
35786
35787 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
35788 if let Some(ref offset) = sample.offset {
35789 self.write_space();
35790 self.write_keyword("OFFSET");
35791 self.write_space();
35792 self.generate_expression(offset)?;
35793 }
35794 }
35795 if !emit_size_no_parens {
35796 self.write(")");
35797 }
35798
35799 Ok(())
35800 }
35801
35802 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
35803 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
35805 self.write_keyword("SAMPLE BY");
35806 } else {
35807 self.write_keyword("SAMPLE");
35808 }
35809 self.write_space();
35810 self.generate_expression(&e.this)?;
35811 Ok(())
35812 }
35813
35814 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
35815 if let Some(this) = &e.this {
35817 self.generate_expression(this)?;
35818 }
35819 if !e.expressions.is_empty() {
35820 if e.this.is_some() {
35822 self.write_space();
35823 }
35824 self.write("(");
35825 for (i, expr) in e.expressions.iter().enumerate() {
35826 if i > 0 {
35827 self.write(", ");
35828 }
35829 self.generate_expression(expr)?;
35830 }
35831 self.write(")");
35832 }
35833 Ok(())
35834 }
35835
35836 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
35837 self.write_keyword("COMMENT");
35839 self.write_space();
35840 self.generate_expression(&e.this)?;
35841 Ok(())
35842 }
35843
35844 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
35845 if let Some(this) = &e.this {
35847 self.generate_expression(this)?;
35848 self.write("::");
35849 }
35850 self.generate_expression(&e.expression)?;
35851 Ok(())
35852 }
35853
35854 fn generate_search(&mut self, e: &Search) -> Result<()> {
35855 self.write_keyword("SEARCH");
35857 self.write("(");
35858 self.generate_expression(&e.this)?;
35859 self.write(", ");
35860 self.generate_expression(&e.expression)?;
35861 if let Some(json_scope) = &e.json_scope {
35862 self.write(", ");
35863 self.generate_expression(json_scope)?;
35864 }
35865 if let Some(analyzer) = &e.analyzer {
35866 self.write(", ");
35867 self.generate_expression(analyzer)?;
35868 }
35869 if let Some(analyzer_options) = &e.analyzer_options {
35870 self.write(", ");
35871 self.generate_expression(analyzer_options)?;
35872 }
35873 if let Some(search_mode) = &e.search_mode {
35874 self.write(", ");
35875 self.generate_expression(search_mode)?;
35876 }
35877 self.write(")");
35878 Ok(())
35879 }
35880
35881 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
35882 self.write_keyword("SEARCH_IP");
35884 self.write("(");
35885 self.generate_expression(&e.this)?;
35886 self.write(", ");
35887 self.generate_expression(&e.expression)?;
35888 self.write(")");
35889 Ok(())
35890 }
35891
35892 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
35893 self.write_keyword("SECURITY");
35895 self.write_space();
35896 self.generate_expression(&e.this)?;
35897 Ok(())
35898 }
35899
35900 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
35901 self.write("SEMANTIC_VIEW(");
35903
35904 if self.config.pretty {
35905 self.write_newline();
35907 self.indent_level += 1;
35908 self.write_indent();
35909 self.generate_expression(&e.this)?;
35910
35911 if let Some(metrics) = &e.metrics {
35912 self.write_newline();
35913 self.write_indent();
35914 self.write_keyword("METRICS");
35915 self.write_space();
35916 self.generate_semantic_view_tuple(metrics)?;
35917 }
35918 if let Some(dimensions) = &e.dimensions {
35919 self.write_newline();
35920 self.write_indent();
35921 self.write_keyword("DIMENSIONS");
35922 self.write_space();
35923 self.generate_semantic_view_tuple(dimensions)?;
35924 }
35925 if let Some(facts) = &e.facts {
35926 self.write_newline();
35927 self.write_indent();
35928 self.write_keyword("FACTS");
35929 self.write_space();
35930 self.generate_semantic_view_tuple(facts)?;
35931 }
35932 if let Some(where_) = &e.where_ {
35933 self.write_newline();
35934 self.write_indent();
35935 self.write_keyword("WHERE");
35936 self.write_space();
35937 self.generate_expression(where_)?;
35938 }
35939 self.write_newline();
35940 self.indent_level -= 1;
35941 self.write_indent();
35942 } else {
35943 self.generate_expression(&e.this)?;
35945 if let Some(metrics) = &e.metrics {
35946 self.write_space();
35947 self.write_keyword("METRICS");
35948 self.write_space();
35949 self.generate_semantic_view_tuple(metrics)?;
35950 }
35951 if let Some(dimensions) = &e.dimensions {
35952 self.write_space();
35953 self.write_keyword("DIMENSIONS");
35954 self.write_space();
35955 self.generate_semantic_view_tuple(dimensions)?;
35956 }
35957 if let Some(facts) = &e.facts {
35958 self.write_space();
35959 self.write_keyword("FACTS");
35960 self.write_space();
35961 self.generate_semantic_view_tuple(facts)?;
35962 }
35963 if let Some(where_) = &e.where_ {
35964 self.write_space();
35965 self.write_keyword("WHERE");
35966 self.write_space();
35967 self.generate_expression(where_)?;
35968 }
35969 }
35970 self.write(")");
35971 Ok(())
35972 }
35973
35974 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
35976 if let Expression::Tuple(t) = expr {
35977 for (i, e) in t.expressions.iter().enumerate() {
35978 if i > 0 {
35979 self.write(", ");
35980 }
35981 self.generate_expression(e)?;
35982 }
35983 } else {
35984 self.generate_expression(expr)?;
35985 }
35986 Ok(())
35987 }
35988
35989 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
35990 if let Some(start) = &e.start {
35992 self.write_keyword("START WITH");
35993 self.write_space();
35994 self.generate_expression(start)?;
35995 }
35996 if let Some(increment) = &e.increment {
35997 self.write_space();
35998 self.write_keyword("INCREMENT BY");
35999 self.write_space();
36000 self.generate_expression(increment)?;
36001 }
36002 if let Some(minvalue) = &e.minvalue {
36003 self.write_space();
36004 self.write_keyword("MINVALUE");
36005 self.write_space();
36006 self.generate_expression(minvalue)?;
36007 }
36008 if let Some(maxvalue) = &e.maxvalue {
36009 self.write_space();
36010 self.write_keyword("MAXVALUE");
36011 self.write_space();
36012 self.generate_expression(maxvalue)?;
36013 }
36014 if let Some(cache) = &e.cache {
36015 self.write_space();
36016 self.write_keyword("CACHE");
36017 self.write_space();
36018 self.generate_expression(cache)?;
36019 }
36020 if let Some(owned) = &e.owned {
36021 self.write_space();
36022 self.write_keyword("OWNED BY");
36023 self.write_space();
36024 self.generate_expression(owned)?;
36025 }
36026 for opt in &e.options {
36027 self.write_space();
36028 self.generate_expression(opt)?;
36029 }
36030 Ok(())
36031 }
36032
36033 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
36034 if e.with_.is_some() {
36036 self.write_keyword("WITH");
36037 self.write_space();
36038 }
36039 self.write_keyword("SERDEPROPERTIES");
36040 self.write(" (");
36041 for (i, expr) in e.expressions.iter().enumerate() {
36042 if i > 0 {
36043 self.write(", ");
36044 }
36045 match expr {
36047 Expression::Eq(eq) => {
36048 self.generate_expression(&eq.left)?;
36049 self.write("=");
36050 self.generate_expression(&eq.right)?;
36051 }
36052 _ => self.generate_expression(expr)?,
36053 }
36054 }
36055 self.write(")");
36056 Ok(())
36057 }
36058
36059 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
36060 self.write("@@");
36062 if let Some(kind) = &e.kind {
36063 self.write(kind);
36064 self.write(".");
36065 }
36066 self.generate_expression(&e.this)?;
36067 Ok(())
36068 }
36069
36070 fn generate_set(&mut self, e: &Set) -> Result<()> {
36071 if e.unset.is_some() {
36073 self.write_keyword("UNSET");
36074 } else {
36075 self.write_keyword("SET");
36076 }
36077 if e.tag.is_some() {
36078 self.write_space();
36079 self.write_keyword("TAG");
36080 }
36081 if !e.expressions.is_empty() {
36082 self.write_space();
36083 for (i, expr) in e.expressions.iter().enumerate() {
36084 if i > 0 {
36085 self.write(", ");
36086 }
36087 self.generate_expression(expr)?;
36088 }
36089 }
36090 Ok(())
36091 }
36092
36093 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
36094 self.write_keyword("SET");
36096 self.write_space();
36097 self.generate_expression(&e.this)?;
36098 Ok(())
36099 }
36100
36101 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
36102 if let Some(kind) = &e.kind {
36104 self.write_keyword(kind);
36105 self.write_space();
36106 }
36107 self.generate_expression(&e.name)?;
36108 self.write(" = ");
36109 self.generate_expression(&e.value)?;
36110 Ok(())
36111 }
36112
36113 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
36114 if let Some(with_) = &e.with_ {
36116 self.generate_expression(with_)?;
36117 self.write_space();
36118 }
36119 self.generate_expression(&e.this)?;
36120 self.write_space();
36121 if let Some(kind) = &e.kind {
36123 self.write_keyword(kind);
36124 }
36125 if e.distinct {
36126 self.write_space();
36127 self.write_keyword("DISTINCT");
36128 } else {
36129 self.write_space();
36130 self.write_keyword("ALL");
36131 }
36132 if e.by_name.is_some() {
36133 self.write_space();
36134 self.write_keyword("BY NAME");
36135 }
36136 self.write_space();
36137 self.generate_expression(&e.expression)?;
36138 Ok(())
36139 }
36140
36141 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
36142 if e.multi.is_some() {
36144 self.write_keyword("MULTISET");
36145 } else {
36146 self.write_keyword("SET");
36147 }
36148 Ok(())
36149 }
36150
36151 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
36152 self.write_keyword("SETTINGS");
36154 if self.config.pretty && e.expressions.len() > 1 {
36155 self.indent_level += 1;
36157 for (i, expr) in e.expressions.iter().enumerate() {
36158 if i > 0 {
36159 self.write(",");
36160 }
36161 self.write_newline();
36162 self.write_indent();
36163 self.generate_expression(expr)?;
36164 }
36165 self.indent_level -= 1;
36166 } else {
36167 self.write_space();
36168 for (i, expr) in e.expressions.iter().enumerate() {
36169 if i > 0 {
36170 self.write(", ");
36171 }
36172 self.generate_expression(expr)?;
36173 }
36174 }
36175 Ok(())
36176 }
36177
36178 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
36179 self.write_keyword("SHARING");
36181 if let Some(this) = &e.this {
36182 self.write(" = ");
36183 self.generate_expression(this)?;
36184 }
36185 Ok(())
36186 }
36187
36188 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
36189 if let Some(begin) = &e.this {
36191 self.generate_expression(begin)?;
36192 }
36193 self.write(":");
36194 if let Some(end) = &e.expression {
36195 self.generate_expression(end)?;
36196 }
36197 if let Some(step) = &e.step {
36198 self.write(":");
36199 self.generate_expression(step)?;
36200 }
36201 Ok(())
36202 }
36203
36204 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
36205 self.write_keyword("SORT_ARRAY");
36207 self.write("(");
36208 self.generate_expression(&e.this)?;
36209 if let Some(asc) = &e.asc {
36210 self.write(", ");
36211 self.generate_expression(asc)?;
36212 }
36213 self.write(")");
36214 Ok(())
36215 }
36216
36217 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
36218 self.write_keyword("SORT BY");
36220 self.write_space();
36221 for (i, expr) in e.expressions.iter().enumerate() {
36222 if i > 0 {
36223 self.write(", ");
36224 }
36225 self.generate_ordered(expr)?;
36226 }
36227 Ok(())
36228 }
36229
36230 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
36231 if e.compound.is_some() {
36233 self.write_keyword("COMPOUND");
36234 self.write_space();
36235 }
36236 self.write_keyword("SORTKEY");
36237 self.write("(");
36238 if let Expression::Tuple(t) = e.this.as_ref() {
36240 for (i, expr) in t.expressions.iter().enumerate() {
36241 if i > 0 {
36242 self.write(", ");
36243 }
36244 self.generate_expression(expr)?;
36245 }
36246 } else {
36247 self.generate_expression(&e.this)?;
36248 }
36249 self.write(")");
36250 Ok(())
36251 }
36252
36253 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
36254 self.write_keyword("SPLIT_PART");
36256 self.write("(");
36257 self.generate_expression(&e.this)?;
36258 if let Some(delimiter) = &e.delimiter {
36259 self.write(", ");
36260 self.generate_expression(delimiter)?;
36261 }
36262 if let Some(part_index) = &e.part_index {
36263 self.write(", ");
36264 self.generate_expression(part_index)?;
36265 }
36266 self.write(")");
36267 Ok(())
36268 }
36269
36270 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
36271 self.generate_expression(&e.this)?;
36273 Ok(())
36274 }
36275
36276 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
36277 self.write_keyword("SQL SECURITY");
36279 self.write_space();
36280 self.generate_expression(&e.this)?;
36281 Ok(())
36282 }
36283
36284 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
36285 self.write_keyword("ST_DISTANCE");
36287 self.write("(");
36288 self.generate_expression(&e.this)?;
36289 self.write(", ");
36290 self.generate_expression(&e.expression)?;
36291 if let Some(use_spheroid) = &e.use_spheroid {
36292 self.write(", ");
36293 self.generate_expression(use_spheroid)?;
36294 }
36295 self.write(")");
36296 Ok(())
36297 }
36298
36299 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
36300 self.write_keyword("ST_POINT");
36302 self.write("(");
36303 self.generate_expression(&e.this)?;
36304 self.write(", ");
36305 self.generate_expression(&e.expression)?;
36306 self.write(")");
36307 Ok(())
36308 }
36309
36310 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
36311 self.generate_expression(&e.this)?;
36313 Ok(())
36314 }
36315
36316 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
36317 self.write_keyword("STANDARD_HASH");
36319 self.write("(");
36320 self.generate_expression(&e.this)?;
36321 if let Some(expression) = &e.expression {
36322 self.write(", ");
36323 self.generate_expression(expression)?;
36324 }
36325 self.write(")");
36326 Ok(())
36327 }
36328
36329 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
36330 self.write_keyword("STORED BY");
36332 self.write_space();
36333 self.generate_expression(&e.this)?;
36334 Ok(())
36335 }
36336
36337 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
36338 use crate::dialects::DialectType;
36341 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36342 self.write_keyword("CHARINDEX");
36344 self.write("(");
36345 if let Some(substr) = &e.substr {
36346 self.generate_expression(substr)?;
36347 self.write(", ");
36348 }
36349 self.generate_expression(&e.this)?;
36350 if let Some(position) = &e.position {
36351 self.write(", ");
36352 self.generate_expression(position)?;
36353 }
36354 self.write(")");
36355 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
36356 self.write_keyword("POSITION");
36357 self.write("(");
36358 self.generate_expression(&e.this)?;
36359 if let Some(substr) = &e.substr {
36360 self.write(", ");
36361 self.generate_expression(substr)?;
36362 }
36363 if let Some(position) = &e.position {
36364 self.write(", ");
36365 self.generate_expression(position)?;
36366 }
36367 if let Some(occurrence) = &e.occurrence {
36368 self.write(", ");
36369 self.generate_expression(occurrence)?;
36370 }
36371 self.write(")");
36372 } else if matches!(
36373 self.config.dialect,
36374 Some(DialectType::SQLite)
36375 | Some(DialectType::Oracle)
36376 | Some(DialectType::BigQuery)
36377 | Some(DialectType::Teradata)
36378 ) {
36379 self.write_keyword("INSTR");
36380 self.write("(");
36381 self.generate_expression(&e.this)?;
36382 if let Some(substr) = &e.substr {
36383 self.write(", ");
36384 self.generate_expression(substr)?;
36385 }
36386 if let Some(position) = &e.position {
36387 self.write(", ");
36388 self.generate_expression(position)?;
36389 } else if e.occurrence.is_some() {
36390 self.write(", 1");
36393 }
36394 if let Some(occurrence) = &e.occurrence {
36395 self.write(", ");
36396 self.generate_expression(occurrence)?;
36397 }
36398 self.write(")");
36399 } else if matches!(
36400 self.config.dialect,
36401 Some(DialectType::MySQL)
36402 | Some(DialectType::SingleStore)
36403 | Some(DialectType::Doris)
36404 | Some(DialectType::StarRocks)
36405 | Some(DialectType::Hive)
36406 | Some(DialectType::Spark)
36407 | Some(DialectType::Databricks)
36408 ) {
36409 self.write_keyword("LOCATE");
36411 self.write("(");
36412 if let Some(substr) = &e.substr {
36413 self.generate_expression(substr)?;
36414 self.write(", ");
36415 }
36416 self.generate_expression(&e.this)?;
36417 if let Some(position) = &e.position {
36418 self.write(", ");
36419 self.generate_expression(position)?;
36420 }
36421 self.write(")");
36422 } else if matches!(
36423 self.config.dialect,
36424 Some(DialectType::TSQL) | Some(DialectType::Fabric)
36425 ) {
36426 self.write_keyword("CHARINDEX");
36428 self.write("(");
36429 if let Some(substr) = &e.substr {
36430 self.generate_expression(substr)?;
36431 self.write(", ");
36432 }
36433 self.generate_expression(&e.this)?;
36434 if let Some(position) = &e.position {
36435 self.write(", ");
36436 self.generate_expression(position)?;
36437 }
36438 self.write(")");
36439 } else if matches!(
36440 self.config.dialect,
36441 Some(DialectType::PostgreSQL)
36442 | Some(DialectType::Materialize)
36443 | Some(DialectType::RisingWave)
36444 | Some(DialectType::Redshift)
36445 ) {
36446 self.write_keyword("POSITION");
36448 self.write("(");
36449 if let Some(substr) = &e.substr {
36450 self.generate_expression(substr)?;
36451 self.write(" IN ");
36452 }
36453 self.generate_expression(&e.this)?;
36454 self.write(")");
36455 } else {
36456 self.write_keyword("STRPOS");
36457 self.write("(");
36458 self.generate_expression(&e.this)?;
36459 if let Some(substr) = &e.substr {
36460 self.write(", ");
36461 self.generate_expression(substr)?;
36462 }
36463 if let Some(position) = &e.position {
36464 self.write(", ");
36465 self.generate_expression(position)?;
36466 }
36467 if let Some(occurrence) = &e.occurrence {
36468 self.write(", ");
36469 self.generate_expression(occurrence)?;
36470 }
36471 self.write(")");
36472 }
36473 Ok(())
36474 }
36475
36476 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
36477 match self.config.dialect {
36478 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
36479 self.generate_tsql_str_to_temporal(&e.this, e.format.as_deref(), "DATE")?;
36480 }
36481 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
36482 self.write_keyword("TO_DATE");
36484 self.write("(");
36485 self.generate_expression(&e.this)?;
36486 if let Some(format) = &e.format {
36487 self.write(", '");
36488 self.write(&Self::strftime_to_java_format(format));
36489 self.write("'");
36490 }
36491 self.write(")");
36492 }
36493 Some(DialectType::DuckDB) => {
36494 self.write_keyword("CAST");
36496 self.write("(");
36497 self.write_keyword("STRPTIME");
36498 self.write("(");
36499 self.generate_expression(&e.this)?;
36500 if let Some(format) = &e.format {
36501 self.write(", '");
36502 self.write(format);
36503 self.write("'");
36504 }
36505 self.write(")");
36506 self.write_keyword(" AS ");
36507 self.write_keyword("DATE");
36508 self.write(")");
36509 }
36510 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
36511 self.write_keyword("TO_DATE");
36513 self.write("(");
36514 self.generate_expression(&e.this)?;
36515 if let Some(format) = &e.format {
36516 self.write(", '");
36517 self.write(&Self::strftime_to_postgres_format(format));
36518 self.write("'");
36519 }
36520 self.write(")");
36521 }
36522 Some(DialectType::BigQuery) => {
36523 self.write_keyword("PARSE_DATE");
36525 self.write("(");
36526 if let Some(format) = &e.format {
36527 self.write("'");
36528 self.write(format);
36529 self.write("'");
36530 self.write(", ");
36531 }
36532 self.generate_expression(&e.this)?;
36533 self.write(")");
36534 }
36535 Some(DialectType::Teradata) => {
36536 self.write_keyword("CAST");
36538 self.write("(");
36539 self.generate_expression(&e.this)?;
36540 self.write_keyword(" AS ");
36541 self.write_keyword("DATE");
36542 if let Some(format) = &e.format {
36543 self.write_keyword(" FORMAT ");
36544 self.write("'");
36545 self.write(&Self::strftime_to_teradata_format(format));
36546 self.write("'");
36547 }
36548 self.write(")");
36549 }
36550 _ => {
36551 self.write_keyword("STR_TO_DATE");
36553 self.write("(");
36554 self.generate_expression(&e.this)?;
36555 if let Some(format) = &e.format {
36556 self.write(", '");
36557 self.write(format);
36558 self.write("'");
36559 }
36560 self.write(")");
36561 }
36562 }
36563 Ok(())
36564 }
36565
36566 fn strftime_to_teradata_format(fmt: &str) -> String {
36568 let mut result = String::with_capacity(fmt.len() * 2);
36569 let bytes = fmt.as_bytes();
36570 let len = bytes.len();
36571 let mut i = 0;
36572 while i < len {
36573 if bytes[i] == b'%' && i + 1 < len {
36574 let replacement = match bytes[i + 1] {
36575 b'Y' => "YYYY",
36576 b'y' => "YY",
36577 b'm' => "MM",
36578 b'B' => "MMMM",
36579 b'b' => "MMM",
36580 b'd' => "DD",
36581 b'j' => "DDD",
36582 b'H' => "HH",
36583 b'M' => "MI",
36584 b'S' => "SS",
36585 b'f' => "SSSSSS",
36586 b'A' => "EEEE",
36587 b'a' => "EEE",
36588 _ => {
36589 result.push('%');
36590 i += 1;
36591 continue;
36592 }
36593 };
36594 result.push_str(replacement);
36595 i += 2;
36596 } else {
36597 result.push(bytes[i] as char);
36598 i += 1;
36599 }
36600 }
36601 result
36602 }
36603
36604 pub fn strftime_to_java_format_static(fmt: &str) -> String {
36607 Self::strftime_to_java_format(fmt)
36608 }
36609
36610 fn strftime_to_java_format(fmt: &str) -> String {
36612 let mut result = String::with_capacity(fmt.len() * 2);
36613 let bytes = fmt.as_bytes();
36614 let len = bytes.len();
36615 let mut i = 0;
36616 while i < len {
36617 if bytes[i] == b'%' && i + 1 < len {
36618 if bytes[i + 1] == b'-' && i + 2 < len {
36620 let replacement = match bytes[i + 2] {
36621 b'd' => "d",
36622 b'm' => "M",
36623 b'H' => "H",
36624 b'M' => "m",
36625 b'S' => "s",
36626 _ => {
36627 result.push('%');
36628 i += 1;
36629 continue;
36630 }
36631 };
36632 result.push_str(replacement);
36633 i += 3;
36634 } else {
36635 let replacement = match bytes[i + 1] {
36636 b'Y' => "yyyy",
36637 b'y' => "yy",
36638 b'm' => "MM",
36639 b'B' => "MMMM",
36640 b'b' => "MMM",
36641 b'd' => "dd",
36642 b'j' => "DDD",
36643 b'H' => "HH",
36644 b'M' => "mm",
36645 b'S' => "ss",
36646 b'f' => "SSSSSS",
36647 b'A' => "EEEE",
36648 b'a' => "EEE",
36649 _ => {
36650 result.push('%');
36651 i += 1;
36652 continue;
36653 }
36654 };
36655 result.push_str(replacement);
36656 i += 2;
36657 }
36658 } else {
36659 result.push(bytes[i] as char);
36660 i += 1;
36661 }
36662 }
36663 result
36664 }
36665
36666 fn strftime_to_tsql_format(fmt: &str) -> String {
36669 let mut result = String::with_capacity(fmt.len() * 2);
36670 let bytes = fmt.as_bytes();
36671 let len = bytes.len();
36672 let mut i = 0;
36673 while i < len {
36674 if bytes[i] == b'%' && i + 1 < len {
36675 if bytes[i + 1] == b'-' && i + 2 < len {
36677 let replacement = match bytes[i + 2] {
36678 b'd' => "d",
36679 b'm' => "M",
36680 b'H' => "H",
36681 b'M' => "m",
36682 b'S' => "s",
36683 _ => {
36684 result.push('%');
36685 i += 1;
36686 continue;
36687 }
36688 };
36689 result.push_str(replacement);
36690 i += 3;
36691 } else {
36692 let replacement = match bytes[i + 1] {
36693 b'Y' => "yyyy",
36694 b'y' => "yy",
36695 b'm' => "MM",
36696 b'B' => "MMMM",
36697 b'b' => "MMM",
36698 b'd' => "dd",
36699 b'j' => "DDD",
36700 b'H' => "HH",
36701 b'M' => "mm",
36702 b'S' => "ss",
36703 b'f' => "ffffff",
36704 b'A' => "dddd",
36705 b'a' => "ddd",
36706 _ => {
36707 result.push('%');
36708 i += 1;
36709 continue;
36710 }
36711 };
36712 result.push_str(replacement);
36713 i += 2;
36714 }
36715 } else {
36716 result.push(bytes[i] as char);
36717 i += 1;
36718 }
36719 }
36720 result
36721 }
36722
36723 fn tsql_convert_style_for_strftime(fmt: &str) -> Option<u16> {
36724 match fmt.trim() {
36725 "%b %d %Y %-I:%M%p" => Some(100),
36726 "%m/%d/%y" => Some(1),
36727 "%y.%m.%d" => Some(2),
36728 "%d/%m/%y" => Some(3),
36729 "%d.%m.%y" => Some(4),
36730 "%d-%m-%y" => Some(5),
36731 "%d %b %y" => Some(6),
36732 "%b %d, %y" => Some(7),
36733 "%H:%M:%S" => Some(108),
36734 "%b %d %Y %-I:%M:%S:%f%p" => Some(109),
36735 "%m-%d-%y" => Some(10),
36736 "%y/%m/%d" => Some(11),
36737 "%y%m%d" => Some(12),
36738 "%d %b %Y %H:%M:%S:%f" => Some(113),
36739 "%H:%M:%S:%f" => Some(114),
36740 "%m/%d/%Y" => Some(101),
36741 "%Y.%m.%d" => Some(102),
36742 "%d/%m/%Y" => Some(103),
36743 "%d.%m.%Y" => Some(104),
36744 "%d-%m-%Y" => Some(105),
36745 "%d %b %Y" => Some(106),
36746 "%b %d, %Y" => Some(107),
36747 "%m-%d-%Y" => Some(110),
36748 "%Y/%m/%d" => Some(111),
36749 "%Y%m%d" => Some(112),
36750 "%Y-%m-%d %H:%M:%S" => Some(120),
36751 "%Y-%m-%d %H:%M:%S.%f" => Some(121),
36752 "%Y-%m-%dT%H:%M:%S" | "%Y-%m-%dT%H:%M:%S.%f" => Some(126),
36753 "%Y-%m-%d" => Some(23),
36754 _ => None,
36755 }
36756 }
36757
36758 fn generate_tsql_str_to_temporal(
36759 &mut self,
36760 this: &Expression,
36761 format: Option<&str>,
36762 target_type: &str,
36763 ) -> Result<()> {
36764 if let Some(format) = format {
36765 if let Some(style) = Self::tsql_convert_style_for_strftime(format) {
36766 self.write_keyword("CONVERT");
36767 self.write("(");
36768 self.write_keyword(target_type);
36769 self.write(", ");
36770 self.generate_expression(this)?;
36771 self.write(", ");
36772 self.write(&style.to_string());
36773 self.write(")");
36774 return Ok(());
36775 }
36776
36777 self.unsupported(format!(
36778 "T-SQL/Fabric {target_type} parsing format '{format}' has no CONVERT style mapping"
36779 ))?;
36780 }
36781
36782 self.write_keyword("CAST");
36783 self.write("(");
36784 self.generate_expression(this)?;
36785 self.write(" AS ");
36786 self.write_keyword(target_type);
36787 self.write(")");
36788 Ok(())
36789 }
36790
36791 fn decompose_json_path(path: &str) -> Vec<String> {
36794 let mut parts = Vec::new();
36795 let path = if path.starts_with("$.") {
36797 &path[2..]
36798 } else if path.starts_with('$') {
36799 &path[1..]
36800 } else {
36801 path
36802 };
36803 if path.is_empty() {
36804 return parts;
36805 }
36806 let mut current = String::new();
36807 let chars: Vec<char> = path.chars().collect();
36808 let mut i = 0;
36809 while i < chars.len() {
36810 match chars[i] {
36811 '.' => {
36812 if !current.is_empty() {
36813 parts.push(current.clone());
36814 current.clear();
36815 }
36816 i += 1;
36817 }
36818 '[' => {
36819 if !current.is_empty() {
36820 parts.push(current.clone());
36821 current.clear();
36822 }
36823 i += 1;
36824 let mut bracket_content = String::new();
36826 while i < chars.len() && chars[i] != ']' {
36827 if chars[i] == '"' || chars[i] == '\'' {
36829 let quote = chars[i];
36830 i += 1;
36831 while i < chars.len() && chars[i] != quote {
36832 bracket_content.push(chars[i]);
36833 i += 1;
36834 }
36835 if i < chars.len() {
36836 i += 1;
36837 } } else {
36839 bracket_content.push(chars[i]);
36840 i += 1;
36841 }
36842 }
36843 if i < chars.len() {
36844 i += 1;
36845 } if bracket_content != "*" {
36848 parts.push(bracket_content);
36849 }
36850 }
36851 _ => {
36852 current.push(chars[i]);
36853 i += 1;
36854 }
36855 }
36856 }
36857 if !current.is_empty() {
36858 parts.push(current);
36859 }
36860 parts
36861 }
36862
36863 fn strftime_to_postgres_format(fmt: &str) -> String {
36865 let mut result = String::with_capacity(fmt.len() * 2);
36866 let bytes = fmt.as_bytes();
36867 let len = bytes.len();
36868 let mut i = 0;
36869 while i < len {
36870 if bytes[i] == b'%' && i + 1 < len {
36871 if bytes[i + 1] == b'-' && i + 2 < len {
36873 let replacement = match bytes[i + 2] {
36874 b'd' => "FMDD",
36875 b'm' => "FMMM",
36876 b'H' => "FMHH24",
36877 b'M' => "FMMI",
36878 b'S' => "FMSS",
36879 _ => {
36880 result.push('%');
36881 i += 1;
36882 continue;
36883 }
36884 };
36885 result.push_str(replacement);
36886 i += 3;
36887 } else {
36888 let replacement = match bytes[i + 1] {
36889 b'Y' => "YYYY",
36890 b'y' => "YY",
36891 b'm' => "MM",
36892 b'B' => "Month",
36893 b'b' => "Mon",
36894 b'd' => "DD",
36895 b'j' => "DDD",
36896 b'H' => "HH24",
36897 b'M' => "MI",
36898 b'S' => "SS",
36899 b'f' => "US",
36900 b'A' => "Day",
36901 b'a' => "Dy",
36902 _ => {
36903 result.push('%');
36904 i += 1;
36905 continue;
36906 }
36907 };
36908 result.push_str(replacement);
36909 i += 2;
36910 }
36911 } else {
36912 result.push(bytes[i] as char);
36913 i += 1;
36914 }
36915 }
36916 result
36917 }
36918
36919 fn strftime_to_snowflake_format(fmt: &str) -> String {
36921 let mut result = String::with_capacity(fmt.len() * 2);
36922 let bytes = fmt.as_bytes();
36923 let len = bytes.len();
36924 let mut i = 0;
36925 while i < len {
36926 if bytes[i] == b'%' && i + 1 < len {
36927 if bytes[i + 1] == b'-' && i + 2 < len {
36929 let replacement = match bytes[i + 2] {
36930 b'd' => "dd",
36931 b'm' => "mm",
36932 _ => {
36933 result.push('%');
36934 i += 1;
36935 continue;
36936 }
36937 };
36938 result.push_str(replacement);
36939 i += 3;
36940 } else {
36941 let replacement = match bytes[i + 1] {
36942 b'Y' => "yyyy",
36943 b'y' => "yy",
36944 b'm' => "mm",
36945 b'd' => "DD",
36946 b'H' => "hh24",
36947 b'M' => "mi",
36948 b'S' => "ss",
36949 b'f' => "ff",
36950 _ => {
36951 result.push('%');
36952 i += 1;
36953 continue;
36954 }
36955 };
36956 result.push_str(replacement);
36957 i += 2;
36958 }
36959 } else {
36960 result.push(bytes[i] as char);
36961 i += 1;
36962 }
36963 }
36964 result
36965 }
36966
36967 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
36968 self.write_keyword("STR_TO_MAP");
36970 self.write("(");
36971 self.generate_expression(&e.this)?;
36972 let needs_defaults = matches!(
36974 self.config.dialect,
36975 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
36976 );
36977 if let Some(pair_delim) = &e.pair_delim {
36978 self.write(", ");
36979 self.generate_expression(pair_delim)?;
36980 } else if needs_defaults {
36981 self.write(", ','");
36982 }
36983 if let Some(key_value_delim) = &e.key_value_delim {
36984 self.write(", ");
36985 self.generate_expression(key_value_delim)?;
36986 } else if needs_defaults {
36987 self.write(", ':'");
36988 }
36989 self.write(")");
36990 Ok(())
36991 }
36992
36993 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
36994 let is_strftime = e.format.contains('%');
36996 let to_strftime = |f: &str| -> String {
36998 if is_strftime {
36999 f.to_string()
37000 } else {
37001 Self::snowflake_format_to_strftime(f)
37002 }
37003 };
37004 let to_java = |f: &str| -> String {
37006 if is_strftime {
37007 Self::strftime_to_java_format(f)
37008 } else {
37009 Self::snowflake_format_to_spark(f)
37010 }
37011 };
37012 let to_pg = |f: &str| -> String {
37014 if is_strftime {
37015 Self::strftime_to_postgres_format(f)
37016 } else {
37017 Self::convert_strptime_to_postgres_format(f)
37018 }
37019 };
37020
37021 match self.config.dialect {
37022 Some(DialectType::Exasol) => {
37023 self.write_keyword("TO_DATE");
37024 self.write("(");
37025 self.generate_expression(&e.this)?;
37026 self.write(", '");
37027 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
37028 self.write("'");
37029 self.write(")");
37030 }
37031 Some(DialectType::BigQuery) => {
37032 let fmt = to_strftime(&e.format);
37034 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
37036 self.write_keyword("PARSE_TIMESTAMP");
37037 self.write("('");
37038 self.write(&fmt);
37039 self.write("', ");
37040 self.generate_expression(&e.this)?;
37041 self.write(")");
37042 }
37043 Some(DialectType::Hive) => {
37044 let java_fmt = to_java(&e.format);
37047 if java_fmt == "yyyy-MM-dd HH:mm:ss"
37048 || java_fmt == "yyyy-MM-dd"
37049 || e.format == "yyyy-MM-dd HH:mm:ss"
37050 || e.format == "yyyy-MM-dd"
37051 {
37052 self.write_keyword("CAST");
37053 self.write("(");
37054 self.generate_expression(&e.this)?;
37055 self.write(" ");
37056 self.write_keyword("AS TIMESTAMP");
37057 self.write(")");
37058 } else {
37059 self.write_keyword("CAST");
37061 self.write("(");
37062 self.write_keyword("FROM_UNIXTIME");
37063 self.write("(");
37064 self.write_keyword("UNIX_TIMESTAMP");
37065 self.write("(");
37066 self.generate_expression(&e.this)?;
37067 self.write(", '");
37068 self.write(&java_fmt);
37069 self.write("')");
37070 self.write(") ");
37071 self.write_keyword("AS TIMESTAMP");
37072 self.write(")");
37073 }
37074 }
37075 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37076 let java_fmt = to_java(&e.format);
37078 self.write_keyword("TO_TIMESTAMP");
37079 self.write("(");
37080 self.generate_expression(&e.this)?;
37081 self.write(", '");
37082 self.write(&java_fmt);
37083 self.write("')");
37084 }
37085 Some(DialectType::MySQL) => {
37086 let mut fmt = to_strftime(&e.format);
37088 fmt = fmt.replace("%-d", "%e");
37090 fmt = fmt.replace("%-m", "%c");
37091 fmt = fmt.replace("%H:%M:%S", "%T");
37092 self.write_keyword("STR_TO_DATE");
37093 self.write("(");
37094 self.generate_expression(&e.this)?;
37095 self.write(", '");
37096 self.write(&fmt);
37097 self.write("')");
37098 }
37099 Some(DialectType::Drill) => {
37100 let java_fmt = to_java(&e.format);
37102 let java_fmt = java_fmt.replace('T', "''T''");
37104 self.write_keyword("TO_TIMESTAMP");
37105 self.write("(");
37106 self.generate_expression(&e.this)?;
37107 self.write(", '");
37108 self.write(&java_fmt);
37109 self.write("')");
37110 }
37111 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
37112 let mut fmt = to_strftime(&e.format);
37114 fmt = fmt.replace("%-d", "%e");
37116 fmt = fmt.replace("%-m", "%c");
37117 fmt = fmt.replace("%H:%M:%S", "%T");
37118 self.write_keyword("DATE_PARSE");
37119 self.write("(");
37120 self.generate_expression(&e.this)?;
37121 self.write(", '");
37122 self.write(&fmt);
37123 self.write("')");
37124 }
37125 Some(DialectType::DuckDB) => {
37126 let fmt = to_strftime(&e.format);
37128 self.write_keyword("STRPTIME");
37129 self.write("(");
37130 self.generate_expression(&e.this)?;
37131 self.write(", '");
37132 self.write(&fmt);
37133 self.write("')");
37134 }
37135 Some(DialectType::PostgreSQL)
37136 | Some(DialectType::Redshift)
37137 | Some(DialectType::Materialize) => {
37138 let pg_fmt = to_pg(&e.format);
37140 self.write_keyword("TO_TIMESTAMP");
37141 self.write("(");
37142 self.generate_expression(&e.this)?;
37143 self.write(", '");
37144 self.write(&pg_fmt);
37145 self.write("')");
37146 }
37147 Some(DialectType::Oracle) => {
37148 let pg_fmt = to_pg(&e.format);
37150 self.write_keyword("TO_TIMESTAMP");
37151 self.write("(");
37152 self.generate_expression(&e.this)?;
37153 self.write(", '");
37154 self.write(&pg_fmt);
37155 self.write("')");
37156 }
37157 Some(DialectType::Snowflake) => {
37158 self.write_keyword("TO_TIMESTAMP");
37160 self.write("(");
37161 self.generate_expression(&e.this)?;
37162 self.write(", '");
37163 self.write(&e.format);
37164 self.write("')");
37165 }
37166 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
37167 self.generate_tsql_str_to_temporal(&e.this, Some(&e.format), "DATETIME2")?;
37168 }
37169 _ => {
37170 self.write_keyword("STR_TO_TIME");
37172 self.write("(");
37173 self.generate_expression(&e.this)?;
37174 self.write(", '");
37175 self.write(&e.format);
37176 self.write("'");
37177 self.write(")");
37178 }
37179 }
37180 Ok(())
37181 }
37182
37183 fn snowflake_format_to_strftime(format: &str) -> String {
37185 let mut result = String::new();
37186 let chars: Vec<char> = format.chars().collect();
37187 let mut i = 0;
37188 while i < chars.len() {
37189 let remaining = &format[i..];
37190 if remaining.starts_with("yyyy") {
37191 result.push_str("%Y");
37192 i += 4;
37193 } else if remaining.starts_with("yy") {
37194 result.push_str("%y");
37195 i += 2;
37196 } else if remaining.starts_with("mmmm") {
37197 result.push_str("%B"); i += 4;
37199 } else if remaining.starts_with("mon") {
37200 result.push_str("%b"); i += 3;
37202 } else if remaining.starts_with("mm") {
37203 result.push_str("%m");
37204 i += 2;
37205 } else if remaining.starts_with("DD") {
37206 result.push_str("%d");
37207 i += 2;
37208 } else if remaining.starts_with("dy") {
37209 result.push_str("%a"); i += 2;
37211 } else if remaining.starts_with("hh24") {
37212 result.push_str("%H");
37213 i += 4;
37214 } else if remaining.starts_with("hh12") {
37215 result.push_str("%I");
37216 i += 4;
37217 } else if remaining.starts_with("hh") {
37218 result.push_str("%H");
37219 i += 2;
37220 } else if remaining.starts_with("mi") {
37221 result.push_str("%M");
37222 i += 2;
37223 } else if remaining.starts_with("ss") {
37224 result.push_str("%S");
37225 i += 2;
37226 } else if remaining.starts_with("ff") {
37227 result.push_str("%f");
37229 i += 2;
37230 while i < chars.len() && chars[i].is_ascii_digit() {
37232 i += 1;
37233 }
37234 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
37235 result.push_str("%p");
37236 i += 2;
37237 } else if remaining.starts_with("tz") {
37238 result.push_str("%Z");
37239 i += 2;
37240 } else {
37241 result.push(chars[i]);
37242 i += 1;
37243 }
37244 }
37245 result
37246 }
37247
37248 fn snowflake_format_to_spark(format: &str) -> String {
37250 let mut result = String::new();
37251 let chars: Vec<char> = format.chars().collect();
37252 let mut i = 0;
37253 while i < chars.len() {
37254 let remaining = &format[i..];
37255 if remaining.starts_with("yyyy") {
37256 result.push_str("yyyy");
37257 i += 4;
37258 } else if remaining.starts_with("yy") {
37259 result.push_str("yy");
37260 i += 2;
37261 } else if remaining.starts_with("mmmm") {
37262 result.push_str("MMMM"); i += 4;
37264 } else if remaining.starts_with("mon") {
37265 result.push_str("MMM"); i += 3;
37267 } else if remaining.starts_with("mm") {
37268 result.push_str("MM");
37269 i += 2;
37270 } else if remaining.starts_with("DD") {
37271 result.push_str("dd");
37272 i += 2;
37273 } else if remaining.starts_with("dy") {
37274 result.push_str("EEE"); i += 2;
37276 } else if remaining.starts_with("hh24") {
37277 result.push_str("HH");
37278 i += 4;
37279 } else if remaining.starts_with("hh12") {
37280 result.push_str("hh");
37281 i += 4;
37282 } else if remaining.starts_with("hh") {
37283 result.push_str("HH");
37284 i += 2;
37285 } else if remaining.starts_with("mi") {
37286 result.push_str("mm");
37287 i += 2;
37288 } else if remaining.starts_with("ss") {
37289 result.push_str("ss");
37290 i += 2;
37291 } else if remaining.starts_with("ff") {
37292 result.push_str("SSS"); i += 2;
37294 while i < chars.len() && chars[i].is_ascii_digit() {
37296 i += 1;
37297 }
37298 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
37299 result.push_str("a");
37300 i += 2;
37301 } else if remaining.starts_with("tz") {
37302 result.push_str("z");
37303 i += 2;
37304 } else {
37305 result.push(chars[i]);
37306 i += 1;
37307 }
37308 }
37309 result
37310 }
37311
37312 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
37313 match self.config.dialect {
37314 Some(DialectType::DuckDB) => {
37315 self.write_keyword("EPOCH");
37317 self.write("(");
37318 self.write_keyword("STRPTIME");
37319 self.write("(");
37320 if let Some(this) = &e.this {
37321 self.generate_expression(this)?;
37322 }
37323 if let Some(format) = &e.format {
37324 self.write(", '");
37325 self.write(format);
37326 self.write("'");
37327 }
37328 self.write("))");
37329 }
37330 Some(DialectType::Hive) => {
37331 self.write_keyword("UNIX_TIMESTAMP");
37333 self.write("(");
37334 if let Some(this) = &e.this {
37335 self.generate_expression(this)?;
37336 }
37337 if let Some(format) = &e.format {
37338 let java_fmt = Self::strftime_to_java_format(format);
37339 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
37340 self.write(", '");
37341 self.write(&java_fmt);
37342 self.write("'");
37343 }
37344 }
37345 self.write(")");
37346 }
37347 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
37348 self.write_keyword("UNIX_TIMESTAMP");
37350 self.write("(");
37351 if let Some(this) = &e.this {
37352 self.generate_expression(this)?;
37353 }
37354 if let Some(format) = &e.format {
37355 self.write(", '");
37356 self.write(format);
37357 self.write("'");
37358 }
37359 self.write(")");
37360 }
37361 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37362 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
37365 let java_fmt = Self::strftime_to_java_format(c_fmt);
37366 self.write_keyword("TO_UNIXTIME");
37367 self.write("(");
37368 self.write_keyword("COALESCE");
37369 self.write("(");
37370 self.write_keyword("TRY");
37371 self.write("(");
37372 self.write_keyword("DATE_PARSE");
37373 self.write("(");
37374 self.write_keyword("CAST");
37375 self.write("(");
37376 if let Some(this) = &e.this {
37377 self.generate_expression(this)?;
37378 }
37379 self.write(" ");
37380 self.write_keyword("AS VARCHAR");
37381 self.write("), '");
37382 self.write(c_fmt);
37383 self.write("')), ");
37384 self.write_keyword("PARSE_DATETIME");
37385 self.write("(");
37386 self.write_keyword("DATE_FORMAT");
37387 self.write("(");
37388 self.write_keyword("CAST");
37389 self.write("(");
37390 if let Some(this) = &e.this {
37391 self.generate_expression(this)?;
37392 }
37393 self.write(" ");
37394 self.write_keyword("AS TIMESTAMP");
37395 self.write("), '");
37396 self.write(c_fmt);
37397 self.write("'), '");
37398 self.write(&java_fmt);
37399 self.write("')))");
37400 }
37401 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37402 self.write_keyword("UNIX_TIMESTAMP");
37404 self.write("(");
37405 if let Some(this) = &e.this {
37406 self.generate_expression(this)?;
37407 }
37408 if let Some(format) = &e.format {
37409 let java_fmt = Self::strftime_to_java_format(format);
37410 self.write(", '");
37411 self.write(&java_fmt);
37412 self.write("'");
37413 }
37414 self.write(")");
37415 }
37416 _ => {
37417 self.write_keyword("STR_TO_UNIX");
37419 self.write("(");
37420 if let Some(this) = &e.this {
37421 self.generate_expression(this)?;
37422 }
37423 if let Some(format) = &e.format {
37424 self.write(", '");
37425 self.write(format);
37426 self.write("'");
37427 }
37428 self.write(")");
37429 }
37430 }
37431 Ok(())
37432 }
37433
37434 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
37435 self.write_keyword("STRING_TO_ARRAY");
37437 self.write("(");
37438 self.generate_expression(&e.this)?;
37439 if let Some(expression) = &e.expression {
37440 self.write(", ");
37441 self.generate_expression(expression)?;
37442 }
37443 if let Some(null_val) = &e.null {
37444 self.write(", ");
37445 self.generate_expression(null_val)?;
37446 }
37447 self.write(")");
37448 Ok(())
37449 }
37450
37451 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
37452 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
37453 self.write_keyword("OBJECT_CONSTRUCT");
37455 self.write("(");
37456 for (i, (name, expr)) in e.fields.iter().enumerate() {
37457 if i > 0 {
37458 self.write(", ");
37459 }
37460 if let Some(name) = name {
37461 self.write("'");
37462 self.write(name);
37463 self.write("'");
37464 self.write(", ");
37465 } else {
37466 self.write("'_");
37467 self.write(&i.to_string());
37468 self.write("'");
37469 self.write(", ");
37470 }
37471 self.generate_expression(expr)?;
37472 }
37473 self.write(")");
37474 } else if self.config.struct_curly_brace_notation {
37475 self.write("{");
37477 for (i, (name, expr)) in e.fields.iter().enumerate() {
37478 if i > 0 {
37479 self.write(", ");
37480 }
37481 if let Some(name) = name {
37482 self.write("'");
37484 self.write(name);
37485 self.write("'");
37486 self.write(": ");
37487 } else {
37488 self.write("'_");
37490 self.write(&i.to_string());
37491 self.write("'");
37492 self.write(": ");
37493 }
37494 self.generate_expression(expr)?;
37495 }
37496 self.write("}");
37497 } else {
37498 let value_as_name = matches!(
37502 self.config.dialect,
37503 Some(DialectType::BigQuery)
37504 | Some(DialectType::Spark)
37505 | Some(DialectType::Databricks)
37506 | Some(DialectType::Hive)
37507 );
37508 self.write_keyword("STRUCT");
37509 self.write("(");
37510 for (i, (name, expr)) in e.fields.iter().enumerate() {
37511 if i > 0 {
37512 self.write(", ");
37513 }
37514 if let Some(name) = name {
37515 if value_as_name {
37516 self.generate_expression(expr)?;
37518 self.write_space();
37519 self.write_keyword("AS");
37520 self.write_space();
37521 let needs_quoting = name.contains(' ') || name.contains('-');
37523 if needs_quoting {
37524 if matches!(
37525 self.config.dialect,
37526 Some(DialectType::Spark)
37527 | Some(DialectType::Databricks)
37528 | Some(DialectType::Hive)
37529 ) {
37530 self.write("`");
37531 self.write(name);
37532 self.write("`");
37533 } else {
37534 self.write(name);
37535 }
37536 } else {
37537 self.write(name);
37538 }
37539 } else {
37540 self.write(name);
37542 self.write_space();
37543 self.write_keyword("AS");
37544 self.write_space();
37545 self.generate_expression(expr)?;
37546 }
37547 } else {
37548 self.generate_expression(expr)?;
37549 }
37550 }
37551 self.write(")");
37552 }
37553 Ok(())
37554 }
37555
37556 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
37557 self.write_keyword("STUFF");
37559 self.write("(");
37560 self.generate_expression(&e.this)?;
37561 if let Some(start) = &e.start {
37562 self.write(", ");
37563 self.generate_expression(start)?;
37564 }
37565 if let Some(length) = e.length {
37566 self.write(", ");
37567 self.write(&length.to_string());
37568 }
37569 self.write(", ");
37570 self.generate_expression(&e.expression)?;
37571 self.write(")");
37572 Ok(())
37573 }
37574
37575 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
37576 self.write_keyword("SUBSTRING_INDEX");
37578 self.write("(");
37579 self.generate_expression(&e.this)?;
37580 if let Some(delimiter) = &e.delimiter {
37581 self.write(", ");
37582 self.generate_expression(delimiter)?;
37583 }
37584 if let Some(count) = &e.count {
37585 self.write(", ");
37586 self.generate_expression(count)?;
37587 }
37588 self.write(")");
37589 Ok(())
37590 }
37591
37592 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
37593 self.write_keyword("SUMMARIZE");
37595 if e.table.is_some() {
37596 self.write_space();
37597 self.write_keyword("TABLE");
37598 }
37599 self.write_space();
37600 self.generate_expression(&e.this)?;
37601 Ok(())
37602 }
37603
37604 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
37605 self.write_keyword("SYSTIMESTAMP");
37607 Ok(())
37608 }
37609
37610 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
37611 if let Some(this) = &e.this {
37613 self.generate_expression(this)?;
37614 }
37615 if !e.columns.is_empty() {
37616 self.write("(");
37617 for (i, col) in e.columns.iter().enumerate() {
37618 if i > 0 {
37619 self.write(", ");
37620 }
37621 self.generate_expression(col)?;
37622 }
37623 self.write(")");
37624 }
37625 Ok(())
37626 }
37627
37628 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
37629 self.write_keyword("TABLE");
37631 self.write("(");
37632 self.generate_expression(&e.this)?;
37633 self.write(")");
37634 if let Some(alias) = &e.alias {
37635 self.write_space();
37636 self.write_keyword("AS");
37637 self.write_space();
37638 self.write(alias);
37639 }
37640 Ok(())
37641 }
37642
37643 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
37644 self.write_keyword("ROWS FROM");
37646 self.write(" (");
37647 for (i, expr) in e.expressions.iter().enumerate() {
37648 if i > 0 {
37649 self.write(", ");
37650 }
37651 match expr {
37655 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
37656 self.generate_expression(&tuple.expressions[0])?;
37658 self.write_space();
37659 self.write_keyword("AS");
37660 self.write_space();
37661 self.generate_expression(&tuple.expressions[1])?;
37662 }
37663 _ => {
37664 self.generate_expression(expr)?;
37665 }
37666 }
37667 }
37668 self.write(")");
37669 if e.ordinality {
37670 self.write_space();
37671 self.write_keyword("WITH ORDINALITY");
37672 }
37673 if let Some(alias) = &e.alias {
37674 self.write_space();
37675 self.write_keyword("AS");
37676 self.write_space();
37677 self.generate_expression(alias)?;
37678 }
37679 Ok(())
37680 }
37681
37682 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
37683 use crate::dialects::DialectType;
37684
37685 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
37687 if self.config.alias_post_tablesample {
37689 if let Expression::Subquery(ref s) = **this {
37691 if let Some(ref alias) = s.alias {
37692 let mut subquery_no_alias = (**s).clone();
37694 subquery_no_alias.alias = None;
37695 subquery_no_alias.column_aliases = Vec::new();
37696 self.generate_expression(&Expression::Subquery(Box::new(
37697 subquery_no_alias,
37698 )))?;
37699 self.write_space();
37700 self.write_keyword(self.config.tablesample_keywords);
37701 self.generate_sample_body(sample)?;
37702 if let Some(ref seed) = sample.seed {
37703 self.write_space();
37704 let use_seed = sample.use_seed_keyword
37705 && !matches!(
37706 self.config.dialect,
37707 Some(crate::dialects::DialectType::Databricks)
37708 | Some(crate::dialects::DialectType::Spark)
37709 );
37710 if use_seed {
37711 self.write_keyword("SEED");
37712 } else {
37713 self.write_keyword("REPEATABLE");
37714 }
37715 self.write(" (");
37716 self.generate_expression(seed)?;
37717 self.write(")");
37718 }
37719 self.write_space();
37720 self.write_keyword("AS");
37721 self.write_space();
37722 self.generate_identifier(alias)?;
37723 return Ok(());
37724 }
37725 } else if let Expression::Alias(ref a) = **this {
37726 self.generate_expression(&a.this)?;
37728 self.write_space();
37729 self.write_keyword(self.config.tablesample_keywords);
37730 self.generate_sample_body(sample)?;
37731 if let Some(ref seed) = sample.seed {
37732 self.write_space();
37733 let use_seed = sample.use_seed_keyword
37734 && !matches!(
37735 self.config.dialect,
37736 Some(crate::dialects::DialectType::Databricks)
37737 | Some(crate::dialects::DialectType::Spark)
37738 );
37739 if use_seed {
37740 self.write_keyword("SEED");
37741 } else {
37742 self.write_keyword("REPEATABLE");
37743 }
37744 self.write(" (");
37745 self.generate_expression(seed)?;
37746 self.write(")");
37747 }
37748 self.write_space();
37750 self.write_keyword("AS");
37751 self.write_space();
37752 self.generate_identifier(&a.alias)?;
37753 return Ok(());
37754 }
37755 }
37756 self.generate_expression(this)?;
37758 self.write_space();
37759 self.write_keyword(self.config.tablesample_keywords);
37760 self.generate_sample_body(sample)?;
37761 if let Some(ref seed) = sample.seed {
37763 self.write_space();
37764 let use_seed = sample.use_seed_keyword
37766 && !matches!(
37767 self.config.dialect,
37768 Some(crate::dialects::DialectType::Databricks)
37769 | Some(crate::dialects::DialectType::Spark)
37770 );
37771 if use_seed {
37772 self.write_keyword("SEED");
37773 } else {
37774 self.write_keyword("REPEATABLE");
37775 }
37776 self.write(" (");
37777 self.generate_expression(seed)?;
37778 self.write(")");
37779 }
37780 return Ok(());
37781 }
37782
37783 self.write_keyword(self.config.tablesample_keywords);
37785 if let Some(method) = &e.method {
37786 self.write_space();
37787 self.write_keyword(method);
37788 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
37789 self.write_space();
37791 self.write_keyword("BERNOULLI");
37792 }
37793 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
37794 self.write_space();
37795 self.write_keyword("BUCKET");
37796 self.write_space();
37797 self.generate_expression(numerator)?;
37798 self.write_space();
37799 self.write_keyword("OUT OF");
37800 self.write_space();
37801 self.generate_expression(denominator)?;
37802 if let Some(field) = &e.bucket_field {
37803 self.write_space();
37804 self.write_keyword("ON");
37805 self.write_space();
37806 self.generate_expression(field)?;
37807 }
37808 } else if !e.expressions.is_empty() {
37809 self.write(" (");
37810 for (i, expr) in e.expressions.iter().enumerate() {
37811 if i > 0 {
37812 self.write(", ");
37813 }
37814 self.generate_expression(expr)?;
37815 }
37816 self.write(")");
37817 } else if let Some(percent) = &e.percent {
37818 self.write(" (");
37819 self.generate_expression(percent)?;
37820 self.write_space();
37821 self.write_keyword("PERCENT");
37822 self.write(")");
37823 }
37824 Ok(())
37825 }
37826
37827 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
37828 if let Some(prefix) = &e.prefix {
37830 self.generate_expression(prefix)?;
37831 }
37832 if let Some(this) = &e.this {
37833 self.generate_expression(this)?;
37834 }
37835 if let Some(postfix) = &e.postfix {
37836 self.generate_expression(postfix)?;
37837 }
37838 Ok(())
37839 }
37840
37841 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
37842 self.write_keyword("TAG");
37844 self.write(" (");
37845 for (i, expr) in e.expressions.iter().enumerate() {
37846 if i > 0 {
37847 self.write(", ");
37848 }
37849 self.generate_expression(expr)?;
37850 }
37851 self.write(")");
37852 Ok(())
37853 }
37854
37855 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
37856 if let Some(this) = &e.this {
37858 self.generate_expression(this)?;
37859 self.write_space();
37860 }
37861 self.write_keyword("TEMPORARY");
37862 Ok(())
37863 }
37864
37865 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
37868 self.write_keyword("TIME");
37870 self.write("(");
37871 self.generate_expression(&e.this)?;
37872 self.write(")");
37873 Ok(())
37874 }
37875
37876 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
37877 self.write_keyword("TIME_ADD");
37879 self.write("(");
37880 self.generate_expression(&e.this)?;
37881 self.write(", ");
37882 self.generate_expression(&e.expression)?;
37883 if let Some(unit) = &e.unit {
37884 self.write(", ");
37885 self.write_keyword(unit);
37886 }
37887 self.write(")");
37888 Ok(())
37889 }
37890
37891 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
37892 self.write_keyword("TIME_DIFF");
37894 self.write("(");
37895 self.generate_expression(&e.this)?;
37896 self.write(", ");
37897 self.generate_expression(&e.expression)?;
37898 if let Some(unit) = &e.unit {
37899 self.write(", ");
37900 self.write_keyword(unit);
37901 }
37902 self.write(")");
37903 Ok(())
37904 }
37905
37906 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
37907 self.write_keyword("TIME_FROM_PARTS");
37909 self.write("(");
37910 let mut first = true;
37911 if let Some(hour) = &e.hour {
37912 self.generate_expression(hour)?;
37913 first = false;
37914 }
37915 if let Some(minute) = &e.min {
37916 if !first {
37917 self.write(", ");
37918 }
37919 self.generate_expression(minute)?;
37920 first = false;
37921 }
37922 if let Some(second) = &e.sec {
37923 if !first {
37924 self.write(", ");
37925 }
37926 self.generate_expression(second)?;
37927 first = false;
37928 }
37929 if let Some(ns) = &e.nano {
37930 if !first {
37931 self.write(", ");
37932 }
37933 self.generate_expression(ns)?;
37934 }
37935 self.write(")");
37936 Ok(())
37937 }
37938
37939 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
37940 self.write_keyword("TIME_SLICE");
37942 self.write("(");
37943 self.generate_expression(&e.this)?;
37944 self.write(", ");
37945 self.generate_expression(&e.expression)?;
37946 self.write(", ");
37947 self.write_keyword(&e.unit);
37948 self.write(")");
37949 Ok(())
37950 }
37951
37952 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
37953 self.write_keyword("TIME_STR_TO_TIME");
37955 self.write("(");
37956 self.generate_expression(&e.this)?;
37957 self.write(")");
37958 Ok(())
37959 }
37960
37961 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
37962 self.write_keyword("TIME_SUB");
37964 self.write("(");
37965 self.generate_expression(&e.this)?;
37966 self.write(", ");
37967 self.generate_expression(&e.expression)?;
37968 if let Some(unit) = &e.unit {
37969 self.write(", ");
37970 self.write_keyword(unit);
37971 }
37972 self.write(")");
37973 Ok(())
37974 }
37975
37976 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
37977 match self.config.dialect {
37978 Some(DialectType::Exasol) => {
37979 self.write_keyword("TO_CHAR");
37981 self.write("(");
37982 self.generate_expression(&e.this)?;
37983 self.write(", '");
37984 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
37985 self.write("'");
37986 self.write(")");
37987 }
37988 Some(DialectType::PostgreSQL)
37989 | Some(DialectType::Redshift)
37990 | Some(DialectType::Materialize) => {
37991 self.write_keyword("TO_CHAR");
37993 self.write("(");
37994 self.generate_expression(&e.this)?;
37995 self.write(", '");
37996 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
37997 self.write("'");
37998 self.write(")");
37999 }
38000 Some(DialectType::Oracle) => {
38001 self.write_keyword("TO_CHAR");
38003 self.write("(");
38004 self.generate_expression(&e.this)?;
38005 self.write(", '");
38006 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
38007 self.write("'");
38008 self.write(")");
38009 }
38010 Some(DialectType::Drill) => {
38011 self.write_keyword("TO_CHAR");
38013 self.write("(");
38014 self.generate_expression(&e.this)?;
38015 self.write(", '");
38016 self.write(&Self::strftime_to_java_format(&e.format));
38017 self.write("'");
38018 self.write(")");
38019 }
38020 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
38021 self.write_keyword("FORMAT");
38023 self.write("(");
38024 self.generate_expression(&e.this)?;
38025 self.write(", '");
38026 self.write(&Self::strftime_to_tsql_format(&e.format));
38027 self.write("'");
38028 self.write(")");
38029 }
38030 Some(DialectType::DuckDB) => {
38031 self.write_keyword("STRFTIME");
38033 self.write("(");
38034 self.generate_expression(&e.this)?;
38035 self.write(", '");
38036 self.write(&e.format);
38037 self.write("'");
38038 self.write(")");
38039 }
38040 Some(DialectType::BigQuery) => {
38041 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
38044 self.write_keyword("FORMAT_DATE");
38045 self.write("('");
38046 self.write(&fmt);
38047 self.write("', ");
38048 self.generate_expression(&e.this)?;
38049 self.write(")");
38050 }
38051 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
38052 self.write_keyword("DATE_FORMAT");
38054 self.write("(");
38055 self.generate_expression(&e.this)?;
38056 self.write(", '");
38057 self.write(&Self::strftime_to_java_format(&e.format));
38058 self.write("'");
38059 self.write(")");
38060 }
38061 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
38062 self.write_keyword("DATE_FORMAT");
38064 self.write("(");
38065 self.generate_expression(&e.this)?;
38066 self.write(", '");
38067 self.write(&e.format);
38068 self.write("'");
38069 self.write(")");
38070 }
38071 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
38072 self.write_keyword("DATE_FORMAT");
38074 self.write("(");
38075 self.generate_expression(&e.this)?;
38076 self.write(", '");
38077 self.write(&e.format);
38078 self.write("'");
38079 self.write(")");
38080 }
38081 _ => {
38082 self.write_keyword("TIME_TO_STR");
38084 self.write("(");
38085 self.generate_expression(&e.this)?;
38086 self.write(", '");
38087 self.write(&e.format);
38088 self.write("'");
38089 self.write(")");
38090 }
38091 }
38092 Ok(())
38093 }
38094
38095 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
38096 match self.config.dialect {
38097 Some(DialectType::DuckDB) => {
38098 self.write_keyword("EPOCH");
38100 self.write("(");
38101 self.generate_expression(&e.this)?;
38102 self.write(")");
38103 }
38104 Some(DialectType::Hive)
38105 | Some(DialectType::Spark)
38106 | Some(DialectType::Databricks)
38107 | Some(DialectType::Doris)
38108 | Some(DialectType::StarRocks)
38109 | Some(DialectType::Drill) => {
38110 self.write_keyword("UNIX_TIMESTAMP");
38112 self.write("(");
38113 self.generate_expression(&e.this)?;
38114 self.write(")");
38115 }
38116 Some(DialectType::Presto) | Some(DialectType::Trino) => {
38117 self.write_keyword("TO_UNIXTIME");
38119 self.write("(");
38120 self.generate_expression(&e.this)?;
38121 self.write(")");
38122 }
38123 _ => {
38124 self.write_keyword("TIME_TO_UNIX");
38126 self.write("(");
38127 self.generate_expression(&e.this)?;
38128 self.write(")");
38129 }
38130 }
38131 Ok(())
38132 }
38133
38134 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
38135 match self.config.dialect {
38136 Some(DialectType::Hive) => {
38137 self.write_keyword("TO_DATE");
38139 self.write("(");
38140 self.generate_expression(&e.this)?;
38141 self.write(")");
38142 }
38143 _ => {
38144 self.write_keyword("TIME_STR_TO_DATE");
38146 self.write("(");
38147 self.generate_expression(&e.this)?;
38148 self.write(")");
38149 }
38150 }
38151 Ok(())
38152 }
38153
38154 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
38155 self.write_keyword("TIME_TRUNC");
38157 self.write("(");
38158 self.generate_expression(&e.this)?;
38159 self.write(", ");
38160 self.write_keyword(&e.unit);
38161 self.write(")");
38162 Ok(())
38163 }
38164
38165 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
38166 if let Some(unit) = &e.unit {
38168 self.write_keyword(unit);
38169 }
38170 Ok(())
38171 }
38172
38173 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
38177 use crate::dialects::DialectType;
38178 use crate::expressions::Literal;
38179
38180 match self.config.dialect {
38181 Some(DialectType::Exasol) => {
38183 self.write_keyword("TO_TIMESTAMP");
38184 self.write("(");
38185 if let Some(this) = &e.this {
38187 match this.as_ref() {
38188 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
38189 let Literal::String(s) = lit.as_ref() else {
38190 unreachable!()
38191 };
38192 self.write("'");
38193 self.write(s);
38194 self.write("'");
38195 }
38196 _ => {
38197 self.generate_expression(this)?;
38198 }
38199 }
38200 }
38201 self.write(")");
38202 }
38203 _ => {
38205 self.write_keyword("TIMESTAMP");
38206 self.write("(");
38207 if let Some(this) = &e.this {
38208 self.generate_expression(this)?;
38209 }
38210 if let Some(zone) = &e.zone {
38211 self.write(", ");
38212 self.generate_expression(zone)?;
38213 }
38214 self.write(")");
38215 }
38216 }
38217 Ok(())
38218 }
38219
38220 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
38221 self.write_keyword("TIMESTAMP_ADD");
38223 self.write("(");
38224 self.generate_expression(&e.this)?;
38225 self.write(", ");
38226 self.generate_expression(&e.expression)?;
38227 if let Some(unit) = &e.unit {
38228 self.write(", ");
38229 self.write_keyword(unit);
38230 }
38231 self.write(")");
38232 Ok(())
38233 }
38234
38235 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
38236 self.write_keyword("TIMESTAMP_DIFF");
38238 self.write("(");
38239 self.generate_expression(&e.this)?;
38240 self.write(", ");
38241 self.generate_expression(&e.expression)?;
38242 if let Some(unit) = &e.unit {
38243 self.write(", ");
38244 self.write_keyword(unit);
38245 }
38246 self.write(")");
38247 Ok(())
38248 }
38249
38250 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
38251 self.write_keyword("TIMESTAMP_FROM_PARTS");
38253 self.write("(");
38254 if let Some(this) = &e.this {
38255 self.generate_expression(this)?;
38256 }
38257 if let Some(expression) = &e.expression {
38258 self.write(", ");
38259 self.generate_expression(expression)?;
38260 }
38261 if let Some(zone) = &e.zone {
38262 self.write(", ");
38263 self.generate_expression(zone)?;
38264 }
38265 if let Some(milli) = &e.milli {
38266 self.write(", ");
38267 self.generate_expression(milli)?;
38268 }
38269 self.write(")");
38270 Ok(())
38271 }
38272
38273 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
38274 self.write_keyword("TIMESTAMP_SUB");
38276 self.write("(");
38277 self.generate_expression(&e.this)?;
38278 self.write(", ");
38279 self.write_keyword("INTERVAL");
38280 self.write_space();
38281 self.generate_expression(&e.expression)?;
38282 if let Some(unit) = &e.unit {
38283 self.write_space();
38284 self.write_keyword(unit);
38285 }
38286 self.write(")");
38287 Ok(())
38288 }
38289
38290 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
38291 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
38293 self.write("(");
38294 if let Some(zone) = &e.zone {
38295 self.generate_expression(zone)?;
38296 }
38297 self.write(")");
38298 Ok(())
38299 }
38300
38301 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
38302 self.write_keyword("TO_BINARY");
38304 self.write("(");
38305 self.generate_expression(&e.this)?;
38306 if let Some(format) = &e.format {
38307 self.write(", '");
38308 self.write(format);
38309 self.write("'");
38310 }
38311 self.write(")");
38312 Ok(())
38313 }
38314
38315 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
38316 self.write_keyword("TO_BOOLEAN");
38318 self.write("(");
38319 self.generate_expression(&e.this)?;
38320 self.write(")");
38321 Ok(())
38322 }
38323
38324 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
38325 self.write_keyword("TO_CHAR");
38327 self.write("(");
38328 self.generate_expression(&e.this)?;
38329 if let Some(format) = &e.format {
38330 self.write(", '");
38331 self.write(format);
38332 self.write("'");
38333 }
38334 if let Some(nlsparam) = &e.nlsparam {
38335 self.write(", ");
38336 self.generate_expression(nlsparam)?;
38337 }
38338 self.write(")");
38339 Ok(())
38340 }
38341
38342 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
38343 self.write_keyword("TO_DECFLOAT");
38345 self.write("(");
38346 self.generate_expression(&e.this)?;
38347 if let Some(format) = &e.format {
38348 self.write(", '");
38349 self.write(format);
38350 self.write("'");
38351 }
38352 self.write(")");
38353 Ok(())
38354 }
38355
38356 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
38357 self.write_keyword("TO_DOUBLE");
38359 self.write("(");
38360 self.generate_expression(&e.this)?;
38361 if let Some(format) = &e.format {
38362 self.write(", '");
38363 self.write(format);
38364 self.write("'");
38365 }
38366 self.write(")");
38367 Ok(())
38368 }
38369
38370 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
38371 self.write_keyword("TO_FILE");
38373 self.write("(");
38374 self.generate_expression(&e.this)?;
38375 if let Some(path) = &e.path {
38376 self.write(", ");
38377 self.generate_expression(path)?;
38378 }
38379 self.write(")");
38380 Ok(())
38381 }
38382
38383 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
38384 let is_safe = e.safe.is_some();
38387 if is_safe {
38388 self.write_keyword("TRY_TO_NUMBER");
38389 } else {
38390 self.write_keyword("TO_NUMBER");
38391 }
38392 self.write("(");
38393 self.generate_expression(&e.this)?;
38394 let precision_is_snowflake_default = e.precision.is_none()
38395 || matches!(
38396 e.precision.as_deref(),
38397 Some(Expression::Literal(lit))
38398 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
38399 );
38400 let is_snowflake_default_precision =
38401 matches!(self.config.dialect, Some(DialectType::Snowflake))
38402 && e.nlsparam.is_none()
38403 && e.scale.is_none()
38404 && matches!(
38405 e.format.as_deref(),
38406 Some(Expression::Literal(lit))
38407 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
38408 )
38409 && precision_is_snowflake_default;
38410
38411 if !is_snowflake_default_precision {
38412 if let Some(format) = &e.format {
38413 self.write(", ");
38414 self.generate_expression(format)?;
38415 }
38416 if let Some(nlsparam) = &e.nlsparam {
38417 self.write(", ");
38418 self.generate_expression(nlsparam)?;
38419 }
38420 if let Some(precision) = &e.precision {
38421 self.write(", ");
38422 self.generate_expression(precision)?;
38423 }
38424 if let Some(scale) = &e.scale {
38425 self.write(", ");
38426 self.generate_expression(scale)?;
38427 }
38428 }
38429 self.write(")");
38430 Ok(())
38431 }
38432
38433 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
38434 self.write_keyword("TO_TABLE");
38436 self.write_space();
38437 self.generate_expression(&e.this)?;
38438 Ok(())
38439 }
38440
38441 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
38442 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
38444 Expression::Identifier(id) => id.name.clone(),
38445 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
38446 let Literal::String(s) = lit.as_ref() else {
38447 unreachable!()
38448 };
38449 s.clone()
38450 }
38451 _ => String::new(),
38452 });
38453
38454 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
38455 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
38456 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
38457 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
38458 });
38459
38460 let use_start_transaction = matches!(
38462 self.config.dialect,
38463 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
38464 );
38465 let strip_transaction = matches!(
38467 self.config.dialect,
38468 Some(DialectType::Snowflake)
38469 | Some(DialectType::PostgreSQL)
38470 | Some(DialectType::Redshift)
38471 | Some(DialectType::MySQL)
38472 | Some(DialectType::Hive)
38473 | Some(DialectType::Spark)
38474 | Some(DialectType::Databricks)
38475 | Some(DialectType::DuckDB)
38476 | Some(DialectType::Oracle)
38477 | Some(DialectType::Doris)
38478 | Some(DialectType::StarRocks)
38479 | Some(DialectType::Materialize)
38480 | Some(DialectType::ClickHouse)
38481 );
38482
38483 if is_start || use_start_transaction {
38484 self.write_keyword("START TRANSACTION");
38486 if let Some(modes) = &e.modes {
38487 self.write_space();
38488 self.generate_expression(modes)?;
38489 }
38490 } else {
38491 self.write_keyword("BEGIN");
38493
38494 let is_kind = e.this.as_ref().map_or(false, |t| {
38496 if let Expression::Identifier(id) = t.as_ref() {
38497 id.name.eq_ignore_ascii_case("DEFERRED")
38498 || id.name.eq_ignore_ascii_case("IMMEDIATE")
38499 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
38500 } else {
38501 false
38502 }
38503 });
38504
38505 if is_kind {
38507 if let Some(this) = &e.this {
38508 self.write_space();
38509 if let Expression::Identifier(id) = this.as_ref() {
38510 self.write_keyword(&id.name);
38511 }
38512 }
38513 }
38514
38515 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
38517 self.write_space();
38518 self.write_keyword("TRANSACTION");
38519 }
38520
38521 if !is_kind {
38523 if let Some(this) = &e.this {
38524 self.write_space();
38525 self.generate_expression(this)?;
38526 }
38527 }
38528
38529 if has_with_mark {
38531 self.write_space();
38532 self.write_keyword("WITH MARK");
38533 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
38534 if let Literal::String(desc) = lit.as_ref() {
38535 if !desc.is_empty() {
38536 self.write_space();
38537 self.write(&format!("'{}'", desc));
38538 }
38539 }
38540 }
38541 }
38542
38543 if let Some(modes) = &e.modes {
38545 self.write_space();
38546 self.generate_expression(modes)?;
38547 }
38548 }
38549 Ok(())
38550 }
38551
38552 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
38553 self.write_keyword("TRANSFORM");
38555 self.write("(");
38556 self.generate_expression(&e.this)?;
38557 self.write(", ");
38558 self.generate_expression(&e.expression)?;
38559 self.write(")");
38560 Ok(())
38561 }
38562
38563 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
38564 self.write_keyword("TRANSFORM");
38566 self.write("(");
38567 if self.config.pretty && !e.expressions.is_empty() {
38568 self.indent_level += 1;
38569 for (i, expr) in e.expressions.iter().enumerate() {
38570 if i > 0 {
38571 self.write(",");
38572 }
38573 self.write_newline();
38574 self.write_indent();
38575 self.generate_expression(expr)?;
38576 }
38577 self.indent_level -= 1;
38578 self.write_newline();
38579 self.write(")");
38580 } else {
38581 for (i, expr) in e.expressions.iter().enumerate() {
38582 if i > 0 {
38583 self.write(", ");
38584 }
38585 self.generate_expression(expr)?;
38586 }
38587 self.write(")");
38588 }
38589 Ok(())
38590 }
38591
38592 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
38593 use crate::dialects::DialectType;
38594 if let Some(this) = &e.this {
38596 self.generate_expression(this)?;
38597 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
38598 self.write_space();
38599 }
38600 }
38601 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
38602 self.write_keyword("TRANSIENT");
38603 }
38604 Ok(())
38605 }
38606
38607 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
38608 self.write_keyword("TRANSLATE");
38610 self.write("(");
38611 self.generate_expression(&e.this)?;
38612 if let Some(from) = &e.from_ {
38613 self.write(", ");
38614 self.generate_expression(from)?;
38615 }
38616 if let Some(to) = &e.to {
38617 self.write(", ");
38618 self.generate_expression(to)?;
38619 }
38620 self.write(")");
38621 Ok(())
38622 }
38623
38624 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
38625 self.write_keyword("TRANSLATE");
38627 self.write("(");
38628 self.generate_expression(&e.this)?;
38629 self.write_space();
38630 self.write_keyword("USING");
38631 self.write_space();
38632 self.generate_expression(&e.expression)?;
38633 if e.with_error.is_some() {
38634 self.write_space();
38635 self.write_keyword("WITH ERROR");
38636 }
38637 self.write(")");
38638 Ok(())
38639 }
38640
38641 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
38642 self.write_keyword("TRUNCATE TABLE");
38644 self.write_space();
38645 for (i, expr) in e.expressions.iter().enumerate() {
38646 if i > 0 {
38647 self.write(", ");
38648 }
38649 self.generate_expression(expr)?;
38650 }
38651 Ok(())
38652 }
38653
38654 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
38655 self.write_keyword("TRY_BASE64_DECODE_BINARY");
38657 self.write("(");
38658 self.generate_expression(&e.this)?;
38659 if let Some(alphabet) = &e.alphabet {
38660 self.write(", ");
38661 self.generate_expression(alphabet)?;
38662 }
38663 self.write(")");
38664 Ok(())
38665 }
38666
38667 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
38668 self.write_keyword("TRY_BASE64_DECODE_STRING");
38670 self.write("(");
38671 self.generate_expression(&e.this)?;
38672 if let Some(alphabet) = &e.alphabet {
38673 self.write(", ");
38674 self.generate_expression(alphabet)?;
38675 }
38676 self.write(")");
38677 Ok(())
38678 }
38679
38680 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
38681 self.write_keyword("TRY_TO_DECFLOAT");
38683 self.write("(");
38684 self.generate_expression(&e.this)?;
38685 if let Some(format) = &e.format {
38686 self.write(", '");
38687 self.write(format);
38688 self.write("'");
38689 }
38690 self.write(")");
38691 Ok(())
38692 }
38693
38694 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
38695 self.write_keyword("TS_OR_DS_ADD");
38697 self.write("(");
38698 self.generate_expression(&e.this)?;
38699 self.write(", ");
38700 self.generate_expression(&e.expression)?;
38701 if let Some(unit) = &e.unit {
38702 self.write(", ");
38703 self.write_keyword(unit);
38704 }
38705 if let Some(return_type) = &e.return_type {
38706 self.write(", ");
38707 self.generate_expression(return_type)?;
38708 }
38709 self.write(")");
38710 Ok(())
38711 }
38712
38713 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
38714 self.write_keyword("TS_OR_DS_DIFF");
38716 self.write("(");
38717 self.generate_expression(&e.this)?;
38718 self.write(", ");
38719 self.generate_expression(&e.expression)?;
38720 if let Some(unit) = &e.unit {
38721 self.write(", ");
38722 self.write_keyword(unit);
38723 }
38724 self.write(")");
38725 Ok(())
38726 }
38727
38728 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
38729 let default_time_format = "%Y-%m-%d %H:%M:%S";
38730 let default_date_format = "%Y-%m-%d";
38731 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
38732 f != default_time_format && f != default_date_format
38733 });
38734
38735 if has_non_default_format {
38736 let fmt = e.format.as_ref().unwrap();
38738 match self.config.dialect {
38739 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
38740 let str_to_time = crate::expressions::StrToTime {
38743 this: Box::new((*e.this).clone()),
38744 format: fmt.clone(),
38745 zone: None,
38746 safe: None,
38747 target_type: None,
38748 };
38749 self.generate_str_to_time(&str_to_time)?;
38750 }
38751 Some(DialectType::Hive)
38752 | Some(DialectType::Spark)
38753 | Some(DialectType::Databricks) => {
38754 self.write_keyword("TO_DATE");
38756 self.write("(");
38757 self.generate_expression(&e.this)?;
38758 self.write(", '");
38759 self.write(&Self::strftime_to_java_format(fmt));
38760 self.write("')");
38761 }
38762 Some(DialectType::Snowflake) => {
38763 self.write_keyword("TO_DATE");
38765 self.write("(");
38766 self.generate_expression(&e.this)?;
38767 self.write(", '");
38768 self.write(&Self::strftime_to_snowflake_format(fmt));
38769 self.write("')");
38770 }
38771 Some(DialectType::Doris) => {
38772 self.write_keyword("TO_DATE");
38774 self.write("(");
38775 self.generate_expression(&e.this)?;
38776 self.write(")");
38777 }
38778 _ => {
38779 self.write_keyword("CAST");
38781 self.write("(");
38782 let str_to_time = crate::expressions::StrToTime {
38783 this: Box::new((*e.this).clone()),
38784 format: fmt.clone(),
38785 zone: None,
38786 safe: None,
38787 target_type: None,
38788 };
38789 self.generate_str_to_time(&str_to_time)?;
38790 self.write_keyword(" AS ");
38791 self.write_keyword("DATE");
38792 self.write(")");
38793 }
38794 }
38795 } else {
38796 match self.config.dialect {
38798 Some(DialectType::MySQL)
38799 | Some(DialectType::SQLite)
38800 | Some(DialectType::StarRocks) => {
38801 self.write_keyword("DATE");
38803 self.write("(");
38804 self.generate_expression(&e.this)?;
38805 self.write(")");
38806 }
38807 Some(DialectType::Hive)
38808 | Some(DialectType::Spark)
38809 | Some(DialectType::Databricks)
38810 | Some(DialectType::Snowflake)
38811 | Some(DialectType::Doris) => {
38812 self.write_keyword("TO_DATE");
38814 self.write("(");
38815 self.generate_expression(&e.this)?;
38816 self.write(")");
38817 }
38818 Some(DialectType::Presto)
38819 | Some(DialectType::Trino)
38820 | Some(DialectType::Athena) => {
38821 self.write_keyword("CAST");
38823 self.write("(");
38824 self.write_keyword("CAST");
38825 self.write("(");
38826 self.generate_expression(&e.this)?;
38827 self.write_keyword(" AS ");
38828 self.write_keyword("TIMESTAMP");
38829 self.write(")");
38830 self.write_keyword(" AS ");
38831 self.write_keyword("DATE");
38832 self.write(")");
38833 }
38834 Some(DialectType::ClickHouse) => {
38835 self.write_keyword("CAST");
38837 self.write("(");
38838 self.generate_expression(&e.this)?;
38839 self.write_keyword(" AS ");
38840 self.write("Nullable(DATE)");
38841 self.write(")");
38842 }
38843 _ => {
38844 self.write_keyword("CAST");
38846 self.write("(");
38847 self.generate_expression(&e.this)?;
38848 self.write_keyword(" AS ");
38849 self.write_keyword("DATE");
38850 self.write(")");
38851 }
38852 }
38853 }
38854 Ok(())
38855 }
38856
38857 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
38858 self.write_keyword("TS_OR_DS_TO_TIME");
38860 self.write("(");
38861 self.generate_expression(&e.this)?;
38862 if let Some(format) = &e.format {
38863 self.write(", '");
38864 self.write(format);
38865 self.write("'");
38866 }
38867 self.write(")");
38868 Ok(())
38869 }
38870
38871 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
38872 self.write_keyword("UNHEX");
38874 self.write("(");
38875 self.generate_expression(&e.this)?;
38876 if let Some(expression) = &e.expression {
38877 self.write(", ");
38878 self.generate_expression(expression)?;
38879 }
38880 self.write(")");
38881 Ok(())
38882 }
38883
38884 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
38885 self.write("U&");
38887 self.generate_expression(&e.this)?;
38888 if let Some(escape) = &e.escape {
38889 self.write_space();
38890 self.write_keyword("UESCAPE");
38891 self.write_space();
38892 self.generate_expression(escape)?;
38893 }
38894 Ok(())
38895 }
38896
38897 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
38898 self.write_keyword("UNIFORM");
38900 self.write("(");
38901 self.generate_expression(&e.this)?;
38902 self.write(", ");
38903 self.generate_expression(&e.expression)?;
38904 if let Some(gen) = &e.gen {
38905 self.write(", ");
38906 self.generate_expression(gen)?;
38907 }
38908 if let Some(seed) = &e.seed {
38909 self.write(", ");
38910 self.generate_expression(seed)?;
38911 }
38912 self.write(")");
38913 Ok(())
38914 }
38915
38916 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
38917 self.write_keyword("UNIQUE");
38919 if e.nulls.is_some() {
38921 self.write(" NULLS NOT DISTINCT");
38922 }
38923 if let Some(this) = &e.this {
38924 self.write_space();
38925 self.generate_expression(this)?;
38926 }
38927 if let Some(index_type) = &e.index_type {
38928 self.write(" USING ");
38929 self.generate_expression(index_type)?;
38930 }
38931 if let Some(on_conflict) = &e.on_conflict {
38932 self.write_space();
38933 self.generate_expression(on_conflict)?;
38934 }
38935 for opt in &e.options {
38936 self.write_space();
38937 self.generate_expression(opt)?;
38938 }
38939 Ok(())
38940 }
38941
38942 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
38943 self.write_keyword("UNIQUE KEY");
38945 self.write(" (");
38946 for (i, expr) in e.expressions.iter().enumerate() {
38947 if i > 0 {
38948 self.write(", ");
38949 }
38950 self.generate_expression(expr)?;
38951 }
38952 self.write(")");
38953 Ok(())
38954 }
38955
38956 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
38957 self.write_keyword("ROLLUP");
38959 self.write(" (");
38960 for (i, index) in e.expressions.iter().enumerate() {
38961 if i > 0 {
38962 self.write(", ");
38963 }
38964 self.generate_identifier(&index.name)?;
38965 self.write("(");
38966 for (j, col) in index.expressions.iter().enumerate() {
38967 if j > 0 {
38968 self.write(", ");
38969 }
38970 self.generate_identifier(col)?;
38971 }
38972 self.write(")");
38973 }
38974 self.write(")");
38975 Ok(())
38976 }
38977
38978 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
38979 match self.config.dialect {
38980 Some(DialectType::DuckDB) => {
38981 self.write_keyword("STRFTIME");
38983 self.write("(");
38984 self.write_keyword("TO_TIMESTAMP");
38985 self.write("(");
38986 self.generate_expression(&e.this)?;
38987 self.write("), '");
38988 if let Some(format) = &e.format {
38989 self.write(format);
38990 }
38991 self.write("')");
38992 }
38993 Some(DialectType::Hive) => {
38994 self.write_keyword("FROM_UNIXTIME");
38996 self.write("(");
38997 self.generate_expression(&e.this)?;
38998 if let Some(format) = &e.format {
38999 if format != "yyyy-MM-dd HH:mm:ss" {
39000 self.write(", '");
39001 self.write(format);
39002 self.write("'");
39003 }
39004 }
39005 self.write(")");
39006 }
39007 Some(DialectType::Presto) | Some(DialectType::Trino) => {
39008 self.write_keyword("DATE_FORMAT");
39010 self.write("(");
39011 self.write_keyword("FROM_UNIXTIME");
39012 self.write("(");
39013 self.generate_expression(&e.this)?;
39014 self.write("), '");
39015 if let Some(format) = &e.format {
39016 self.write(format);
39017 }
39018 self.write("')");
39019 }
39020 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
39021 self.write_keyword("FROM_UNIXTIME");
39023 self.write("(");
39024 self.generate_expression(&e.this)?;
39025 if let Some(format) = &e.format {
39026 self.write(", '");
39027 self.write(format);
39028 self.write("'");
39029 }
39030 self.write(")");
39031 }
39032 _ => {
39033 self.write_keyword("UNIX_TO_STR");
39035 self.write("(");
39036 self.generate_expression(&e.this)?;
39037 if let Some(format) = &e.format {
39038 self.write(", '");
39039 self.write(format);
39040 self.write("'");
39041 }
39042 self.write(")");
39043 }
39044 }
39045 Ok(())
39046 }
39047
39048 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
39049 use crate::dialects::DialectType;
39050 let scale = e.scale.unwrap_or(0); match self.config.dialect {
39053 Some(DialectType::Snowflake) => {
39054 self.write_keyword("TO_TIMESTAMP");
39056 self.write("(");
39057 self.generate_expression(&e.this)?;
39058 if let Some(s) = e.scale {
39059 if s > 0 {
39060 self.write(", ");
39061 self.write(&s.to_string());
39062 }
39063 }
39064 self.write(")");
39065 }
39066 Some(DialectType::BigQuery) => {
39067 match scale {
39070 0 => {
39071 self.write_keyword("TIMESTAMP_SECONDS");
39072 self.write("(");
39073 self.generate_expression(&e.this)?;
39074 self.write(")");
39075 }
39076 3 => {
39077 self.write_keyword("TIMESTAMP_MILLIS");
39078 self.write("(");
39079 self.generate_expression(&e.this)?;
39080 self.write(")");
39081 }
39082 6 => {
39083 self.write_keyword("TIMESTAMP_MICROS");
39084 self.write("(");
39085 self.generate_expression(&e.this)?;
39086 self.write(")");
39087 }
39088 _ => {
39089 self.write_keyword("TIMESTAMP_SECONDS");
39091 self.write("(CAST(");
39092 self.generate_expression(&e.this)?;
39093 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
39094 }
39095 }
39096 }
39097 Some(DialectType::Spark) => {
39098 match scale {
39103 0 => {
39104 self.write_keyword("CAST");
39105 self.write("(");
39106 self.write_keyword("FROM_UNIXTIME");
39107 self.write("(");
39108 self.generate_expression(&e.this)?;
39109 self.write(") ");
39110 self.write_keyword("AS TIMESTAMP");
39111 self.write(")");
39112 }
39113 3 => {
39114 self.write_keyword("TIMESTAMP_MILLIS");
39115 self.write("(");
39116 self.generate_expression(&e.this)?;
39117 self.write(")");
39118 }
39119 6 => {
39120 self.write_keyword("TIMESTAMP_MICROS");
39121 self.write("(");
39122 self.generate_expression(&e.this)?;
39123 self.write(")");
39124 }
39125 _ => {
39126 self.write_keyword("TIMESTAMP_SECONDS");
39127 self.write("(");
39128 self.generate_expression(&e.this)?;
39129 self.write(&format!(" / POWER(10, {}))", scale));
39130 }
39131 }
39132 }
39133 Some(DialectType::Databricks) => {
39134 match scale {
39138 0 => {
39139 self.write_keyword("CAST");
39140 self.write("(");
39141 self.write_keyword("FROM_UNIXTIME");
39142 self.write("(");
39143 self.generate_expression(&e.this)?;
39144 self.write(") ");
39145 self.write_keyword("AS TIMESTAMP");
39146 self.write(")");
39147 }
39148 3 => {
39149 self.write_keyword("TIMESTAMP_MILLIS");
39150 self.write("(");
39151 self.generate_expression(&e.this)?;
39152 self.write(")");
39153 }
39154 6 => {
39155 self.write_keyword("TIMESTAMP_MICROS");
39156 self.write("(");
39157 self.generate_expression(&e.this)?;
39158 self.write(")");
39159 }
39160 _ => {
39161 self.write_keyword("TIMESTAMP_SECONDS");
39162 self.write("(");
39163 self.generate_expression(&e.this)?;
39164 self.write(&format!(" / POWER(10, {}))", scale));
39165 }
39166 }
39167 }
39168 Some(DialectType::Hive) => {
39169 if scale == 0 {
39171 self.write_keyword("FROM_UNIXTIME");
39172 self.write("(");
39173 self.generate_expression(&e.this)?;
39174 self.write(")");
39175 } else {
39176 self.write_keyword("FROM_UNIXTIME");
39177 self.write("(");
39178 self.generate_expression(&e.this)?;
39179 self.write(&format!(" / POWER(10, {})", scale));
39180 self.write(")");
39181 }
39182 }
39183 Some(DialectType::Presto) | Some(DialectType::Trino) => {
39184 if scale == 0 {
39187 self.write_keyword("FROM_UNIXTIME");
39188 self.write("(");
39189 self.generate_expression(&e.this)?;
39190 self.write(")");
39191 } else {
39192 self.write_keyword("FROM_UNIXTIME");
39193 self.write("(CAST(");
39194 self.generate_expression(&e.this)?;
39195 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
39196 }
39197 }
39198 Some(DialectType::DuckDB) => {
39199 match scale {
39203 0 => {
39204 self.write_keyword("TO_TIMESTAMP");
39205 self.write("(");
39206 self.generate_expression(&e.this)?;
39207 self.write(")");
39208 }
39209 3 => {
39210 self.write_keyword("EPOCH_MS");
39211 self.write("(");
39212 self.generate_expression(&e.this)?;
39213 self.write(")");
39214 }
39215 6 => {
39216 self.write_keyword("MAKE_TIMESTAMP");
39217 self.write("(");
39218 self.generate_expression(&e.this)?;
39219 self.write(")");
39220 }
39221 _ => {
39222 self.write_keyword("TO_TIMESTAMP");
39223 self.write("(");
39224 self.generate_expression(&e.this)?;
39225 self.write(&format!(" / POWER(10, {}))", scale));
39226 self.write_keyword(" AT TIME ZONE");
39227 self.write(" 'UTC'");
39228 }
39229 }
39230 }
39231 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
39232 self.write_keyword("FROM_UNIXTIME");
39234 self.write("(");
39235 self.generate_expression(&e.this)?;
39236 self.write(")");
39237 }
39238 Some(DialectType::Oracle) => {
39239 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
39241 self.generate_expression(&e.this)?;
39242 self.write(" / 86400)");
39243 }
39244 Some(DialectType::Redshift) => {
39245 self.write("(TIMESTAMP 'epoch' + ");
39248 if scale == 0 {
39249 self.generate_expression(&e.this)?;
39250 } else {
39251 self.write("(");
39252 self.generate_expression(&e.this)?;
39253 self.write(&format!(" / POWER(10, {}))", scale));
39254 }
39255 self.write(" * INTERVAL '1 SECOND')");
39256 }
39257 Some(DialectType::Exasol) => {
39258 self.write_keyword("FROM_POSIX_TIME");
39260 self.write("(");
39261 self.generate_expression(&e.this)?;
39262 self.write(")");
39263 }
39264 _ => {
39265 self.write_keyword("TO_TIMESTAMP");
39267 self.write("(");
39268 self.generate_expression(&e.this)?;
39269 if let Some(s) = e.scale {
39270 self.write(", ");
39271 self.write(&s.to_string());
39272 }
39273 self.write(")");
39274 }
39275 }
39276 Ok(())
39277 }
39278
39279 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
39280 if !matches!(&*e.this, Expression::Null(_)) {
39282 self.write_keyword("NAME");
39283 self.write_space();
39284 self.generate_expression(&e.this)?;
39285 }
39286 if !e.expressions.is_empty() {
39287 self.write_space();
39288 self.write_keyword("VALUE");
39289 self.write_space();
39290 for (i, expr) in e.expressions.iter().enumerate() {
39291 if i > 0 {
39292 self.write(", ");
39293 }
39294 self.generate_expression(expr)?;
39295 }
39296 }
39297 Ok(())
39298 }
39299
39300 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
39301 if e.wrapped.is_some() {
39303 self.write("(");
39304 }
39305 self.generate_expression(&e.this)?;
39306 if e.wrapped.is_some() {
39307 self.write(")");
39308 }
39309 self.write("(");
39310 for (i, expr) in e.expressions.iter().enumerate() {
39311 if i > 0 {
39312 self.write(", ");
39313 }
39314 self.generate_expression(expr)?;
39315 }
39316 self.write(")");
39317 Ok(())
39318 }
39319
39320 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
39321 self.write_keyword("USING TEMPLATE");
39323 self.write_space();
39324 self.generate_expression(&e.this)?;
39325 Ok(())
39326 }
39327
39328 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
39329 self.write_keyword("UTC_TIME");
39331 Ok(())
39332 }
39333
39334 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
39335 if matches!(
39336 self.config.dialect,
39337 Some(crate::dialects::DialectType::ClickHouse)
39338 ) {
39339 self.write_keyword("CURRENT_TIMESTAMP");
39340 self.write("('UTC')");
39341 } else {
39342 self.write_keyword("UTC_TIMESTAMP");
39343 }
39344 Ok(())
39345 }
39346
39347 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
39348 use crate::dialects::DialectType;
39349 let func_name = match self.config.dialect {
39351 Some(DialectType::Snowflake) => "UUID_STRING",
39352 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
39353 Some(DialectType::BigQuery) => "GENERATE_UUID",
39354 _ => {
39355 if let Some(name) = &e.name {
39356 name.as_str()
39357 } else {
39358 "UUID"
39359 }
39360 }
39361 };
39362 self.write_keyword(func_name);
39363 self.write("(");
39364 if let Some(this) = &e.this {
39365 self.generate_expression(this)?;
39366 }
39367 self.write(")");
39368 Ok(())
39369 }
39370
39371 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
39372 self.write_keyword("MAP");
39374 self.write("(");
39375 let mut first = true;
39376 for (k, v) in e.keys.iter().zip(e.values.iter()) {
39377 if !first {
39378 self.write(", ");
39379 }
39380 self.generate_expression(k)?;
39381 self.write(", ");
39382 self.generate_expression(v)?;
39383 first = false;
39384 }
39385 self.write(")");
39386 Ok(())
39387 }
39388
39389 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
39390 self.write_keyword("VECTOR_SEARCH");
39392 self.write("(");
39393 self.generate_expression(&e.this)?;
39394 if let Some(col) = &e.column_to_search {
39395 self.write(", ");
39396 self.generate_expression(col)?;
39397 }
39398 if let Some(query_table) = &e.query_table {
39399 self.write(", ");
39400 self.generate_expression(query_table)?;
39401 }
39402 if let Some(query_col) = &e.query_column_to_search {
39403 self.write(", ");
39404 self.generate_expression(query_col)?;
39405 }
39406 if let Some(top_k) = &e.top_k {
39407 self.write(", ");
39408 self.generate_expression(top_k)?;
39409 }
39410 if let Some(dist_type) = &e.distance_type {
39411 self.write(", ");
39412 self.generate_expression(dist_type)?;
39413 }
39414 self.write(")");
39415 Ok(())
39416 }
39417
39418 fn generate_version(&mut self, e: &Version) -> Result<()> {
39419 use crate::dialects::DialectType;
39425 let skip_for = matches!(
39426 self.config.dialect,
39427 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
39428 );
39429 if !skip_for {
39430 self.write_keyword("FOR");
39431 self.write_space();
39432 }
39433 match e.this.as_ref() {
39435 Expression::Identifier(ident) => {
39436 self.write_keyword(&ident.name);
39437 }
39438 _ => {
39439 self.generate_expression(&e.this)?;
39440 }
39441 }
39442 self.write_space();
39443 self.write_keyword(&e.kind);
39444 if let Some(expression) = &e.expression {
39445 self.write_space();
39446 self.generate_expression(expression)?;
39447 }
39448 Ok(())
39449 }
39450
39451 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
39452 self.generate_expression(&e.this)?;
39454 Ok(())
39455 }
39456
39457 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
39458 if e.this.is_some() {
39460 self.write_keyword("NOT VOLATILE");
39461 } else {
39462 self.write_keyword("VOLATILE");
39463 }
39464 Ok(())
39465 }
39466
39467 fn generate_watermark_column_constraint(
39468 &mut self,
39469 e: &WatermarkColumnConstraint,
39470 ) -> Result<()> {
39471 self.write_keyword("WATERMARK FOR");
39473 self.write_space();
39474 self.generate_expression(&e.this)?;
39475 self.write_space();
39476 self.write_keyword("AS");
39477 self.write_space();
39478 self.generate_expression(&e.expression)?;
39479 Ok(())
39480 }
39481
39482 fn generate_week(&mut self, e: &Week) -> Result<()> {
39483 self.write_keyword("WEEK");
39485 self.write("(");
39486 self.generate_expression(&e.this)?;
39487 if let Some(mode) = &e.mode {
39488 self.write(", ");
39489 self.generate_expression(mode)?;
39490 }
39491 self.write(")");
39492 Ok(())
39493 }
39494
39495 fn generate_when(&mut self, e: &When) -> Result<()> {
39496 self.write_keyword("WHEN");
39500 self.write_space();
39501
39502 if let Some(matched) = &e.matched {
39504 match matched.as_ref() {
39506 Expression::Boolean(b) if b.value => {
39507 self.write_keyword("MATCHED");
39508 }
39509 _ => {
39510 self.write_keyword("NOT MATCHED");
39511 }
39512 }
39513 } else {
39514 self.write_keyword("NOT MATCHED");
39515 }
39516
39517 if self.config.matched_by_source {
39522 if let Some(source) = &e.source {
39523 if let Expression::Boolean(b) = source.as_ref() {
39524 if b.value {
39525 self.write_space();
39527 self.write_keyword("BY SOURCE");
39528 }
39529 } else {
39531 self.write_space();
39533 self.write_keyword("BY SOURCE");
39534 }
39535 }
39536 }
39537
39538 if let Some(condition) = &e.condition {
39540 self.write_space();
39541 self.write_keyword("AND");
39542 self.write_space();
39543 self.generate_expression(condition)?;
39544 }
39545
39546 self.write_space();
39547 self.write_keyword("THEN");
39548 self.write_space();
39549
39550 self.generate_merge_action(&e.then)?;
39553
39554 Ok(())
39555 }
39556
39557 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
39558 match action {
39559 Expression::Tuple(tuple) => {
39560 let elements = &tuple.expressions;
39561 if elements.is_empty() {
39562 return self.generate_expression(action);
39563 }
39564 match &elements[0] {
39566 Expression::Var(v) if v.this == "INSERT" => {
39567 self.write_keyword("INSERT");
39568 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
39570 self.write(" *");
39571 if let Some(Expression::Where(w)) = elements.get(2) {
39572 self.write_space();
39573 self.generate_where(w)?;
39574 }
39575 } else {
39576 let mut values_idx = 1;
39577 if elements.len() > 1 {
39579 if let Expression::Tuple(cols) = &elements[1] {
39580 if elements.len() > 2 {
39582 self.write(" (");
39584 for (i, col) in cols.expressions.iter().enumerate() {
39585 if i > 0 {
39586 self.write(", ");
39587 }
39588 if !self.merge_strip_qualifiers.is_empty() {
39590 let stripped = self.strip_merge_qualifier(col);
39591 self.generate_expression(&stripped)?;
39592 } else {
39593 self.generate_expression(col)?;
39594 }
39595 }
39596 self.write(")");
39597 values_idx = 2;
39598 } else {
39599 values_idx = 1;
39601 }
39602 }
39603 }
39604 let mut next_idx = values_idx;
39605 if values_idx < elements.len()
39607 && !matches!(&elements[values_idx], Expression::Where(_))
39608 {
39609 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
39611 if !is_row {
39612 self.write_space();
39613 self.write_keyword("VALUES");
39614 }
39615 self.write(" ");
39616 if let Expression::Tuple(vals) = &elements[values_idx] {
39617 self.write("(");
39618 for (i, val) in vals.expressions.iter().enumerate() {
39619 if i > 0 {
39620 self.write(", ");
39621 }
39622 self.generate_expression(val)?;
39623 }
39624 self.write(")");
39625 } else {
39626 self.generate_expression(&elements[values_idx])?;
39627 }
39628 next_idx += 1;
39629 }
39630 if let Some(Expression::Where(w)) = elements.get(next_idx) {
39631 self.write_space();
39632 self.generate_where(w)?;
39633 }
39634 } }
39636 Expression::Var(v) if v.this == "UPDATE" => {
39637 self.write_keyword("UPDATE");
39638 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
39640 self.write(" *");
39641 if let Some(Expression::Where(w)) = elements.get(2) {
39642 self.write_space();
39643 self.generate_where(w)?;
39644 }
39645 } else if elements.len() > 1 {
39646 self.write_space();
39647 self.write_keyword("SET");
39648 if self.config.pretty {
39650 self.write_newline();
39651 self.indent_level += 1;
39652 self.write_indent();
39653 } else {
39654 self.write_space();
39655 }
39656 if let Expression::Tuple(assignments) = &elements[1] {
39657 for (i, assignment) in assignments.expressions.iter().enumerate() {
39658 if i > 0 {
39659 if self.config.pretty {
39660 self.write(",");
39661 self.write_newline();
39662 self.write_indent();
39663 } else {
39664 self.write(", ");
39665 }
39666 }
39667 if !self.merge_strip_qualifiers.is_empty() {
39669 self.generate_merge_set_assignment(assignment)?;
39670 } else {
39671 self.generate_expression(assignment)?;
39672 }
39673 }
39674 } else {
39675 self.generate_expression(&elements[1])?;
39676 }
39677 if self.config.pretty {
39678 self.indent_level -= 1;
39679 }
39680 if let Some(Expression::Where(w)) = elements.get(2) {
39681 self.write_space();
39682 self.generate_where(w)?;
39683 }
39684 }
39685 }
39686 Expression::Var(v) if v.this == "DELETE" => {
39687 self.write_keyword("DELETE");
39688 if let Some(Expression::Where(w)) = elements.get(1) {
39689 self.write_space();
39690 self.generate_where(w)?;
39691 }
39692 }
39693 _ => {
39694 self.generate_expression(action)?;
39696 }
39697 }
39698 }
39699 Expression::Var(v)
39700 if v.this == "INSERT"
39701 || v.this == "UPDATE"
39702 || v.this == "DELETE"
39703 || v.this == "DO NOTHING" =>
39704 {
39705 self.write_keyword(&v.this);
39706 }
39707 _ => {
39708 self.generate_expression(action)?;
39709 }
39710 }
39711 Ok(())
39712 }
39713
39714 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
39716 match assignment {
39717 Expression::Eq(eq) => {
39718 let stripped_left = self.strip_merge_qualifier(&eq.left);
39720 self.generate_expression(&stripped_left)?;
39721 self.write(" = ");
39722 self.generate_expression(&eq.right)?;
39723 Ok(())
39724 }
39725 other => self.generate_expression(other),
39726 }
39727 }
39728
39729 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
39731 match expr {
39732 Expression::Column(col) => {
39733 if let Some(ref table_ident) = col.table {
39734 if self
39735 .merge_strip_qualifiers
39736 .iter()
39737 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
39738 {
39739 let mut col = col.clone();
39741 col.table = None;
39742 return Expression::Column(col);
39743 }
39744 }
39745 expr.clone()
39746 }
39747 Expression::Dot(dot) => {
39748 if let Expression::Identifier(id) = &dot.this {
39750 if self
39751 .merge_strip_qualifiers
39752 .iter()
39753 .any(|n| n.eq_ignore_ascii_case(&id.name))
39754 {
39755 return Expression::Identifier(dot.field.clone());
39756 }
39757 }
39758 expr.clone()
39759 }
39760 _ => expr.clone(),
39761 }
39762 }
39763
39764 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
39765 for (i, expr) in e.expressions.iter().enumerate() {
39767 if i > 0 {
39768 if self.config.pretty {
39770 self.write_newline();
39771 self.write_indent();
39772 } else {
39773 self.write_space();
39774 }
39775 }
39776 self.generate_expression(expr)?;
39777 }
39778 Ok(())
39779 }
39780
39781 fn generate_where(&mut self, e: &Where) -> Result<()> {
39782 self.write_keyword("WHERE");
39784 self.write_space();
39785 self.generate_expression(&e.this)?;
39786 Ok(())
39787 }
39788
39789 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
39790 self.write_keyword("WIDTH_BUCKET");
39792 self.write("(");
39793 self.generate_expression(&e.this)?;
39794 if let Some(min_value) = &e.min_value {
39795 self.write(", ");
39796 self.generate_expression(min_value)?;
39797 }
39798 if let Some(max_value) = &e.max_value {
39799 self.write(", ");
39800 self.generate_expression(max_value)?;
39801 }
39802 if let Some(num_buckets) = &e.num_buckets {
39803 self.write(", ");
39804 self.generate_expression(num_buckets)?;
39805 }
39806 self.write(")");
39807 Ok(())
39808 }
39809
39810 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
39811 self.generate_window_spec(e)
39813 }
39814
39815 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
39816 let mut has_content = false;
39818
39819 if !e.partition_by.is_empty() {
39821 self.write_keyword("PARTITION BY");
39822 self.write_space();
39823 for (i, expr) in e.partition_by.iter().enumerate() {
39824 if i > 0 {
39825 self.write(", ");
39826 }
39827 self.generate_expression(expr)?;
39828 }
39829 has_content = true;
39830 }
39831
39832 if !e.order_by.is_empty() {
39834 if has_content {
39835 self.write_space();
39836 }
39837 self.write_keyword("ORDER BY");
39838 self.write_space();
39839 for (i, ordered) in e.order_by.iter().enumerate() {
39840 if i > 0 {
39841 self.write(", ");
39842 }
39843 self.generate_expression(&ordered.this)?;
39844 if ordered.desc {
39845 self.write_space();
39846 self.write_keyword("DESC");
39847 } else if ordered.explicit_asc {
39848 self.write_space();
39849 self.write_keyword("ASC");
39850 }
39851 if let Some(nulls_first) = ordered.nulls_first {
39852 self.write_space();
39853 self.write_keyword("NULLS");
39854 self.write_space();
39855 if nulls_first {
39856 self.write_keyword("FIRST");
39857 } else {
39858 self.write_keyword("LAST");
39859 }
39860 }
39861 }
39862 has_content = true;
39863 }
39864
39865 if let Some(frame) = &e.frame {
39867 if has_content {
39868 self.write_space();
39869 }
39870 self.generate_window_frame(frame)?;
39871 }
39872
39873 Ok(())
39874 }
39875
39876 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
39877 self.write_keyword("WITH");
39879 self.write_space();
39880 if e.no.is_some() {
39881 self.write_keyword("NO");
39882 self.write_space();
39883 }
39884 self.write_keyword("DATA");
39885
39886 if let Some(statistics) = &e.statistics {
39888 self.write_space();
39889 self.write_keyword("AND");
39890 self.write_space();
39891 match statistics.as_ref() {
39893 Expression::Boolean(b) if !b.value => {
39894 self.write_keyword("NO");
39895 self.write_space();
39896 }
39897 _ => {}
39898 }
39899 self.write_keyword("STATISTICS");
39900 }
39901 Ok(())
39902 }
39903
39904 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
39905 self.write_keyword("WITH FILL");
39907
39908 if let Some(from_) = &e.from_ {
39909 self.write_space();
39910 self.write_keyword("FROM");
39911 self.write_space();
39912 self.generate_expression(from_)?;
39913 }
39914
39915 if let Some(to) = &e.to {
39916 self.write_space();
39917 self.write_keyword("TO");
39918 self.write_space();
39919 self.generate_expression(to)?;
39920 }
39921
39922 if let Some(step) = &e.step {
39923 self.write_space();
39924 self.write_keyword("STEP");
39925 self.write_space();
39926 self.generate_expression(step)?;
39927 }
39928
39929 if let Some(staleness) = &e.staleness {
39930 self.write_space();
39931 self.write_keyword("STALENESS");
39932 self.write_space();
39933 self.generate_expression(staleness)?;
39934 }
39935
39936 if let Some(interpolate) = &e.interpolate {
39937 self.write_space();
39938 self.write_keyword("INTERPOLATE");
39939 self.write(" (");
39940 self.generate_interpolate_item(interpolate)?;
39942 self.write(")");
39943 }
39944
39945 Ok(())
39946 }
39947
39948 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
39950 match expr {
39951 Expression::Alias(alias) => {
39952 self.generate_identifier(&alias.alias)?;
39954 self.write_space();
39955 self.write_keyword("AS");
39956 self.write_space();
39957 self.generate_expression(&alias.this)?;
39958 }
39959 Expression::Tuple(tuple) => {
39960 for (i, item) in tuple.expressions.iter().enumerate() {
39961 if i > 0 {
39962 self.write(", ");
39963 }
39964 self.generate_interpolate_item(item)?;
39965 }
39966 }
39967 other => {
39968 self.generate_expression(other)?;
39969 }
39970 }
39971 Ok(())
39972 }
39973
39974 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
39975 self.write_keyword("WITH JOURNAL TABLE");
39977 self.write("=");
39978 self.generate_expression(&e.this)?;
39979 Ok(())
39980 }
39981
39982 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
39983 self.generate_expression(&e.this)?;
39985 self.write_space();
39986 self.write_keyword("WITH");
39987 self.write_space();
39988 self.write_keyword(&e.op);
39989 Ok(())
39990 }
39991
39992 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
39993 self.write_keyword("WITH");
39995 self.write_space();
39996 for (i, expr) in e.expressions.iter().enumerate() {
39997 if i > 0 {
39998 self.write(", ");
39999 }
40000 self.generate_expression(expr)?;
40001 }
40002 Ok(())
40003 }
40004
40005 fn generate_with_schema_binding_property(
40006 &mut self,
40007 e: &WithSchemaBindingProperty,
40008 ) -> Result<()> {
40009 self.write_keyword("WITH");
40011 self.write_space();
40012 self.generate_expression(&e.this)?;
40013 Ok(())
40014 }
40015
40016 fn generate_with_system_versioning_property(
40017 &mut self,
40018 e: &WithSystemVersioningProperty,
40019 ) -> Result<()> {
40020 let mut parts = Vec::new();
40026
40027 if let Some(this) = &e.this {
40028 let mut s = String::from("HISTORY_TABLE=");
40030 let mut gen = Generator::new();
40031 gen.generate_expression(this)?;
40032 s.push_str(&gen.output);
40033 parts.push(s);
40034 }
40035
40036 if let Some(data_consistency) = &e.data_consistency {
40037 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
40038 let mut gen = Generator::new();
40039 gen.generate_expression(data_consistency)?;
40040 s.push_str(&gen.output);
40041 parts.push(s);
40042 }
40043
40044 if let Some(retention_period) = &e.retention_period {
40045 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
40046 let mut gen = Generator::new();
40047 gen.generate_expression(retention_period)?;
40048 s.push_str(&gen.output);
40049 parts.push(s);
40050 }
40051
40052 self.write_keyword("SYSTEM_VERSIONING");
40053 self.write("=");
40054
40055 if !parts.is_empty() {
40056 self.write_keyword("ON");
40057 self.write("(");
40058 self.write(&parts.join(", "));
40059 self.write(")");
40060 } else if e.on.is_some() {
40061 self.write_keyword("ON");
40062 } else {
40063 self.write_keyword("OFF");
40064 }
40065
40066 if e.with_.is_some() {
40068 let inner = self.output.clone();
40069 self.output.clear();
40070 self.write("WITH(");
40071 self.write(&inner);
40072 self.write(")");
40073 }
40074
40075 Ok(())
40076 }
40077
40078 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
40079 self.write_keyword("WITH");
40081 self.write(" (");
40082 for (i, expr) in e.expressions.iter().enumerate() {
40083 if i > 0 {
40084 self.write(", ");
40085 }
40086 self.generate_expression(expr)?;
40087 }
40088 self.write(")");
40089 Ok(())
40090 }
40091
40092 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
40093 self.write_keyword("XMLELEMENT");
40096 self.write("(");
40097
40098 if e.evalname.is_some() {
40099 self.write_keyword("EVALNAME");
40100 } else {
40101 self.write_keyword("NAME");
40102 }
40103 self.write_space();
40104 self.generate_expression(&e.this)?;
40105
40106 for expr in &e.expressions {
40107 self.write(", ");
40108 self.generate_expression(expr)?;
40109 }
40110 self.write(")");
40111 Ok(())
40112 }
40113
40114 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
40115 self.write_keyword("XMLGET");
40117 self.write("(");
40118 self.generate_expression(&e.this)?;
40119 self.write(", ");
40120 self.generate_expression(&e.expression)?;
40121 if let Some(instance) = &e.instance {
40122 self.write(", ");
40123 self.generate_expression(instance)?;
40124 }
40125 self.write(")");
40126 Ok(())
40127 }
40128
40129 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
40130 self.generate_expression(&e.this)?;
40132 if let Some(expression) = &e.expression {
40133 self.write("(");
40134 self.generate_expression(expression)?;
40135 self.write(")");
40136 }
40137 Ok(())
40138 }
40139
40140 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
40141 self.write_keyword("XMLTABLE");
40143 self.write("(");
40144
40145 if self.config.pretty {
40146 self.indent_level += 1;
40147 self.write_newline();
40148 self.write_indent();
40149 self.generate_expression(&e.this)?;
40150
40151 if let Some(passing) = &e.passing {
40152 self.write_newline();
40153 self.write_indent();
40154 self.write_keyword("PASSING");
40155 if let Expression::Tuple(tuple) = passing.as_ref() {
40156 for expr in &tuple.expressions {
40157 self.write_newline();
40158 self.indent_level += 1;
40159 self.write_indent();
40160 self.generate_expression(expr)?;
40161 self.indent_level -= 1;
40162 }
40163 } else {
40164 self.write_newline();
40165 self.indent_level += 1;
40166 self.write_indent();
40167 self.generate_expression(passing)?;
40168 self.indent_level -= 1;
40169 }
40170 }
40171
40172 if e.by_ref.is_some() {
40173 self.write_newline();
40174 self.write_indent();
40175 self.write_keyword("RETURNING SEQUENCE BY REF");
40176 }
40177
40178 if !e.columns.is_empty() {
40179 self.write_newline();
40180 self.write_indent();
40181 self.write_keyword("COLUMNS");
40182 for (i, col) in e.columns.iter().enumerate() {
40183 self.write_newline();
40184 self.indent_level += 1;
40185 self.write_indent();
40186 self.generate_expression(col)?;
40187 self.indent_level -= 1;
40188 if i < e.columns.len() - 1 {
40189 self.write(",");
40190 }
40191 }
40192 }
40193
40194 self.indent_level -= 1;
40195 self.write_newline();
40196 self.write_indent();
40197 self.write(")");
40198 return Ok(());
40199 }
40200
40201 if let Some(namespaces) = &e.namespaces {
40203 self.write_keyword("XMLNAMESPACES");
40204 self.write("(");
40205 if let Expression::Tuple(tuple) = namespaces.as_ref() {
40207 for (i, expr) in tuple.expressions.iter().enumerate() {
40208 if i > 0 {
40209 self.write(", ");
40210 }
40211 if !matches!(expr, Expression::Alias(_)) {
40214 self.write_keyword("DEFAULT");
40215 self.write_space();
40216 }
40217 self.generate_expression(expr)?;
40218 }
40219 } else {
40220 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
40222 self.write_keyword("DEFAULT");
40223 self.write_space();
40224 }
40225 self.generate_expression(namespaces)?;
40226 }
40227 self.write("), ");
40228 }
40229
40230 self.generate_expression(&e.this)?;
40232
40233 if let Some(passing) = &e.passing {
40235 self.write_space();
40236 self.write_keyword("PASSING");
40237 self.write_space();
40238 if let Expression::Tuple(tuple) = passing.as_ref() {
40240 for (i, expr) in tuple.expressions.iter().enumerate() {
40241 if i > 0 {
40242 self.write(", ");
40243 }
40244 self.generate_expression(expr)?;
40245 }
40246 } else {
40247 self.generate_expression(passing)?;
40248 }
40249 }
40250
40251 if e.by_ref.is_some() {
40253 self.write_space();
40254 self.write_keyword("RETURNING SEQUENCE BY REF");
40255 }
40256
40257 if !e.columns.is_empty() {
40259 self.write_space();
40260 self.write_keyword("COLUMNS");
40261 self.write_space();
40262 for (i, col) in e.columns.iter().enumerate() {
40263 if i > 0 {
40264 self.write(", ");
40265 }
40266 self.generate_expression(col)?;
40267 }
40268 }
40269
40270 self.write(")");
40271 Ok(())
40272 }
40273
40274 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
40275 if let Some(this) = &e.this {
40278 self.generate_expression(this)?;
40279 if let Some(expression) = &e.expression {
40280 self.write_space();
40281 self.write_keyword("XOR");
40282 self.write_space();
40283 self.generate_expression(expression)?;
40284 }
40285 }
40286
40287 for (i, expr) in e.expressions.iter().enumerate() {
40289 if i > 0 || e.this.is_some() {
40290 self.write_space();
40291 self.write_keyword("XOR");
40292 self.write_space();
40293 }
40294 self.generate_expression(expr)?;
40295 }
40296 Ok(())
40297 }
40298
40299 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
40300 self.write_keyword("ZIPF");
40302 self.write("(");
40303 self.generate_expression(&e.this)?;
40304 if let Some(elementcount) = &e.elementcount {
40305 self.write(", ");
40306 self.generate_expression(elementcount)?;
40307 }
40308 if let Some(gen) = &e.gen {
40309 self.write(", ");
40310 self.generate_expression(gen)?;
40311 }
40312 self.write(")");
40313 Ok(())
40314 }
40315}
40316
40317impl Default for Generator {
40318 fn default() -> Self {
40319 Self::new()
40320 }
40321}
40322
40323#[cfg(test)]
40324mod tests {
40325 use super::*;
40326 use crate::parser::Parser;
40327
40328 fn roundtrip(sql: &str) -> String {
40329 let ast = Parser::parse_sql(sql).unwrap();
40330 Generator::sql(&ast[0]).unwrap()
40331 }
40332
40333 #[test]
40334 fn test_simple_select() {
40335 let result = roundtrip("SELECT 1");
40336 assert_eq!(result, "SELECT 1");
40337 }
40338
40339 #[test]
40340 fn test_select_from() {
40341 let result = roundtrip("SELECT a, b FROM t");
40342 assert_eq!(result, "SELECT a, b FROM t");
40343 }
40344
40345 #[test]
40346 fn test_select_where() {
40347 let result = roundtrip("SELECT * FROM t WHERE x = 1");
40348 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
40349 }
40350
40351 #[test]
40352 fn test_select_join() {
40353 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
40354 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
40355 }
40356
40357 #[test]
40358 fn test_insert() {
40359 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
40360 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
40361 }
40362
40363 #[test]
40364 fn test_pretty_print() {
40365 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
40366 let result = Generator::pretty_sql(&ast[0]).unwrap();
40367 assert!(result.contains('\n'));
40368 }
40369
40370 #[test]
40371 fn test_window_function() {
40372 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
40373 assert_eq!(
40374 result,
40375 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
40376 );
40377 }
40378
40379 #[test]
40380 fn test_window_function_with_frame() {
40381 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
40382 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
40383 }
40384
40385 #[test]
40386 fn test_aggregate_with_filter() {
40387 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
40388 assert_eq!(
40389 result,
40390 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
40391 );
40392 }
40393
40394 #[test]
40395 fn test_subscript() {
40396 let result = roundtrip("SELECT arr[0]");
40397 assert_eq!(result, "SELECT arr[0]");
40398 }
40399
40400 #[test]
40402 fn test_create_table() {
40403 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
40404 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
40405 }
40406
40407 #[test]
40408 fn test_create_table_with_constraints() {
40409 let result = roundtrip(
40410 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
40411 );
40412 assert_eq!(
40413 result,
40414 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
40415 );
40416 }
40417
40418 #[test]
40419 fn test_create_table_if_not_exists() {
40420 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
40421 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
40422 }
40423
40424 #[test]
40425 fn test_drop_table() {
40426 let result = roundtrip("DROP TABLE users");
40427 assert_eq!(result, "DROP TABLE users");
40428 }
40429
40430 #[test]
40431 fn test_drop_table_if_exists_cascade() {
40432 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
40433 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
40434 }
40435
40436 #[test]
40437 fn test_alter_table_add_column() {
40438 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
40439 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
40440 }
40441
40442 #[test]
40443 fn test_alter_table_drop_column() {
40444 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
40445 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
40446 }
40447
40448 #[test]
40449 fn test_create_index() {
40450 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
40451 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
40452 }
40453
40454 #[test]
40455 fn test_create_unique_index() {
40456 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
40457 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
40458 }
40459
40460 #[test]
40461 fn test_drop_index() {
40462 let result = roundtrip("DROP INDEX idx_name");
40463 assert_eq!(result, "DROP INDEX idx_name");
40464
40465 let result = roundtrip(r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#);
40466 assert_eq!(
40467 result,
40468 r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#
40469 );
40470
40471 let result = roundtrip(r#"DROP INDEX "public"."IdxMixed""#);
40472 assert_eq!(result, r#"DROP INDEX "public"."IdxMixed""#);
40473 }
40474
40475 #[test]
40476 fn test_create_view() {
40477 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
40478 assert_eq!(
40479 result,
40480 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
40481 );
40482 }
40483
40484 #[test]
40485 fn test_drop_view() {
40486 let result = roundtrip("DROP VIEW active_users");
40487 assert_eq!(result, "DROP VIEW active_users");
40488 }
40489
40490 #[test]
40491 fn test_truncate() {
40492 let result = roundtrip("TRUNCATE TABLE users");
40493 assert_eq!(result, "TRUNCATE TABLE users");
40494 }
40495
40496 #[test]
40497 fn test_string_literal_escaping_default() {
40498 let result = roundtrip("SELECT 'hello'");
40500 assert_eq!(result, "SELECT 'hello'");
40501
40502 let result = roundtrip("SELECT 'it''s a test'");
40504 assert_eq!(result, "SELECT 'it''s a test'");
40505 }
40506
40507 #[test]
40508 fn test_not_in_style_prefix_default_generic() {
40509 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
40510 assert_eq!(
40511 result,
40512 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
40513 );
40514 }
40515
40516 #[test]
40517 fn test_not_in_style_infix_generic_override() {
40518 let ast =
40519 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
40520 .unwrap();
40521 let config = GeneratorConfig {
40522 not_in_style: NotInStyle::Infix,
40523 ..Default::default()
40524 };
40525 let mut gen = Generator::with_config(config);
40526 let result = gen.generate(&ast[0]).unwrap();
40527 assert_eq!(
40528 result,
40529 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
40530 );
40531 }
40532
40533 #[test]
40534 fn test_string_literal_escaping_mysql() {
40535 use crate::dialects::DialectType;
40536
40537 let config = GeneratorConfig {
40538 dialect: Some(DialectType::MySQL),
40539 ..Default::default()
40540 };
40541
40542 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
40543 let mut gen = Generator::with_config(config.clone());
40544 let result = gen.generate(&ast[0]).unwrap();
40545 assert_eq!(result, "SELECT 'hello'");
40546
40547 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
40549 let mut gen = Generator::with_config(config.clone());
40550 let result = gen.generate(&ast[0]).unwrap();
40551 assert_eq!(result, "SELECT 'it''s'");
40552 }
40553
40554 #[test]
40555 fn test_string_literal_escaping_postgres() {
40556 use crate::dialects::DialectType;
40557
40558 let config = GeneratorConfig {
40559 dialect: Some(DialectType::PostgreSQL),
40560 ..Default::default()
40561 };
40562
40563 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
40564 let mut gen = Generator::with_config(config.clone());
40565 let result = gen.generate(&ast[0]).unwrap();
40566 assert_eq!(result, "SELECT 'hello'");
40567
40568 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
40570 let mut gen = Generator::with_config(config.clone());
40571 let result = gen.generate(&ast[0]).unwrap();
40572 assert_eq!(result, "SELECT 'it''s'");
40573 }
40574
40575 #[test]
40576 fn test_string_literal_escaping_bigquery() {
40577 use crate::dialects::DialectType;
40578
40579 let config = GeneratorConfig {
40580 dialect: Some(DialectType::BigQuery),
40581 ..Default::default()
40582 };
40583
40584 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
40585 let mut gen = Generator::with_config(config.clone());
40586 let result = gen.generate(&ast[0]).unwrap();
40587 assert_eq!(result, "SELECT 'hello'");
40588
40589 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
40591 let mut gen = Generator::with_config(config.clone());
40592 let result = gen.generate(&ast[0]).unwrap();
40593 assert_eq!(result, "SELECT 'it\\'s'");
40594 }
40595
40596 #[test]
40597 fn test_generate_deep_and_chain_without_stack_growth() {
40598 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
40599 Expression::column("c0"),
40600 Expression::number(0),
40601 )));
40602
40603 for i in 1..2500 {
40604 let predicate = Expression::Eq(Box::new(BinaryOp::new(
40605 Expression::column(format!("c{i}")),
40606 Expression::number(i as i64),
40607 )));
40608 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
40609 }
40610
40611 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
40612 assert!(sql.contains("c2499 = 2499"), "{}", sql);
40613 }
40614
40615 #[test]
40616 fn test_generate_deep_or_chain_without_stack_growth() {
40617 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
40618 Expression::column("c0"),
40619 Expression::number(0),
40620 )));
40621
40622 for i in 1..2500 {
40623 let predicate = Expression::Eq(Box::new(BinaryOp::new(
40624 Expression::column(format!("c{i}")),
40625 Expression::number(i as i64),
40626 )));
40627 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
40628 }
40629
40630 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
40631 assert!(sql.contains("c2499 = 2499"), "{}", sql);
40632 }
40633}