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::SplitTable(st) => self.generate_split_table(st),
3446 Expression::FlashbackTable(ft) => self.generate_flashback_table(ft),
3447 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3448 Expression::DropIndex(di) => self.generate_drop_index(di),
3449 Expression::CreateView(cv) => self.generate_create_view(cv),
3450 Expression::DropView(dv) => self.generate_drop_view(dv),
3451 Expression::AlterView(av) => self.generate_alter_view(av),
3452 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3453 Expression::Truncate(tr) => self.generate_truncate(tr),
3454 Expression::Use(u) => self.generate_use(u),
3455 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3457 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3458 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3459 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3460 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3461 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3462 Expression::DropFunction(df) => self.generate_drop_function(df),
3463 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3464 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3465 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3466 Expression::CreateSynonym(cs) => {
3467 self.write_keyword("CREATE SYNONYM");
3468 self.write_space();
3469 self.generate_table(&cs.name)?;
3470 self.write_space();
3471 self.write_keyword("FOR");
3472 self.write_space();
3473 self.generate_table(&cs.target)?;
3474 Ok(())
3475 }
3476 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3477 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3478 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3479 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3480 Expression::CreateType(ct) => self.generate_create_type(ct),
3481 Expression::DropType(dt) => self.generate_drop_type(dt),
3482 Expression::Describe(d) => self.generate_describe(d),
3483 Expression::Show(s) => self.generate_show(s),
3484
3485 Expression::Cache(c) => self.generate_cache(c),
3487 Expression::Uncache(u) => self.generate_uncache(u),
3488 Expression::LoadData(l) => self.generate_load_data(l),
3489 Expression::Pragma(p) => self.generate_pragma(p),
3490 Expression::Grant(g) => self.generate_grant(g),
3491 Expression::Revoke(r) => self.generate_revoke(r),
3492 Expression::Comment(c) => self.generate_comment(c),
3493 Expression::SetStatement(s) => self.generate_set_statement(s),
3494
3495 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3497 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3498
3499 Expression::Values(values) => self.generate_values(values),
3501
3502 Expression::AIAgg(e) => self.generate_ai_agg(e),
3504 Expression::AIClassify(e) => self.generate_ai_classify(e),
3505 Expression::AddPartition(e) => self.generate_add_partition(e),
3506 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3507 Expression::Aliases(e) => self.generate_aliases(e),
3508 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3509 Expression::AlterColumn(e) => self.generate_alter_column(e),
3510 Expression::AlterSession(e) => self.generate_alter_session(e),
3511 Expression::AlterSet(e) => self.generate_alter_set(e),
3512 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3513 Expression::Analyze(e) => self.generate_analyze(e),
3514 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3515 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3516 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3517 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3518 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3519 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3520 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3521 Expression::Anonymous(e) => self.generate_anonymous(e),
3522 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3523 Expression::Apply(e) => self.generate_apply(e),
3524 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3525 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3526 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3527 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3528 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3529 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3530 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3531 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3532 Expression::ArgMax(e) => self.generate_arg_max(e),
3533 Expression::ArgMin(e) => self.generate_arg_min(e),
3534 Expression::ArrayAll(e) => self.generate_array_all(e),
3535 Expression::ArrayAny(e) => self.generate_array_any(e),
3536 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3537 Expression::ArraySum(e) => self.generate_array_sum(e),
3538 Expression::AtIndex(e) => self.generate_at_index(e),
3539 Expression::Attach(e) => self.generate_attach(e),
3540 Expression::AttachOption(e) => self.generate_attach_option(e),
3541 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3542 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3543 Expression::BackupProperty(e) => self.generate_backup_property(e),
3544 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3545 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3546 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3547 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3548 Expression::Booland(e) => self.generate_booland(e),
3549 Expression::Boolor(e) => self.generate_boolor(e),
3550 Expression::BuildProperty(e) => self.generate_build_property(e),
3551 Expression::ByteString(e) => self.generate_byte_string(e),
3552 Expression::CaseSpecificColumnConstraint(e) => {
3553 self.generate_case_specific_column_constraint(e)
3554 }
3555 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3556 Expression::Changes(e) => self.generate_changes(e),
3557 Expression::CharacterSetColumnConstraint(e) => {
3558 self.generate_character_set_column_constraint(e)
3559 }
3560 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3561 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3562 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3563 Expression::CheckJson(e) => self.generate_check_json(e),
3564 Expression::CheckXml(e) => self.generate_check_xml(e),
3565 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3566 Expression::Clone(e) => self.generate_clone(e),
3567 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3568 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3569 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3570 Expression::CollateProperty(e) => self.generate_collate_property(e),
3571 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3572 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3573 Expression::ColumnPosition(e) => self.generate_column_position(e),
3574 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3575 Expression::Columns(e) => self.generate_columns(e),
3576 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3577 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3578 Expression::Commit(e) => self.generate_commit(e),
3579 Expression::Comprehension(e) => self.generate_comprehension(e),
3580 Expression::Compress(e) => self.generate_compress(e),
3581 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3582 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3583 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3584 Expression::Constraint(e) => self.generate_constraint(e),
3585 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3586 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3587 Expression::Copy(e) => self.generate_copy(e),
3588 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3589 Expression::Corr(e) => self.generate_corr(e),
3590 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3591 Expression::CovarPop(e) => self.generate_covar_pop(e),
3592 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3593 Expression::Credentials(e) => self.generate_credentials(e),
3594 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3595 Expression::Cte(e) => self.generate_cte(e),
3596 Expression::Cube(e) => self.generate_cube(e),
3597 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3598 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3599 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3600 Expression::CurrentUser(e) => self.generate_current_user(e),
3601 Expression::DPipe(e) => self.generate_d_pipe(e),
3602 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3603 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3604 Expression::Date(e) => self.generate_date_func(e),
3605 Expression::DateBin(e) => self.generate_date_bin(e),
3606 Expression::DateFormatColumnConstraint(e) => {
3607 self.generate_date_format_column_constraint(e)
3608 }
3609 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3610 Expression::Datetime(e) => self.generate_datetime(e),
3611 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3612 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3613 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3614 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3615 Expression::Dayname(e) => self.generate_dayname(e),
3616 Expression::Declare(e) => self.generate_declare(e),
3617 Expression::DeclareItem(e) => self.generate_declare_item(e),
3618 Expression::DecodeCase(e) => self.generate_decode_case(e),
3619 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3620 Expression::DecompressString(e) => self.generate_decompress_string(e),
3621 Expression::Decrypt(e) => self.generate_decrypt(e),
3622 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3623 Expression::DefaultColumnConstraint(e) => {
3624 self.write_keyword("DEFAULT");
3625 self.write_space();
3626 self.generate_expression(&e.this)?;
3627 if let Some(ref col) = e.for_column {
3628 self.write_space();
3629 self.write_keyword("FOR");
3630 self.write_space();
3631 self.generate_identifier(col)?;
3632 }
3633 Ok(())
3634 }
3635 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3636 Expression::Detach(e) => self.generate_detach(e),
3637 Expression::DictProperty(e) => self.generate_dict_property(e),
3638 Expression::DictRange(e) => self.generate_dict_range(e),
3639 Expression::Directory(e) => self.generate_directory(e),
3640 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3641 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3642 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3643 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3644 Expression::DotProduct(e) => self.generate_dot_product(e),
3645 Expression::DropPartition(e) => self.generate_drop_partition(e),
3646 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3647 Expression::Elt(e) => self.generate_elt(e),
3648 Expression::Encode(e) => self.generate_encode(e),
3649 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3650 Expression::Encrypt(e) => self.generate_encrypt(e),
3651 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3652 Expression::EngineProperty(e) => self.generate_engine_property(e),
3653 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3654 Expression::EphemeralColumnConstraint(e) => {
3655 self.generate_ephemeral_column_constraint(e)
3656 }
3657 Expression::EqualNull(e) => self.generate_equal_null(e),
3658 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3659 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3660 Expression::Export(e) => self.generate_export(e),
3661 Expression::ExternalProperty(e) => self.generate_external_property(e),
3662 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3663 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3664 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3665 Expression::Fetch(e) => self.generate_fetch(e),
3666 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3667 Expression::Filter(e) => self.generate_filter(e),
3668 Expression::Float64(e) => self.generate_float64(e),
3669 Expression::ForIn(e) => self.generate_for_in(e),
3670 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3671 Expression::Format(e) => self.generate_format(e),
3672 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3673 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3674 Expression::From(e) => self.generate_from(e),
3675 Expression::FromBase(e) => self.generate_from_base(e),
3676 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3677 Expression::GapFill(e) => self.generate_gap_fill(e),
3678 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3679 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3680 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3681 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3682 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3683 self.generate_generated_as_identity_column_constraint(e)
3684 }
3685 Expression::GeneratedAsRowColumnConstraint(e) => {
3686 self.generate_generated_as_row_column_constraint(e)
3687 }
3688 Expression::Get(e) => self.generate_get(e),
3689 Expression::GetExtract(e) => self.generate_get_extract(e),
3690 Expression::Getbit(e) => self.generate_getbit(e),
3691 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3692 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3693 Expression::Group(e) => self.generate_group(e),
3694 Expression::GroupBy(e) => self.generate_group_by(e),
3695 Expression::Grouping(e) => self.generate_grouping(e),
3696 Expression::GroupingId(e) => self.generate_grouping_id(e),
3697 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3698 Expression::HashAgg(e) => self.generate_hash_agg(e),
3699 Expression::Having(e) => self.generate_having(e),
3700 Expression::HavingMax(e) => self.generate_having_max(e),
3701 Expression::Heredoc(e) => self.generate_heredoc(e),
3702 Expression::HexEncode(e) => self.generate_hex_encode(e),
3703 Expression::Hll(e) => self.generate_hll(e),
3704 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3705 Expression::IncludeProperty(e) => self.generate_include_property(e),
3706 Expression::Index(e) => self.generate_index(e),
3707 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3708 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3709 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3710 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3711 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3712 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3713 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3714 Expression::Install(e) => self.generate_install(e),
3715 Expression::IntervalOp(e) => self.generate_interval_op(e),
3716 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3717 Expression::IntoClause(e) => self.generate_into_clause(e),
3718 Expression::Introducer(e) => self.generate_introducer(e),
3719 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3720 Expression::JSON(e) => self.generate_json(e),
3721 Expression::JSONArray(e) => self.generate_json_array(e),
3722 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3723 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3724 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3725 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3726 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3727 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3728 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3729 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3730 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3731 Expression::JSONExists(e) => self.generate_json_exists(e),
3732 Expression::JSONCast(e) => self.generate_json_cast(e),
3733 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3734 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3735 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3736 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3737 Expression::JSONFormat(e) => self.generate_json_format(e),
3738 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3739 Expression::JSONKeys(e) => self.generate_json_keys(e),
3740 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3741 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3742 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3743 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3744 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3745 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3746 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3747 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3748 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3749 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3750 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3751 Expression::JSONRemove(e) => self.generate_json_remove(e),
3752 Expression::JSONSchema(e) => self.generate_json_schema(e),
3753 Expression::JSONSet(e) => self.generate_json_set(e),
3754 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3755 Expression::JSONTable(e) => self.generate_json_table(e),
3756 Expression::JSONType(e) => self.generate_json_type(e),
3757 Expression::JSONValue(e) => self.generate_json_value(e),
3758 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3759 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3760 Expression::JoinHint(e) => self.generate_join_hint(e),
3761 Expression::JournalProperty(e) => self.generate_journal_property(e),
3762 Expression::LanguageProperty(e) => self.generate_language_property(e),
3763 Expression::Lateral(e) => self.generate_lateral(e),
3764 Expression::LikeProperty(e) => self.generate_like_property(e),
3765 Expression::Limit(e) => self.generate_limit(e),
3766 Expression::LimitOptions(e) => self.generate_limit_options(e),
3767 Expression::List(e) => self.generate_list(e),
3768 Expression::ToMap(e) => self.generate_tomap(e),
3769 Expression::Localtime(e) => self.generate_localtime(e),
3770 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3771 Expression::LocationProperty(e) => self.generate_location_property(e),
3772 Expression::Lock(e) => self.generate_lock(e),
3773 Expression::LockProperty(e) => self.generate_lock_property(e),
3774 Expression::LockingProperty(e) => self.generate_locking_property(e),
3775 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3776 Expression::LogProperty(e) => self.generate_log_property(e),
3777 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3778 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3779 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3780 Expression::MakeInterval(e) => self.generate_make_interval(e),
3781 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3782 Expression::Map(e) => self.generate_map(e),
3783 Expression::MapCat(e) => self.generate_map_cat(e),
3784 Expression::MapDelete(e) => self.generate_map_delete(e),
3785 Expression::MapInsert(e) => self.generate_map_insert(e),
3786 Expression::MapPick(e) => self.generate_map_pick(e),
3787 Expression::MaskingPolicyColumnConstraint(e) => {
3788 self.generate_masking_policy_column_constraint(e)
3789 }
3790 Expression::MatchAgainst(e) => self.generate_match_against(e),
3791 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3792 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3793 Expression::Merge(e) => self.generate_merge(e),
3794 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3795 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3796 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3797 Expression::Minhash(e) => self.generate_minhash(e),
3798 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3799 Expression::Monthname(e) => self.generate_monthname(e),
3800 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3801 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3802 Expression::Normal(e) => self.generate_normal(e),
3803 Expression::Normalize(e) => self.generate_normalize(e),
3804 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3805 Expression::Nullif(e) => self.generate_nullif(e),
3806 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3807 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3808 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3809 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3810 Expression::Offset(e) => self.generate_offset(e),
3811 Expression::Qualify(e) => self.generate_qualify(e),
3812 Expression::OnCluster(e) => self.generate_on_cluster(e),
3813 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3814 Expression::OnCondition(e) => self.generate_on_condition(e),
3815 Expression::OnConflict(e) => self.generate_on_conflict(e),
3816 Expression::OnProperty(e) => self.generate_on_property(e),
3817 Expression::Opclass(e) => self.generate_opclass(e),
3818 Expression::OpenJSON(e) => self.generate_open_json(e),
3819 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3820 Expression::Operator(e) => self.generate_operator(e),
3821 Expression::OrderBy(e) => self.generate_order_by(e),
3822 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3823 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3824 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3825 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3826 Expression::ParseIp(e) => self.generate_parse_ip(e),
3827 Expression::ParseJSON(e) => self.generate_parse_json(e),
3828 Expression::ParseTime(e) => self.generate_parse_time(e),
3829 Expression::ParseUrl(e) => self.generate_parse_url(e),
3830 Expression::Partition(e) => self.generate_partition_expr(e),
3831 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3832 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3833 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3834 Expression::PartitionByRangePropertyDynamic(e) => {
3835 self.generate_partition_by_range_property_dynamic(e)
3836 }
3837 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3838 Expression::PartitionList(e) => self.generate_partition_list(e),
3839 Expression::PartitionRange(e) => self.generate_partition_range(e),
3840 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3841 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3842 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3843 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3844 Expression::PeriodForSystemTimeConstraint(e) => {
3845 self.generate_period_for_system_time_constraint(e)
3846 }
3847 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3848 Expression::PivotAny(e) => self.generate_pivot_any(e),
3849 Expression::Predict(e) => self.generate_predict(e),
3850 Expression::PreviousDay(e) => self.generate_previous_day(e),
3851 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3852 Expression::PrimaryKeyColumnConstraint(e) => {
3853 self.generate_primary_key_column_constraint(e)
3854 }
3855 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3856 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3857 Expression::OptionsProperty(e) => self.generate_options_property(e),
3858 Expression::Properties(e) => self.generate_properties(e),
3859 Expression::Property(e) => self.generate_property(e),
3860 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3861 Expression::Put(e) => self.generate_put(e),
3862 Expression::Quantile(e) => self.generate_quantile(e),
3863 Expression::QueryBand(e) => self.generate_query_band(e),
3864 Expression::QueryOption(e) => self.generate_query_option(e),
3865 Expression::QueryTransform(e) => self.generate_query_transform(e),
3866 Expression::Randn(e) => self.generate_randn(e),
3867 Expression::Randstr(e) => self.generate_randstr(e),
3868 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3869 Expression::RangeN(e) => self.generate_range_n(e),
3870 Expression::ReadCSV(e) => self.generate_read_csv(e),
3871 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3872 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3873 Expression::Reduce(e) => self.generate_reduce(e),
3874 Expression::Reference(e) => self.generate_reference(e),
3875 Expression::Refresh(e) => self.generate_refresh(e),
3876 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3877 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3878 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3879 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3880 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3881 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3882 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3883 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3884 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3885 Expression::RegrCount(e) => self.generate_regr_count(e),
3886 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3887 Expression::RegrR2(e) => self.generate_regr_r2(e),
3888 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3889 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3890 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3891 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3892 Expression::RegrValx(e) => self.generate_regr_valx(e),
3893 Expression::RegrValy(e) => self.generate_regr_valy(e),
3894 Expression::RemoteWithConnectionModelProperty(e) => {
3895 self.generate_remote_with_connection_model_property(e)
3896 }
3897 Expression::RenameColumn(e) => self.generate_rename_column(e),
3898 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3899 Expression::Returning(e) => self.generate_returning(e),
3900 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3901 Expression::Rollback(e) => self.generate_rollback(e),
3902 Expression::Rollup(e) => self.generate_rollup(e),
3903 Expression::RowFormatDelimitedProperty(e) => {
3904 self.generate_row_format_delimited_property(e)
3905 }
3906 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3907 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3908 Expression::SHA2(e) => self.generate_sha2(e),
3909 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3910 Expression::SafeAdd(e) => self.generate_safe_add(e),
3911 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3912 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3913 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3914 Expression::SampleProperty(e) => self.generate_sample_property(e),
3915 Expression::Schema(e) => self.generate_schema(e),
3916 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3917 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3918 Expression::Search(e) => self.generate_search(e),
3919 Expression::SearchIp(e) => self.generate_search_ip(e),
3920 Expression::SecurityProperty(e) => self.generate_security_property(e),
3921 Expression::SemanticView(e) => self.generate_semantic_view(e),
3922 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3923 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3924 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3925 Expression::Set(e) => self.generate_set(e),
3926 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3927 Expression::SetItem(e) => self.generate_set_item(e),
3928 Expression::SetOperation(e) => self.generate_set_operation(e),
3929 Expression::SetProperty(e) => self.generate_set_property(e),
3930 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3931 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3932 Expression::Slice(e) => self.generate_slice(e),
3933 Expression::SortArray(e) => self.generate_sort_array(e),
3934 Expression::SortBy(e) => self.generate_sort_by(e),
3935 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3936 Expression::SplitPart(e) => self.generate_split_part(e),
3937 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3938 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3939 Expression::StDistance(e) => self.generate_st_distance(e),
3940 Expression::StPoint(e) => self.generate_st_point(e),
3941 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3942 Expression::StandardHash(e) => self.generate_standard_hash(e),
3943 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3944 Expression::StrPosition(e) => self.generate_str_position(e),
3945 Expression::StrToDate(e) => self.generate_str_to_date(e),
3946 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3947 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3948 Expression::StrToMap(e) => self.generate_str_to_map(e),
3949 Expression::StrToTime(e) => self.generate_str_to_time(e),
3950 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3951 Expression::StringToArray(e) => self.generate_string_to_array(e),
3952 Expression::Struct(e) => self.generate_struct(e),
3953 Expression::Stuff(e) => self.generate_stuff(e),
3954 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3955 Expression::Summarize(e) => self.generate_summarize(e),
3956 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3957 Expression::TableAlias(e) => self.generate_table_alias(e),
3958 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3959 Expression::RowsFrom(e) => self.generate_rows_from(e),
3960 Expression::TableSample(e) => self.generate_table_sample(e),
3961 Expression::Tag(e) => self.generate_tag(e),
3962 Expression::Tags(e) => self.generate_tags(e),
3963 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3964 Expression::Time(e) => self.generate_time_func(e),
3965 Expression::TimeAdd(e) => self.generate_time_add(e),
3966 Expression::TimeDiff(e) => self.generate_time_diff(e),
3967 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3968 Expression::TimeSlice(e) => self.generate_time_slice(e),
3969 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3970 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3971 Expression::TimeSub(e) => self.generate_time_sub(e),
3972 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3973 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3974 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3975 Expression::TimeUnit(e) => self.generate_time_unit(e),
3976 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3977 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3978 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3979 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3980 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3981 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3982 Expression::ToBinary(e) => self.generate_to_binary(e),
3983 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3984 Expression::ToChar(e) => self.generate_to_char(e),
3985 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3986 Expression::ToDouble(e) => self.generate_to_double(e),
3987 Expression::ToFile(e) => self.generate_to_file(e),
3988 Expression::ToNumber(e) => self.generate_to_number(e),
3989 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3990 Expression::Transaction(e) => self.generate_transaction(e),
3991 Expression::Transform(e) => self.generate_transform(e),
3992 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3993 Expression::TransientProperty(e) => self.generate_transient_property(e),
3994 Expression::Translate(e) => self.generate_translate(e),
3995 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3996 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3997 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3998 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3999 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
4000 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
4001 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
4002 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
4003 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
4004 Expression::Unhex(e) => self.generate_unhex(e),
4005 Expression::UnicodeString(e) => self.generate_unicode_string(e),
4006 Expression::Uniform(e) => self.generate_uniform(e),
4007 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
4008 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
4009 Expression::RollupProperty(e) => self.generate_rollup_property(e),
4010 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
4011 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
4012 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
4013 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
4014 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
4015 Expression::UtcTime(e) => self.generate_utc_time(e),
4016 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
4017 Expression::Uuid(e) => self.generate_uuid(e),
4018 Expression::Var(v) => {
4019 if matches!(self.config.dialect, Some(DialectType::MySQL))
4020 && v.this.len() > 2
4021 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
4022 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
4023 {
4024 return self.generate_identifier(&Identifier {
4025 name: v.this.clone(),
4026 quoted: true,
4027 trailing_comments: Vec::new(),
4028 span: None,
4029 });
4030 }
4031 self.write(&v.this);
4032 Ok(())
4033 }
4034 Expression::Variadic(e) => {
4035 self.write_keyword("VARIADIC");
4036 self.write_space();
4037 self.generate_expression(&e.this)?;
4038 Ok(())
4039 }
4040 Expression::VarMap(e) => self.generate_var_map(e),
4041 Expression::VectorSearch(e) => self.generate_vector_search(e),
4042 Expression::Version(e) => self.generate_version(e),
4043 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
4044 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
4045 Expression::WatermarkColumnConstraint(e) => {
4046 self.generate_watermark_column_constraint(e)
4047 }
4048 Expression::Week(e) => self.generate_week(e),
4049 Expression::When(e) => self.generate_when(e),
4050 Expression::Whens(e) => self.generate_whens(e),
4051 Expression::Where(e) => self.generate_where(e),
4052 Expression::WidthBucket(e) => self.generate_width_bucket(e),
4053 Expression::Window(e) => self.generate_window(e),
4054 Expression::WindowSpec(e) => self.generate_window_spec(e),
4055 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
4056 Expression::WithFill(e) => self.generate_with_fill(e),
4057 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
4058 Expression::WithOperator(e) => self.generate_with_operator(e),
4059 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
4060 Expression::WithSchemaBindingProperty(e) => {
4061 self.generate_with_schema_binding_property(e)
4062 }
4063 Expression::WithSystemVersioningProperty(e) => {
4064 self.generate_with_system_versioning_property(e)
4065 }
4066 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
4067 Expression::XMLElement(e) => self.generate_xml_element(e),
4068 Expression::XMLGet(e) => self.generate_xml_get(e),
4069 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
4070 Expression::XMLTable(e) => self.generate_xml_table(e),
4071 Expression::Xor(e) => self.generate_xor(e),
4072 Expression::Zipf(e) => self.generate_zipf(e),
4073 _ => self.write_unsupported_comment("unsupported expression"),
4074 }
4075 }
4076
4077 fn should_handle_tsql_distinct_null_ordering(&self, select: &Select) -> bool {
4078 matches!(
4079 self.config.dialect,
4080 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4081 ) && !self.config.null_ordering_supported
4082 && select.distinct
4083 && select.order_by.as_ref().is_some_and(|order_by| {
4084 order_by
4085 .expressions
4086 .iter()
4087 .any(Self::ordered_requires_tsql_null_ordering_emulation)
4088 })
4089 }
4090
4091 fn ordered_requires_tsql_null_ordering_emulation(ordered: &Ordered) -> bool {
4092 let Some(nulls_first) = ordered.nulls_first else {
4093 return false;
4094 };
4095
4096 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
4097 let target_default_nulls_first = !ordered.desc;
4098
4099 nulls_first != target_default_nulls_first && !random_ordering
4100 }
4101
4102 fn projection_output_identifier(expression: &Expression) -> Option<Identifier> {
4103 match expression {
4104 Expression::Alias(alias) if !alias.alias.name.is_empty() => Some(alias.alias.clone()),
4105 Expression::Column(column) => Some(column.name.clone()),
4106 Expression::Identifier(identifier) => Some(identifier.clone()),
4107 _ => None,
4108 }
4109 }
4110
4111 fn identifier_names_match(left: &Identifier, right: &Identifier) -> bool {
4112 if left.quoted || right.quoted {
4113 left.name == right.name
4114 } else {
4115 left.name.eq_ignore_ascii_case(&right.name)
4116 }
4117 }
4118
4119 fn expression_matches_identifier(expression: &Expression, identifier: &Identifier) -> bool {
4120 match expression {
4121 Expression::Column(column) if column.table.is_none() => {
4122 Self::identifier_names_match(&column.name, identifier)
4123 }
4124 Expression::Identifier(other) => Self::identifier_names_match(other, identifier),
4125 _ => false,
4126 }
4127 }
4128
4129 fn column_expression(identifier: Identifier) -> Expression {
4130 Expression::Column(Box::new(Column {
4131 name: identifier,
4132 table: None,
4133 join_mark: false,
4134 trailing_comments: Vec::new(),
4135 span: None,
4136 inferred_type: None,
4137 }))
4138 }
4139
4140 fn positional_ordering_index(expression: &Expression) -> Option<usize> {
4141 match expression {
4142 Expression::Literal(lit) => match lit.as_ref() {
4143 Literal::Number(n) => {
4144 let value = n.parse::<usize>().ok()?;
4145 value.checked_sub(1)
4146 }
4147 _ => None,
4148 },
4149 _ => None,
4150 }
4151 }
4152
4153 fn projection_sort_expression(expression: &Expression) -> Option<Expression> {
4154 let expression = match expression {
4155 Expression::Alias(alias) => &alias.this,
4156 other => other,
4157 };
4158
4159 match expression {
4160 Expression::Star(_)
4161 | Expression::Literal(_)
4162 | Expression::Null(_)
4163 | Expression::Boolean(_) => None,
4164 _ => Some(expression.clone()),
4165 }
4166 }
4167
4168 fn resolve_positional_order_projection(
4169 projections: &[Expression],
4170 index: usize,
4171 ) -> Option<Expression> {
4172 Self::projection_sort_expression(projections.get(index)?)
4173 }
4174
4175 fn is_direct_grouping_expression(expression: &Expression) -> bool {
4176 match expression {
4177 Expression::Paren(paren) => Self::is_direct_grouping_expression(&paren.this),
4178 Expression::Grouping(_) | Expression::GroupingId(_) => true,
4179 Expression::Function(function) => {
4180 function.name.eq_ignore_ascii_case("GROUPING")
4181 || function.name.eq_ignore_ascii_case("GROUPING_ID")
4182 }
4183 _ => false,
4184 }
4185 }
4186
4187 fn group_by_has_multiple_grouping_levels(group_by: &GroupBy) -> bool {
4188 group_by
4189 .expressions
4190 .iter()
4191 .any(|expression| match expression {
4192 Expression::Cube(_) | Expression::Rollup(_) => true,
4193 Expression::GroupingSets(grouping_sets) => grouping_sets.expressions.len() > 1,
4194 Expression::Function(function)
4195 if function.name.eq_ignore_ascii_case("CUBE")
4196 || function.name.eq_ignore_ascii_case("ROLLUP") =>
4197 {
4198 !function.args.is_empty()
4199 }
4200 Expression::Function(function)
4201 if function.name.eq_ignore_ascii_case("GROUPING SETS") =>
4202 {
4203 function.args.len() > 1
4204 || function.args.first().is_some_and(|expression| {
4205 matches!(expression, Expression::Cube(_) | Expression::Rollup(_))
4206 || matches!(expression,
4207 Expression::Function(nested)
4208 if nested.name.eq_ignore_ascii_case("CUBE")
4209 || nested.name.eq_ignore_ascii_case("ROLLUP")
4210 )
4211 })
4212 }
4213 _ => false,
4214 })
4215 }
4216
4217 fn set_output_identifier_at(expression: &Expression, index: usize) -> Option<Identifier> {
4218 match expression {
4219 Expression::Select(select) => {
4220 Self::projection_output_identifier(select.expressions.get(index)?)
4221 }
4222 Expression::Union(union) => Self::set_output_identifier_at(&union.left, index),
4223 Expression::Intersect(intersect) => {
4224 Self::set_output_identifier_at(&intersect.left, index)
4225 }
4226 Expression::Except(except) => Self::set_output_identifier_at(&except.left, index),
4227 Expression::Subquery(subquery) => subquery
4228 .column_aliases
4229 .get(index)
4230 .cloned()
4231 .or_else(|| Self::set_output_identifier_at(&subquery.this, index)),
4232 _ => None,
4233 }
4234 }
4235
4236 fn resolve_single_subquery_star_projection(
4237 select: &Select,
4238 index: usize,
4239 ) -> Option<Expression> {
4240 if select.expressions.len() != 1
4241 || !matches!(select.expressions.first(), Some(Expression::Star(_)))
4242 {
4243 return None;
4244 }
4245
4246 let from = select.from.as_ref()?;
4247 if from.expressions.len() != 1 {
4248 return None;
4249 }
4250
4251 let Expression::Subquery(subquery) = from.expressions.first()? else {
4252 return None;
4253 };
4254
4255 subquery
4256 .column_aliases
4257 .get(index)
4258 .cloned()
4259 .or_else(|| Self::set_output_identifier_at(&subquery.this, index))
4260 .map(Self::column_expression)
4261 }
4262
4263 fn sole_tsql_ordering_source_qualifier(select: &Select) -> Option<Identifier> {
4264 if !select.joins.is_empty() {
4265 return None;
4266 }
4267
4268 let from = select.from.as_ref()?;
4269 if from.expressions.len() != 1 {
4270 return None;
4271 }
4272
4273 match from.expressions.first()? {
4274 Expression::Table(table) => {
4275 Some(table.alias.clone().unwrap_or_else(|| table.name.clone()))
4276 }
4277 Expression::Subquery(subquery) => subquery.alias.clone(),
4278 _ => None,
4279 }
4280 }
4281
4282 fn resolve_duplicate_tsql_ordering_column(
4283 select: &Select,
4284 expression: &Expression,
4285 ) -> Option<Expression> {
4286 let Expression::Column(order_column) = expression else {
4287 return None;
4288 };
4289 if order_column.table.is_some() {
4290 return None;
4291 }
4292
4293 let matching_projections: Vec<_> = select
4294 .expressions
4295 .iter()
4296 .filter(|projection| {
4297 Self::projection_output_identifier(projection).is_some_and(|identifier| {
4298 Self::identifier_names_match(&identifier, &order_column.name)
4299 })
4300 })
4301 .filter_map(Self::projection_sort_expression)
4302 .collect();
4303
4304 if matching_projections.len() < 2
4305 || matching_projections[1..]
4306 .iter()
4307 .any(|projection| projection != &matching_projections[0])
4308 {
4309 return None;
4310 }
4311
4312 let Expression::Column(projected_column) = &matching_projections[0] else {
4313 return None;
4314 };
4315 if !Self::identifier_names_match(&projected_column.name, &order_column.name) {
4316 return None;
4317 }
4318
4319 let qualifier = projected_column
4320 .table
4321 .clone()
4322 .or_else(|| Self::sole_tsql_ordering_source_qualifier(select))?;
4323 let mut resolved = order_column.as_ref().clone();
4324 resolved.table = Some(qualifier);
4325 Some(Expression::Column(Box::new(resolved)))
4326 }
4327
4328 fn resolve_tsql_null_ordering_for_select(&self, select: &Select) -> Option<Select> {
4329 if !matches!(
4330 self.config.dialect,
4331 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4332 ) || self.config.null_ordering_supported
4333 {
4334 return None;
4335 }
4336
4337 let order_by = select.order_by.as_ref()?;
4338 let grouping_order_is_constant = matches!(self.config.dialect, Some(DialectType::Fabric))
4339 && select
4340 .group_by
4341 .as_ref()
4342 .is_some_and(|group_by| !Self::group_by_has_multiple_grouping_levels(group_by));
4343 let mut resolved_expressions = Vec::with_capacity(order_by.expressions.len());
4344 let mut changed = false;
4345
4346 for mut ordered in order_by.expressions.iter().cloned() {
4347 if Self::ordered_requires_tsql_null_ordering_emulation(&ordered) {
4348 if let Some(index) = Self::positional_ordering_index(&ordered.this) {
4349 if let Some(resolved) =
4350 Self::resolve_positional_order_projection(&select.expressions, index)
4351 .or_else(|| {
4352 Self::resolve_single_subquery_star_projection(select, index)
4353 })
4354 {
4355 if resolved != ordered.this {
4356 ordered.this = resolved;
4357 changed = true;
4358 }
4359 }
4360 }
4361
4362 if let Some(resolved) =
4363 Self::resolve_duplicate_tsql_ordering_column(select, &ordered.this)
4364 {
4365 ordered.this = resolved;
4366 changed = true;
4367 }
4368 }
4369
4370 if grouping_order_is_constant && Self::is_direct_grouping_expression(&ordered.this) {
4374 changed = true;
4375 continue;
4376 }
4377
4378 resolved_expressions.push(ordered);
4379 }
4380
4381 if changed {
4382 let mut resolved_select = select.clone();
4383 resolved_select.order_by = if resolved_expressions.is_empty() {
4384 None
4385 } else {
4386 Some(OrderBy {
4387 expressions: resolved_expressions,
4388 siblings: order_by.siblings,
4389 comments: order_by.comments.clone(),
4390 })
4391 };
4392 Some(resolved_select)
4393 } else {
4394 None
4395 }
4396 }
4397
4398 fn resolve_distinct_order_projection(
4399 projections: &[Expression],
4400 order_expression: &Expression,
4401 ) -> Option<Expression> {
4402 for projection in projections {
4403 if let Expression::Alias(alias) = projection {
4404 if Self::expression_matches_identifier(order_expression, &alias.alias)
4405 || &alias.this == order_expression
4406 {
4407 return Some(alias.this.clone());
4408 }
4409 } else if projection == order_expression {
4410 return Some(projection.clone());
4411 } else if let Some(identifier) = Self::projection_output_identifier(projection) {
4412 if Self::expression_matches_identifier(order_expression, &identifier) {
4413 return Some(projection.clone());
4414 }
4415 }
4416 }
4417
4418 None
4419 }
4420
4421 fn fresh_polyglot_alias(base: &str, index: usize, used_names: &mut Vec<String>) -> String {
4422 let mut suffix = 0;
4423 loop {
4424 let candidate = if suffix == 0 {
4425 format!("{base}_{index}")
4426 } else {
4427 format!("{base}_{index}_{suffix}")
4428 };
4429
4430 if !used_names
4431 .iter()
4432 .any(|name| name.eq_ignore_ascii_case(&candidate))
4433 {
4434 used_names.push(candidate.clone());
4435 return candidate;
4436 }
4437
4438 suffix += 1;
4439 }
4440 }
4441
4442 fn tsql_null_ordering_case(expression: Expression) -> Expression {
4443 Expression::Case(Box::new(Case {
4444 operand: None,
4445 whens: vec![(
4446 Expression::IsNull(Box::new(IsNull {
4447 this: expression,
4448 not: false,
4449 postfix_form: false,
4450 })),
4451 Expression::number(1),
4452 )],
4453 else_: Some(Expression::number(0)),
4454 comments: Vec::new(),
4455 inferred_type: None,
4456 }))
4457 }
4458
4459 fn try_build_tsql_distinct_null_ordering_wrapper(&self, select: &Select) -> Option<Select> {
4460 let order_by = select.order_by.as_ref()?;
4461
4462 if order_by.siblings
4463 || select.distinct_on.is_some()
4464 || select.distribute_by.is_some()
4465 || select.cluster_by.is_some()
4466 || select.sort_by.is_some()
4467 || select.limit.is_some()
4468 || select.offset.is_some()
4469 || select.limit_by.is_some()
4470 || select.fetch.is_some()
4471 || select.top.is_some()
4472 || select.settings.is_some()
4473 || select.format.is_some()
4474 || select.kind.is_some()
4475 || select.hint.is_some()
4476 || select.into.is_some()
4477 || !select.locks.is_empty()
4478 || !select.for_xml.is_empty()
4479 || !select.for_json.is_empty()
4480 || !select.operation_modifiers.is_empty()
4481 || select.option.is_some()
4482 || select.exclude.is_some()
4483 {
4484 return None;
4485 }
4486
4487 let projection_identifiers: Vec<_> = select
4488 .expressions
4489 .iter()
4490 .map(Self::projection_output_identifier)
4491 .collect::<Option<_>>()?;
4492 let mut used_names: Vec<_> = projection_identifiers
4493 .iter()
4494 .map(|identifier| identifier.name.clone())
4495 .collect();
4496
4497 let mut inner = select.clone();
4498 inner.order_by = None;
4499
4500 let outer_with = inner.with.take();
4501 let outer_leading_comments = std::mem::take(&mut inner.leading_comments);
4502 let outer_post_select_comments = std::mem::take(&mut inner.post_select_comments);
4503
4504 let mut outer_order_expressions = Vec::with_capacity(order_by.expressions.len() * 2);
4505 for (index, ordered) in order_by.expressions.iter().enumerate() {
4506 if ordered.with_fill.is_some() {
4507 return None;
4508 }
4509
4510 let sort_expression =
4511 Self::resolve_distinct_order_projection(&select.expressions, &ordered.this)?;
4512
4513 if Self::ordered_requires_tsql_null_ordering_emulation(ordered) {
4514 let null_alias =
4515 Self::fresh_polyglot_alias("_polyglot_order_null", index, &mut used_names);
4516 inner.expressions.push(
4517 Self::tsql_null_ordering_case(sort_expression.clone())
4518 .alias(null_alias.clone()),
4519 );
4520 outer_order_expressions.push(Ordered {
4521 this: Expression::column(null_alias),
4522 desc: ordered.nulls_first == Some(true),
4523 nulls_first: None,
4524 explicit_asc: false,
4525 with_fill: None,
4526 });
4527 }
4528
4529 let key_alias =
4530 Self::fresh_polyglot_alias("_polyglot_order_key", index, &mut used_names);
4531 inner
4532 .expressions
4533 .push(sort_expression.alias(key_alias.clone()));
4534 outer_order_expressions.push(Ordered {
4535 this: Expression::column(key_alias),
4536 desc: ordered.desc,
4537 nulls_first: None,
4538 explicit_asc: ordered.explicit_asc,
4539 with_fill: None,
4540 });
4541 }
4542
4543 let subquery = Subquery {
4544 this: Expression::Select(Box::new(inner)),
4545 alias: Some(Identifier::new("_polyglot_distinct_order")),
4546 column_aliases: Vec::new(),
4547 alias_explicit_as: true,
4548 alias_keyword: None,
4549 order_by: None,
4550 limit: None,
4551 offset: None,
4552 distribute_by: None,
4553 sort_by: None,
4554 cluster_by: None,
4555 lateral: false,
4556 modifiers_inside: false,
4557 trailing_comments: Vec::new(),
4558 inferred_type: None,
4559 };
4560
4561 let mut outer = Select::new();
4562 outer.with = outer_with;
4563 outer.leading_comments = outer_leading_comments;
4564 outer.post_select_comments = outer_post_select_comments;
4565 outer.expressions = projection_identifiers
4566 .into_iter()
4567 .map(Self::column_expression)
4568 .collect();
4569 outer.from = Some(From {
4570 expressions: vec![Expression::Subquery(Box::new(subquery))],
4571 });
4572 outer.order_by = Some(OrderBy {
4573 expressions: outer_order_expressions,
4574 siblings: false,
4575 comments: order_by.comments.clone(),
4576 });
4577
4578 Some(outer)
4579 }
4580
4581 fn generate_select(&mut self, select: &Select) -> Result<()> {
4582 use crate::dialects::DialectType;
4583
4584 if let Some(resolved_select) = self.resolve_tsql_null_ordering_for_select(select) {
4585 return self.generate_select(&resolved_select);
4586 }
4587
4588 if self.should_handle_tsql_distinct_null_ordering(select) {
4589 if let Some(wrapped_select) = self.try_build_tsql_distinct_null_ordering_wrapper(select)
4590 {
4591 return self.generate_select(&wrapped_select);
4592 }
4593
4594 self.unsupported(
4595 "SELECT DISTINCT with emulated NULL ordering is not supported for TSQL/Fabric",
4596 )?;
4597 }
4598
4599 if let Some(exclude) = &select.exclude {
4603 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4604 let mut inner_select = select.clone();
4606 inner_select.exclude = None;
4607 let inner_expr = Expression::Select(Box::new(inner_select));
4608
4609 let subquery = crate::expressions::Subquery {
4611 this: inner_expr,
4612 alias: None,
4613 column_aliases: Vec::new(),
4614 alias_explicit_as: false,
4615 alias_keyword: None,
4616 order_by: None,
4617 limit: None,
4618 offset: None,
4619 distribute_by: None,
4620 sort_by: None,
4621 cluster_by: None,
4622 lateral: false,
4623 modifiers_inside: false,
4624 trailing_comments: Vec::new(),
4625 inferred_type: None,
4626 };
4627
4628 let star = Expression::Star(crate::expressions::Star {
4630 table: None,
4631 except: Some(
4632 exclude
4633 .iter()
4634 .map(|e| match e {
4635 Expression::Column(col) => col.name.clone(),
4636 Expression::Identifier(id) => id.clone(),
4637 _ => crate::expressions::Identifier::new("unknown".to_string()),
4638 })
4639 .collect(),
4640 ),
4641 replace: None,
4642 rename: None,
4643 trailing_comments: Vec::new(),
4644 span: None,
4645 });
4646
4647 let outer_select = Select {
4648 expressions: vec![star],
4649 from: Some(crate::expressions::From {
4650 expressions: vec![Expression::Subquery(Box::new(subquery))],
4651 }),
4652 ..Select::new()
4653 };
4654
4655 return self.generate_select(&outer_select);
4656 }
4657 }
4658
4659 for comment in &select.leading_comments {
4661 self.write_formatted_comment(comment);
4662 self.write(" ");
4663 }
4664
4665 if let Some(with) = &select.with {
4667 self.generate_with(with)?;
4668 if self.config.pretty {
4669 self.write_newline();
4670 self.write_indent();
4671 } else {
4672 self.write_space();
4673 }
4674 }
4675
4676 for comment in &select.post_select_comments {
4679 self.write_formatted_comment(comment);
4680 self.write(" ");
4681 }
4682
4683 self.write_keyword("SELECT");
4684
4685 if let Some(hint) = &select.hint {
4687 self.generate_hint(hint)?;
4688 }
4689
4690 let use_top_from_limit = matches!(
4694 self.config.dialect,
4695 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4696 ) && select.top.is_none()
4697 && select
4698 .limit
4699 .as_ref()
4700 .is_some_and(|limit| !Self::is_noop_limit_expr(&limit.this))
4701 && select.offset.is_none(); let is_top_dialect = matches!(
4706 self.config.dialect,
4707 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4708 );
4709 let keep_top_verbatim = !is_top_dialect
4710 && select.limit.is_none()
4711 && select
4712 .top
4713 .as_ref()
4714 .map_or(false, |top| top.percent || top.with_ties);
4715
4716 if select.distinct && (is_top_dialect || select.top.is_some()) {
4717 self.write_space();
4718 self.write_keyword("DISTINCT");
4719 }
4720
4721 if is_top_dialect || keep_top_verbatim {
4722 if let Some(top) = &select.top {
4723 self.write_space();
4724 self.write_keyword("TOP");
4725 if top.parenthesized {
4726 if matches!(&top.this, Expression::Subquery(_) | Expression::Paren(_)) {
4727 self.write_space();
4728 self.generate_expression(&top.this)?;
4729 } else {
4730 self.write(" (");
4731 self.generate_expression(&top.this)?;
4732 self.write(")");
4733 }
4734 } else {
4735 self.write_space();
4736 self.generate_expression(&top.this)?;
4737 }
4738 if top.percent {
4739 self.write_space();
4740 self.write_keyword("PERCENT");
4741 }
4742 if top.with_ties {
4743 self.write_space();
4744 self.write_keyword("WITH TIES");
4745 }
4746 } else if use_top_from_limit {
4747 if let Some(limit) = &select.limit {
4749 self.write_space();
4750 self.write_keyword("TOP");
4751 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4753 if is_simple_literal {
4754 self.write_space();
4755 self.generate_expression(&limit.this)?;
4756 } else {
4757 self.write(" (");
4758 self.generate_expression(&limit.this)?;
4759 self.write(")");
4760 }
4761 }
4762 }
4763 }
4764
4765 if select.distinct && !is_top_dialect && select.top.is_none() {
4766 self.write_space();
4767 self.write_keyword("DISTINCT");
4768 }
4769
4770 if let Some(distinct_on) = &select.distinct_on {
4772 self.write_space();
4773 self.write_keyword("ON");
4774 self.write(" (");
4775 for (i, expr) in distinct_on.iter().enumerate() {
4776 if i > 0 {
4777 self.write(", ");
4778 }
4779 self.generate_expression(expr)?;
4780 }
4781 self.write(")");
4782 }
4783
4784 for modifier in &select.operation_modifiers {
4786 self.write_space();
4787 self.write_keyword(modifier);
4788 }
4789
4790 if let Some(kind) = &select.kind {
4792 self.write_space();
4793 self.write_keyword("AS");
4794 self.write_space();
4795 self.write_keyword(kind);
4796 }
4797
4798 if !select.expressions.is_empty() {
4800 if self.config.pretty {
4801 self.write_newline();
4802 self.indent_level += 1;
4803 } else {
4804 self.write_space();
4805 }
4806 }
4807
4808 for (i, expr) in select.expressions.iter().enumerate() {
4809 if i > 0 {
4810 self.write(",");
4811 if self.config.pretty {
4812 self.write_newline();
4813 } else {
4814 self.write_space();
4815 }
4816 }
4817 if self.config.pretty {
4818 self.write_indent();
4819 }
4820 self.generate_expression(expr)?;
4821 }
4822
4823 if self.config.pretty && !select.expressions.is_empty() {
4824 self.indent_level -= 1;
4825 }
4826
4827 if let Some(exclude) = &select.exclude {
4832 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4833 self.write_space();
4834 self.write_keyword("EXCLUDE");
4835 self.write(" (");
4836 for (i, col) in exclude.iter().enumerate() {
4837 if i > 0 {
4838 self.write(", ");
4839 }
4840 self.generate_expression(col)?;
4841 }
4842 self.write(")");
4843 }
4844 }
4845
4846 if let Some(into) = &select.into {
4849 if self.config.pretty {
4850 self.write_newline();
4851 self.write_indent();
4852 } else {
4853 self.write_space();
4854 }
4855 if into.bulk_collect {
4856 self.write_keyword("BULK COLLECT INTO");
4857 } else {
4858 self.write_keyword("INTO");
4859 }
4860 if into.temporary {
4861 self.write_space();
4862 self.write_keyword("TEMPORARY");
4863 }
4864 if into.unlogged {
4865 self.write_space();
4866 self.write_keyword("UNLOGGED");
4867 }
4868 self.write_space();
4869 if !into.expressions.is_empty() {
4871 for (i, expr) in into.expressions.iter().enumerate() {
4872 if i > 0 {
4873 self.write(", ");
4874 }
4875 self.generate_expression(expr)?;
4876 }
4877 } else {
4878 self.generate_expression(&into.this)?;
4879 }
4880 }
4881
4882 if let Some(from) = &select.from {
4884 if self.config.pretty {
4885 self.write_newline();
4886 self.write_indent();
4887 } else {
4888 self.write_space();
4889 }
4890 self.write_keyword("FROM");
4891 self.write_space();
4892
4893 let has_tablesample = from
4898 .expressions
4899 .iter()
4900 .any(|e| matches!(e, Expression::TableSample(_)));
4901 let is_cross_join_dialect = matches!(
4902 self.config.dialect,
4903 Some(DialectType::BigQuery)
4904 | Some(DialectType::Hive)
4905 | Some(DialectType::Spark)
4906 | Some(DialectType::Databricks)
4907 | Some(DialectType::SQLite)
4908 | Some(DialectType::ClickHouse)
4909 );
4910 let source_is_same_as_target = self.config.source_dialect.is_some()
4913 && self.config.source_dialect == self.config.dialect;
4914 let source_is_cross_join_dialect = matches!(
4915 self.config.source_dialect,
4916 Some(DialectType::BigQuery)
4917 | Some(DialectType::Hive)
4918 | Some(DialectType::Spark)
4919 | Some(DialectType::Databricks)
4920 | Some(DialectType::SQLite)
4921 | Some(DialectType::ClickHouse)
4922 );
4923 let use_cross_join = !has_tablesample
4924 && is_cross_join_dialect
4925 && (source_is_same_as_target
4926 || source_is_cross_join_dialect
4927 || self.config.source_dialect.is_none());
4928
4929 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4931
4932 for (i, expr) in from.expressions.iter().enumerate() {
4933 if i > 0 {
4934 if use_cross_join {
4935 self.write(" CROSS JOIN ");
4936 } else {
4937 self.write(", ");
4938 }
4939 }
4940 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4941 self.write("(");
4942 self.generate_expression(expr)?;
4943 self.write(")");
4944 } else {
4945 self.generate_expression(expr)?;
4946 }
4947 let leading = Self::extract_table_leading_comments(expr);
4950 for comment in &leading {
4951 self.write_space();
4952 self.write_formatted_comment(comment);
4953 }
4954 }
4955 }
4956
4957 if self.config.pretty {
4961 self.generate_joins_with_nesting(&select.joins)?;
4962 } else {
4963 for join in &select.joins {
4964 self.generate_join(join)?;
4965 }
4966 for join in select.joins.iter().rev() {
4968 if join.deferred_condition {
4969 self.generate_join_condition(join)?;
4970 }
4971 }
4972 }
4973
4974 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4976 self.generate_lateral_view(lateral_view, lv_idx)?;
4977 }
4978
4979 if let Some(prewhere) = &select.prewhere {
4981 self.write_clause_condition("PREWHERE", prewhere)?;
4982 }
4983
4984 if let Some(where_clause) = &select.where_clause {
4986 self.write_clause_condition("WHERE", &where_clause.this)?;
4987 }
4988
4989 if let Some(connect) = &select.connect {
4991 self.generate_connect(connect)?;
4992 }
4993
4994 if let Some(group_by) = &select.group_by {
4996 if self.config.pretty {
4997 for comment in &group_by.comments {
4999 self.write_newline();
5000 self.write_indent();
5001 self.write_formatted_comment(comment);
5002 }
5003 self.write_newline();
5004 self.write_indent();
5005 } else {
5006 self.write_space();
5007 for comment in &group_by.comments {
5009 self.write_formatted_comment(comment);
5010 self.write_space();
5011 }
5012 }
5013 let clickhouse_bare_modifiers =
5014 matches!(self.config.dialect, Some(DialectType::ClickHouse))
5015 && group_by.all.is_none()
5016 && (group_by.totals || !group_by.expressions.is_empty())
5017 && group_by.expressions.iter().all(|expr| match expr {
5018 Expression::Cube(c) => c.expressions.is_empty(),
5019 Expression::Rollup(r) => r.expressions.is_empty(),
5020 _ => false,
5021 });
5022
5023 if clickhouse_bare_modifiers {
5024 let trailing_cube = group_by
5025 .expressions
5026 .iter()
5027 .any(|expr| matches!(expr, Expression::Cube(c) if c.expressions.is_empty()));
5028 let trailing_rollup = group_by
5029 .expressions
5030 .iter()
5031 .any(|expr| matches!(expr, Expression::Rollup(r) if r.expressions.is_empty()));
5032
5033 if trailing_cube {
5034 self.write_keyword("WITH CUBE");
5035 } else if trailing_rollup {
5036 self.write_keyword("WITH ROLLUP");
5037 }
5038
5039 if group_by.totals {
5040 if trailing_cube || trailing_rollup {
5041 self.write_space();
5042 }
5043 self.write_keyword("WITH TOTALS");
5044 }
5045 } else {
5046 self.write_keyword("GROUP BY");
5047 match group_by.all {
5049 Some(true) => {
5050 self.write_space();
5051 self.write_keyword("ALL");
5052 }
5053 Some(false) => {
5054 self.write_space();
5055 self.write_keyword("DISTINCT");
5056 }
5057 None => {}
5058 }
5059 if !group_by.expressions.is_empty() {
5060 let mut trailing_cube = false;
5063 let mut trailing_rollup = false;
5064 let mut plain_expressions: Vec<&Expression> = Vec::new();
5065 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
5066 let mut cube_expressions: Vec<&Expression> = Vec::new();
5067 let mut rollup_expressions: Vec<&Expression> = Vec::new();
5068
5069 for expr in &group_by.expressions {
5070 match expr {
5071 Expression::Cube(c) if c.expressions.is_empty() => {
5072 trailing_cube = true;
5073 }
5074 Expression::Rollup(r) if r.expressions.is_empty() => {
5075 trailing_rollup = true;
5076 }
5077 Expression::Function(f) if f.name == "CUBE" => {
5078 cube_expressions.push(expr);
5079 }
5080 Expression::Function(f) if f.name == "ROLLUP" => {
5081 rollup_expressions.push(expr);
5082 }
5083 Expression::Function(f) if f.name == "GROUPING SETS" => {
5084 grouping_sets_expressions.push(expr);
5085 }
5086 _ => {
5087 plain_expressions.push(expr);
5088 }
5089 }
5090 }
5091
5092 let mut regular_expressions: Vec<&Expression> = Vec::new();
5094 regular_expressions.extend(plain_expressions);
5095 regular_expressions.extend(grouping_sets_expressions);
5096 regular_expressions.extend(cube_expressions);
5097 regular_expressions.extend(rollup_expressions);
5098
5099 if self.config.pretty {
5100 self.write_newline();
5101 self.indent_level += 1;
5102 self.write_indent();
5103 } else {
5104 self.write_space();
5105 }
5106
5107 for (i, expr) in regular_expressions.iter().enumerate() {
5108 if i > 0 {
5109 if self.config.pretty {
5110 self.write(",");
5111 self.write_newline();
5112 self.write_indent();
5113 } else {
5114 self.write(", ");
5115 }
5116 }
5117 self.generate_expression(expr)?;
5118 }
5119
5120 if self.config.pretty {
5121 self.indent_level -= 1;
5122 }
5123
5124 if trailing_cube {
5126 self.write_space();
5127 self.write_keyword("WITH CUBE");
5128 } else if trailing_rollup {
5129 self.write_space();
5130 self.write_keyword("WITH ROLLUP");
5131 }
5132 }
5133
5134 if group_by.totals {
5136 self.write_space();
5137 self.write_keyword("WITH TOTALS");
5138 }
5139 }
5140 }
5141
5142 if let Some(having) = &select.having {
5144 if self.config.pretty {
5145 for comment in &having.comments {
5147 self.write_newline();
5148 self.write_indent();
5149 self.write_formatted_comment(comment);
5150 }
5151 } else {
5152 for comment in &having.comments {
5153 self.write_space();
5154 self.write_formatted_comment(comment);
5155 }
5156 }
5157 self.write_clause_condition("HAVING", &having.this)?;
5158 }
5159
5160 if select.qualify_after_window {
5162 if let Some(windows) = &select.windows {
5164 self.write_window_clause(windows)?;
5165 }
5166 if let Some(qualify) = &select.qualify {
5167 self.write_clause_condition("QUALIFY", &qualify.this)?;
5168 }
5169 } else {
5170 if let Some(qualify) = &select.qualify {
5172 self.write_clause_condition("QUALIFY", &qualify.this)?;
5173 }
5174 if let Some(windows) = &select.windows {
5175 self.write_window_clause(windows)?;
5176 }
5177 }
5178
5179 if let Some(distribute_by) = &select.distribute_by {
5181 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
5182 }
5183
5184 if let Some(cluster_by) = &select.cluster_by {
5186 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
5187 }
5188
5189 if let Some(sort_by) = &select.sort_by {
5191 self.write_order_clause("SORT BY", &sort_by.expressions)?;
5192 }
5193
5194 if let Some(order_by) = &select.order_by {
5196 if self.config.pretty {
5197 for comment in &order_by.comments {
5199 self.write_newline();
5200 self.write_indent();
5201 self.write_formatted_comment(comment);
5202 }
5203 } else {
5204 for comment in &order_by.comments {
5205 self.write_space();
5206 self.write_formatted_comment(comment);
5207 }
5208 }
5209 let keyword = if order_by.siblings {
5210 "ORDER SIBLINGS BY"
5211 } else {
5212 "ORDER BY"
5213 };
5214 self.write_order_clause(keyword, &order_by.expressions)?;
5215 }
5216
5217 if select.order_by.is_none()
5219 && select.fetch.is_some()
5220 && matches!(
5221 self.config.dialect,
5222 Some(DialectType::TSQL) | Some(DialectType::Fabric)
5223 )
5224 {
5225 if self.config.pretty {
5226 self.write_newline();
5227 self.write_indent();
5228 } else {
5229 self.write_space();
5230 }
5231 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
5232 }
5233
5234 let is_presto_like = matches!(
5239 self.config.dialect,
5240 Some(DialectType::Presto) | Some(DialectType::Trino)
5241 );
5242
5243 if is_presto_like && select.offset.is_some() {
5244 if let Some(offset) = &select.offset {
5246 if self.config.pretty {
5247 self.write_newline();
5248 self.write_indent();
5249 } else {
5250 self.write_space();
5251 }
5252 self.write_keyword("OFFSET");
5253 self.write_space();
5254 self.write_limit_expr(&offset.this)?;
5255 if offset.rows == Some(true) {
5256 self.write_space();
5257 self.write_keyword("ROWS");
5258 }
5259 }
5260 if let Some(limit) = &select.limit {
5261 if self.config.pretty {
5262 self.write_newline();
5263 self.write_indent();
5264 } else {
5265 self.write_space();
5266 }
5267 self.write_keyword("LIMIT");
5268 self.write_space();
5269 self.write_limit_expr(&limit.this)?;
5270 if limit.percent {
5271 self.write_space();
5272 self.write_keyword("PERCENT");
5273 }
5274 for comment in &limit.comments {
5276 self.write(" ");
5277 self.write_formatted_comment(comment);
5278 }
5279 }
5280 } else {
5281 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
5283 !fetch.percent
5284 && !fetch.with_ties
5285 && fetch.count.is_some()
5286 && matches!(
5287 self.config.dialect,
5288 Some(DialectType::Spark)
5289 | Some(DialectType::Hive)
5290 | Some(DialectType::DuckDB)
5291 | Some(DialectType::SQLite)
5292 | Some(DialectType::MySQL)
5293 | Some(DialectType::BigQuery)
5294 | Some(DialectType::Databricks)
5295 | Some(DialectType::StarRocks)
5296 | Some(DialectType::Doris)
5297 | Some(DialectType::Athena)
5298 | Some(DialectType::ClickHouse)
5299 | Some(DialectType::Redshift)
5300 )
5301 });
5302
5303 if let Some(limit) = &select.limit {
5305 if !matches!(
5307 self.config.dialect,
5308 Some(DialectType::TSQL) | Some(DialectType::Fabric)
5309 ) {
5310 if self.config.pretty {
5311 self.write_newline();
5312 self.write_indent();
5313 } else {
5314 self.write_space();
5315 }
5316 self.write_keyword("LIMIT");
5317 self.write_space();
5318 self.write_limit_expr(&limit.this)?;
5319 if limit.percent {
5320 self.write_space();
5321 self.write_keyword("PERCENT");
5322 }
5323 for comment in &limit.comments {
5325 self.write(" ");
5326 self.write_formatted_comment(comment);
5327 }
5328 }
5329 }
5330
5331 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
5333 if let Some(top) = &select.top {
5334 if !top.percent && !top.with_ties {
5335 if self.config.pretty {
5336 self.write_newline();
5337 self.write_indent();
5338 } else {
5339 self.write_space();
5340 }
5341 self.write_keyword("LIMIT");
5342 self.write_space();
5343 self.generate_expression(&top.this)?;
5344 }
5345 }
5346 }
5347
5348 if fetch_as_limit && select.offset.is_some() {
5351 if let Some(fetch) = &select.fetch {
5352 if self.config.pretty {
5353 self.write_newline();
5354 self.write_indent();
5355 } else {
5356 self.write_space();
5357 }
5358 self.write_keyword("LIMIT");
5359 self.write_space();
5360 self.generate_expression(fetch.count.as_ref().unwrap())?;
5361 }
5362 }
5363
5364 if let Some(offset) = &select.offset {
5368 if self.config.pretty {
5369 self.write_newline();
5370 self.write_indent();
5371 } else {
5372 self.write_space();
5373 }
5374 if matches!(
5375 self.config.dialect,
5376 Some(DialectType::TSQL) | Some(DialectType::Fabric)
5377 ) {
5378 self.write_keyword("OFFSET");
5380 self.write_space();
5381 self.write_limit_expr(&offset.this)?;
5382 self.write_space();
5383 self.write_keyword("ROWS");
5384 if let Some(limit) = &select.limit {
5388 if !Self::is_noop_limit_expr(&limit.this) {
5389 self.write_space();
5390 self.write_keyword("FETCH NEXT");
5391 self.write_space();
5392 self.write_limit_expr(&limit.this)?;
5393 self.write_space();
5394 self.write_keyword("ROWS ONLY");
5395 }
5396 }
5397 } else {
5398 self.write_keyword("OFFSET");
5399 self.write_space();
5400 self.write_limit_expr(&offset.this)?;
5401 if offset.rows == Some(true) {
5403 self.write_space();
5404 self.write_keyword("ROWS");
5405 }
5406 }
5407 }
5408 }
5409
5410 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5412 if let Some(limit_by) = &select.limit_by {
5413 if !limit_by.is_empty() {
5414 self.write_space();
5415 self.write_keyword("BY");
5416 self.write_space();
5417 for (i, expr) in limit_by.iter().enumerate() {
5418 if i > 0 {
5419 self.write(", ");
5420 }
5421 self.generate_expression(expr)?;
5422 }
5423 }
5424 }
5425 }
5426
5427 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5429 if let Some(settings) = &select.settings {
5430 if self.config.pretty {
5431 self.write_newline();
5432 self.write_indent();
5433 } else {
5434 self.write_space();
5435 }
5436 self.write_keyword("SETTINGS");
5437 self.write_space();
5438 for (i, expr) in settings.iter().enumerate() {
5439 if i > 0 {
5440 self.write(", ");
5441 }
5442 self.generate_expression(expr)?;
5443 }
5444 }
5445
5446 if let Some(format_expr) = &select.format {
5447 if self.config.pretty {
5448 self.write_newline();
5449 self.write_indent();
5450 } else {
5451 self.write_space();
5452 }
5453 self.write_keyword("FORMAT");
5454 self.write_space();
5455 self.generate_expression(format_expr)?;
5456 }
5457 }
5458
5459 if let Some(fetch) = &select.fetch {
5461 let fetch_already_as_limit = select.offset.is_some()
5463 && !fetch.percent
5464 && !fetch.with_ties
5465 && fetch.count.is_some()
5466 && matches!(
5467 self.config.dialect,
5468 Some(DialectType::Spark)
5469 | Some(DialectType::Hive)
5470 | Some(DialectType::DuckDB)
5471 | Some(DialectType::SQLite)
5472 | Some(DialectType::MySQL)
5473 | Some(DialectType::BigQuery)
5474 | Some(DialectType::Databricks)
5475 | Some(DialectType::StarRocks)
5476 | Some(DialectType::Doris)
5477 | Some(DialectType::Athena)
5478 | Some(DialectType::ClickHouse)
5479 | Some(DialectType::Redshift)
5480 );
5481
5482 if fetch_already_as_limit {
5483 } else {
5485 if self.config.pretty {
5486 self.write_newline();
5487 self.write_indent();
5488 } else {
5489 self.write_space();
5490 }
5491
5492 let use_limit = !fetch.percent
5494 && !fetch.with_ties
5495 && fetch.count.is_some()
5496 && matches!(
5497 self.config.dialect,
5498 Some(DialectType::Spark)
5499 | Some(DialectType::Hive)
5500 | Some(DialectType::DuckDB)
5501 | Some(DialectType::SQLite)
5502 | Some(DialectType::MySQL)
5503 | Some(DialectType::BigQuery)
5504 | Some(DialectType::Databricks)
5505 | Some(DialectType::StarRocks)
5506 | Some(DialectType::Doris)
5507 | Some(DialectType::Athena)
5508 | Some(DialectType::ClickHouse)
5509 | Some(DialectType::Redshift)
5510 );
5511
5512 if use_limit {
5513 self.write_keyword("LIMIT");
5514 self.write_space();
5515 self.generate_expression(fetch.count.as_ref().unwrap())?;
5516 } else {
5517 self.write_keyword("FETCH");
5518 self.write_space();
5519 self.write_keyword(&fetch.direction);
5520 if let Some(ref count) = fetch.count {
5521 self.write_space();
5522 self.generate_expression(count)?;
5523 }
5524 if fetch.percent {
5525 self.write_space();
5526 self.write_keyword("PERCENT");
5527 }
5528 if fetch.rows {
5529 self.write_space();
5530 self.write_keyword("ROWS");
5531 }
5532 if fetch.with_ties {
5533 self.write_space();
5534 self.write_keyword("WITH TIES");
5535 } else {
5536 self.write_space();
5537 self.write_keyword("ONLY");
5538 }
5539 }
5540 } }
5542
5543 if let Some(sample) = &select.sample {
5545 use crate::dialects::DialectType;
5546 if self.config.pretty {
5547 self.write_newline();
5548 } else {
5549 self.write_space();
5550 }
5551
5552 if sample.is_using_sample {
5553 self.write_keyword("USING SAMPLE");
5555 self.generate_sample_body(sample)?;
5556 } else {
5557 self.write_keyword("TABLESAMPLE");
5558
5559 let snowflake_bernoulli =
5561 matches!(self.config.dialect, Some(DialectType::Snowflake))
5562 && !sample.explicit_method;
5563 if snowflake_bernoulli {
5564 self.write_space();
5565 self.write_keyword("BERNOULLI");
5566 }
5567
5568 if matches!(sample.method, SampleMethod::Bucket) {
5570 self.write_space();
5571 self.write("(");
5572 self.write_keyword("BUCKET");
5573 self.write_space();
5574 if let Some(ref num) = sample.bucket_numerator {
5575 self.generate_expression(num)?;
5576 }
5577 self.write_space();
5578 self.write_keyword("OUT OF");
5579 self.write_space();
5580 if let Some(ref denom) = sample.bucket_denominator {
5581 self.generate_expression(denom)?;
5582 }
5583 if let Some(ref field) = sample.bucket_field {
5584 self.write_space();
5585 self.write_keyword("ON");
5586 self.write_space();
5587 self.generate_expression(field)?;
5588 }
5589 self.write(")");
5590 } else if sample.unit_after_size {
5591 if sample.explicit_method && sample.method_before_size {
5593 self.write_space();
5594 match sample.method {
5595 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5596 SampleMethod::System => self.write_keyword("SYSTEM"),
5597 SampleMethod::Block => self.write_keyword("BLOCK"),
5598 SampleMethod::Row => self.write_keyword("ROW"),
5599 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5600 _ => {}
5601 }
5602 }
5603 self.write(" (");
5604 self.generate_expression(&sample.size)?;
5605 self.write_space();
5606 match sample.method {
5607 SampleMethod::Percent => self.write_keyword("PERCENT"),
5608 SampleMethod::Row => self.write_keyword("ROWS"),
5609 SampleMethod::Reservoir => self.write_keyword("ROWS"),
5610 _ => {
5611 self.write_keyword("PERCENT");
5612 }
5613 }
5614 self.write(")");
5615 } else {
5616 self.write_space();
5618 match sample.method {
5619 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5620 SampleMethod::System => self.write_keyword("SYSTEM"),
5621 SampleMethod::Block => self.write_keyword("BLOCK"),
5622 SampleMethod::Row => self.write_keyword("ROW"),
5623 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
5624 SampleMethod::Bucket => {}
5625 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5626 }
5627 self.write(" (");
5628 self.generate_expression(&sample.size)?;
5629 if matches!(sample.method, SampleMethod::Percent) {
5630 self.write_space();
5631 self.write_keyword("PERCENT");
5632 }
5633 self.write(")");
5634 }
5635 }
5636
5637 if let Some(seed) = &sample.seed {
5638 self.write_space();
5639 let use_seed = sample.use_seed_keyword
5641 && !matches!(
5642 self.config.dialect,
5643 Some(crate::dialects::DialectType::Databricks)
5644 | Some(crate::dialects::DialectType::Spark)
5645 );
5646 if use_seed {
5647 self.write_keyword("SEED");
5648 } else {
5649 self.write_keyword("REPEATABLE");
5650 }
5651 self.write(" (");
5652 self.generate_expression(seed)?;
5653 self.write(")");
5654 }
5655 }
5656
5657 if self.config.locking_reads_supported {
5660 for lock in &select.locks {
5661 if self.config.pretty {
5662 self.write_newline();
5663 self.write_indent();
5664 } else {
5665 self.write_space();
5666 }
5667 self.generate_lock(lock)?;
5668 }
5669 }
5670
5671 if !select.for_xml.is_empty() {
5673 if self.config.pretty {
5674 self.write_newline();
5675 self.write_indent();
5676 } else {
5677 self.write_space();
5678 }
5679 self.write_keyword("FOR XML");
5680 for (i, opt) in select.for_xml.iter().enumerate() {
5681 if self.config.pretty {
5682 if i > 0 {
5683 self.write(",");
5684 }
5685 self.write_newline();
5686 self.write_indent();
5687 self.write(" "); } else {
5689 if i > 0 {
5690 self.write(",");
5691 }
5692 self.write_space();
5693 }
5694 self.generate_for_xml_option(opt)?;
5695 }
5696 }
5697
5698 if !select.for_json.is_empty()
5700 && matches!(
5701 self.config.dialect,
5702 None | Some(DialectType::TSQL) | Some(DialectType::Fabric)
5703 )
5704 {
5705 if self.config.pretty {
5706 self.write_newline();
5707 self.write_indent();
5708 } else {
5709 self.write_space();
5710 }
5711 self.write_keyword("FOR JSON");
5712 for (i, opt) in select.for_json.iter().enumerate() {
5713 if self.config.pretty {
5714 if i > 0 {
5715 self.write(",");
5716 }
5717 self.write_newline();
5718 self.write_indent();
5719 self.write(" "); } else {
5721 if i > 0 {
5722 self.write(",");
5723 }
5724 self.write_space();
5725 }
5726 self.generate_for_xml_option(opt)?;
5727 }
5728 }
5729
5730 if let Some(ref option) = select.option {
5732 if matches!(
5733 self.config.dialect,
5734 Some(crate::dialects::DialectType::TSQL)
5735 | Some(crate::dialects::DialectType::Fabric)
5736 ) {
5737 self.write_space();
5738 self.write(option);
5739 }
5740 }
5741
5742 Ok(())
5743 }
5744
5745 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5747 match opt {
5748 Expression::QueryOption(qo) => {
5749 if let Expression::Var(var) = &*qo.this {
5751 self.write(&var.this);
5752 } else {
5753 self.generate_expression(&qo.this)?;
5754 }
5755 if let Some(expr) = &qo.expression {
5757 self.write("(");
5758 self.generate_expression(expr)?;
5759 self.write(")");
5760 }
5761 }
5762 _ => {
5763 self.generate_expression(opt)?;
5764 }
5765 }
5766 Ok(())
5767 }
5768
5769 fn generate_with(&mut self, with: &With) -> Result<()> {
5770 use crate::dialects::DialectType;
5771
5772 for comment in &with.leading_comments {
5774 self.write_formatted_comment(comment);
5775 self.write(" ");
5776 }
5777 self.write_keyword("WITH");
5778 if with.recursive && self.config.cte_recursive_keyword_required {
5779 self.write_space();
5780 self.write_keyword("RECURSIVE");
5781 }
5782 self.write_space();
5783
5784 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5786
5787 for (i, cte) in with.ctes.iter().enumerate() {
5788 if i > 0 {
5789 self.write(",");
5790 if self.config.pretty {
5791 self.write_space();
5792 } else {
5793 self.write(" ");
5794 }
5795 }
5796 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5797 self.generate_expression(&cte.this)?;
5798 self.write_space();
5799 self.write_keyword("AS");
5800 self.write_space();
5801 self.generate_identifier(&cte.alias)?;
5802 continue;
5803 }
5804 self.generate_identifier(&cte.alias)?;
5805 for comment in &cte.comments {
5807 self.write_space();
5808 self.write_formatted_comment(comment);
5809 }
5810 if !cte.columns.is_empty() && !skip_cte_columns {
5811 self.write("(");
5812 for (j, col) in cte.columns.iter().enumerate() {
5813 if j > 0 {
5814 self.write(", ");
5815 }
5816 self.generate_identifier(col)?;
5817 }
5818 self.write(")");
5819 }
5820 if !cte.key_expressions.is_empty() {
5822 self.write_space();
5823 self.write_keyword("USING KEY");
5824 self.write(" (");
5825 for (i, key) in cte.key_expressions.iter().enumerate() {
5826 if i > 0 {
5827 self.write(", ");
5828 }
5829 self.generate_identifier(key)?;
5830 }
5831 self.write(")");
5832 }
5833 self.write_space();
5834 self.write_keyword("AS");
5835 if let Some(materialized) = cte.materialized {
5837 self.write_space();
5838 if materialized {
5839 self.write_keyword("MATERIALIZED");
5840 } else {
5841 self.write_keyword("NOT MATERIALIZED");
5842 }
5843 }
5844 self.write(" (");
5845 if self.config.pretty {
5846 self.write_newline();
5847 self.indent_level += 1;
5848 self.write_indent();
5849 }
5850 let wrap_values_in_select = matches!(
5853 self.config.dialect,
5854 Some(DialectType::Spark) | Some(DialectType::Databricks)
5855 ) && matches!(&cte.this, Expression::Values(_));
5856
5857 if wrap_values_in_select {
5858 self.write_keyword("SELECT");
5859 self.write(" * ");
5860 self.write_keyword("FROM");
5861 self.write_space();
5862 }
5863 self.generate_expression(&cte.this)?;
5864 if self.config.pretty {
5865 self.write_newline();
5866 self.indent_level -= 1;
5867 self.write_indent();
5868 }
5869 self.write(")");
5870 }
5871
5872 if let Some(search) = &with.search {
5874 self.write_space();
5875 self.generate_expression(search)?;
5876 }
5877
5878 Ok(())
5879 }
5880
5881 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5885 let mut i = 0;
5886 while i < joins.len() {
5887 if joins[i].deferred_condition {
5888 let parent_group = joins[i].nesting_group;
5889
5890 self.generate_join_without_condition(&joins[i])?;
5893
5894 let child_start = i + 1;
5896 let mut child_end = child_start;
5897 while child_end < joins.len()
5898 && !joins[child_end].deferred_condition
5899 && joins[child_end].nesting_group == parent_group
5900 {
5901 child_end += 1;
5902 }
5903
5904 if child_start < child_end {
5906 self.indent_level += 1;
5907 for j in child_start..child_end {
5908 self.generate_join(&joins[j])?;
5909 }
5910 self.indent_level -= 1;
5911 }
5912
5913 self.generate_join_condition(&joins[i])?;
5915
5916 i = child_end;
5917 } else {
5918 self.generate_join(&joins[i])?;
5920 i += 1;
5921 }
5922 }
5923 Ok(())
5924 }
5925
5926 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5929 let mut join_copy = join.clone();
5932 join_copy.on = None;
5933 join_copy.using = Vec::new();
5934 join_copy.deferred_condition = false;
5935 self.generate_join(&join_copy)
5936 }
5937
5938 fn generate_join(&mut self, join: &Join) -> Result<()> {
5939 if join.kind == JoinKind::Implicit {
5941 self.write(",");
5942 if self.config.pretty {
5943 self.write_newline();
5944 self.write_indent();
5945 } else {
5946 self.write_space();
5947 }
5948 self.generate_expression(&join.this)?;
5949 return Ok(());
5950 }
5951
5952 if self.config.pretty {
5953 self.write_newline();
5954 self.write_indent();
5955 } else {
5956 self.write_space();
5957 }
5958
5959 let hint_str = if self.config.join_hints {
5962 join.join_hint
5963 .as_ref()
5964 .map(|h| format!(" {}", h))
5965 .unwrap_or_default()
5966 } else {
5967 String::new()
5968 };
5969
5970 let clickhouse_join_keyword =
5971 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5972 if let Some(hint) = &join.join_hint {
5973 let mut global = false;
5974 let mut strictness: Option<&'static str> = None;
5975 for part in hint.split_whitespace() {
5976 if part.eq_ignore_ascii_case("GLOBAL") {
5977 global = true;
5978 } else if part.eq_ignore_ascii_case("ALL") {
5979 strictness = Some("ALL");
5980 } else if part.eq_ignore_ascii_case("ANY") {
5981 strictness = Some("ANY");
5982 } else if part.eq_ignore_ascii_case("ASOF") {
5983 strictness = Some("ASOF");
5984 } else if part.eq_ignore_ascii_case("SEMI") {
5985 strictness = Some("SEMI");
5986 } else if part.eq_ignore_ascii_case("ANTI") {
5987 strictness = Some("ANTI");
5988 }
5989 }
5990
5991 if global || strictness.is_some() {
5992 let join_type = match join.kind {
5993 JoinKind::Left => {
5994 if join.use_outer_keyword {
5995 "LEFT OUTER"
5996 } else if join.use_inner_keyword {
5997 "LEFT INNER"
5998 } else {
5999 "LEFT"
6000 }
6001 }
6002 JoinKind::Right => {
6003 if join.use_outer_keyword {
6004 "RIGHT OUTER"
6005 } else if join.use_inner_keyword {
6006 "RIGHT INNER"
6007 } else {
6008 "RIGHT"
6009 }
6010 }
6011 JoinKind::Full => {
6012 if join.use_outer_keyword {
6013 "FULL OUTER"
6014 } else {
6015 "FULL"
6016 }
6017 }
6018 JoinKind::Inner => {
6019 if join.use_inner_keyword {
6020 "INNER"
6021 } else {
6022 ""
6023 }
6024 }
6025 _ => "",
6026 };
6027
6028 let mut parts = Vec::new();
6029 if global {
6030 parts.push("GLOBAL");
6031 }
6032 if !join_type.is_empty() {
6033 parts.push(join_type);
6034 }
6035 if let Some(strict) = strictness {
6036 parts.push(strict);
6037 }
6038 parts.push("JOIN");
6039 Some(parts.join(" "))
6040 } else {
6041 None
6042 }
6043 } else {
6044 None
6045 }
6046 } else {
6047 None
6048 };
6049
6050 if !join.comments.is_empty() {
6054 if self.config.pretty {
6055 let trimmed = self.output.trim_end().len();
6060 self.output.truncate(trimmed);
6061 for comment in &join.comments {
6062 self.write_newline();
6063 self.write_indent();
6064 self.write_formatted_comment(comment);
6065 }
6066 self.write_newline();
6067 self.write_indent();
6068 } else {
6069 for comment in &join.comments {
6070 self.write_formatted_comment(comment);
6071 self.write_space();
6072 }
6073 }
6074 }
6075
6076 let directed_str = if join.directed { " DIRECTED" } else { "" };
6077
6078 if let Some(keyword) = clickhouse_join_keyword {
6079 self.write_keyword(&keyword);
6080 } else {
6081 match join.kind {
6082 JoinKind::Inner => {
6083 if join.use_inner_keyword {
6084 if hint_str.is_empty() && directed_str.is_empty() {
6085 self.write_keyword("INNER JOIN");
6086 } else {
6087 self.write_keyword("INNER");
6088 if !hint_str.is_empty() {
6089 self.write_keyword(&hint_str);
6090 }
6091 if !directed_str.is_empty() {
6092 self.write_keyword(directed_str);
6093 }
6094 self.write_keyword(" JOIN");
6095 }
6096 } else {
6097 if !hint_str.is_empty() {
6098 self.write_keyword(hint_str.trim());
6099 self.write_keyword(" ");
6100 }
6101 if !directed_str.is_empty() {
6102 self.write_keyword("DIRECTED ");
6103 }
6104 self.write_keyword("JOIN");
6105 }
6106 }
6107 JoinKind::Left => {
6108 if join.use_outer_keyword {
6109 if hint_str.is_empty() && directed_str.is_empty() {
6110 self.write_keyword("LEFT OUTER JOIN");
6111 } else {
6112 self.write_keyword("LEFT OUTER");
6113 if !hint_str.is_empty() {
6114 self.write_keyword(&hint_str);
6115 }
6116 if !directed_str.is_empty() {
6117 self.write_keyword(directed_str);
6118 }
6119 self.write_keyword(" JOIN");
6120 }
6121 } else if join.use_inner_keyword {
6122 if hint_str.is_empty() && directed_str.is_empty() {
6123 self.write_keyword("LEFT INNER JOIN");
6124 } else {
6125 self.write_keyword("LEFT INNER");
6126 if !hint_str.is_empty() {
6127 self.write_keyword(&hint_str);
6128 }
6129 if !directed_str.is_empty() {
6130 self.write_keyword(directed_str);
6131 }
6132 self.write_keyword(" JOIN");
6133 }
6134 } else {
6135 if hint_str.is_empty() && directed_str.is_empty() {
6136 self.write_keyword("LEFT JOIN");
6137 } else {
6138 self.write_keyword("LEFT");
6139 if !hint_str.is_empty() {
6140 self.write_keyword(&hint_str);
6141 }
6142 if !directed_str.is_empty() {
6143 self.write_keyword(directed_str);
6144 }
6145 self.write_keyword(" JOIN");
6146 }
6147 }
6148 }
6149 JoinKind::Right => {
6150 if join.use_outer_keyword {
6151 if hint_str.is_empty() && directed_str.is_empty() {
6152 self.write_keyword("RIGHT OUTER JOIN");
6153 } else {
6154 self.write_keyword("RIGHT OUTER");
6155 if !hint_str.is_empty() {
6156 self.write_keyword(&hint_str);
6157 }
6158 if !directed_str.is_empty() {
6159 self.write_keyword(directed_str);
6160 }
6161 self.write_keyword(" JOIN");
6162 }
6163 } else if join.use_inner_keyword {
6164 if hint_str.is_empty() && directed_str.is_empty() {
6165 self.write_keyword("RIGHT INNER JOIN");
6166 } else {
6167 self.write_keyword("RIGHT INNER");
6168 if !hint_str.is_empty() {
6169 self.write_keyword(&hint_str);
6170 }
6171 if !directed_str.is_empty() {
6172 self.write_keyword(directed_str);
6173 }
6174 self.write_keyword(" JOIN");
6175 }
6176 } else {
6177 if hint_str.is_empty() && directed_str.is_empty() {
6178 self.write_keyword("RIGHT JOIN");
6179 } else {
6180 self.write_keyword("RIGHT");
6181 if !hint_str.is_empty() {
6182 self.write_keyword(&hint_str);
6183 }
6184 if !directed_str.is_empty() {
6185 self.write_keyword(directed_str);
6186 }
6187 self.write_keyword(" JOIN");
6188 }
6189 }
6190 }
6191 JoinKind::Full => {
6192 if join.use_outer_keyword {
6193 if hint_str.is_empty() && directed_str.is_empty() {
6194 self.write_keyword("FULL OUTER JOIN");
6195 } else {
6196 self.write_keyword("FULL OUTER");
6197 if !hint_str.is_empty() {
6198 self.write_keyword(&hint_str);
6199 }
6200 if !directed_str.is_empty() {
6201 self.write_keyword(directed_str);
6202 }
6203 self.write_keyword(" JOIN");
6204 }
6205 } else {
6206 if hint_str.is_empty() && directed_str.is_empty() {
6207 self.write_keyword("FULL JOIN");
6208 } else {
6209 self.write_keyword("FULL");
6210 if !hint_str.is_empty() {
6211 self.write_keyword(&hint_str);
6212 }
6213 if !directed_str.is_empty() {
6214 self.write_keyword(directed_str);
6215 }
6216 self.write_keyword(" JOIN");
6217 }
6218 }
6219 }
6220 JoinKind::Outer => {
6221 if directed_str.is_empty() {
6222 self.write_keyword("OUTER JOIN");
6223 } else {
6224 self.write_keyword("OUTER");
6225 self.write_keyword(directed_str);
6226 self.write_keyword(" JOIN");
6227 }
6228 }
6229 JoinKind::Cross => {
6230 if directed_str.is_empty() {
6231 self.write_keyword("CROSS JOIN");
6232 } else {
6233 self.write_keyword("CROSS");
6234 self.write_keyword(directed_str);
6235 self.write_keyword(" JOIN");
6236 }
6237 }
6238 JoinKind::Natural => {
6239 if join.use_inner_keyword {
6240 if directed_str.is_empty() {
6241 self.write_keyword("NATURAL INNER JOIN");
6242 } else {
6243 self.write_keyword("NATURAL INNER");
6244 self.write_keyword(directed_str);
6245 self.write_keyword(" JOIN");
6246 }
6247 } else {
6248 if directed_str.is_empty() {
6249 self.write_keyword("NATURAL JOIN");
6250 } else {
6251 self.write_keyword("NATURAL");
6252 self.write_keyword(directed_str);
6253 self.write_keyword(" JOIN");
6254 }
6255 }
6256 }
6257 JoinKind::NaturalLeft => {
6258 if join.use_outer_keyword {
6259 if directed_str.is_empty() {
6260 self.write_keyword("NATURAL LEFT OUTER JOIN");
6261 } else {
6262 self.write_keyword("NATURAL LEFT OUTER");
6263 self.write_keyword(directed_str);
6264 self.write_keyword(" JOIN");
6265 }
6266 } else {
6267 if directed_str.is_empty() {
6268 self.write_keyword("NATURAL LEFT JOIN");
6269 } else {
6270 self.write_keyword("NATURAL LEFT");
6271 self.write_keyword(directed_str);
6272 self.write_keyword(" JOIN");
6273 }
6274 }
6275 }
6276 JoinKind::NaturalRight => {
6277 if join.use_outer_keyword {
6278 if directed_str.is_empty() {
6279 self.write_keyword("NATURAL RIGHT OUTER JOIN");
6280 } else {
6281 self.write_keyword("NATURAL RIGHT OUTER");
6282 self.write_keyword(directed_str);
6283 self.write_keyword(" JOIN");
6284 }
6285 } else {
6286 if directed_str.is_empty() {
6287 self.write_keyword("NATURAL RIGHT JOIN");
6288 } else {
6289 self.write_keyword("NATURAL RIGHT");
6290 self.write_keyword(directed_str);
6291 self.write_keyword(" JOIN");
6292 }
6293 }
6294 }
6295 JoinKind::NaturalFull => {
6296 if join.use_outer_keyword {
6297 if directed_str.is_empty() {
6298 self.write_keyword("NATURAL FULL OUTER JOIN");
6299 } else {
6300 self.write_keyword("NATURAL FULL OUTER");
6301 self.write_keyword(directed_str);
6302 self.write_keyword(" JOIN");
6303 }
6304 } else {
6305 if directed_str.is_empty() {
6306 self.write_keyword("NATURAL FULL JOIN");
6307 } else {
6308 self.write_keyword("NATURAL FULL");
6309 self.write_keyword(directed_str);
6310 self.write_keyword(" JOIN");
6311 }
6312 }
6313 }
6314 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
6315 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
6316 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
6317 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
6318 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
6319 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
6320 JoinKind::CrossApply => {
6321 if matches!(
6323 self.config.dialect,
6324 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
6325 ) {
6326 self.write_keyword("CROSS APPLY");
6327 } else {
6328 self.write_keyword("INNER JOIN LATERAL");
6329 }
6330 }
6331 JoinKind::OuterApply => {
6332 if matches!(
6334 self.config.dialect,
6335 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
6336 ) {
6337 self.write_keyword("OUTER APPLY");
6338 } else {
6339 self.write_keyword("LEFT JOIN LATERAL");
6340 }
6341 }
6342 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
6343 JoinKind::AsOfLeft => {
6344 if join.use_outer_keyword {
6345 self.write_keyword("ASOF LEFT OUTER JOIN");
6346 } else {
6347 self.write_keyword("ASOF LEFT JOIN");
6348 }
6349 }
6350 JoinKind::AsOfRight => {
6351 if join.use_outer_keyword {
6352 self.write_keyword("ASOF RIGHT OUTER JOIN");
6353 } else {
6354 self.write_keyword("ASOF RIGHT JOIN");
6355 }
6356 }
6357 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
6358 JoinKind::LeftLateral => {
6359 if join.use_outer_keyword {
6360 self.write_keyword("LEFT OUTER LATERAL JOIN");
6361 } else {
6362 self.write_keyword("LEFT LATERAL JOIN");
6363 }
6364 }
6365 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
6366 JoinKind::Implicit => {
6367 use crate::dialects::DialectType;
6371 let is_cj_dialect = matches!(
6372 self.config.dialect,
6373 Some(DialectType::BigQuery)
6374 | Some(DialectType::Hive)
6375 | Some(DialectType::Spark)
6376 | Some(DialectType::Databricks)
6377 );
6378 let source_is_same = self.config.source_dialect.is_some()
6379 && self.config.source_dialect == self.config.dialect;
6380 let source_is_cj = matches!(
6381 self.config.source_dialect,
6382 Some(DialectType::BigQuery)
6383 | Some(DialectType::Hive)
6384 | Some(DialectType::Spark)
6385 | Some(DialectType::Databricks)
6386 );
6387 if is_cj_dialect
6388 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
6389 {
6390 self.write_keyword("CROSS JOIN");
6391 } else {
6392 self.output.truncate(self.output.trim_end().len());
6396 self.write(",");
6397 }
6398 }
6399 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
6400 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
6401 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
6402 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
6403 }
6404 }
6405
6406 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
6408 match &join.this {
6409 Expression::Tuple(t) if t.expressions.is_empty() => {}
6410 Expression::Tuple(t) => {
6411 self.write_space();
6412 for (i, item) in t.expressions.iter().enumerate() {
6413 if i > 0 {
6414 self.write(", ");
6415 }
6416 self.generate_expression(item)?;
6417 }
6418 }
6419 other => {
6420 self.write_space();
6421 self.generate_expression(other)?;
6422 }
6423 }
6424 } else {
6425 self.write_space();
6426 self.generate_expression(&join.this)?;
6427 }
6428
6429 if !join.deferred_condition {
6431 if let Some(match_cond) = &join.match_condition {
6433 self.write_space();
6434 self.write_keyword("MATCH_CONDITION");
6435 self.write(" (");
6436 self.generate_expression(match_cond)?;
6437 self.write(")");
6438 }
6439
6440 if let Some(on) = &join.on {
6441 if self.config.pretty {
6442 self.write_newline();
6443 self.indent_level += 1;
6444 self.write_indent();
6445 self.write_keyword("ON");
6446 self.write_space();
6447 self.generate_join_on_condition(on)?;
6448 self.indent_level -= 1;
6449 } else {
6450 self.write_space();
6451 self.write_keyword("ON");
6452 self.write_space();
6453 self.generate_expression(on)?;
6454 }
6455 }
6456
6457 if !join.using.is_empty() {
6458 if self.config.pretty {
6459 self.write_newline();
6460 self.indent_level += 1;
6461 self.write_indent();
6462 self.write_keyword("USING");
6463 self.write(" (");
6464 for (i, col) in join.using.iter().enumerate() {
6465 if i > 0 {
6466 self.write(", ");
6467 }
6468 self.generate_identifier(col)?;
6469 }
6470 self.write(")");
6471 self.indent_level -= 1;
6472 } else {
6473 self.write_space();
6474 self.write_keyword("USING");
6475 self.write(" (");
6476 for (i, col) in join.using.iter().enumerate() {
6477 if i > 0 {
6478 self.write(", ");
6479 }
6480 self.generate_identifier(col)?;
6481 }
6482 self.write(")");
6483 }
6484 }
6485 }
6486
6487 for pivot in &join.pivots {
6489 self.write_space();
6490 self.generate_expression(pivot)?;
6491 }
6492
6493 Ok(())
6494 }
6495
6496 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
6498 if let Some(match_cond) = &join.match_condition {
6500 self.write_space();
6501 self.write_keyword("MATCH_CONDITION");
6502 self.write(" (");
6503 self.generate_expression(match_cond)?;
6504 self.write(")");
6505 }
6506
6507 if let Some(on) = &join.on {
6508 if self.config.pretty {
6509 self.write_newline();
6510 self.indent_level += 1;
6511 self.write_indent();
6512 self.write_keyword("ON");
6513 self.write_space();
6514 self.generate_join_on_condition(on)?;
6516 self.indent_level -= 1;
6517 } else {
6518 self.write_space();
6519 self.write_keyword("ON");
6520 self.write_space();
6521 self.generate_expression(on)?;
6522 }
6523 }
6524
6525 if !join.using.is_empty() {
6526 if self.config.pretty {
6527 self.write_newline();
6528 self.indent_level += 1;
6529 self.write_indent();
6530 self.write_keyword("USING");
6531 self.write(" (");
6532 for (i, col) in join.using.iter().enumerate() {
6533 if i > 0 {
6534 self.write(", ");
6535 }
6536 self.generate_identifier(col)?;
6537 }
6538 self.write(")");
6539 self.indent_level -= 1;
6540 } else {
6541 self.write_space();
6542 self.write_keyword("USING");
6543 self.write(" (");
6544 for (i, col) in join.using.iter().enumerate() {
6545 if i > 0 {
6546 self.write(", ");
6547 }
6548 self.generate_identifier(col)?;
6549 }
6550 self.write(")");
6551 }
6552 }
6553
6554 for pivot in &join.pivots {
6556 self.write_space();
6557 self.generate_expression(pivot)?;
6558 }
6559
6560 Ok(())
6561 }
6562
6563 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
6565 if let Expression::And(and_op) = expr {
6566 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
6567 self.generate_expression(conditions[0])?;
6568 for condition in conditions.iter().skip(1) {
6569 self.write_newline();
6570 self.write_indent();
6571 self.write_keyword("AND");
6572 self.write_space();
6573 self.generate_expression(condition)?;
6574 }
6575 return Ok(());
6576 }
6577 }
6578
6579 self.generate_expression(expr)
6580 }
6581
6582 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
6583 self.write("(");
6585 self.generate_expression(&jt.left)?;
6586
6587 for join in &jt.joins {
6589 self.generate_join(join)?;
6590 }
6591
6592 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
6594 self.generate_lateral_view(lv, lv_idx)?;
6595 }
6596
6597 self.write(")");
6598
6599 if let Some(alias) = &jt.alias {
6601 self.write_space();
6602 self.write_keyword("AS");
6603 self.write_space();
6604 self.generate_identifier(alias)?;
6605 }
6606
6607 Ok(())
6608 }
6609
6610 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
6611 use crate::dialects::DialectType;
6612
6613 if self.config.pretty {
6614 self.write_newline();
6615 self.write_indent();
6616 } else {
6617 self.write_space();
6618 }
6619
6620 let use_lateral_join = matches!(
6623 self.config.dialect,
6624 Some(DialectType::PostgreSQL)
6625 | Some(DialectType::DuckDB)
6626 | Some(DialectType::Snowflake)
6627 | Some(DialectType::TSQL)
6628 | Some(DialectType::Presto)
6629 | Some(DialectType::Trino)
6630 | Some(DialectType::Athena)
6631 );
6632
6633 let use_unnest = matches!(
6635 self.config.dialect,
6636 Some(DialectType::DuckDB)
6637 | Some(DialectType::Presto)
6638 | Some(DialectType::Trino)
6639 | Some(DialectType::Athena)
6640 );
6641
6642 let (is_posexplode, is_inline, func_args) = match &lv.this {
6644 Expression::Explode(uf) => {
6645 (false, false, vec![uf.this.clone()])
6647 }
6648 Expression::Unnest(uf) => {
6649 let mut args = vec![uf.this.clone()];
6650 args.extend(uf.expressions.clone());
6651 (false, false, args)
6652 }
6653 Expression::Function(func) => {
6654 if func.name.eq_ignore_ascii_case("POSEXPLODE")
6655 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
6656 {
6657 (true, false, func.args.clone())
6658 } else if func.name.eq_ignore_ascii_case("INLINE") {
6659 (false, true, func.args.clone())
6660 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6661 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6662 {
6663 (false, false, func.args.clone())
6664 } else {
6665 (false, false, vec![])
6666 }
6667 }
6668 _ => (false, false, vec![]),
6669 };
6670
6671 if use_lateral_join {
6672 if lv.outer {
6674 self.write_keyword("LEFT JOIN LATERAL");
6675 } else {
6676 self.write_keyword("CROSS JOIN");
6677 }
6678 self.write_space();
6679
6680 if use_unnest && !func_args.is_empty() {
6681 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6684 func_args
6686 .iter()
6687 .map(|a| {
6688 if let Expression::Function(ref f) = a {
6689 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6690 return Expression::ArrayFunc(Box::new(
6691 crate::expressions::ArrayConstructor {
6692 expressions: f.args.clone(),
6693 bracket_notation: true,
6694 use_list_keyword: false,
6695 },
6696 ));
6697 }
6698 }
6699 a.clone()
6700 })
6701 .collect::<Vec<_>>()
6702 } else if matches!(
6703 self.config.dialect,
6704 Some(DialectType::Presto)
6705 | Some(DialectType::Trino)
6706 | Some(DialectType::Athena)
6707 ) {
6708 func_args
6710 .iter()
6711 .map(|a| {
6712 if let Expression::Function(ref f) = a {
6713 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6714 return Expression::ArrayFunc(Box::new(
6715 crate::expressions::ArrayConstructor {
6716 expressions: f.args.clone(),
6717 bracket_notation: true,
6718 use_list_keyword: false,
6719 },
6720 ));
6721 }
6722 }
6723 a.clone()
6724 })
6725 .collect::<Vec<_>>()
6726 } else {
6727 func_args
6728 };
6729
6730 if is_posexplode {
6732 self.write_keyword("LATERAL");
6733 self.write(" (");
6734 self.write_keyword("SELECT");
6735 self.write_space();
6736
6737 let pos_alias = if !lv.column_aliases.is_empty() {
6740 lv.column_aliases[0].clone()
6741 } else {
6742 Identifier::new("pos")
6743 };
6744 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6745 lv.column_aliases[1..].to_vec()
6746 } else {
6747 vec![Identifier::new("col")]
6748 };
6749
6750 self.generate_identifier(&pos_alias)?;
6752 self.write(" - 1");
6753 self.write_space();
6754 self.write_keyword("AS");
6755 self.write_space();
6756 self.generate_identifier(&pos_alias)?;
6757
6758 for data_col in &data_aliases {
6760 self.write(", ");
6761 self.generate_identifier(data_col)?;
6762 }
6763
6764 self.write_space();
6765 self.write_keyword("FROM");
6766 self.write_space();
6767 self.write_keyword("UNNEST");
6768 self.write("(");
6769 for (i, arg) in unnest_args.iter().enumerate() {
6770 if i > 0 {
6771 self.write(", ");
6772 }
6773 self.generate_expression(arg)?;
6774 }
6775 self.write(")");
6776 self.write_space();
6777 self.write_keyword("WITH ORDINALITY");
6778 self.write_space();
6779 self.write_keyword("AS");
6780 self.write_space();
6781
6782 let table_alias_ident = lv
6784 .table_alias
6785 .clone()
6786 .unwrap_or_else(|| Identifier::new("t"));
6787 self.generate_identifier(&table_alias_ident)?;
6788 self.write("(");
6789 for (i, data_col) in data_aliases.iter().enumerate() {
6790 if i > 0 {
6791 self.write(", ");
6792 }
6793 self.generate_identifier(data_col)?;
6794 }
6795 self.write(", ");
6796 self.generate_identifier(&pos_alias)?;
6797 self.write("))");
6798 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6799 self.write_keyword("LATERAL");
6801 self.write(" (");
6802 self.write_keyword("SELECT");
6803 self.write_space();
6804 self.write_keyword("UNNEST");
6805 self.write("(");
6806 for (i, arg) in unnest_args.iter().enumerate() {
6807 if i > 0 {
6808 self.write(", ");
6809 }
6810 self.generate_expression(arg)?;
6811 }
6812 self.write(", ");
6813 self.write_keyword("max_depth");
6814 self.write(" => 2))");
6815
6816 if let Some(alias) = &lv.table_alias {
6818 self.write_space();
6819 self.write_keyword("AS");
6820 self.write_space();
6821 self.generate_identifier(alias)?;
6822 if !lv.column_aliases.is_empty() {
6823 self.write("(");
6824 for (i, col) in lv.column_aliases.iter().enumerate() {
6825 if i > 0 {
6826 self.write(", ");
6827 }
6828 self.generate_identifier(col)?;
6829 }
6830 self.write(")");
6831 }
6832 } else if !lv.column_aliases.is_empty() {
6833 self.write_space();
6835 self.write_keyword("AS");
6836 self.write_space();
6837 self.write(&format!("_u_{}", lv_index));
6838 self.write("(");
6839 for (i, col) in lv.column_aliases.iter().enumerate() {
6840 if i > 0 {
6841 self.write(", ");
6842 }
6843 self.generate_identifier(col)?;
6844 }
6845 self.write(")");
6846 }
6847 } else {
6848 self.write_keyword("UNNEST");
6849 self.write("(");
6850 for (i, arg) in unnest_args.iter().enumerate() {
6851 if i > 0 {
6852 self.write(", ");
6853 }
6854 self.generate_expression(arg)?;
6855 }
6856 self.write(")");
6857
6858 if let Some(alias) = &lv.table_alias {
6860 self.write_space();
6861 self.write_keyword("AS");
6862 self.write_space();
6863 self.generate_identifier(alias)?;
6864 if !lv.column_aliases.is_empty() {
6865 self.write("(");
6866 for (i, col) in lv.column_aliases.iter().enumerate() {
6867 if i > 0 {
6868 self.write(", ");
6869 }
6870 self.generate_identifier(col)?;
6871 }
6872 self.write(")");
6873 }
6874 } else if !lv.column_aliases.is_empty() {
6875 self.write_space();
6876 self.write_keyword("AS");
6877 self.write(" t(");
6878 for (i, col) in lv.column_aliases.iter().enumerate() {
6879 if i > 0 {
6880 self.write(", ");
6881 }
6882 self.generate_identifier(col)?;
6883 }
6884 self.write(")");
6885 }
6886 }
6887 } else {
6888 if !lv.outer {
6890 self.write_keyword("LATERAL");
6891 self.write_space();
6892 }
6893 self.generate_expression(&lv.this)?;
6894
6895 if let Some(alias) = &lv.table_alias {
6897 self.write_space();
6898 self.write_keyword("AS");
6899 self.write_space();
6900 self.generate_identifier(alias)?;
6901 if !lv.column_aliases.is_empty() {
6902 self.write("(");
6903 for (i, col) in lv.column_aliases.iter().enumerate() {
6904 if i > 0 {
6905 self.write(", ");
6906 }
6907 self.generate_identifier(col)?;
6908 }
6909 self.write(")");
6910 }
6911 } else if !lv.column_aliases.is_empty() {
6912 self.write_space();
6913 self.write_keyword("AS");
6914 self.write(" t(");
6915 for (i, col) in lv.column_aliases.iter().enumerate() {
6916 if i > 0 {
6917 self.write(", ");
6918 }
6919 self.generate_identifier(col)?;
6920 }
6921 self.write(")");
6922 }
6923 }
6924
6925 if lv.outer {
6927 self.write_space();
6928 self.write_keyword("ON TRUE");
6929 }
6930 } else {
6931 self.write_keyword("LATERAL VIEW");
6933 if lv.outer {
6934 self.write_space();
6935 self.write_keyword("OUTER");
6936 }
6937 if self.config.pretty {
6938 self.write_newline();
6939 self.write_indent();
6940 } else {
6941 self.write_space();
6942 }
6943 self.generate_expression(&lv.this)?;
6944
6945 if let Some(alias) = &lv.table_alias {
6947 self.write_space();
6948 self.generate_identifier(alias)?;
6949 }
6950
6951 if !lv.column_aliases.is_empty() {
6953 self.write_space();
6954 self.write_keyword("AS");
6955 self.write_space();
6956 for (i, col) in lv.column_aliases.iter().enumerate() {
6957 if i > 0 {
6958 self.write(", ");
6959 }
6960 self.generate_identifier(col)?;
6961 }
6962 }
6963 }
6964
6965 Ok(())
6966 }
6967
6968 fn should_wrap_set_operation_modifiers(
6969 &self,
6970 order_by: &Option<OrderBy>,
6971 limit: &Option<Box<Expression>>,
6972 offset: &Option<Box<Expression>>,
6973 ) -> bool {
6974 let has_row_limit = limit.is_some() || offset.is_some();
6975 let has_emulated_null_ordering = order_by.as_ref().map_or(false, |order_by| {
6976 order_by
6977 .expressions
6978 .iter()
6979 .any(|ordered| ordered.nulls_first.is_some())
6980 });
6981
6982 (has_row_limit || has_emulated_null_ordering)
6983 && matches!(
6984 self.config.dialect,
6985 Some(DialectType::TSQL) | Some(DialectType::Fabric)
6986 )
6987 }
6988
6989 fn generate_tsql_wrapped_set_operation(
6990 &mut self,
6991 inner: Expression,
6992 with: Option<With>,
6993 order_by: Option<OrderBy>,
6994 limit: Option<Box<Expression>>,
6995 offset: Option<Box<Expression>>,
6996 ) -> Result<()> {
6997 let subquery = Subquery {
6998 this: inner,
6999 alias: Some(Identifier::new("_l_0".to_string())),
7000 column_aliases: Vec::new(),
7001 alias_explicit_as: true,
7002 alias_keyword: None,
7003 order_by: None,
7004 limit: None,
7005 offset: None,
7006 lateral: false,
7007 modifiers_inside: false,
7008 trailing_comments: Vec::new(),
7009 distribute_by: None,
7010 sort_by: None,
7011 cluster_by: None,
7012 inferred_type: None,
7013 };
7014
7015 let mut outer_select = Select {
7016 expressions: vec![Expression::Star(Star {
7017 table: None,
7018 except: None,
7019 replace: None,
7020 rename: None,
7021 trailing_comments: Vec::new(),
7022 span: None,
7023 })],
7024 from: Some(From {
7025 expressions: vec![Expression::Subquery(Box::new(subquery))],
7026 }),
7027 with,
7028 order_by,
7029 limit: limit.map(|limit| Limit {
7030 this: *limit,
7031 percent: false,
7032 comments: Vec::new(),
7033 }),
7034 offset: offset.map(|offset| Offset {
7035 this: *offset,
7036 rows: Some(true),
7037 }),
7038 ..Select::new()
7039 };
7040
7041 if outer_select.offset.is_some() && outer_select.order_by.is_none() {
7042 outer_select.order_by = Some(Self::dummy_tsql_order_by());
7043 }
7044
7045 self.generate_select(&outer_select)
7046 }
7047
7048 pub(crate) fn dummy_tsql_order_by() -> OrderBy {
7049 let null_select = Expression::Select(Box::new(Select {
7050 expressions: vec![Expression::Null(Null)],
7051 ..Select::new()
7052 }));
7053
7054 OrderBy {
7055 expressions: vec![Ordered {
7056 this: Expression::Subquery(Box::new(Subquery {
7057 this: null_select,
7058 alias: None,
7059 column_aliases: Vec::new(),
7060 alias_explicit_as: false,
7061 alias_keyword: None,
7062 order_by: None,
7063 limit: None,
7064 offset: None,
7065 lateral: false,
7066 modifiers_inside: false,
7067 trailing_comments: Vec::new(),
7068 distribute_by: None,
7069 sort_by: None,
7070 cluster_by: None,
7071 inferred_type: None,
7072 })),
7073 desc: false,
7074 nulls_first: None,
7075 explicit_asc: false,
7076 with_fill: None,
7077 }],
7078 siblings: false,
7079 comments: Vec::new(),
7080 }
7081 }
7082
7083 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
7084 if self.should_wrap_set_operation_modifiers(
7085 &outermost.order_by,
7086 &outermost.limit,
7087 &outermost.offset,
7088 ) {
7089 let mut inner = outermost.clone();
7090 let with = inner.with.take();
7091 let order_by = inner.order_by.take();
7092 let limit = inner.limit.take();
7093 let offset = inner.offset.take();
7094
7095 return self.generate_tsql_wrapped_set_operation(
7096 Expression::Union(Box::new(inner)),
7097 with,
7098 order_by,
7099 limit,
7100 offset,
7101 );
7102 }
7103
7104 let mut chain: Vec<&Union> = vec![outermost];
7109 let mut leftmost: &Expression = &outermost.left;
7110 while let Expression::Union(inner) = leftmost {
7111 chain.push(inner);
7112 leftmost = &inner.left;
7113 }
7114 if let Some(with) = &outermost.with {
7119 self.generate_with(with)?;
7120 self.write_space();
7121 }
7122
7123 self.generate_expression(leftmost)?;
7125
7126 for union in chain.iter().rev() {
7128 self.generate_union_step(union)?;
7129 }
7130 Ok(())
7131 }
7132
7133 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
7135 if self.config.pretty {
7136 self.write_newline();
7137 self.write_indent();
7138 } else {
7139 self.write_space();
7140 }
7141
7142 if let Some(side) = &union.side {
7144 self.write_keyword(side);
7145 self.write_space();
7146 }
7147 if let Some(kind) = &union.kind {
7148 self.write_keyword(kind);
7149 self.write_space();
7150 }
7151
7152 self.write_keyword("UNION");
7153 if union.all {
7154 self.write_space();
7155 self.write_keyword("ALL");
7156 } else if union.distinct {
7157 self.write_space();
7158 self.write_keyword("DISTINCT");
7159 }
7160
7161 if union.corresponding || union.by_name {
7164 self.write_space();
7165 self.write_keyword("BY NAME");
7166 }
7167 if !union.on_columns.is_empty() {
7168 self.write_space();
7169 self.write_keyword("ON");
7170 self.write(" (");
7171 for (i, col) in union.on_columns.iter().enumerate() {
7172 if i > 0 {
7173 self.write(", ");
7174 }
7175 self.generate_expression(col)?;
7176 }
7177 self.write(")");
7178 }
7179
7180 if self.config.pretty {
7181 self.write_newline();
7182 self.write_indent();
7183 } else {
7184 self.write_space();
7185 }
7186 self.generate_expression(&union.right)?;
7187 if let Some(order_by) = &union.order_by {
7189 if self.config.pretty {
7190 self.write_newline();
7191 } else {
7192 self.write_space();
7193 }
7194 self.write_keyword("ORDER BY");
7195 self.write_space();
7196 for (i, ordered) in order_by.expressions.iter().enumerate() {
7197 if i > 0 {
7198 self.write(", ");
7199 }
7200 self.generate_ordered(ordered)?;
7201 }
7202 }
7203 if let Some(limit) = &union.limit {
7204 if self.config.pretty {
7205 self.write_newline();
7206 } else {
7207 self.write_space();
7208 }
7209 self.write_keyword("LIMIT");
7210 self.write_space();
7211 self.generate_expression(limit)?;
7212 }
7213 if let Some(offset) = &union.offset {
7214 if self.config.pretty {
7215 self.write_newline();
7216 } else {
7217 self.write_space();
7218 }
7219 self.write_keyword("OFFSET");
7220 self.write_space();
7221 self.generate_expression(offset)?;
7222 }
7223 if let Some(distribute_by) = &union.distribute_by {
7225 self.write_space();
7226 self.write_keyword("DISTRIBUTE BY");
7227 self.write_space();
7228 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7229 if i > 0 {
7230 self.write(", ");
7231 }
7232 self.generate_expression(expr)?;
7233 }
7234 }
7235 if let Some(sort_by) = &union.sort_by {
7237 self.write_space();
7238 self.write_keyword("SORT BY");
7239 self.write_space();
7240 for (i, ord) in sort_by.expressions.iter().enumerate() {
7241 if i > 0 {
7242 self.write(", ");
7243 }
7244 self.generate_ordered(ord)?;
7245 }
7246 }
7247 if let Some(cluster_by) = &union.cluster_by {
7249 self.write_space();
7250 self.write_keyword("CLUSTER BY");
7251 self.write_space();
7252 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7253 if i > 0 {
7254 self.write(", ");
7255 }
7256 self.generate_ordered(ord)?;
7257 }
7258 }
7259 Ok(())
7260 }
7261
7262 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
7263 if self.should_wrap_set_operation_modifiers(
7264 &outermost.order_by,
7265 &outermost.limit,
7266 &outermost.offset,
7267 ) {
7268 let mut inner = outermost.clone();
7269 let with = inner.with.take();
7270 let order_by = inner.order_by.take();
7271 let limit = inner.limit.take();
7272 let offset = inner.offset.take();
7273
7274 return self.generate_tsql_wrapped_set_operation(
7275 Expression::Intersect(Box::new(inner)),
7276 with,
7277 order_by,
7278 limit,
7279 offset,
7280 );
7281 }
7282
7283 let mut chain: Vec<&Intersect> = vec![outermost];
7285 let mut leftmost: &Expression = &outermost.left;
7286 while let Expression::Intersect(inner) = leftmost {
7287 chain.push(inner);
7288 leftmost = &inner.left;
7289 }
7290
7291 if let Some(with) = &outermost.with {
7292 self.generate_with(with)?;
7293 self.write_space();
7294 }
7295
7296 self.generate_expression(leftmost)?;
7297
7298 for intersect in chain.iter().rev() {
7299 self.generate_intersect_step(intersect)?;
7300 }
7301 Ok(())
7302 }
7303
7304 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
7306 if self.config.pretty {
7307 self.write_newline();
7308 self.write_indent();
7309 } else {
7310 self.write_space();
7311 }
7312
7313 if let Some(side) = &intersect.side {
7315 self.write_keyword(side);
7316 self.write_space();
7317 }
7318 if let Some(kind) = &intersect.kind {
7319 self.write_keyword(kind);
7320 self.write_space();
7321 }
7322
7323 self.write_keyword("INTERSECT");
7324 if intersect.all {
7325 if !self.config.except_intersect_support_all_clause {
7326 self.unsupported("INTERSECT ALL is not supported")?;
7327 }
7328 self.write_space();
7329 self.write_keyword("ALL");
7330 } else if intersect.distinct {
7331 self.write_space();
7332 self.write_keyword("DISTINCT");
7333 }
7334
7335 if intersect.corresponding || intersect.by_name {
7338 self.write_space();
7339 self.write_keyword("BY NAME");
7340 }
7341 if !intersect.on_columns.is_empty() {
7342 self.write_space();
7343 self.write_keyword("ON");
7344 self.write(" (");
7345 for (i, col) in intersect.on_columns.iter().enumerate() {
7346 if i > 0 {
7347 self.write(", ");
7348 }
7349 self.generate_expression(col)?;
7350 }
7351 self.write(")");
7352 }
7353
7354 if self.config.pretty {
7355 self.write_newline();
7356 self.write_indent();
7357 } else {
7358 self.write_space();
7359 }
7360 self.generate_expression(&intersect.right)?;
7361 if let Some(order_by) = &intersect.order_by {
7363 if self.config.pretty {
7364 self.write_newline();
7365 } else {
7366 self.write_space();
7367 }
7368 self.write_keyword("ORDER BY");
7369 self.write_space();
7370 for (i, ordered) in order_by.expressions.iter().enumerate() {
7371 if i > 0 {
7372 self.write(", ");
7373 }
7374 self.generate_ordered(ordered)?;
7375 }
7376 }
7377 if let Some(limit) = &intersect.limit {
7378 if self.config.pretty {
7379 self.write_newline();
7380 } else {
7381 self.write_space();
7382 }
7383 self.write_keyword("LIMIT");
7384 self.write_space();
7385 self.generate_expression(limit)?;
7386 }
7387 if let Some(offset) = &intersect.offset {
7388 if self.config.pretty {
7389 self.write_newline();
7390 } else {
7391 self.write_space();
7392 }
7393 self.write_keyword("OFFSET");
7394 self.write_space();
7395 self.generate_expression(offset)?;
7396 }
7397 if let Some(distribute_by) = &intersect.distribute_by {
7399 self.write_space();
7400 self.write_keyword("DISTRIBUTE BY");
7401 self.write_space();
7402 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7403 if i > 0 {
7404 self.write(", ");
7405 }
7406 self.generate_expression(expr)?;
7407 }
7408 }
7409 if let Some(sort_by) = &intersect.sort_by {
7411 self.write_space();
7412 self.write_keyword("SORT BY");
7413 self.write_space();
7414 for (i, ord) in sort_by.expressions.iter().enumerate() {
7415 if i > 0 {
7416 self.write(", ");
7417 }
7418 self.generate_ordered(ord)?;
7419 }
7420 }
7421 if let Some(cluster_by) = &intersect.cluster_by {
7423 self.write_space();
7424 self.write_keyword("CLUSTER BY");
7425 self.write_space();
7426 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7427 if i > 0 {
7428 self.write(", ");
7429 }
7430 self.generate_ordered(ord)?;
7431 }
7432 }
7433 Ok(())
7434 }
7435
7436 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
7437 if self.should_wrap_set_operation_modifiers(
7438 &outermost.order_by,
7439 &outermost.limit,
7440 &outermost.offset,
7441 ) {
7442 let mut inner = outermost.clone();
7443 let with = inner.with.take();
7444 let order_by = inner.order_by.take();
7445 let limit = inner.limit.take();
7446 let offset = inner.offset.take();
7447
7448 return self.generate_tsql_wrapped_set_operation(
7449 Expression::Except(Box::new(inner)),
7450 with,
7451 order_by,
7452 limit,
7453 offset,
7454 );
7455 }
7456
7457 let mut chain: Vec<&Except> = vec![outermost];
7459 let mut leftmost: &Expression = &outermost.left;
7460 while let Expression::Except(inner) = leftmost {
7461 chain.push(inner);
7462 leftmost = &inner.left;
7463 }
7464
7465 if let Some(with) = &outermost.with {
7466 self.generate_with(with)?;
7467 self.write_space();
7468 }
7469
7470 self.generate_expression(leftmost)?;
7471
7472 for except in chain.iter().rev() {
7473 self.generate_except_step(except)?;
7474 }
7475 Ok(())
7476 }
7477
7478 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
7480 use crate::dialects::DialectType;
7481
7482 if self.config.pretty {
7483 self.write_newline();
7484 self.write_indent();
7485 } else {
7486 self.write_space();
7487 }
7488
7489 if let Some(side) = &except.side {
7491 self.write_keyword(side);
7492 self.write_space();
7493 }
7494 if let Some(kind) = &except.kind {
7495 self.write_keyword(kind);
7496 self.write_space();
7497 }
7498
7499 match self.config.dialect {
7501 Some(DialectType::Oracle) if !except.all => {
7502 self.write_keyword("MINUS");
7503 }
7504 Some(DialectType::ClickHouse) => {
7505 self.write_keyword("EXCEPT");
7506 let preserve_all = self.config.source_dialect.is_none()
7507 || matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
7508 if except.all && preserve_all {
7509 self.write_space();
7510 self.write_keyword("ALL");
7511 }
7512 if except.distinct {
7513 self.write_space();
7514 self.write_keyword("DISTINCT");
7515 }
7516 }
7517 Some(DialectType::BigQuery) => {
7518 self.write_keyword("EXCEPT");
7520 if except.all {
7521 self.write_space();
7522 self.write_keyword("ALL");
7523 } else {
7524 self.write_space();
7525 self.write_keyword("DISTINCT");
7526 }
7527 }
7528 _ => {
7529 self.write_keyword("EXCEPT");
7530 if except.all {
7531 if !self.config.except_intersect_support_all_clause {
7532 self.unsupported("EXCEPT ALL is not supported")?;
7533 }
7534 self.write_space();
7535 self.write_keyword("ALL");
7536 } else if except.distinct {
7537 self.write_space();
7538 self.write_keyword("DISTINCT");
7539 }
7540 }
7541 }
7542
7543 if except.corresponding || except.by_name {
7546 self.write_space();
7547 self.write_keyword("BY NAME");
7548 }
7549 if !except.on_columns.is_empty() {
7550 self.write_space();
7551 self.write_keyword("ON");
7552 self.write(" (");
7553 for (i, col) in except.on_columns.iter().enumerate() {
7554 if i > 0 {
7555 self.write(", ");
7556 }
7557 self.generate_expression(col)?;
7558 }
7559 self.write(")");
7560 }
7561
7562 if self.config.pretty {
7563 self.write_newline();
7564 self.write_indent();
7565 } else {
7566 self.write_space();
7567 }
7568 self.generate_expression(&except.right)?;
7569 if let Some(order_by) = &except.order_by {
7571 if self.config.pretty {
7572 self.write_newline();
7573 } else {
7574 self.write_space();
7575 }
7576 self.write_keyword("ORDER BY");
7577 self.write_space();
7578 for (i, ordered) in order_by.expressions.iter().enumerate() {
7579 if i > 0 {
7580 self.write(", ");
7581 }
7582 self.generate_ordered(ordered)?;
7583 }
7584 }
7585 if let Some(limit) = &except.limit {
7586 if self.config.pretty {
7587 self.write_newline();
7588 } else {
7589 self.write_space();
7590 }
7591 self.write_keyword("LIMIT");
7592 self.write_space();
7593 self.generate_expression(limit)?;
7594 }
7595 if let Some(offset) = &except.offset {
7596 if self.config.pretty {
7597 self.write_newline();
7598 } else {
7599 self.write_space();
7600 }
7601 self.write_keyword("OFFSET");
7602 self.write_space();
7603 self.generate_expression(offset)?;
7604 }
7605 if let Some(distribute_by) = &except.distribute_by {
7607 self.write_space();
7608 self.write_keyword("DISTRIBUTE BY");
7609 self.write_space();
7610 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7611 if i > 0 {
7612 self.write(", ");
7613 }
7614 self.generate_expression(expr)?;
7615 }
7616 }
7617 if let Some(sort_by) = &except.sort_by {
7619 self.write_space();
7620 self.write_keyword("SORT BY");
7621 self.write_space();
7622 for (i, ord) in sort_by.expressions.iter().enumerate() {
7623 if i > 0 {
7624 self.write(", ");
7625 }
7626 self.generate_ordered(ord)?;
7627 }
7628 }
7629 if let Some(cluster_by) = &except.cluster_by {
7631 self.write_space();
7632 self.write_keyword("CLUSTER BY");
7633 self.write_space();
7634 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7635 if i > 0 {
7636 self.write(", ");
7637 }
7638 self.generate_ordered(ord)?;
7639 }
7640 }
7641 Ok(())
7642 }
7643
7644 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
7645 let prepend_query_cte = if insert.with.is_none() {
7647 use crate::dialects::DialectType;
7648 let should_prepend = matches!(
7649 self.config.dialect,
7650 Some(DialectType::TSQL)
7651 | Some(DialectType::Fabric)
7652 | Some(DialectType::Spark)
7653 | Some(DialectType::Databricks)
7654 | Some(DialectType::Hive)
7655 );
7656 if should_prepend {
7657 if let Some(Expression::Select(select)) = &insert.query {
7658 select.with.clone()
7659 } else {
7660 None
7661 }
7662 } else {
7663 None
7664 }
7665 } else {
7666 None
7667 };
7668
7669 if let Some(with) = &insert.with {
7671 self.generate_with(with)?;
7672 self.write_space();
7673 } else if let Some(with) = &prepend_query_cte {
7674 self.generate_with(with)?;
7675 self.write_space();
7676 }
7677
7678 for comment in &insert.leading_comments {
7680 self.write_formatted_comment(comment);
7681 self.write(" ");
7682 }
7683
7684 if let Some(dir) = &insert.directory {
7686 self.write_keyword("INSERT OVERWRITE");
7687 if dir.local {
7688 self.write_space();
7689 self.write_keyword("LOCAL");
7690 }
7691 self.write_space();
7692 self.write_keyword("DIRECTORY");
7693 self.write_space();
7694 self.write("'");
7695 self.write(&dir.path);
7696 self.write("'");
7697
7698 if let Some(row_format) = &dir.row_format {
7700 self.write_space();
7701 self.write_keyword("ROW FORMAT");
7702 if row_format.delimited {
7703 self.write_space();
7704 self.write_keyword("DELIMITED");
7705 }
7706 if let Some(val) = &row_format.fields_terminated_by {
7707 self.write_space();
7708 self.write_keyword("FIELDS TERMINATED BY");
7709 self.write_space();
7710 self.generate_string_literal(val)?;
7711 }
7712 if let Some(val) = &row_format.collection_items_terminated_by {
7713 self.write_space();
7714 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
7715 self.write_space();
7716 self.write("'");
7717 self.write(val);
7718 self.write("'");
7719 }
7720 if let Some(val) = &row_format.map_keys_terminated_by {
7721 self.write_space();
7722 self.write_keyword("MAP KEYS TERMINATED BY");
7723 self.write_space();
7724 self.write("'");
7725 self.write(val);
7726 self.write("'");
7727 }
7728 if let Some(val) = &row_format.lines_terminated_by {
7729 self.write_space();
7730 self.write_keyword("LINES TERMINATED BY");
7731 self.write_space();
7732 self.write("'");
7733 self.write(val);
7734 self.write("'");
7735 }
7736 if let Some(val) = &row_format.null_defined_as {
7737 self.write_space();
7738 self.write_keyword("NULL DEFINED AS");
7739 self.write_space();
7740 self.write("'");
7741 self.write(val);
7742 self.write("'");
7743 }
7744 }
7745
7746 if let Some(format) = &dir.stored_as {
7748 self.write_space();
7749 self.write_keyword("STORED AS");
7750 self.write_space();
7751 self.write_keyword(format);
7752 }
7753
7754 if let Some(query) = &insert.query {
7756 self.write_space();
7757 self.generate_expression(query)?;
7758 }
7759
7760 return Ok(());
7761 }
7762
7763 if insert.is_replace {
7764 self.write_keyword("REPLACE INTO");
7766 } else if insert.overwrite {
7767 self.write_keyword("INSERT");
7769 if let Some(ref hint) = insert.hint {
7771 self.generate_hint(hint)?;
7772 }
7773 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
7774 } else if let Some(ref action) = insert.conflict_action {
7775 self.write_keyword("INSERT OR");
7777 self.write_space();
7778 self.write_keyword(action);
7779 self.write_space();
7780 self.write_keyword("INTO");
7781 } else if insert.ignore {
7782 self.write_keyword("INSERT IGNORE INTO");
7784 } else {
7785 self.write_keyword("INSERT");
7786 if let Some(ref hint) = insert.hint {
7788 self.generate_hint(hint)?;
7789 }
7790 self.write_space();
7791 self.write_keyword("INTO");
7792 }
7793 if let Some(ref func) = insert.function_target {
7795 self.write_space();
7796 self.write_keyword("FUNCTION");
7797 self.write_space();
7798 self.generate_expression(func)?;
7799 } else {
7800 self.write_space();
7801 self.generate_table(&insert.table)?;
7802 }
7803
7804 if let Some(ref alias) = insert.alias {
7806 self.write_space();
7807 if insert.alias_explicit_as {
7808 self.write_keyword("AS");
7809 self.write_space();
7810 }
7811 self.generate_identifier(alias)?;
7812 }
7813
7814 if insert.if_exists {
7816 self.write_space();
7817 self.write_keyword("IF EXISTS");
7818 }
7819
7820 if let Some(ref replace_where) = insert.replace_where {
7822 if self.config.pretty {
7823 self.write_newline();
7824 self.write_indent();
7825 } else {
7826 self.write_space();
7827 }
7828 self.write_keyword("REPLACE WHERE");
7829 self.write_space();
7830 self.generate_expression(replace_where)?;
7831 }
7832
7833 if !insert.partition.is_empty() {
7835 self.write_space();
7836 self.write_keyword("PARTITION");
7837 self.write("(");
7838 for (i, (col, val)) in insert.partition.iter().enumerate() {
7839 if i > 0 {
7840 self.write(", ");
7841 }
7842 self.generate_identifier(col)?;
7843 if let Some(v) = val {
7844 self.write(" = ");
7845 self.generate_expression(v)?;
7846 }
7847 }
7848 self.write(")");
7849 }
7850
7851 if let Some(ref partition_by) = insert.partition_by {
7853 self.write_space();
7854 self.write_keyword("PARTITION BY");
7855 self.write_space();
7856 self.generate_expression(partition_by)?;
7857 }
7858
7859 if !insert.settings.is_empty() {
7861 self.write_space();
7862 self.write_keyword("SETTINGS");
7863 self.write_space();
7864 for (i, setting) in insert.settings.iter().enumerate() {
7865 if i > 0 {
7866 self.write(", ");
7867 }
7868 self.generate_expression(setting)?;
7869 }
7870 }
7871
7872 if !insert.columns.is_empty() {
7873 if insert.alias.is_some() && insert.alias_explicit_as {
7874 self.write("(");
7876 } else {
7877 self.write(" (");
7879 }
7880 for (i, col) in insert.columns.iter().enumerate() {
7881 if i > 0 {
7882 self.write(", ");
7883 }
7884 self.generate_identifier(col)?;
7885 }
7886 self.write(")");
7887 }
7888
7889 if let Some(ref output) = insert.output {
7891 self.generate_output_clause(output)?;
7892 }
7893
7894 if insert.by_name {
7896 self.write_space();
7897 self.write_keyword("BY NAME");
7898 }
7899
7900 if insert.default_values {
7901 self.write_space();
7902 self.write_keyword("DEFAULT VALUES");
7903 } else if let Some(query) = &insert.query {
7904 if self.config.pretty {
7905 self.write_newline();
7906 } else {
7907 self.write_space();
7908 }
7909 if prepend_query_cte.is_some() {
7911 if let Expression::Select(select) = query {
7912 let mut select_no_with = select.clone();
7913 select_no_with.with = None;
7914 self.generate_select(&select_no_with)?;
7915 } else {
7916 self.generate_expression(query)?;
7917 }
7918 } else {
7919 self.generate_expression(query)?;
7920 }
7921 } else if !insert.values.is_empty() {
7922 if self.config.pretty {
7923 self.write_newline();
7925 self.write_keyword("VALUES");
7926 self.write_newline();
7927 self.indent_level += 1;
7928 for (i, row) in insert.values.iter().enumerate() {
7929 if i > 0 {
7930 self.write(",");
7931 self.write_newline();
7932 }
7933 self.write_indent();
7934 self.write("(");
7935 for (j, val) in row.iter().enumerate() {
7936 if j > 0 {
7937 self.write(", ");
7938 }
7939 self.generate_expression(val)?;
7940 }
7941 self.write(")");
7942 }
7943 self.indent_level -= 1;
7944 } else {
7945 self.write_space();
7947 self.write_keyword("VALUES");
7948 for (i, row) in insert.values.iter().enumerate() {
7949 if i > 0 {
7950 self.write(",");
7951 }
7952 self.write(" (");
7953 for (j, val) in row.iter().enumerate() {
7954 if j > 0 {
7955 self.write(", ");
7956 }
7957 self.generate_expression(val)?;
7958 }
7959 self.write(")");
7960 }
7961 }
7962 }
7963
7964 if let Some(ref source) = insert.source {
7966 self.write_space();
7967 self.write_keyword("TABLE");
7968 self.write_space();
7969 self.generate_expression(source)?;
7970 }
7971
7972 if let Some(alias) = &insert.source_alias {
7974 self.write_space();
7975 self.write_keyword("AS");
7976 self.write_space();
7977 self.generate_identifier(alias)?;
7978 }
7979
7980 if let Some(on_conflict) = &insert.on_conflict {
7982 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7983 self.write_space();
7984 self.generate_expression(on_conflict)?;
7985 }
7986 }
7987
7988 if !insert.returning.is_empty() {
7990 self.write_space();
7991 self.write_keyword("RETURNING");
7992 self.write_space();
7993 for (i, expr) in insert.returning.iter().enumerate() {
7994 if i > 0 {
7995 self.write(", ");
7996 }
7997 self.generate_expression(expr)?;
7998 }
7999 }
8000
8001 Ok(())
8002 }
8003
8004 fn generate_update(&mut self, update: &Update) -> Result<()> {
8005 for comment in &update.leading_comments {
8007 self.write_formatted_comment(comment);
8008 self.write(" ");
8009 }
8010
8011 if let Some(ref with) = update.with {
8013 self.generate_with(with)?;
8014 self.write_space();
8015 }
8016
8017 self.write_keyword("UPDATE");
8018 if let Some(hint) = &update.hint {
8019 self.generate_hint(hint)?;
8020 }
8021 self.write_space();
8022 self.generate_table(&update.table)?;
8023
8024 let mysql_like_update_from = matches!(
8025 self.config.dialect,
8026 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
8027 ) && update.from_clause.is_some();
8028
8029 let mut set_pairs = update.set.clone();
8030
8031 let mut pre_set_joins = update.table_joins.clone();
8033 if mysql_like_update_from {
8034 let target_name = update
8035 .table
8036 .alias
8037 .as_ref()
8038 .map(|a| a.name.clone())
8039 .unwrap_or_else(|| update.table.name.name.clone());
8040
8041 for (col, _) in &mut set_pairs {
8042 if !col.name.contains('.') {
8043 col.name = format!("{}.{}", target_name, col.name);
8044 }
8045 }
8046
8047 if let Some(from_clause) = &update.from_clause {
8048 for table_expr in &from_clause.expressions {
8049 pre_set_joins.push(crate::expressions::Join {
8050 this: table_expr.clone(),
8051 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
8052 value: true,
8053 })),
8054 using: Vec::new(),
8055 kind: crate::expressions::JoinKind::Inner,
8056 use_inner_keyword: false,
8057 use_outer_keyword: false,
8058 deferred_condition: false,
8059 join_hint: None,
8060 match_condition: None,
8061 pivots: Vec::new(),
8062 comments: Vec::new(),
8063 nesting_group: 0,
8064 directed: false,
8065 });
8066 }
8067 }
8068 for join in &update.from_joins {
8069 let mut join = join.clone();
8070 if join.on.is_none() && join.using.is_empty() {
8071 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
8072 value: true,
8073 }));
8074 }
8075 pre_set_joins.push(join);
8076 }
8077 }
8078
8079 for extra_table in &update.extra_tables {
8081 self.write(", ");
8082 self.generate_table(extra_table)?;
8083 }
8084
8085 for join in &pre_set_joins {
8087 self.generate_join(join)?;
8089 }
8090
8091 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
8093 if teradata_from_before_set && !mysql_like_update_from {
8094 if let Some(ref from_clause) = update.from_clause {
8095 self.write_space();
8096 self.write_keyword("FROM");
8097 self.write_space();
8098 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
8099 if i > 0 {
8100 self.write(", ");
8101 }
8102 self.generate_expression(table_expr)?;
8103 }
8104 }
8105 for join in &update.from_joins {
8106 self.generate_join(join)?;
8107 }
8108 }
8109
8110 self.write_space();
8111 self.write_keyword("SET");
8112 self.write_space();
8113
8114 for (i, (col, val)) in set_pairs.iter().enumerate() {
8115 if i > 0 {
8116 self.write(", ");
8117 }
8118 self.generate_identifier(col)?;
8119 self.write(" = ");
8120 self.generate_expression(val)?;
8121 }
8122
8123 if let Some(ref output) = update.output {
8125 self.generate_output_clause(output)?;
8126 }
8127
8128 if !mysql_like_update_from && !teradata_from_before_set {
8130 if let Some(ref from_clause) = update.from_clause {
8131 self.write_space();
8132 self.write_keyword("FROM");
8133 self.write_space();
8134 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
8136 if i > 0 {
8137 self.write(", ");
8138 }
8139 self.generate_expression(table_expr)?;
8140 }
8141 }
8142 }
8143
8144 if !mysql_like_update_from && !teradata_from_before_set {
8145 for join in &update.from_joins {
8147 self.generate_join(join)?;
8148 }
8149 }
8150
8151 if let Some(where_clause) = &update.where_clause {
8152 self.write_space();
8153 self.write_keyword("WHERE");
8154 self.write_space();
8155 self.generate_expression(&where_clause.this)?;
8156 }
8157
8158 if !update.returning.is_empty() {
8160 self.write_space();
8161 self.write_keyword("RETURNING");
8162 self.write_space();
8163 for (i, expr) in update.returning.iter().enumerate() {
8164 if i > 0 {
8165 self.write(", ");
8166 }
8167 self.generate_expression(expr)?;
8168 }
8169 }
8170
8171 if let Some(ref order_by) = update.order_by {
8173 self.write_space();
8174 self.generate_order_by(order_by)?;
8175 }
8176
8177 if let Some(ref limit) = update.limit {
8179 self.write_space();
8180 self.write_keyword("LIMIT");
8181 self.write_space();
8182 self.generate_expression(limit)?;
8183 }
8184
8185 Ok(())
8186 }
8187
8188 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
8189 if let Some(with) = &delete.with {
8191 self.generate_with(with)?;
8192 self.write_space();
8193 }
8194
8195 for comment in &delete.leading_comments {
8197 self.write_formatted_comment(comment);
8198 self.write(" ");
8199 }
8200
8201 if !delete.tables.is_empty() && !delete.tables_from_using {
8203 self.write_keyword("DELETE");
8205 if let Some(hint) = &delete.hint {
8206 self.generate_hint(hint)?;
8207 }
8208 self.write_space();
8209 for (i, tbl) in delete.tables.iter().enumerate() {
8210 if i > 0 {
8211 self.write(", ");
8212 }
8213 self.generate_table(tbl)?;
8214 }
8215 if let Some(ref output) = delete.output {
8217 self.generate_output_clause(output)?;
8218 }
8219 self.write_space();
8220 self.write_keyword("FROM");
8221 self.write_space();
8222 self.generate_table(&delete.table)?;
8223 } else if !delete.tables.is_empty() && delete.tables_from_using {
8224 self.write_keyword("DELETE");
8226 if let Some(hint) = &delete.hint {
8227 self.generate_hint(hint)?;
8228 }
8229 self.write_space();
8230 self.write_keyword("FROM");
8231 self.write_space();
8232 for (i, tbl) in delete.tables.iter().enumerate() {
8233 if i > 0 {
8234 self.write(", ");
8235 }
8236 self.generate_table(tbl)?;
8237 }
8238 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
8239 self.write_keyword("DELETE");
8241 if let Some(hint) = &delete.hint {
8242 self.generate_hint(hint)?;
8243 }
8244 self.write_space();
8245 self.generate_table(&delete.table)?;
8246 } else {
8247 self.write_keyword("DELETE");
8248 if let Some(hint) = &delete.hint {
8249 self.generate_hint(hint)?;
8250 }
8251 self.write_space();
8252 self.write_keyword("FROM");
8253 self.write_space();
8254 self.generate_table(&delete.table)?;
8255 }
8256
8257 if let Some(ref on_cluster) = delete.on_cluster {
8259 self.write_space();
8260 self.generate_on_cluster(on_cluster)?;
8261 }
8262
8263 if let Some(ref idx) = delete.force_index {
8265 self.write_space();
8266 self.write_keyword("FORCE INDEX");
8267 self.write(" (");
8268 self.write(idx);
8269 self.write(")");
8270 }
8271
8272 if let Some(ref alias) = delete.alias {
8274 self.write_space();
8275 if delete.alias_explicit_as
8276 || matches!(self.config.dialect, Some(DialectType::BigQuery))
8277 {
8278 self.write_keyword("AS");
8279 self.write_space();
8280 }
8281 self.generate_identifier(alias)?;
8282 }
8283
8284 if !delete.tables_from_using {
8286 for join in &delete.joins {
8287 self.generate_join(join)?;
8288 }
8289 }
8290
8291 if !delete.using.is_empty() {
8293 self.write_space();
8294 self.write_keyword("USING");
8295 for (i, table) in delete.using.iter().enumerate() {
8296 if i > 0 {
8297 self.write(",");
8298 }
8299 self.write_space();
8300 if !table.hints.is_empty() && table.name.is_empty() {
8302 self.generate_expression(&table.hints[0])?;
8304 if let Some(ref alias) = table.alias {
8305 self.write_space();
8306 if table.alias_explicit_as {
8307 self.write_keyword("AS");
8308 self.write_space();
8309 }
8310 self.generate_identifier(alias)?;
8311 if !table.column_aliases.is_empty() {
8312 self.write("(");
8313 for (j, col_alias) in table.column_aliases.iter().enumerate() {
8314 if j > 0 {
8315 self.write(", ");
8316 }
8317 self.generate_identifier(col_alias)?;
8318 }
8319 self.write(")");
8320 }
8321 }
8322 } else {
8323 self.generate_table(table)?;
8324 }
8325 }
8326 }
8327
8328 if delete.tables_from_using {
8330 for join in &delete.joins {
8331 self.generate_join(join)?;
8332 }
8333 }
8334
8335 let output_already_emitted =
8337 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
8338 if !output_already_emitted {
8339 if let Some(ref output) = delete.output {
8340 self.generate_output_clause(output)?;
8341 }
8342 }
8343
8344 if let Some(where_clause) = &delete.where_clause {
8345 self.write_space();
8346 self.write_keyword("WHERE");
8347 self.write_space();
8348 self.generate_expression(&where_clause.this)?;
8349 }
8350
8351 if let Some(ref order_by) = delete.order_by {
8353 self.write_space();
8354 self.generate_order_by(order_by)?;
8355 }
8356
8357 if let Some(ref limit) = delete.limit {
8359 self.write_space();
8360 self.write_keyword("LIMIT");
8361 self.write_space();
8362 self.generate_expression(limit)?;
8363 }
8364
8365 if !delete.returning.is_empty() {
8367 self.write_space();
8368 self.write_keyword("RETURNING");
8369 self.write_space();
8370 for (i, expr) in delete.returning.iter().enumerate() {
8371 if i > 0 {
8372 self.write(", ");
8373 }
8374 self.generate_expression(expr)?;
8375 }
8376 }
8377
8378 Ok(())
8379 }
8380
8381 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
8384 let saved_athena_hive_context = self.athena_hive_context;
8388 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
8389 if matches!(
8390 self.config.dialect,
8391 Some(crate::dialects::DialectType::Athena)
8392 ) {
8393 let is_external = ct
8397 .table_modifier
8398 .as_ref()
8399 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
8400 .unwrap_or(false);
8401 let has_as_select = ct.as_select.is_some();
8402 self.athena_hive_context = is_external || !has_as_select;
8403 }
8404
8405 if matches!(
8407 self.config.dialect,
8408 Some(crate::dialects::DialectType::TSQL)
8409 ) {
8410 if let Some(ref query) = ct.as_select {
8411 if let Some(with_cte) = &ct.with_cte {
8413 self.generate_with(with_cte)?;
8414 self.write_space();
8415 }
8416
8417 self.write_keyword("SELECT");
8419 self.write(" * ");
8420 self.write_keyword("INTO");
8421 self.write_space();
8422
8423 if ct.temporary {
8425 self.write("#");
8426 }
8427 self.generate_table(&ct.name)?;
8428
8429 self.write_space();
8430 self.write_keyword("FROM");
8431 self.write(" (");
8432 let aliased_query = Self::add_column_aliases_to_query(query.clone());
8434 self.generate_expression(&aliased_query)?;
8435 self.write(") ");
8436 self.write_keyword("AS");
8437 self.write(" temp");
8438 return Ok(());
8439 }
8440 }
8441
8442 if let Some(with_cte) = &ct.with_cte {
8444 self.generate_with(with_cte)?;
8445 self.write_space();
8446 }
8447
8448 for comment in &ct.leading_comments {
8450 self.write_formatted_comment(comment);
8451 self.write(" ");
8452 }
8453 self.write_keyword("CREATE");
8454
8455 if ct.or_replace {
8456 self.write_space();
8457 self.write_keyword("OR REPLACE");
8458 }
8459
8460 if ct.temporary {
8461 self.write_space();
8462 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
8464 self.write_keyword("GLOBAL TEMPORARY");
8465 } else {
8466 self.write_keyword("TEMPORARY");
8467 }
8468 }
8469
8470 let is_dictionary = ct
8472 .table_modifier
8473 .as_ref()
8474 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
8475 .unwrap_or(false);
8476 if let Some(ref modifier) = ct.table_modifier {
8477 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
8479 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
8480 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
8482 || modifier.eq_ignore_ascii_case("SET")
8483 || modifier.eq_ignore_ascii_case("MULTISET")
8484 || modifier.to_ascii_uppercase().contains("VOLATILE")
8485 || modifier.to_ascii_uppercase().starts_with("SET ")
8486 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
8487 let skip_teradata =
8488 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
8489 if !skip_transient && !skip_teradata {
8490 self.write_space();
8491 self.write_keyword(modifier);
8492 }
8493 }
8494
8495 if !is_dictionary {
8496 self.write_space();
8497 self.write_keyword("TABLE");
8498 }
8499
8500 if ct.if_not_exists {
8501 self.write_space();
8502 self.write_keyword("IF NOT EXISTS");
8503 }
8504
8505 self.write_space();
8506 self.generate_table(&ct.name)?;
8507
8508 if let Some(ref uuid) = ct.uuid {
8510 self.write_space();
8511 self.write_keyword("UUID");
8512 self.write(" '");
8513 self.write(uuid);
8514 self.write("'");
8515 }
8516
8517 if let Some(ref on_cluster) = ct.on_cluster {
8519 self.write_space();
8520 self.generate_on_cluster(on_cluster)?;
8521 }
8522
8523 if matches!(
8525 self.config.dialect,
8526 Some(crate::dialects::DialectType::Teradata)
8527 ) && !ct.teradata_post_name_options.is_empty()
8528 {
8529 for opt in &ct.teradata_post_name_options {
8530 self.write(", ");
8531 self.write(opt);
8532 }
8533 }
8534
8535 if ct.copy_grants {
8537 self.write_space();
8538 self.write_keyword("COPY GRANTS");
8539 }
8540
8541 if let Some(ref using_template) = ct.using_template {
8543 self.write_space();
8544 self.write_keyword("USING TEMPLATE");
8545 self.write_space();
8546 self.generate_expression(using_template)?;
8547 return Ok(());
8548 }
8549
8550 if is_clickhouse {
8554 if let Some(ref clone_source) = ct.clone_source {
8555 if ct.columns.is_empty() && ct.constraints.is_empty() {
8556 self.write_space();
8557 self.write_keyword("AS");
8558 self.write_space();
8559 self.generate_table(clone_source)?;
8560 }
8561 }
8562 }
8563
8564 if !is_clickhouse {
8566 if let Some(ref clone_source) = ct.clone_source {
8567 self.write_space();
8568 if ct.is_copy && self.config.supports_table_copy {
8569 self.write_keyword("COPY");
8571 } else if ct.shallow_clone {
8572 self.write_keyword("SHALLOW CLONE");
8573 } else if ct.deep_clone {
8574 self.write_keyword("DEEP CLONE");
8575 } else {
8576 self.write_keyword("CLONE");
8577 }
8578 self.write_space();
8579 self.generate_table(clone_source)?;
8580 if let Some(ref at_clause) = ct.clone_at_clause {
8582 self.write_space();
8583 self.generate_expression(at_clause)?;
8584 }
8585 return Ok(());
8586 }
8587 }
8588
8589 if let Some(ref partition_of) = ct.partition_of {
8593 self.write_space();
8594
8595 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
8597 self.write_keyword("PARTITION OF");
8599 self.write_space();
8600 self.generate_expression(&pop.this)?;
8601
8602 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8604 self.write(" (");
8605 let mut first = true;
8606 for col in &ct.columns {
8607 if !first {
8608 self.write(", ");
8609 }
8610 first = false;
8611 self.generate_column_def(col)?;
8612 }
8613 for constraint in &ct.constraints {
8614 if !first {
8615 self.write(", ");
8616 }
8617 first = false;
8618 self.generate_table_constraint(constraint)?;
8619 }
8620 self.write(")");
8621 }
8622
8623 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
8625 self.write_space();
8626 self.write_keyword("FOR VALUES");
8627 self.write_space();
8628 self.generate_expression(&pop.expression)?;
8629 } else {
8630 self.write_space();
8631 self.write_keyword("DEFAULT");
8632 }
8633 } else {
8634 self.generate_expression(partition_of)?;
8636
8637 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8639 self.write(" (");
8640 let mut first = true;
8641 for col in &ct.columns {
8642 if !first {
8643 self.write(", ");
8644 }
8645 first = false;
8646 self.generate_column_def(col)?;
8647 }
8648 for constraint in &ct.constraints {
8649 if !first {
8650 self.write(", ");
8651 }
8652 first = false;
8653 self.generate_table_constraint(constraint)?;
8654 }
8655 self.write(")");
8656 }
8657 }
8658
8659 for prop in &ct.properties {
8661 self.write_space();
8662 self.generate_expression(prop)?;
8663 }
8664
8665 return Ok(());
8666 }
8667
8668 self.sqlite_inline_pk_columns.clear();
8671 if matches!(
8672 self.config.dialect,
8673 Some(crate::dialects::DialectType::SQLite)
8674 ) {
8675 for constraint in &ct.constraints {
8676 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8677 if columns.len() == 1 && name.is_none() {
8679 let pk_col_name = columns[0].name.to_ascii_lowercase();
8680 if ct
8682 .columns
8683 .iter()
8684 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
8685 {
8686 self.sqlite_inline_pk_columns.insert(pk_col_name);
8687 }
8688 }
8689 }
8690 }
8691 }
8692
8693 if !ct.columns.is_empty() {
8695 if self.config.pretty {
8696 self.write(" (");
8698 self.write_newline();
8699 self.indent_level += 1;
8700 for (i, col) in ct.columns.iter().enumerate() {
8701 if i > 0 {
8702 self.write(",");
8703 self.write_newline();
8704 }
8705 self.write_indent();
8706 self.generate_column_def(col)?;
8707 }
8708 for constraint in &ct.constraints {
8710 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8712 if columns.len() == 1
8713 && name.is_none()
8714 && self
8715 .sqlite_inline_pk_columns
8716 .contains(&columns[0].name.to_ascii_lowercase())
8717 {
8718 continue;
8719 }
8720 }
8721 self.write(",");
8722 self.write_newline();
8723 self.write_indent();
8724 self.generate_table_constraint(constraint)?;
8725 }
8726 self.indent_level -= 1;
8727 self.write_newline();
8728 self.write(")");
8729 } else {
8730 self.write(" (");
8731 for (i, col) in ct.columns.iter().enumerate() {
8732 if i > 0 {
8733 self.write(", ");
8734 }
8735 self.generate_column_def(col)?;
8736 }
8737 let mut first_constraint = true;
8739 for constraint in &ct.constraints {
8740 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8742 if columns.len() == 1
8743 && name.is_none()
8744 && self
8745 .sqlite_inline_pk_columns
8746 .contains(&columns[0].name.to_ascii_lowercase())
8747 {
8748 continue;
8749 }
8750 }
8751 if first_constraint {
8752 self.write(", ");
8753 first_constraint = false;
8754 } else {
8755 self.write(", ");
8756 }
8757 self.generate_table_constraint(constraint)?;
8758 }
8759 self.write(")");
8760 }
8761 } else if !ct.constraints.is_empty() {
8762 let has_like_only = ct
8764 .constraints
8765 .iter()
8766 .all(|c| matches!(c, TableConstraint::Like { .. }));
8767 let has_tags_only = ct
8768 .constraints
8769 .iter()
8770 .all(|c| matches!(c, TableConstraint::Tags(_)));
8771 let is_pg_like = matches!(
8775 self.config.dialect,
8776 Some(crate::dialects::DialectType::PostgreSQL)
8777 | Some(crate::dialects::DialectType::CockroachDB)
8778 | Some(crate::dialects::DialectType::Materialize)
8779 | Some(crate::dialects::DialectType::RisingWave)
8780 | Some(crate::dialects::DialectType::Redshift)
8781 | Some(crate::dialects::DialectType::Presto)
8782 | Some(crate::dialects::DialectType::Trino)
8783 | Some(crate::dialects::DialectType::Athena)
8784 );
8785 let use_parens = if has_like_only {
8786 is_pg_like
8787 } else {
8788 !has_tags_only
8789 };
8790 if self.config.pretty && use_parens {
8791 self.write(" (");
8792 self.write_newline();
8793 self.indent_level += 1;
8794 for (i, constraint) in ct.constraints.iter().enumerate() {
8795 if i > 0 {
8796 self.write(",");
8797 self.write_newline();
8798 }
8799 self.write_indent();
8800 self.generate_table_constraint(constraint)?;
8801 }
8802 self.indent_level -= 1;
8803 self.write_newline();
8804 self.write(")");
8805 } else {
8806 if use_parens {
8807 self.write(" (");
8808 } else {
8809 self.write_space();
8810 }
8811 for (i, constraint) in ct.constraints.iter().enumerate() {
8812 if i > 0 {
8813 self.write(", ");
8814 }
8815 self.generate_table_constraint(constraint)?;
8816 }
8817 if use_parens {
8818 self.write(")");
8819 }
8820 }
8821 }
8822
8823 if is_clickhouse && (!ct.columns.is_empty() || !ct.constraints.is_empty()) {
8824 if let Some(ref clone_source) = ct.clone_source {
8825 self.write_space();
8826 self.write_keyword("AS");
8827 self.write_space();
8828 self.generate_table(clone_source)?;
8829 }
8830 }
8831
8832 if let Some(ref on_prop) = ct.on_property {
8834 self.write(" ");
8835 self.write_keyword("ON");
8836 self.write(" ");
8837 self.generate_expression(&on_prop.this)?;
8838 }
8839
8840 if !ct.with_partition_columns.is_empty() {
8842 if self.config.pretty {
8843 self.write_newline();
8844 } else {
8845 self.write_space();
8846 }
8847 self.write_keyword("WITH PARTITION COLUMNS");
8848 self.write(" (");
8849 if self.config.pretty {
8850 self.write_newline();
8851 self.indent_level += 1;
8852 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8853 if i > 0 {
8854 self.write(",");
8855 self.write_newline();
8856 }
8857 self.write_indent();
8858 self.generate_column_def(col)?;
8859 }
8860 self.indent_level -= 1;
8861 self.write_newline();
8862 } else {
8863 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8864 if i > 0 {
8865 self.write(", ");
8866 }
8867 self.generate_column_def(col)?;
8868 }
8869 }
8870 self.write(")");
8871 }
8872
8873 if let Some(ref conn) = ct.with_connection {
8875 if self.config.pretty {
8876 self.write_newline();
8877 } else {
8878 self.write_space();
8879 }
8880 self.write_keyword("WITH CONNECTION");
8881 self.write_space();
8882 self.generate_table(conn)?;
8883 }
8884
8885 if !is_clickhouse {
8888 for prop in &ct.properties {
8889 if let Expression::SchemaCommentProperty(_) = prop {
8890 if self.config.pretty {
8891 self.write_newline();
8892 } else {
8893 self.write_space();
8894 }
8895 self.generate_expression(prop)?;
8896 }
8897 }
8898 }
8899
8900 if !ct.with_properties.is_empty() {
8902 let is_snowflake_special_table = matches!(
8904 self.config.dialect,
8905 Some(crate::dialects::DialectType::Snowflake)
8906 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8907 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8908 if is_snowflake_special_table {
8909 for (key, value) in &ct.with_properties {
8910 self.write_space();
8911 self.write(key);
8912 self.write("=");
8913 self.write(value);
8914 }
8915 } else if self.config.pretty {
8916 self.write_newline();
8917 self.write_keyword("WITH");
8918 self.write(" (");
8919 self.write_newline();
8920 self.indent_level += 1;
8921 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8922 if i > 0 {
8923 self.write(",");
8924 self.write_newline();
8925 }
8926 self.write_indent();
8927 self.write(key);
8928 self.write("=");
8929 self.write(value);
8930 }
8931 self.indent_level -= 1;
8932 self.write_newline();
8933 self.write(")");
8934 } else {
8935 self.write_space();
8936 self.write_keyword("WITH");
8937 self.write(" (");
8938 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8939 if i > 0 {
8940 self.write(", ");
8941 }
8942 self.write(key);
8943 self.write("=");
8944 self.write(value);
8945 }
8946 self.write(")");
8947 }
8948 }
8949
8950 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8951 if is_clickhouse && ct.as_select.is_some() {
8952 let mut pre = Vec::new();
8953 let mut post = Vec::new();
8954 for prop in &ct.properties {
8955 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8956 post.push(prop);
8957 } else {
8958 pre.push(prop);
8959 }
8960 }
8961 (pre, post)
8962 } else {
8963 (ct.properties.iter().collect(), Vec::new())
8964 };
8965
8966 for prop in pre_as_properties {
8968 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8970 continue;
8971 }
8972 if self.config.pretty {
8973 self.write_newline();
8974 } else {
8975 self.write_space();
8976 }
8977 if let Expression::Properties(props) = prop {
8981 let is_hive_dialect = matches!(
8982 self.config.dialect,
8983 Some(crate::dialects::DialectType::Hive)
8984 | Some(crate::dialects::DialectType::Spark)
8985 | Some(crate::dialects::DialectType::Databricks)
8986 | Some(crate::dialects::DialectType::Athena)
8987 );
8988 let is_doris_starrocks = matches!(
8989 self.config.dialect,
8990 Some(crate::dialects::DialectType::Doris)
8991 | Some(crate::dialects::DialectType::StarRocks)
8992 );
8993 if is_hive_dialect {
8994 self.generate_tblproperties_clause(&props.expressions)?;
8995 } else if is_doris_starrocks {
8996 self.generate_properties_clause(&props.expressions)?;
8997 } else {
8998 self.generate_options_clause(&props.expressions)?;
8999 }
9000 } else {
9001 self.generate_expression(prop)?;
9002 }
9003 }
9004
9005 for prop in &ct.post_table_properties {
9007 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
9008 self.write(" WITH(");
9009 self.generate_system_versioning_content(svp)?;
9010 self.write(")");
9011 } else if let Expression::Properties(props) = prop {
9012 let is_doris_starrocks = matches!(
9014 self.config.dialect,
9015 Some(crate::dialects::DialectType::Doris)
9016 | Some(crate::dialects::DialectType::StarRocks)
9017 );
9018 self.write_space();
9019 if is_doris_starrocks {
9020 self.generate_properties_clause(&props.expressions)?;
9021 } else {
9022 self.generate_options_clause(&props.expressions)?;
9023 }
9024 } else {
9025 self.write_space();
9026 self.generate_expression(prop)?;
9027 }
9028 }
9029
9030 if let Some(ref rollup) = ct.rollup {
9033 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
9034 self.write_space();
9035 self.generate_rollup_property(rollup)?;
9036 }
9037 }
9038
9039 let is_mysql_compatible = matches!(
9043 self.config.dialect,
9044 Some(DialectType::MySQL)
9045 | Some(DialectType::TiDB)
9046 | Some(DialectType::SingleStore)
9047 | Some(DialectType::Doris)
9048 | Some(DialectType::StarRocks)
9049 | None
9050 );
9051 let is_hive_compatible = matches!(
9052 self.config.dialect,
9053 Some(DialectType::Hive)
9054 | Some(DialectType::Spark)
9055 | Some(DialectType::Databricks)
9056 | Some(DialectType::Athena)
9057 );
9058 let mysql_pretty_options =
9059 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
9060 for (key, value) in &ct.mysql_table_options {
9061 let should_output = if is_mysql_compatible {
9063 true
9064 } else if is_hive_compatible && key == "COMMENT" {
9065 true } else {
9067 false
9068 };
9069 if should_output {
9070 if mysql_pretty_options {
9071 self.write_newline();
9072 self.write_indent();
9073 } else {
9074 self.write_space();
9075 }
9076 self.write_keyword(key);
9077 if key == "COMMENT" && !self.config.schema_comment_with_eq {
9079 self.write_space();
9080 } else {
9081 self.write("=");
9082 }
9083 self.write(value);
9084 }
9085 }
9086
9087 for option in &ct.tidb_table_options {
9088 if self.config.pretty {
9089 self.write_newline();
9090 self.write_indent();
9091 } else {
9092 self.write_space();
9093 }
9094 self.generate_tidb_table_option(option, false)?;
9095 }
9096
9097 if ct.temporary
9099 && matches!(
9100 self.config.dialect,
9101 Some(DialectType::Spark) | Some(DialectType::Databricks)
9102 )
9103 && ct.as_select.is_none()
9104 {
9105 self.write_space();
9106 self.write_keyword("USING PARQUET");
9107 }
9108
9109 if !ct.inherits.is_empty() {
9111 self.write_space();
9112 self.write_keyword("INHERITS");
9113 self.write(" (");
9114 for (i, parent) in ct.inherits.iter().enumerate() {
9115 if i > 0 {
9116 self.write(", ");
9117 }
9118 self.generate_table(parent)?;
9119 }
9120 self.write(")");
9121 }
9122
9123 if let Some(ref query) = ct.as_select {
9125 self.write_space();
9126 self.write_keyword("AS");
9127 self.write_space();
9128 let source_is_clickhouse =
9129 matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
9130 let wrap_as_select =
9131 ct.as_select_parenthesized && !(is_clickhouse && source_is_clickhouse);
9132 if wrap_as_select {
9133 self.write("(");
9134 }
9135 self.generate_expression(query)?;
9136 if wrap_as_select {
9137 self.write(")");
9138 }
9139
9140 if let Some(with_data) = ct.with_data {
9142 self.write_space();
9143 self.write_keyword("WITH");
9144 if !with_data {
9145 self.write_space();
9146 self.write_keyword("NO");
9147 }
9148 self.write_space();
9149 self.write_keyword("DATA");
9150 }
9151
9152 if let Some(with_statistics) = ct.with_statistics {
9154 self.write_space();
9155 self.write_keyword("AND");
9156 if !with_statistics {
9157 self.write_space();
9158 self.write_keyword("NO");
9159 }
9160 self.write_space();
9161 self.write_keyword("STATISTICS");
9162 }
9163
9164 for index in &ct.teradata_indexes {
9166 self.write_space();
9167 match index.kind {
9168 TeradataIndexKind::NoPrimary => {
9169 self.write_keyword("NO PRIMARY INDEX");
9170 }
9171 TeradataIndexKind::Primary => {
9172 self.write_keyword("PRIMARY INDEX");
9173 }
9174 TeradataIndexKind::PrimaryAmp => {
9175 self.write_keyword("PRIMARY AMP INDEX");
9176 }
9177 TeradataIndexKind::Unique => {
9178 self.write_keyword("UNIQUE INDEX");
9179 }
9180 TeradataIndexKind::UniquePrimary => {
9181 self.write_keyword("UNIQUE PRIMARY INDEX");
9182 }
9183 TeradataIndexKind::Secondary => {
9184 self.write_keyword("INDEX");
9185 }
9186 }
9187 if let Some(ref name) = index.name {
9189 self.write_space();
9190 self.write(name);
9191 }
9192 if !index.columns.is_empty() {
9194 self.write(" (");
9195 for (i, col) in index.columns.iter().enumerate() {
9196 if i > 0 {
9197 self.write(", ");
9198 }
9199 self.write(col);
9200 }
9201 self.write(")");
9202 }
9203 }
9204
9205 if let Some(ref on_commit) = ct.on_commit {
9207 self.write_space();
9208 self.write_keyword("ON COMMIT");
9209 self.write_space();
9210 match on_commit {
9211 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
9212 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
9213 }
9214 }
9215
9216 if !post_as_properties.is_empty() {
9217 for prop in post_as_properties {
9218 self.write_space();
9219 self.generate_expression(prop)?;
9220 }
9221 }
9222
9223 self.athena_hive_context = saved_athena_hive_context;
9225 return Ok(());
9226 }
9227
9228 if let Some(ref on_commit) = ct.on_commit {
9230 self.write_space();
9231 self.write_keyword("ON COMMIT");
9232 self.write_space();
9233 match on_commit {
9234 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
9235 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
9236 }
9237 }
9238
9239 self.athena_hive_context = saved_athena_hive_context;
9241
9242 Ok(())
9243 }
9244
9245 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
9248 self.generate_identifier(&col.name)?;
9250 if !matches!(col.data_type, DataType::Unknown) {
9252 self.write_space();
9253 self.generate_data_type(&col.data_type)?;
9254 }
9255 for constraint in &col.constraints {
9257 if let ColumnConstraint::Path(path_expr) = constraint {
9258 self.write_space();
9259 self.write_keyword("PATH");
9260 self.write_space();
9261 self.generate_expression(path_expr)?;
9262 }
9263 }
9264 Ok(())
9265 }
9266
9267 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
9268 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
9270 && col
9271 .constraints
9272 .iter()
9273 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
9274 let omit_computed_type = !self.config.computed_column_with_type
9276 && col
9277 .constraints
9278 .iter()
9279 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
9280
9281 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
9284
9285 let has_no_type = col.no_type
9288 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
9289 && col.constraints.is_empty());
9290
9291 self.generate_identifier(&col.name)?;
9292
9293 let serial_expansion = if matches!(
9295 self.config.dialect,
9296 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
9297 ) {
9298 if let DataType::Custom { ref name } = col.data_type {
9299 if name.eq_ignore_ascii_case("SERIAL") {
9300 Some("INT")
9301 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
9302 Some("BIGINT")
9303 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
9304 Some("SMALLINT")
9305 } else {
9306 None
9307 }
9308 } else {
9309 None
9310 }
9311 } else {
9312 None
9313 };
9314
9315 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
9316 {
9317 self.write_space();
9318 let saved_nullable_depth = self.clickhouse_nullable_depth;
9321 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
9322 self.clickhouse_nullable_depth = -1;
9323 }
9324 if let Some(int_type) = serial_expansion {
9325 self.write_keyword(int_type);
9327 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
9328 let unsigned_type = match &col.data_type {
9330 DataType::Int { .. } => Some("UINTEGER"),
9331 DataType::BigInt { .. } => Some("UBIGINT"),
9332 DataType::SmallInt { .. } => Some("USMALLINT"),
9333 DataType::TinyInt { .. } => Some("UTINYINT"),
9334 _ => None,
9335 };
9336 if let Some(utype) = unsigned_type {
9337 self.write_keyword(utype);
9338 } else {
9339 self.generate_data_type(&col.data_type)?;
9340 }
9341 } else {
9342 self.generate_data_type(&col.data_type)?;
9343 }
9344 self.clickhouse_nullable_depth = saved_nullable_depth;
9345 }
9346
9347 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
9350 self.write_space();
9351 self.write_keyword("UNSIGNED");
9352 }
9353 if col.zerofill {
9354 self.write_space();
9355 self.write_keyword("ZEROFILL");
9356 }
9357
9358 if let Some(ref charset) = col.character_set {
9362 self.write_space();
9363 self.write_keyword("CHARACTER SET");
9364 self.write_space();
9365 self.write(charset);
9366 }
9367
9368 if col.uppercase {
9369 self.write_space();
9370 self.write_keyword("UPPERCASE");
9371 }
9372
9373 if let Some(casespecific) = col.casespecific {
9374 self.write_space();
9375 if casespecific {
9376 self.write_keyword("CASESPECIFIC");
9377 } else {
9378 self.write_keyword("NOT CASESPECIFIC");
9379 }
9380 }
9381
9382 if let Some(ref format) = col.format {
9383 self.write_space();
9384 self.write_keyword("FORMAT");
9385 self.write(" '");
9386 self.write(format);
9387 self.write("'");
9388 }
9389
9390 if let Some(ref title) = col.title {
9391 self.write_space();
9392 self.write_keyword("TITLE");
9393 self.write(" '");
9394 self.write(title);
9395 self.write("'");
9396 }
9397
9398 if let Some(length) = col.inline_length {
9399 self.write_space();
9400 self.write_keyword("INLINE LENGTH");
9401 self.write(" ");
9402 self.write(&length.to_string());
9403 }
9404
9405 if let Some(ref compress) = col.compress {
9406 self.write_space();
9407 self.write_keyword("COMPRESS");
9408 if !compress.is_empty() {
9409 if compress.len() == 1 {
9411 if let Expression::Literal(lit) = &compress[0] {
9412 if let Literal::String(_) = lit.as_ref() {
9413 self.write_space();
9414 self.generate_expression(&compress[0])?;
9415 }
9416 } else {
9417 self.write(" (");
9418 self.generate_expression(&compress[0])?;
9419 self.write(")");
9420 }
9421 } else {
9422 self.write(" (");
9423 for (i, val) in compress.iter().enumerate() {
9424 if i > 0 {
9425 self.write(", ");
9426 }
9427 self.generate_expression(val)?;
9428 }
9429 self.write(")");
9430 }
9431 }
9432 }
9433
9434 if !col.constraint_order.is_empty() {
9437 let mut references_idx = 0;
9440 let mut check_idx = 0;
9441 let mut generated_idx = 0;
9442 let mut collate_idx = 0;
9443 let mut comment_idx = 0;
9444 let defer_not_null_after_identity = false;
9447 let mut pending_not_null_after_identity = false;
9448
9449 for constraint_type in &col.constraint_order {
9450 match constraint_type {
9451 ConstraintType::PrimaryKey => {
9452 if col.primary_key
9454 && !matches!(self.config.dialect, Some(DialectType::Materialize))
9455 {
9456 if let Some(ref cname) = col.primary_key_constraint_name {
9457 self.write_space();
9458 self.write_keyword("CONSTRAINT");
9459 self.write_space();
9460 self.write(cname);
9461 }
9462 self.write_space();
9463 self.write_keyword("PRIMARY KEY");
9464 if let Some(ref order) = col.primary_key_order {
9465 self.write_space();
9466 match order {
9467 SortOrder::Asc => self.write_keyword("ASC"),
9468 SortOrder::Desc => self.write_keyword("DESC"),
9469 }
9470 }
9471 }
9472 }
9473 ConstraintType::Unique => {
9474 if col.unique {
9475 if let Some(ref cname) = col.unique_constraint_name {
9476 self.write_space();
9477 self.write_keyword("CONSTRAINT");
9478 self.write_space();
9479 self.write(cname);
9480 }
9481 self.write_space();
9482 self.write_keyword("UNIQUE");
9483 if col.unique_nulls_not_distinct {
9485 self.write(" NULLS NOT DISTINCT");
9486 }
9487 }
9488 }
9489 ConstraintType::NotNull => {
9490 if col.nullable == Some(false) {
9491 if defer_not_null_after_identity {
9492 pending_not_null_after_identity = true;
9493 continue;
9494 }
9495 if let Some(ref cname) = col.not_null_constraint_name {
9496 self.write_space();
9497 self.write_keyword("CONSTRAINT");
9498 self.write_space();
9499 self.write(cname);
9500 }
9501 self.write_space();
9502 self.write_keyword("NOT NULL");
9503 }
9504 }
9505 ConstraintType::Null => {
9506 if col.nullable == Some(true) {
9507 self.write_space();
9508 self.write_keyword("NULL");
9509 }
9510 }
9511 ConstraintType::Default => {
9512 if let Some(ref default) = col.default {
9513 self.write_space();
9514 self.write_keyword("DEFAULT");
9515 self.write_space();
9516 self.generate_expression(default)?;
9517 }
9518 }
9519 ConstraintType::AutoIncrement => {
9520 if col.auto_increment {
9521 if matches!(
9523 self.config.dialect,
9524 Some(crate::dialects::DialectType::DuckDB)
9525 ) {
9526 } else if matches!(
9528 self.config.dialect,
9529 Some(crate::dialects::DialectType::Materialize)
9530 ) {
9531 if !matches!(col.nullable, Some(false)) {
9533 self.write_space();
9534 self.write_keyword("NOT NULL");
9535 }
9536 } else if matches!(
9537 self.config.dialect,
9538 Some(crate::dialects::DialectType::PostgreSQL)
9539 ) {
9540 self.write_space();
9542 self.generate_auto_increment_keyword(col)?;
9543 } else if matches!(
9544 self.config.dialect,
9545 Some(crate::dialects::DialectType::SQLite)
9546 ) && !col.primary_key
9547 && self
9548 .sqlite_inline_pk_columns
9549 .contains(&col.name.name.to_ascii_lowercase())
9550 {
9551 } else {
9554 self.write_space();
9555 self.generate_auto_increment_keyword(col)?;
9556 if pending_not_null_after_identity {
9557 self.write_space();
9558 self.write_keyword("NOT NULL");
9559 pending_not_null_after_identity = false;
9560 }
9561 }
9562 } }
9564 ConstraintType::AutoRandom => {
9565 if let Some(ref auto_random) = col.auto_random {
9566 self.write_space();
9567 self.generate_tidb_auto_random(auto_random)?;
9568 }
9569 }
9570 ConstraintType::References => {
9571 while references_idx < col.constraints.len() {
9573 if let ColumnConstraint::References(fk_ref) =
9574 &col.constraints[references_idx]
9575 {
9576 if let Some(ref name) = fk_ref.constraint_name {
9578 self.write_space();
9579 self.write_keyword("CONSTRAINT");
9580 self.write_space();
9581 self.write(name);
9582 }
9583 self.write_space();
9584 if fk_ref.has_foreign_key_keywords {
9585 self.write_keyword("FOREIGN KEY");
9586 self.write_space();
9587 }
9588 self.write_keyword("REFERENCES");
9589 self.write_space();
9590 self.generate_table(&fk_ref.table)?;
9591 if !fk_ref.columns.is_empty() {
9592 self.write(" (");
9593 for (i, c) in fk_ref.columns.iter().enumerate() {
9594 if i > 0 {
9595 self.write(", ");
9596 }
9597 self.generate_identifier(c)?;
9598 }
9599 self.write(")");
9600 }
9601 self.generate_referential_actions(fk_ref)?;
9602 references_idx += 1;
9603 break;
9604 }
9605 references_idx += 1;
9606 }
9607 }
9608 ConstraintType::Check => {
9609 while check_idx < col.constraints.len() {
9611 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
9612 if check_idx == 0 {
9614 if let Some(ref cname) = col.check_constraint_name {
9615 self.write_space();
9616 self.write_keyword("CONSTRAINT");
9617 self.write_space();
9618 self.write(cname);
9619 }
9620 }
9621 self.write_space();
9622 self.write_keyword("CHECK");
9623 self.write(" (");
9624 self.generate_expression(expr)?;
9625 self.write(")");
9626 check_idx += 1;
9627 break;
9628 }
9629 check_idx += 1;
9630 }
9631 }
9632 ConstraintType::GeneratedAsIdentity => {
9633 while generated_idx < col.constraints.len() {
9635 if let ColumnConstraint::GeneratedAsIdentity(gen) =
9636 &col.constraints[generated_idx]
9637 {
9638 self.write_space();
9639 if matches!(
9641 self.config.dialect,
9642 Some(crate::dialects::DialectType::Redshift)
9643 ) {
9644 self.write_keyword("IDENTITY");
9645 self.write("(");
9646 if let Some(ref start) = gen.start {
9647 self.generate_expression(start)?;
9648 } else {
9649 self.write("0");
9650 }
9651 self.write(", ");
9652 if let Some(ref incr) = gen.increment {
9653 self.generate_expression(incr)?;
9654 } else {
9655 self.write("1");
9656 }
9657 self.write(")");
9658 } else {
9659 self.write_keyword("GENERATED");
9660 if gen.always {
9661 self.write_space();
9662 self.write_keyword("ALWAYS");
9663 } else {
9664 self.write_space();
9665 self.write_keyword("BY DEFAULT");
9666 if gen.on_null {
9667 self.write_space();
9668 self.write_keyword("ON NULL");
9669 }
9670 }
9671 self.write_space();
9672 self.write_keyword("AS IDENTITY");
9673
9674 let has_options = gen.start.is_some()
9675 || gen.increment.is_some()
9676 || gen.minvalue.is_some()
9677 || gen.maxvalue.is_some()
9678 || gen.cycle.is_some();
9679 if has_options {
9680 self.write(" (");
9681 let mut first = true;
9682 if let Some(ref start) = gen.start {
9683 if !first {
9684 self.write(" ");
9685 }
9686 first = false;
9687 self.write_keyword("START WITH");
9688 self.write_space();
9689 self.generate_expression(start)?;
9690 }
9691 if let Some(ref incr) = gen.increment {
9692 if !first {
9693 self.write(" ");
9694 }
9695 first = false;
9696 self.write_keyword("INCREMENT BY");
9697 self.write_space();
9698 self.generate_expression(incr)?;
9699 }
9700 if let Some(ref minv) = gen.minvalue {
9701 if !first {
9702 self.write(" ");
9703 }
9704 first = false;
9705 self.write_keyword("MINVALUE");
9706 self.write_space();
9707 self.generate_expression(minv)?;
9708 }
9709 if let Some(ref maxv) = gen.maxvalue {
9710 if !first {
9711 self.write(" ");
9712 }
9713 first = false;
9714 self.write_keyword("MAXVALUE");
9715 self.write_space();
9716 self.generate_expression(maxv)?;
9717 }
9718 if let Some(cycle) = gen.cycle {
9719 if !first {
9720 self.write(" ");
9721 }
9722 if cycle {
9723 self.write_keyword("CYCLE");
9724 } else {
9725 self.write_keyword("NO CYCLE");
9726 }
9727 }
9728 self.write(")");
9729 }
9730 }
9731 generated_idx += 1;
9732 break;
9733 }
9734 generated_idx += 1;
9735 }
9736 }
9737 ConstraintType::Collate => {
9738 while collate_idx < col.constraints.len() {
9740 if let ColumnConstraint::Collate(collation) =
9741 &col.constraints[collate_idx]
9742 {
9743 self.write_space();
9744 self.write_keyword("COLLATE");
9745 self.write_space();
9746 self.generate_identifier(collation)?;
9747 collate_idx += 1;
9748 break;
9749 }
9750 collate_idx += 1;
9751 }
9752 }
9753 ConstraintType::Comment => {
9754 while comment_idx < col.constraints.len() {
9756 if let ColumnConstraint::Comment(comment) =
9757 &col.constraints[comment_idx]
9758 {
9759 self.write_space();
9760 self.write_keyword("COMMENT");
9761 self.write_space();
9762 self.generate_string_literal(comment)?;
9763 comment_idx += 1;
9764 break;
9765 }
9766 comment_idx += 1;
9767 }
9768 }
9769 ConstraintType::Tags => {
9770 for constraint in &col.constraints {
9772 if let ColumnConstraint::Tags(tags) = constraint {
9773 self.write_space();
9774 self.write_keyword("TAG");
9775 self.write(" (");
9776 for (i, expr) in tags.expressions.iter().enumerate() {
9777 if i > 0 {
9778 self.write(", ");
9779 }
9780 self.generate_expression(expr)?;
9781 }
9782 self.write(")");
9783 break;
9784 }
9785 }
9786 }
9787 ConstraintType::ComputedColumn => {
9788 for constraint in &col.constraints {
9790 if let ColumnConstraint::ComputedColumn(cc) = constraint {
9791 self.write_space();
9792 self.generate_computed_column_inline(cc)?;
9793 break;
9794 }
9795 }
9796 }
9797 ConstraintType::GeneratedAsRow => {
9798 for constraint in &col.constraints {
9800 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
9801 self.write_space();
9802 self.generate_generated_as_row_inline(gar)?;
9803 break;
9804 }
9805 }
9806 }
9807 ConstraintType::OnUpdate => {
9808 if let Some(ref expr) = col.on_update {
9809 self.write_space();
9810 self.write_keyword("ON UPDATE");
9811 self.write_space();
9812 self.generate_expression(expr)?;
9813 }
9814 }
9815 ConstraintType::Encode => {
9816 if let Some(ref encoding) = col.encoding {
9817 self.write_space();
9818 self.write_keyword("ENCODE");
9819 self.write_space();
9820 self.write(encoding);
9821 }
9822 }
9823 ConstraintType::Path => {
9824 for constraint in &col.constraints {
9826 if let ColumnConstraint::Path(path_expr) = constraint {
9827 self.write_space();
9828 self.write_keyword("PATH");
9829 self.write_space();
9830 self.generate_expression(path_expr)?;
9831 break;
9832 }
9833 }
9834 }
9835 }
9836 }
9837 if pending_not_null_after_identity {
9838 self.write_space();
9839 self.write_keyword("NOT NULL");
9840 }
9841 } else {
9842 if col.primary_key {
9844 self.write_space();
9845 self.write_keyword("PRIMARY KEY");
9846 if let Some(ref order) = col.primary_key_order {
9847 self.write_space();
9848 match order {
9849 SortOrder::Asc => self.write_keyword("ASC"),
9850 SortOrder::Desc => self.write_keyword("DESC"),
9851 }
9852 }
9853 }
9854
9855 if col.unique {
9856 self.write_space();
9857 self.write_keyword("UNIQUE");
9858 if col.unique_nulls_not_distinct {
9860 self.write(" NULLS NOT DISTINCT");
9861 }
9862 }
9863
9864 match col.nullable {
9865 Some(false) => {
9866 self.write_space();
9867 self.write_keyword("NOT NULL");
9868 }
9869 Some(true) => {
9870 self.write_space();
9871 self.write_keyword("NULL");
9872 }
9873 None => {}
9874 }
9875
9876 if let Some(ref default) = col.default {
9877 self.write_space();
9878 self.write_keyword("DEFAULT");
9879 self.write_space();
9880 self.generate_expression(default)?;
9881 }
9882
9883 if col.auto_increment {
9884 self.write_space();
9885 self.generate_auto_increment_keyword(col)?;
9886 }
9887
9888 if let Some(ref auto_random) = col.auto_random {
9889 self.write_space();
9890 self.generate_tidb_auto_random(auto_random)?;
9891 }
9892
9893 for constraint in &col.constraints {
9895 match constraint {
9896 ColumnConstraint::References(fk_ref) => {
9897 self.write_space();
9898 if fk_ref.has_foreign_key_keywords {
9899 self.write_keyword("FOREIGN KEY");
9900 self.write_space();
9901 }
9902 self.write_keyword("REFERENCES");
9903 self.write_space();
9904 self.generate_table(&fk_ref.table)?;
9905 if !fk_ref.columns.is_empty() {
9906 self.write(" (");
9907 for (i, c) in fk_ref.columns.iter().enumerate() {
9908 if i > 0 {
9909 self.write(", ");
9910 }
9911 self.generate_identifier(c)?;
9912 }
9913 self.write(")");
9914 }
9915 self.generate_referential_actions(fk_ref)?;
9916 }
9917 ColumnConstraint::Check(expr) => {
9918 self.write_space();
9919 self.write_keyword("CHECK");
9920 self.write(" (");
9921 self.generate_expression(expr)?;
9922 self.write(")");
9923 }
9924 ColumnConstraint::GeneratedAsIdentity(gen) => {
9925 self.write_space();
9926 if matches!(
9928 self.config.dialect,
9929 Some(crate::dialects::DialectType::Redshift)
9930 ) {
9931 self.write_keyword("IDENTITY");
9932 self.write("(");
9933 if let Some(ref start) = gen.start {
9934 self.generate_expression(start)?;
9935 } else {
9936 self.write("0");
9937 }
9938 self.write(", ");
9939 if let Some(ref incr) = gen.increment {
9940 self.generate_expression(incr)?;
9941 } else {
9942 self.write("1");
9943 }
9944 self.write(")");
9945 } else {
9946 self.write_keyword("GENERATED");
9947 if gen.always {
9948 self.write_space();
9949 self.write_keyword("ALWAYS");
9950 } else {
9951 self.write_space();
9952 self.write_keyword("BY DEFAULT");
9953 if gen.on_null {
9954 self.write_space();
9955 self.write_keyword("ON NULL");
9956 }
9957 }
9958 self.write_space();
9959 self.write_keyword("AS IDENTITY");
9960
9961 let has_options = gen.start.is_some()
9962 || gen.increment.is_some()
9963 || gen.minvalue.is_some()
9964 || gen.maxvalue.is_some()
9965 || gen.cycle.is_some();
9966 if has_options {
9967 self.write(" (");
9968 let mut first = true;
9969 if let Some(ref start) = gen.start {
9970 if !first {
9971 self.write(" ");
9972 }
9973 first = false;
9974 self.write_keyword("START WITH");
9975 self.write_space();
9976 self.generate_expression(start)?;
9977 }
9978 if let Some(ref incr) = gen.increment {
9979 if !first {
9980 self.write(" ");
9981 }
9982 first = false;
9983 self.write_keyword("INCREMENT BY");
9984 self.write_space();
9985 self.generate_expression(incr)?;
9986 }
9987 if let Some(ref minv) = gen.minvalue {
9988 if !first {
9989 self.write(" ");
9990 }
9991 first = false;
9992 self.write_keyword("MINVALUE");
9993 self.write_space();
9994 self.generate_expression(minv)?;
9995 }
9996 if let Some(ref maxv) = gen.maxvalue {
9997 if !first {
9998 self.write(" ");
9999 }
10000 first = false;
10001 self.write_keyword("MAXVALUE");
10002 self.write_space();
10003 self.generate_expression(maxv)?;
10004 }
10005 if let Some(cycle) = gen.cycle {
10006 if !first {
10007 self.write(" ");
10008 }
10009 if cycle {
10010 self.write_keyword("CYCLE");
10011 } else {
10012 self.write_keyword("NO CYCLE");
10013 }
10014 }
10015 self.write(")");
10016 }
10017 }
10018 }
10019 ColumnConstraint::Collate(collation) => {
10020 self.write_space();
10021 self.write_keyword("COLLATE");
10022 self.write_space();
10023 self.generate_identifier(collation)?;
10024 }
10025 ColumnConstraint::Comment(comment) => {
10026 self.write_space();
10027 self.write_keyword("COMMENT");
10028 self.write_space();
10029 self.generate_string_literal(comment)?;
10030 }
10031 ColumnConstraint::Path(path_expr) => {
10032 self.write_space();
10033 self.write_keyword("PATH");
10034 self.write_space();
10035 self.generate_expression(path_expr)?;
10036 }
10037 _ => {} }
10039 }
10040
10041 if let Some(ref encoding) = col.encoding {
10043 self.write_space();
10044 self.write_keyword("ENCODE");
10045 self.write_space();
10046 self.write(encoding);
10047 }
10048 }
10049
10050 if let Some(ref codec) = col.codec {
10052 self.write_space();
10053 self.write_keyword("CODEC");
10054 self.write("(");
10055 self.write(codec);
10056 self.write(")");
10057 }
10058
10059 if let Some(visible) = col.visible {
10060 self.write_space();
10061 if visible {
10062 self.write_keyword("VISIBLE");
10063 } else {
10064 self.write_keyword("INVISIBLE");
10065 }
10066 }
10067
10068 if let Some(ref ephemeral) = col.ephemeral {
10070 self.write_space();
10071 self.write_keyword("EPHEMERAL");
10072 if let Some(ref expr) = ephemeral {
10073 self.write_space();
10074 self.generate_expression(expr)?;
10075 }
10076 }
10077
10078 if let Some(ref mat_expr) = col.materialized_expr {
10080 self.write_space();
10081 self.write_keyword("MATERIALIZED");
10082 self.write_space();
10083 self.generate_expression(mat_expr)?;
10084 }
10085
10086 if let Some(ref alias_expr) = col.alias_expr {
10088 self.write_space();
10089 self.write_keyword("ALIAS");
10090 self.write_space();
10091 self.generate_expression(alias_expr)?;
10092 }
10093
10094 if let Some(ref ttl_expr) = col.ttl_expr {
10096 self.write_space();
10097 self.write_keyword("TTL");
10098 self.write_space();
10099 self.generate_expression(ttl_expr)?;
10100 }
10101
10102 if col.not_for_replication
10104 && matches!(
10105 self.config.dialect,
10106 Some(crate::dialects::DialectType::TSQL)
10107 | Some(crate::dialects::DialectType::Fabric)
10108 )
10109 {
10110 self.write_space();
10111 self.write_keyword("NOT FOR REPLICATION");
10112 }
10113
10114 if !col.options.is_empty() {
10116 self.write_space();
10117 self.generate_options_clause(&col.options)?;
10118 }
10119
10120 if !col.primary_key
10123 && self
10124 .sqlite_inline_pk_columns
10125 .contains(&col.name.name.to_ascii_lowercase())
10126 {
10127 self.write_space();
10128 self.write_keyword("PRIMARY KEY");
10129 if matches!(self.config.dialect, Some(DialectType::SQLite)) && col.auto_increment {
10130 self.write_space();
10131 self.generate_auto_increment_keyword(col)?;
10132 }
10133 }
10134
10135 if serial_expansion.is_some() {
10138 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
10139 self.write_space();
10140 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
10141 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
10142 self.write_space();
10143 self.write_keyword("NOT NULL");
10144 }
10145 }
10146
10147 Ok(())
10148 }
10149
10150 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
10151 match constraint {
10152 TableConstraint::PrimaryKey {
10153 name,
10154 columns,
10155 include_columns,
10156 modifiers,
10157 has_constraint_keyword,
10158 } => {
10159 if let Some(ref n) = name {
10160 if *has_constraint_keyword {
10161 self.write_keyword("CONSTRAINT");
10162 self.write_space();
10163 self.generate_identifier(n)?;
10164 self.write_space();
10165 }
10166 }
10167 self.write_keyword("PRIMARY KEY");
10168 if let Some(ref clustered) = modifiers.clustered {
10170 self.write_space();
10171 self.write_keyword(clustered);
10172 }
10173 if let Some(ref n) = name {
10175 if !*has_constraint_keyword {
10176 self.write_space();
10177 self.generate_identifier(n)?;
10178 }
10179 }
10180 self.write(" (");
10181 for (i, col) in columns.iter().enumerate() {
10182 if i > 0 {
10183 self.write(", ");
10184 }
10185 self.generate_identifier(col)?;
10186 }
10187 self.write(")");
10188 if !include_columns.is_empty() {
10189 self.write_space();
10190 self.write_keyword("INCLUDE");
10191 self.write(" (");
10192 for (i, col) in include_columns.iter().enumerate() {
10193 if i > 0 {
10194 self.write(", ");
10195 }
10196 self.generate_identifier(col)?;
10197 }
10198 self.write(")");
10199 }
10200 self.generate_constraint_modifiers(modifiers);
10201 }
10202 TableConstraint::Unique {
10203 name,
10204 columns,
10205 columns_parenthesized,
10206 modifiers,
10207 has_constraint_keyword,
10208 nulls_not_distinct,
10209 } => {
10210 if let Some(ref n) = name {
10211 if *has_constraint_keyword {
10212 self.write_keyword("CONSTRAINT");
10213 self.write_space();
10214 self.generate_identifier(n)?;
10215 self.write_space();
10216 }
10217 }
10218 self.write_keyword("UNIQUE");
10219 if let Some(ref clustered) = modifiers.clustered {
10221 self.write_space();
10222 self.write_keyword(clustered);
10223 }
10224 if *nulls_not_distinct {
10226 self.write(" NULLS NOT DISTINCT");
10227 }
10228 if let Some(ref n) = name {
10230 if !*has_constraint_keyword {
10231 self.write_space();
10232 self.generate_identifier(n)?;
10233 }
10234 }
10235 if *columns_parenthesized {
10236 self.write(" (");
10237 for (i, col) in columns.iter().enumerate() {
10238 if i > 0 {
10239 self.write(", ");
10240 }
10241 self.generate_identifier(col)?;
10242 }
10243 self.write(")");
10244 } else {
10245 for col in columns.iter() {
10247 self.write_space();
10248 self.generate_identifier(col)?;
10249 }
10250 }
10251 self.generate_constraint_modifiers(modifiers);
10252 }
10253 TableConstraint::ForeignKey {
10254 name,
10255 columns,
10256 references,
10257 on_delete,
10258 on_update,
10259 modifiers,
10260 } => {
10261 if let Some(ref n) = name {
10262 self.write_keyword("CONSTRAINT");
10263 self.write_space();
10264 self.generate_identifier(n)?;
10265 self.write_space();
10266 }
10267 self.write_keyword("FOREIGN KEY");
10268 self.write(" (");
10269 for (i, col) in columns.iter().enumerate() {
10270 if i > 0 {
10271 self.write(", ");
10272 }
10273 self.generate_identifier(col)?;
10274 }
10275 self.write(")");
10276 if let Some(ref refs) = references {
10277 self.write(" ");
10278 self.write_keyword("REFERENCES");
10279 self.write_space();
10280 self.generate_table(&refs.table)?;
10281 if !refs.columns.is_empty() {
10282 if self.config.pretty {
10283 self.write(" (");
10284 self.write_newline();
10285 self.indent_level += 1;
10286 for (i, col) in refs.columns.iter().enumerate() {
10287 if i > 0 {
10288 self.write(",");
10289 self.write_newline();
10290 }
10291 self.write_indent();
10292 self.generate_identifier(col)?;
10293 }
10294 self.indent_level -= 1;
10295 self.write_newline();
10296 self.write_indent();
10297 self.write(")");
10298 } else {
10299 self.write(" (");
10300 for (i, col) in refs.columns.iter().enumerate() {
10301 if i > 0 {
10302 self.write(", ");
10303 }
10304 self.generate_identifier(col)?;
10305 }
10306 self.write(")");
10307 }
10308 }
10309 self.generate_referential_actions(refs)?;
10310 } else {
10311 if let Some(ref action) = on_delete {
10313 self.write_space();
10314 self.write_keyword("ON DELETE");
10315 self.write_space();
10316 self.generate_referential_action(action);
10317 }
10318 if let Some(ref action) = on_update {
10319 self.write_space();
10320 self.write_keyword("ON UPDATE");
10321 self.write_space();
10322 self.generate_referential_action(action);
10323 }
10324 }
10325 self.generate_constraint_modifiers(modifiers);
10326 }
10327 TableConstraint::Check {
10328 name,
10329 expression,
10330 modifiers,
10331 } => {
10332 if let Some(ref n) = name {
10333 self.write_keyword("CONSTRAINT");
10334 self.write_space();
10335 self.generate_identifier(n)?;
10336 self.write_space();
10337 }
10338 self.write_keyword("CHECK");
10339 self.write(" (");
10340 self.generate_expression(expression)?;
10341 self.write(")");
10342 self.generate_constraint_modifiers(modifiers);
10343 }
10344 TableConstraint::Assume { name, expression } => {
10345 if let Some(ref n) = name {
10346 self.write_keyword("CONSTRAINT");
10347 self.write_space();
10348 self.generate_identifier(n)?;
10349 self.write_space();
10350 }
10351 self.write_keyword("ASSUME");
10352 self.write(" (");
10353 self.generate_expression(expression)?;
10354 self.write(")");
10355 }
10356 TableConstraint::Default {
10357 name,
10358 expression,
10359 column,
10360 } => {
10361 if let Some(ref n) = name {
10362 self.write_keyword("CONSTRAINT");
10363 self.write_space();
10364 self.generate_identifier(n)?;
10365 self.write_space();
10366 }
10367 self.write_keyword("DEFAULT");
10368 self.write_space();
10369 self.generate_expression(expression)?;
10370 self.write_space();
10371 self.write_keyword("FOR");
10372 self.write_space();
10373 self.generate_identifier(column)?;
10374 }
10375 TableConstraint::Index {
10376 name,
10377 columns,
10378 kind,
10379 modifiers,
10380 use_key_keyword,
10381 expression,
10382 index_type,
10383 granularity,
10384 } => {
10385 if expression.is_some() {
10387 self.write_keyword("INDEX");
10388 if let Some(ref n) = name {
10389 self.write_space();
10390 self.generate_identifier(n)?;
10391 }
10392 if let Some(ref expr) = expression {
10393 self.write_space();
10394 self.generate_expression(expr)?;
10395 }
10396 if let Some(ref idx_type) = index_type {
10397 self.write_space();
10398 self.write_keyword("TYPE");
10399 self.write_space();
10400 self.generate_expression(idx_type)?;
10401 }
10402 if let Some(ref gran) = granularity {
10403 self.write_space();
10404 self.write_keyword("GRANULARITY");
10405 self.write_space();
10406 self.generate_expression(gran)?;
10407 }
10408 } else {
10409 use crate::dialects::DialectType;
10413 let index_keyword = if *use_key_keyword
10414 && !matches!(self.config.dialect, Some(DialectType::MySQL))
10415 {
10416 "KEY"
10417 } else {
10418 "INDEX"
10419 };
10420
10421 if let Some(ref k) = kind {
10423 self.write_keyword(k);
10424 if k != "UNIQUE" {
10426 self.write_space();
10427 self.write_keyword(index_keyword);
10428 }
10429 } else {
10430 self.write_keyword(index_keyword);
10431 }
10432
10433 if modifiers.using_before_columns && name.is_none() {
10435 if let Some(ref using) = modifiers.using {
10436 self.write_space();
10437 self.write_keyword("USING");
10438 self.write_space();
10439 self.write_keyword(using);
10440 }
10441 }
10442
10443 if let Some(ref n) = name {
10445 self.write_space();
10446 self.generate_identifier(n)?;
10447 }
10448
10449 if modifiers.using_before_columns && name.is_some() {
10451 if let Some(ref using) = modifiers.using {
10452 self.write_space();
10453 self.write_keyword("USING");
10454 self.write_space();
10455 self.write_keyword(using);
10456 }
10457 }
10458
10459 self.write(" (");
10461 for (i, col) in columns.iter().enumerate() {
10462 if i > 0 {
10463 self.write(", ");
10464 }
10465 self.generate_identifier(col)?;
10466 }
10467 self.write(")");
10468
10469 if !modifiers.using_before_columns {
10471 if let Some(ref using) = modifiers.using {
10472 self.write_space();
10473 self.write_keyword("USING");
10474 self.write_space();
10475 self.write_keyword(using);
10476 }
10477 }
10478
10479 self.generate_constraint_modifiers_without_using(modifiers);
10481 }
10482 }
10483 TableConstraint::Projection { name, expression } => {
10484 self.write_keyword("PROJECTION");
10486 self.write_space();
10487 self.generate_identifier(name)?;
10488 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
10489 if let Expression::Raw(raw) = expression {
10490 if raw
10491 .sql
10492 .trim_start()
10493 .to_ascii_uppercase()
10494 .starts_with("INDEX ")
10495 {
10496 self.write_space();
10497 self.write(raw.sql.trim());
10498 return Ok(());
10499 }
10500 }
10501 }
10502 self.write(" (");
10503 self.generate_expression(expression)?;
10504 self.write(")");
10505 }
10506 TableConstraint::Like { source, options } => {
10507 self.write_keyword("LIKE");
10508 self.write_space();
10509 self.generate_table(source)?;
10510 for (action, prop) in options {
10511 self.write_space();
10512 match action {
10513 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
10514 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
10515 }
10516 self.write_space();
10517 self.write_keyword(prop);
10518 }
10519 }
10520 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
10521 self.write_keyword("PERIOD FOR SYSTEM_TIME");
10522 self.write(" (");
10523 self.generate_identifier(start_col)?;
10524 self.write(", ");
10525 self.generate_identifier(end_col)?;
10526 self.write(")");
10527 }
10528 TableConstraint::Exclude {
10529 name,
10530 using,
10531 elements,
10532 include_columns,
10533 where_clause,
10534 with_params,
10535 using_index_tablespace,
10536 modifiers: _,
10537 } => {
10538 if let Some(ref n) = name {
10539 self.write_keyword("CONSTRAINT");
10540 self.write_space();
10541 self.generate_identifier(n)?;
10542 self.write_space();
10543 }
10544 self.write_keyword("EXCLUDE");
10545 if let Some(ref method) = using {
10546 self.write_space();
10547 self.write_keyword("USING");
10548 self.write_space();
10549 self.write(method);
10550 self.write("(");
10551 } else {
10552 self.write(" (");
10553 }
10554 for (i, elem) in elements.iter().enumerate() {
10555 if i > 0 {
10556 self.write(", ");
10557 }
10558 self.write(&elem.expression);
10559 self.write_space();
10560 self.write_keyword("WITH");
10561 self.write_space();
10562 self.write(&elem.operator);
10563 }
10564 self.write(")");
10565 if !include_columns.is_empty() {
10566 self.write_space();
10567 self.write_keyword("INCLUDE");
10568 self.write(" (");
10569 for (i, col) in include_columns.iter().enumerate() {
10570 if i > 0 {
10571 self.write(", ");
10572 }
10573 self.generate_identifier(col)?;
10574 }
10575 self.write(")");
10576 }
10577 if !with_params.is_empty() {
10578 self.write_space();
10579 self.write_keyword("WITH");
10580 self.write(" (");
10581 for (i, (key, val)) in with_params.iter().enumerate() {
10582 if i > 0 {
10583 self.write(", ");
10584 }
10585 self.write(key);
10586 self.write("=");
10587 self.write(val);
10588 }
10589 self.write(")");
10590 }
10591 if let Some(ref tablespace) = using_index_tablespace {
10592 self.write_space();
10593 self.write_keyword("USING INDEX TABLESPACE");
10594 self.write_space();
10595 self.write(tablespace);
10596 }
10597 if let Some(ref where_expr) = where_clause {
10598 self.write_space();
10599 self.write_keyword("WHERE");
10600 self.write(" (");
10601 self.generate_expression(where_expr)?;
10602 self.write(")");
10603 }
10604 }
10605 TableConstraint::Tags(tags) => {
10606 self.write_keyword("TAG");
10607 self.write(" (");
10608 for (i, expr) in tags.expressions.iter().enumerate() {
10609 if i > 0 {
10610 self.write(", ");
10611 }
10612 self.generate_expression(expr)?;
10613 }
10614 self.write(")");
10615 }
10616 TableConstraint::InitiallyDeferred { deferred } => {
10617 self.write_keyword("INITIALLY");
10618 self.write_space();
10619 if *deferred {
10620 self.write_keyword("DEFERRED");
10621 } else {
10622 self.write_keyword("IMMEDIATE");
10623 }
10624 }
10625 }
10626 Ok(())
10627 }
10628
10629 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10630 if let Some(using) = &modifiers.using {
10632 self.write_space();
10633 self.write_keyword("USING");
10634 self.write_space();
10635 self.write_keyword(using);
10636 }
10637 if let Some(enforced) = modifiers.enforced {
10639 self.write_space();
10640 if enforced {
10641 self.write_keyword("ENFORCED");
10642 } else {
10643 self.write_keyword("NOT ENFORCED");
10644 }
10645 }
10646 if let Some(deferrable) = modifiers.deferrable {
10648 self.write_space();
10649 if deferrable {
10650 self.write_keyword("DEFERRABLE");
10651 } else {
10652 self.write_keyword("NOT DEFERRABLE");
10653 }
10654 }
10655 if let Some(initially_deferred) = modifiers.initially_deferred {
10657 self.write_space();
10658 if initially_deferred {
10659 self.write_keyword("INITIALLY DEFERRED");
10660 } else {
10661 self.write_keyword("INITIALLY IMMEDIATE");
10662 }
10663 }
10664 if modifiers.norely {
10666 self.write_space();
10667 self.write_keyword("NORELY");
10668 }
10669 if modifiers.rely {
10671 self.write_space();
10672 self.write_keyword("RELY");
10673 }
10674 if modifiers.not_valid {
10676 self.write_space();
10677 self.write_keyword("NOT VALID");
10678 }
10679 if let Some(on_conflict) = &modifiers.on_conflict {
10681 self.write_space();
10682 self.write_keyword("ON CONFLICT");
10683 self.write_space();
10684 self.write_keyword(on_conflict);
10685 }
10686 if !modifiers.with_options.is_empty() {
10688 self.write_space();
10689 self.write_keyword("WITH");
10690 self.write(" (");
10691 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
10692 if i > 0 {
10693 self.write(", ");
10694 }
10695 self.write(key);
10696 self.write("=");
10697 self.write(value);
10698 }
10699 self.write(")");
10700 }
10701 if let Some(ref fg) = modifiers.on_filegroup {
10703 self.write_space();
10704 self.write_keyword("ON");
10705 self.write_space();
10706 let _ = self.generate_identifier(fg);
10707 }
10708 }
10709
10710 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
10712 if let Some(enforced) = modifiers.enforced {
10714 self.write_space();
10715 if enforced {
10716 self.write_keyword("ENFORCED");
10717 } else {
10718 self.write_keyword("NOT ENFORCED");
10719 }
10720 }
10721 if let Some(deferrable) = modifiers.deferrable {
10723 self.write_space();
10724 if deferrable {
10725 self.write_keyword("DEFERRABLE");
10726 } else {
10727 self.write_keyword("NOT DEFERRABLE");
10728 }
10729 }
10730 if let Some(initially_deferred) = modifiers.initially_deferred {
10732 self.write_space();
10733 if initially_deferred {
10734 self.write_keyword("INITIALLY DEFERRED");
10735 } else {
10736 self.write_keyword("INITIALLY IMMEDIATE");
10737 }
10738 }
10739 if modifiers.norely {
10741 self.write_space();
10742 self.write_keyword("NORELY");
10743 }
10744 if modifiers.rely {
10746 self.write_space();
10747 self.write_keyword("RELY");
10748 }
10749 if modifiers.not_valid {
10751 self.write_space();
10752 self.write_keyword("NOT VALID");
10753 }
10754 if let Some(on_conflict) = &modifiers.on_conflict {
10756 self.write_space();
10757 self.write_keyword("ON CONFLICT");
10758 self.write_space();
10759 self.write_keyword(on_conflict);
10760 }
10761 self.generate_index_specific_modifiers(modifiers);
10763 }
10764
10765 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10767 if let Some(ref comment) = modifiers.comment {
10768 self.write_space();
10769 self.write_keyword("COMMENT");
10770 self.write(" '");
10771 self.write(comment);
10772 self.write("'");
10773 }
10774 if let Some(visible) = modifiers.visible {
10775 self.write_space();
10776 if visible {
10777 self.write_keyword("VISIBLE");
10778 } else {
10779 self.write_keyword("INVISIBLE");
10780 }
10781 }
10782 if let Some(ref attr) = modifiers.engine_attribute {
10783 self.write_space();
10784 self.write_keyword("ENGINE_ATTRIBUTE");
10785 self.write(" = '");
10786 self.write(attr);
10787 self.write("'");
10788 }
10789 if let Some(ref parser) = modifiers.with_parser {
10790 self.write_space();
10791 self.write_keyword("WITH PARSER");
10792 self.write_space();
10793 self.write(parser);
10794 }
10795 }
10796
10797 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
10798 if !fk_ref.match_after_actions {
10800 if let Some(ref match_type) = fk_ref.match_type {
10801 self.write_space();
10802 self.write_keyword("MATCH");
10803 self.write_space();
10804 match match_type {
10805 MatchType::Full => self.write_keyword("FULL"),
10806 MatchType::Partial => self.write_keyword("PARTIAL"),
10807 MatchType::Simple => self.write_keyword("SIMPLE"),
10808 }
10809 }
10810 }
10811
10812 if fk_ref.on_update_first {
10814 if let Some(ref action) = fk_ref.on_update {
10815 self.write_space();
10816 self.write_keyword("ON UPDATE");
10817 self.write_space();
10818 self.generate_referential_action(action);
10819 }
10820 if let Some(ref action) = fk_ref.on_delete {
10821 self.write_space();
10822 self.write_keyword("ON DELETE");
10823 self.write_space();
10824 self.generate_referential_action(action);
10825 }
10826 } else {
10827 if let Some(ref action) = fk_ref.on_delete {
10828 self.write_space();
10829 self.write_keyword("ON DELETE");
10830 self.write_space();
10831 self.generate_referential_action(action);
10832 }
10833 if let Some(ref action) = fk_ref.on_update {
10834 self.write_space();
10835 self.write_keyword("ON UPDATE");
10836 self.write_space();
10837 self.generate_referential_action(action);
10838 }
10839 }
10840
10841 if fk_ref.match_after_actions {
10843 if let Some(ref match_type) = fk_ref.match_type {
10844 self.write_space();
10845 self.write_keyword("MATCH");
10846 self.write_space();
10847 match match_type {
10848 MatchType::Full => self.write_keyword("FULL"),
10849 MatchType::Partial => self.write_keyword("PARTIAL"),
10850 MatchType::Simple => self.write_keyword("SIMPLE"),
10851 }
10852 }
10853 }
10854
10855 if let Some(deferrable) = fk_ref.deferrable {
10857 self.write_space();
10858 if deferrable {
10859 self.write_keyword("DEFERRABLE");
10860 } else {
10861 self.write_keyword("NOT DEFERRABLE");
10862 }
10863 }
10864
10865 Ok(())
10866 }
10867
10868 fn generate_referential_action(&mut self, action: &ReferentialAction) {
10869 match action {
10870 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
10871 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
10872 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
10873 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
10874 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
10875 }
10876 }
10877
10878 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
10879 if let Some(ref object_id_args) = dt.object_id_args {
10881 if matches!(
10882 self.config.dialect,
10883 Some(crate::dialects::DialectType::TSQL)
10884 | Some(crate::dialects::DialectType::Fabric)
10885 ) {
10886 self.write_keyword("IF NOT OBJECT_ID");
10887 self.write("(");
10888 self.write(object_id_args);
10889 self.write(")");
10890 self.write_space();
10891 self.write_keyword("IS NULL BEGIN DROP TABLE");
10892 self.write_space();
10893 for (i, table) in dt.names.iter().enumerate() {
10894 if i > 0 {
10895 self.write(", ");
10896 }
10897 self.generate_table(table)?;
10898 }
10899 self.write("; ");
10900 self.write_keyword("END");
10901 return Ok(());
10902 }
10903 }
10904
10905 let saved_athena_hive_context = self.athena_hive_context;
10907 if matches!(
10908 self.config.dialect,
10909 Some(crate::dialects::DialectType::Athena)
10910 ) {
10911 self.athena_hive_context = true;
10912 }
10913
10914 for comment in &dt.leading_comments {
10916 self.write_formatted_comment(comment);
10917 self.write_space();
10918 }
10919 if dt.iceberg {
10920 self.write_keyword("DROP ICEBERG TABLE");
10921 } else {
10922 self.write_keyword("DROP TABLE");
10923 }
10924
10925 if dt.if_exists {
10926 self.write_space();
10927 self.write_keyword("IF EXISTS");
10928 }
10929
10930 self.write_space();
10931 for (i, table) in dt.names.iter().enumerate() {
10932 if i > 0 {
10933 self.write(", ");
10934 }
10935 self.generate_table(table)?;
10936 }
10937
10938 if dt.cascade_constraints {
10939 self.write_space();
10940 self.write_keyword("CASCADE CONSTRAINTS");
10941 } else if dt.cascade {
10942 self.write_space();
10943 self.write_keyword("CASCADE");
10944 }
10945
10946 if dt.restrict {
10947 self.write_space();
10948 self.write_keyword("RESTRICT");
10949 }
10950
10951 if dt.purge {
10952 self.write_space();
10953 self.write_keyword("PURGE");
10954 }
10955
10956 if dt.sync {
10957 self.write_space();
10958 self.write_keyword("SYNC");
10959 }
10960
10961 self.athena_hive_context = saved_athena_hive_context;
10963
10964 Ok(())
10965 }
10966
10967 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10968 self.write_keyword("UNDROP");
10969 self.write_space();
10970 self.write_keyword(&u.kind);
10971 if u.if_exists {
10972 self.write_space();
10973 self.write_keyword("IF EXISTS");
10974 }
10975 self.write_space();
10976 self.generate_table(&u.name)?;
10977 if let Some(rename_to) = &u.rename_to {
10978 self.write_space();
10979 self.write_keyword("RENAME TO");
10980 self.write_space();
10981 self.generate_table(rename_to)?;
10982 }
10983 Ok(())
10984 }
10985
10986 fn generate_split_table(&mut self, split: &SplitTable) -> Result<()> {
10987 if !matches!(self.config.dialect, Some(DialectType::TiDB)) {
10988 return self
10989 .write_unsupported_comment("SPLIT TABLE is only supported by the TiDB dialect");
10990 }
10991
10992 match &split.partition_scope {
10993 SplitTablePartitionScope::Table => self.write_keyword("SPLIT TABLE"),
10994 SplitTablePartitionScope::AllPartitions
10995 | SplitTablePartitionScope::Partitions { .. } => {
10996 self.write_keyword("SPLIT PARTITION TABLE")
10997 }
10998 }
10999 self.write_space();
11000 self.generate_table(&split.table)?;
11001 if let SplitTablePartitionScope::Partitions { names } = &split.partition_scope {
11002 self.write_space();
11003 self.write_keyword("PARTITION");
11004 self.write(" (");
11005 for (index, name) in names.iter().enumerate() {
11006 if index > 0 {
11007 self.write(", ");
11008 }
11009 self.generate_identifier(name)?;
11010 }
11011 self.write(")");
11012 }
11013 if let Some(index) = &split.index {
11014 self.write_space();
11015 self.write_keyword("INDEX");
11016 self.write_space();
11017 self.generate_identifier(index)?;
11018 }
11019 match &split.mode {
11020 SplitTableMode::Between {
11021 lower,
11022 upper,
11023 regions,
11024 } => {
11025 self.write_space();
11026 self.write_keyword("BETWEEN");
11027 self.write_space();
11028 self.generate_tidb_split_values(lower)?;
11029 self.write_space();
11030 self.write_keyword("AND");
11031 self.write_space();
11032 self.generate_tidb_split_values(upper)?;
11033 self.write_space();
11034 self.write_keyword("REGIONS");
11035 self.write_space();
11036 self.write(®ions.to_string());
11037 }
11038 SplitTableMode::By { points } => {
11039 self.write_space();
11040 self.write_keyword("BY");
11041 self.write_space();
11042 for (index, point) in points.iter().enumerate() {
11043 if index > 0 {
11044 self.write(", ");
11045 }
11046 self.generate_tidb_split_values(point)?;
11047 }
11048 }
11049 }
11050 Ok(())
11051 }
11052
11053 fn generate_tidb_split_values(&mut self, values: &[Expression]) -> Result<()> {
11054 self.write("(");
11055 for (index, value) in values.iter().enumerate() {
11056 if index > 0 {
11057 self.write(", ");
11058 }
11059 self.generate_expression(value)?;
11060 }
11061 self.write(")");
11062 Ok(())
11063 }
11064
11065 fn generate_flashback_table(&mut self, flashback: &FlashbackTable) -> Result<()> {
11066 if !matches!(self.config.dialect, Some(DialectType::TiDB)) {
11067 return self.write_unsupported_comment(
11068 "FLASHBACK TABLE is only supported by the TiDB dialect",
11069 );
11070 }
11071 self.write_keyword("FLASHBACK TABLE");
11072 self.write_space();
11073 self.generate_table(&flashback.table)?;
11074 if let Some(rename_to) = &flashback.rename_to {
11075 self.write_space();
11076 self.write_keyword("TO");
11077 self.write_space();
11078 self.generate_identifier(rename_to)?;
11079 }
11080 Ok(())
11081 }
11082
11083 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
11084 let saved_athena_hive_context = self.athena_hive_context;
11086 if matches!(
11087 self.config.dialect,
11088 Some(crate::dialects::DialectType::Athena)
11089 ) {
11090 self.athena_hive_context = true;
11091 }
11092
11093 self.write_keyword("ALTER");
11094 if let Some(ref modifier) = at.table_modifier {
11096 if !matches!(
11097 self.config.dialect,
11098 Some(crate::dialects::DialectType::DuckDB)
11099 ) {
11100 self.write_space();
11101 self.write_keyword(modifier);
11102 }
11103 }
11104 self.write(" ");
11105 self.write_keyword("TABLE");
11106 if at.if_exists {
11107 self.write_space();
11108 self.write_keyword("IF EXISTS");
11109 }
11110 self.write_space();
11111 self.generate_table(&at.name)?;
11112
11113 if let Some(ref on_cluster) = at.on_cluster {
11115 self.write_space();
11116 self.generate_on_cluster(on_cluster)?;
11117 }
11118
11119 if let Some(ref partition) = at.partition {
11121 self.write_space();
11122 self.write_keyword("PARTITION");
11123 self.write("(");
11124 for (i, (key, value)) in partition.iter().enumerate() {
11125 if i > 0 {
11126 self.write(", ");
11127 }
11128 self.generate_identifier(key)?;
11129 self.write(" = ");
11130 self.generate_expression(value)?;
11131 }
11132 self.write(")");
11133 }
11134
11135 if let Some(ref with_check) = at.with_check {
11137 self.write_space();
11138 self.write_keyword(with_check);
11139 }
11140
11141 if self.config.pretty {
11142 self.write_newline();
11144 self.indent_level += 1;
11145 for (i, action) in at.actions.iter().enumerate() {
11146 let is_continuation = i > 0
11148 && matches!(
11149 (&at.actions[i - 1], action),
11150 (
11151 AlterTableAction::AddColumn { .. },
11152 AlterTableAction::AddColumn { .. }
11153 ) | (
11154 AlterTableAction::AddConstraint(_),
11155 AlterTableAction::AddConstraint(_)
11156 )
11157 );
11158 if i > 0 {
11159 self.write(",");
11160 self.write_newline();
11161 }
11162 self.write_indent();
11163 self.generate_alter_action_with_continuation(action, is_continuation)?;
11164 }
11165 self.indent_level -= 1;
11166 } else {
11167 for (i, action) in at.actions.iter().enumerate() {
11168 let is_continuation = i > 0
11170 && matches!(
11171 (&at.actions[i - 1], action),
11172 (
11173 AlterTableAction::AddColumn { .. },
11174 AlterTableAction::AddColumn { .. }
11175 ) | (
11176 AlterTableAction::AddConstraint(_),
11177 AlterTableAction::AddConstraint(_)
11178 )
11179 );
11180 if i > 0 {
11181 self.write(",");
11182 }
11183 self.write_space();
11184 self.generate_alter_action_with_continuation(action, is_continuation)?;
11185 }
11186 }
11187
11188 if let Some(ref algorithm) = at.algorithm {
11190 self.write(", ");
11191 self.write_keyword("ALGORITHM");
11192 self.write("=");
11193 self.write_keyword(algorithm);
11194 }
11195 if let Some(ref lock) = at.lock {
11196 self.write(", ");
11197 self.write_keyword("LOCK");
11198 self.write("=");
11199 self.write_keyword(lock);
11200 }
11201
11202 self.athena_hive_context = saved_athena_hive_context;
11204
11205 Ok(())
11206 }
11207
11208 fn generate_alter_action_with_continuation(
11209 &mut self,
11210 action: &AlterTableAction,
11211 is_continuation: bool,
11212 ) -> Result<()> {
11213 match action {
11214 AlterTableAction::AddColumn {
11215 column,
11216 if_not_exists,
11217 position,
11218 } => {
11219 use crate::dialects::DialectType;
11220 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
11224 let is_tsql_like = matches!(
11225 self.config.dialect,
11226 Some(DialectType::TSQL) | Some(DialectType::Fabric)
11227 );
11228 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
11230
11231 if is_continuation && (is_snowflake || is_tsql_like) {
11232 } else if is_snowflake {
11234 self.write_keyword("ADD");
11235 self.write_space();
11236 } else if is_athena {
11237 self.write_keyword("ADD COLUMNS");
11239 self.write(" (");
11240 } else if self.config.alter_table_include_column_keyword {
11241 self.write_keyword("ADD COLUMN");
11242 self.write_space();
11243 } else {
11244 self.write_keyword("ADD");
11246 self.write_space();
11247 }
11248
11249 if *if_not_exists {
11250 self.write_keyword("IF NOT EXISTS");
11251 self.write_space();
11252 }
11253 self.generate_column_def(column)?;
11254
11255 if is_athena {
11257 self.write(")");
11258 }
11259
11260 if let Some(pos) = position {
11262 self.write_space();
11263 match pos {
11264 ColumnPosition::First => self.write_keyword("FIRST"),
11265 ColumnPosition::After(col_name) => {
11266 self.write_keyword("AFTER");
11267 self.write_space();
11268 self.generate_identifier(col_name)?;
11269 }
11270 }
11271 }
11272 }
11273 AlterTableAction::DropColumn {
11274 name,
11275 if_exists,
11276 cascade,
11277 } => {
11278 self.write_keyword("DROP COLUMN");
11279 if *if_exists {
11280 self.write_space();
11281 self.write_keyword("IF EXISTS");
11282 }
11283 self.write_space();
11284 self.generate_identifier(name)?;
11285 if *cascade {
11286 self.write_space();
11287 self.write_keyword("CASCADE");
11288 }
11289 }
11290 AlterTableAction::DropColumns { names } => {
11291 self.write_keyword("DROP COLUMNS");
11292 self.write(" (");
11293 for (i, name) in names.iter().enumerate() {
11294 if i > 0 {
11295 self.write(", ");
11296 }
11297 self.generate_identifier(name)?;
11298 }
11299 self.write(")");
11300 }
11301 AlterTableAction::RenameColumn {
11302 old_name,
11303 new_name,
11304 if_exists,
11305 } => {
11306 self.write_keyword("RENAME COLUMN");
11307 if *if_exists {
11308 self.write_space();
11309 self.write_keyword("IF EXISTS");
11310 }
11311 self.write_space();
11312 self.generate_identifier(old_name)?;
11313 self.write_space();
11314 self.write_keyword("TO");
11315 self.write_space();
11316 self.generate_identifier(new_name)?;
11317 }
11318 AlterTableAction::AlterColumn {
11319 name,
11320 action,
11321 use_modify_keyword,
11322 } => {
11323 use crate::dialects::DialectType;
11324 let use_modify = *use_modify_keyword
11327 || (matches!(self.config.dialect, Some(DialectType::MySQL))
11328 && matches!(action, AlterColumnAction::SetDataType { .. }));
11329 if use_modify {
11330 self.write_keyword("MODIFY COLUMN");
11331 self.write_space();
11332 self.generate_identifier(name)?;
11333 if let AlterColumnAction::SetDataType {
11335 data_type,
11336 using: _,
11337 collate,
11338 } = action
11339 {
11340 self.write_space();
11341 self.generate_data_type(data_type)?;
11342 if let Some(collate_name) = collate {
11344 self.write_space();
11345 self.write_keyword("COLLATE");
11346 self.write_space();
11347 self.write(&format!("'{}'", collate_name));
11349 }
11350 } else {
11351 self.write_space();
11352 self.generate_alter_column_action(action)?;
11353 }
11354 } else if matches!(self.config.dialect, Some(DialectType::Hive))
11355 && matches!(action, AlterColumnAction::SetDataType { .. })
11356 {
11357 self.write_keyword("CHANGE COLUMN");
11359 self.write_space();
11360 self.generate_identifier(name)?;
11361 self.write_space();
11362 self.generate_identifier(name)?;
11363 if let AlterColumnAction::SetDataType { data_type, .. } = action {
11364 self.write_space();
11365 self.generate_data_type(data_type)?;
11366 }
11367 } else {
11368 self.write_keyword("ALTER COLUMN");
11369 self.write_space();
11370 self.generate_identifier(name)?;
11371 self.write_space();
11372 self.generate_alter_column_action(action)?;
11373 }
11374 }
11375 AlterTableAction::ModifyColumn {
11376 column,
11377 if_exists,
11378 position,
11379 } => {
11380 if !matches!(
11381 self.config.dialect,
11382 Some(DialectType::TiDB) | Some(DialectType::MySQL)
11383 ) {
11384 return self.write_unsupported_comment(
11385 "MODIFY COLUMN is only supported by MySQL-compatible dialects",
11386 );
11387 }
11388 self.write_keyword("MODIFY COLUMN");
11389 self.write_space();
11390 if *if_exists {
11391 self.write_keyword("IF EXISTS");
11392 self.write_space();
11393 }
11394 self.generate_column_def(column)?;
11395 if let Some(position) = position {
11396 self.write_space();
11397 match position {
11398 ColumnPosition::First => self.write_keyword("FIRST"),
11399 ColumnPosition::After(name) => {
11400 self.write_keyword("AFTER");
11401 self.write_space();
11402 self.generate_identifier(name)?;
11403 }
11404 }
11405 }
11406 }
11407 AlterTableAction::RenameTable(new_name) => {
11408 let mysql_like = matches!(
11410 self.config.dialect,
11411 Some(DialectType::MySQL)
11412 | Some(DialectType::Doris)
11413 | Some(DialectType::StarRocks)
11414 | Some(DialectType::SingleStore)
11415 );
11416 if mysql_like {
11417 self.write_keyword("RENAME");
11418 } else {
11419 self.write_keyword("RENAME TO");
11420 }
11421 self.write_space();
11422 let rename_table_with_db = !matches!(
11424 self.config.dialect,
11425 Some(DialectType::Doris)
11426 | Some(DialectType::DuckDB)
11427 | Some(DialectType::BigQuery)
11428 | Some(DialectType::PostgreSQL)
11429 );
11430 if !rename_table_with_db {
11431 let mut stripped = new_name.clone();
11432 stripped.schema = None;
11433 stripped.catalog = None;
11434 self.generate_table(&stripped)?;
11435 } else {
11436 self.generate_table(new_name)?;
11437 }
11438 }
11439 AlterTableAction::AddConstraint(constraint) => {
11440 if !is_continuation {
11443 self.write_keyword("ADD");
11444 self.write_space();
11445 }
11446 self.generate_table_constraint(constraint)?;
11447 }
11448 AlterTableAction::DropConstraint { name, if_exists } => {
11449 self.write_keyword("DROP CONSTRAINT");
11450 if *if_exists {
11451 self.write_space();
11452 self.write_keyword("IF EXISTS");
11453 }
11454 self.write_space();
11455 self.generate_identifier(name)?;
11456 }
11457 AlterTableAction::DropForeignKey { name } => {
11458 self.write_keyword("DROP FOREIGN KEY");
11459 self.write_space();
11460 self.generate_identifier(name)?;
11461 }
11462 AlterTableAction::DropPartition {
11463 partitions,
11464 if_exists,
11465 } => {
11466 self.write_keyword("DROP");
11467 if *if_exists {
11468 self.write_space();
11469 self.write_keyword("IF EXISTS");
11470 }
11471 for (i, partition) in partitions.iter().enumerate() {
11472 if i > 0 {
11473 self.write(",");
11474 }
11475 self.write_space();
11476 self.write_keyword("PARTITION");
11477 if partition.len() == 1 && partition[0].0.name == "__expr__" {
11479 self.write_space();
11481 self.generate_expression(&partition[0].1)?;
11482 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
11483 self.write_space();
11485 self.write_keyword("ALL");
11486 } else if partition.len() == 1 && partition[0].0.name == "ID" {
11487 self.write_space();
11489 self.write_keyword("ID");
11490 self.write_space();
11491 self.generate_expression(&partition[0].1)?;
11492 } else {
11493 self.write("(");
11495 for (j, (key, value)) in partition.iter().enumerate() {
11496 if j > 0 {
11497 self.write(", ");
11498 }
11499 self.generate_identifier(key)?;
11500 self.write(" = ");
11501 self.generate_expression(value)?;
11502 }
11503 self.write(")");
11504 }
11505 }
11506 }
11507 AlterTableAction::Delete { where_clause } => {
11508 self.write_keyword("DELETE");
11509 self.write_space();
11510 self.write_keyword("WHERE");
11511 self.write_space();
11512 self.generate_expression(where_clause)?;
11513 }
11514 AlterTableAction::SwapWith(target) => {
11515 self.write_keyword("SWAP WITH");
11516 self.write_space();
11517 self.generate_table(target)?;
11518 }
11519 AlterTableAction::SetProperty { properties } => {
11520 use crate::dialects::DialectType;
11521 self.write_keyword("SET");
11522 let is_trino_presto = matches!(
11524 self.config.dialect,
11525 Some(DialectType::Trino) | Some(DialectType::Presto)
11526 );
11527 if is_trino_presto {
11528 self.write_space();
11529 self.write_keyword("PROPERTIES");
11530 }
11531 let eq = if is_trino_presto { " = " } else { "=" };
11532 for (i, (key, value)) in properties.iter().enumerate() {
11533 if i > 0 {
11534 self.write(",");
11535 }
11536 self.write_space();
11537 if key.contains(' ') {
11539 self.generate_string_literal(key)?;
11540 } else {
11541 self.write(key);
11542 }
11543 self.write(eq);
11544 self.generate_expression(value)?;
11545 }
11546 }
11547 AlterTableAction::UnsetProperty { properties } => {
11548 self.write_keyword("UNSET");
11549 for (i, name) in properties.iter().enumerate() {
11550 if i > 0 {
11551 self.write(",");
11552 }
11553 self.write_space();
11554 self.write(name);
11555 }
11556 }
11557 AlterTableAction::ClusterBy { expressions } => {
11558 self.write_keyword("CLUSTER BY");
11559 self.write(" (");
11560 for (i, expr) in expressions.iter().enumerate() {
11561 if i > 0 {
11562 self.write(", ");
11563 }
11564 self.generate_expression(expr)?;
11565 }
11566 self.write(")");
11567 }
11568 AlterTableAction::SetTag { expressions } => {
11569 self.write_keyword("SET TAG");
11570 for (i, (key, value)) in expressions.iter().enumerate() {
11571 if i > 0 {
11572 self.write(",");
11573 }
11574 self.write_space();
11575 self.write(key);
11576 self.write(" = ");
11577 self.generate_expression(value)?;
11578 }
11579 }
11580 AlterTableAction::UnsetTag { names } => {
11581 self.write_keyword("UNSET TAG");
11582 for (i, name) in names.iter().enumerate() {
11583 if i > 0 {
11584 self.write(",");
11585 }
11586 self.write_space();
11587 self.write(name);
11588 }
11589 }
11590 AlterTableAction::SetOptions { expressions } => {
11591 self.write_keyword("SET");
11592 self.write(" (");
11593 for (i, expr) in expressions.iter().enumerate() {
11594 if i > 0 {
11595 self.write(", ");
11596 }
11597 self.generate_expression(expr)?;
11598 }
11599 self.write(")");
11600 }
11601 AlterTableAction::AlterIndex { name, visible } => {
11602 self.write_keyword("ALTER INDEX");
11603 self.write_space();
11604 self.generate_identifier(name)?;
11605 self.write_space();
11606 if *visible {
11607 self.write_keyword("VISIBLE");
11608 } else {
11609 self.write_keyword("INVISIBLE");
11610 }
11611 }
11612 AlterTableAction::SetAttribute { attribute } => {
11613 self.write_keyword("SET");
11614 self.write_space();
11615 self.write_keyword(attribute);
11616 }
11617 AlterTableAction::SetStageFileFormat { options } => {
11618 self.write_keyword("SET");
11619 self.write_space();
11620 self.write_keyword("STAGE_FILE_FORMAT");
11621 self.write(" = (");
11622 if let Some(opts) = options {
11623 self.generate_space_separated_properties(opts)?;
11624 }
11625 self.write(")");
11626 }
11627 AlterTableAction::SetStageCopyOptions { options } => {
11628 self.write_keyword("SET");
11629 self.write_space();
11630 self.write_keyword("STAGE_COPY_OPTIONS");
11631 self.write(" = (");
11632 if let Some(opts) = options {
11633 self.generate_space_separated_properties(opts)?;
11634 }
11635 self.write(")");
11636 }
11637 AlterTableAction::AddColumns { columns, cascade } => {
11638 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
11641 if is_oracle {
11642 self.write_keyword("ADD");
11643 } else {
11644 self.write_keyword("ADD COLUMNS");
11645 }
11646 self.write(" (");
11647 for (i, col) in columns.iter().enumerate() {
11648 if i > 0 {
11649 self.write(", ");
11650 }
11651 self.generate_column_def(col)?;
11652 }
11653 self.write(")");
11654 if *cascade {
11655 self.write_space();
11656 self.write_keyword("CASCADE");
11657 }
11658 }
11659 AlterTableAction::ChangeColumn {
11660 old_name,
11661 new_name,
11662 data_type,
11663 comment,
11664 cascade,
11665 } => {
11666 use crate::dialects::DialectType;
11667 let is_spark = matches!(
11668 self.config.dialect,
11669 Some(DialectType::Spark) | Some(DialectType::Databricks)
11670 );
11671 let is_rename = old_name.name != new_name.name;
11672
11673 if is_spark {
11674 if is_rename {
11675 self.write_keyword("RENAME COLUMN");
11677 self.write_space();
11678 self.generate_identifier(old_name)?;
11679 self.write_space();
11680 self.write_keyword("TO");
11681 self.write_space();
11682 self.generate_identifier(new_name)?;
11683 } else if comment.is_some() {
11684 self.write_keyword("ALTER COLUMN");
11686 self.write_space();
11687 self.generate_identifier(old_name)?;
11688 self.write_space();
11689 self.write_keyword("COMMENT");
11690 self.write_space();
11691 self.write("'");
11692 self.write(comment.as_ref().unwrap());
11693 self.write("'");
11694 } else if data_type.is_some() {
11695 self.write_keyword("ALTER COLUMN");
11697 self.write_space();
11698 self.generate_identifier(old_name)?;
11699 self.write_space();
11700 self.write_keyword("TYPE");
11701 self.write_space();
11702 self.generate_data_type(data_type.as_ref().unwrap())?;
11703 } else {
11704 self.write_keyword("CHANGE COLUMN");
11706 self.write_space();
11707 self.generate_identifier(old_name)?;
11708 self.write_space();
11709 self.generate_identifier(new_name)?;
11710 }
11711 } else {
11712 if data_type.is_some() {
11714 self.write_keyword("CHANGE COLUMN");
11715 } else {
11716 self.write_keyword("CHANGE");
11717 }
11718 self.write_space();
11719 self.generate_identifier(old_name)?;
11720 self.write_space();
11721 self.generate_identifier(new_name)?;
11722 if let Some(ref dt) = data_type {
11723 self.write_space();
11724 self.generate_data_type(dt)?;
11725 }
11726 if let Some(ref c) = comment {
11727 self.write_space();
11728 self.write_keyword("COMMENT");
11729 self.write_space();
11730 self.write("'");
11731 self.write(c);
11732 self.write("'");
11733 }
11734 if *cascade {
11735 self.write_space();
11736 self.write_keyword("CASCADE");
11737 }
11738 }
11739 }
11740 AlterTableAction::AddPartition {
11741 partition,
11742 if_not_exists,
11743 location,
11744 } => {
11745 self.write_keyword("ADD");
11746 self.write_space();
11747 if *if_not_exists {
11748 self.write_keyword("IF NOT EXISTS");
11749 self.write_space();
11750 }
11751 self.generate_expression(partition)?;
11752 if let Some(ref loc) = location {
11753 self.write_space();
11754 self.write_keyword("LOCATION");
11755 self.write_space();
11756 self.generate_expression(loc)?;
11757 }
11758 }
11759 AlterTableAction::AlterSortKey {
11760 this,
11761 expressions,
11762 compound,
11763 } => {
11764 self.write_keyword("ALTER");
11766 if *compound {
11767 self.write_space();
11768 self.write_keyword("COMPOUND");
11769 }
11770 self.write_space();
11771 self.write_keyword("SORTKEY");
11772 self.write_space();
11773 if let Some(style) = this {
11774 self.write_keyword(style);
11775 } else if !expressions.is_empty() {
11776 self.write("(");
11777 for (i, expr) in expressions.iter().enumerate() {
11778 if i > 0 {
11779 self.write(", ");
11780 }
11781 self.generate_expression(expr)?;
11782 }
11783 self.write(")");
11784 }
11785 }
11786 AlterTableAction::AlterDistStyle { style, distkey } => {
11787 self.write_keyword("ALTER");
11789 self.write_space();
11790 self.write_keyword("DISTSTYLE");
11791 self.write_space();
11792 self.write_keyword(style);
11793 if let Some(col) = distkey {
11794 self.write_space();
11795 self.write_keyword("DISTKEY");
11796 self.write_space();
11797 self.generate_identifier(col)?;
11798 }
11799 }
11800 AlterTableAction::SetTableProperties { properties } => {
11801 self.write_keyword("SET TABLE PROPERTIES");
11803 self.write(" (");
11804 for (i, (key, value)) in properties.iter().enumerate() {
11805 if i > 0 {
11806 self.write(", ");
11807 }
11808 self.generate_expression(key)?;
11809 self.write(" = ");
11810 self.generate_expression(value)?;
11811 }
11812 self.write(")");
11813 }
11814 AlterTableAction::SetLocation { location } => {
11815 self.write_keyword("SET LOCATION");
11817 self.write_space();
11818 self.write("'");
11819 self.write(location);
11820 self.write("'");
11821 }
11822 AlterTableAction::SetFileFormat { format } => {
11823 self.write_keyword("SET FILE FORMAT");
11825 self.write_space();
11826 self.write_keyword(format);
11827 }
11828 AlterTableAction::ReplacePartition { partition, source } => {
11829 self.write_keyword("REPLACE PARTITION");
11831 self.write_space();
11832 self.generate_expression(partition)?;
11833 if let Some(src) = source {
11834 self.write_space();
11835 self.write_keyword("FROM");
11836 self.write_space();
11837 self.generate_expression(src)?;
11838 }
11839 }
11840 AlterTableAction::SetTiDBTableOption { option, force } => {
11841 self.generate_tidb_table_option(option, *force)?;
11842 }
11843 AlterTableAction::RemoveTiDBTtl { executable_comment } => {
11844 if !matches!(self.config.dialect, Some(DialectType::TiDB)) {
11845 return self.write_unsupported_comment(
11846 "REMOVE TTL is only supported by the TiDB dialect",
11847 );
11848 }
11849 if *executable_comment {
11850 self.write("/*T![ttl] REMOVE TTL */");
11851 } else {
11852 self.write_keyword("REMOVE TTL");
11853 }
11854 }
11855 AlterTableAction::Raw { sql } => {
11856 self.write(sql);
11857 }
11858 }
11859 Ok(())
11860 }
11861
11862 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
11863 match action {
11864 AlterColumnAction::SetDataType {
11865 data_type,
11866 using,
11867 collate,
11868 } => {
11869 use crate::dialects::DialectType;
11870 let is_no_prefix = matches!(
11875 self.config.dialect,
11876 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
11877 );
11878 let is_type_only = matches!(
11879 self.config.dialect,
11880 Some(DialectType::Redshift)
11881 | Some(DialectType::Spark)
11882 | Some(DialectType::Databricks)
11883 );
11884 if is_type_only {
11885 self.write_keyword("TYPE");
11886 self.write_space();
11887 } else if !is_no_prefix {
11888 self.write_keyword("SET DATA TYPE");
11889 self.write_space();
11890 }
11891 self.generate_data_type(data_type)?;
11892 if let Some(ref collation) = collate {
11893 self.write_space();
11894 self.write_keyword("COLLATE");
11895 self.write_space();
11896 self.write(collation);
11897 }
11898 if let Some(ref using_expr) = using {
11899 self.write_space();
11900 self.write_keyword("USING");
11901 self.write_space();
11902 self.generate_expression(using_expr)?;
11903 }
11904 }
11905 AlterColumnAction::SetDefault(expr) => {
11906 self.write_keyword("SET DEFAULT");
11907 self.write_space();
11908 self.generate_expression(expr)?;
11909 }
11910 AlterColumnAction::DropDefault => {
11911 self.write_keyword("DROP DEFAULT");
11912 }
11913 AlterColumnAction::SetNotNull => {
11914 self.write_keyword("SET NOT NULL");
11915 }
11916 AlterColumnAction::DropNotNull => {
11917 self.write_keyword("DROP NOT NULL");
11918 }
11919 AlterColumnAction::Comment(comment) => {
11920 self.write_keyword("COMMENT");
11921 self.write_space();
11922 self.generate_string_literal(comment)?;
11923 }
11924 AlterColumnAction::SetVisible => {
11925 self.write_keyword("SET VISIBLE");
11926 }
11927 AlterColumnAction::SetInvisible => {
11928 self.write_keyword("SET INVISIBLE");
11929 }
11930 }
11931 Ok(())
11932 }
11933
11934 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
11935 self.write_keyword("CREATE");
11936
11937 if ci.unique {
11938 self.write_space();
11939 self.write_keyword("UNIQUE");
11940 }
11941
11942 if let Some(ref clustered) = ci.clustered {
11944 self.write_space();
11945 self.write_keyword(clustered);
11946 }
11947
11948 self.write_space();
11949 self.write_keyword("INDEX");
11950
11951 if ci.concurrently {
11953 self.write_space();
11954 self.write_keyword("CONCURRENTLY");
11955 }
11956
11957 if ci.if_not_exists {
11958 self.write_space();
11959 self.write_keyword("IF NOT EXISTS");
11960 }
11961
11962 if !ci.name.name.is_empty() {
11964 self.write_space();
11965 self.generate_identifier(&ci.name)?;
11966 }
11967 self.write_space();
11968 self.write_keyword("ON");
11969 if matches!(self.config.dialect, Some(DialectType::Hive)) {
11971 self.write_space();
11972 self.write_keyword("TABLE");
11973 }
11974 self.write_space();
11975 self.generate_table(&ci.table)?;
11976
11977 if !ci.columns.is_empty() || ci.using.is_some() {
11980 let space_before_paren = false;
11981
11982 if let Some(ref using) = ci.using {
11983 self.write_space();
11984 self.write_keyword("USING");
11985 self.write_space();
11986 self.write(using);
11987 if space_before_paren {
11988 self.write(" (");
11989 } else {
11990 self.write("(");
11991 }
11992 } else {
11993 if space_before_paren {
11994 self.write(" (");
11995 } else {
11996 self.write("(");
11997 }
11998 }
11999 for (i, col) in ci.columns.iter().enumerate() {
12000 if i > 0 {
12001 self.write(", ");
12002 }
12003 self.generate_identifier(&col.column)?;
12004 if let Some(ref opclass) = col.opclass {
12005 self.write_space();
12006 self.write(opclass);
12007 }
12008 if col.desc {
12009 self.write_space();
12010 self.write_keyword("DESC");
12011 } else if col.asc {
12012 self.write_space();
12013 self.write_keyword("ASC");
12014 }
12015 if let Some(nulls_first) = col.nulls_first {
12016 self.write_space();
12017 self.write_keyword("NULLS");
12018 self.write_space();
12019 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
12020 }
12021 }
12022 self.write(")");
12023 }
12024
12025 if !ci.include_columns.is_empty() {
12027 self.write_space();
12028 self.write_keyword("INCLUDE");
12029 self.write(" (");
12030 for (i, col) in ci.include_columns.iter().enumerate() {
12031 if i > 0 {
12032 self.write(", ");
12033 }
12034 self.generate_identifier(col)?;
12035 }
12036 self.write(")");
12037 }
12038
12039 if !ci.with_options.is_empty() {
12041 self.write_space();
12042 self.write_keyword("WITH");
12043 self.write(" (");
12044 for (i, (key, value)) in ci.with_options.iter().enumerate() {
12045 if i > 0 {
12046 self.write(", ");
12047 }
12048 self.write(key);
12049 self.write("=");
12050 self.write(value);
12051 }
12052 self.write(")");
12053 }
12054
12055 if let Some(ref where_clause) = ci.where_clause {
12057 self.write_space();
12058 self.write_keyword("WHERE");
12059 self.write_space();
12060 self.generate_expression(where_clause)?;
12061 }
12062
12063 if let Some(ref on_fg) = ci.on_filegroup {
12065 self.write_space();
12066 self.write_keyword("ON");
12067 self.write_space();
12068 self.write(on_fg);
12069 }
12070
12071 Ok(())
12072 }
12073
12074 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
12075 self.write_keyword("DROP INDEX");
12076
12077 if di.concurrently {
12078 self.write_space();
12079 self.write_keyword("CONCURRENTLY");
12080 }
12081
12082 if di.if_exists {
12083 self.write_space();
12084 self.write_keyword("IF EXISTS");
12085 }
12086
12087 self.write_space();
12088 self.generate_table(&di.name)?;
12089
12090 if let Some(ref table) = di.table {
12091 self.write_space();
12092 self.write_keyword("ON");
12093 self.write_space();
12094 self.generate_table(table)?;
12095 }
12096
12097 Ok(())
12098 }
12099
12100 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
12101 self.write_keyword("CREATE");
12102
12103 if let Some(ref algorithm) = cv.algorithm {
12105 self.write_space();
12106 self.write_keyword("ALGORITHM");
12107 self.write("=");
12108 self.write_keyword(algorithm);
12109 }
12110
12111 if let Some(ref definer) = cv.definer {
12113 self.write_space();
12114 self.write_keyword("DEFINER");
12115 self.write("=");
12116 self.write(definer);
12117 }
12118
12119 if cv.security_sql_style && !cv.security_after_name {
12121 if let Some(ref security) = cv.security {
12122 self.write_space();
12123 self.write_keyword("SQL SECURITY");
12124 self.write_space();
12125 match security {
12126 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12127 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12128 FunctionSecurity::None => self.write_keyword("NONE"),
12129 }
12130 }
12131 }
12132
12133 if cv.or_alter {
12134 self.write_space();
12135 self.write_keyword("OR ALTER");
12136 } else if cv.or_replace {
12137 self.write_space();
12138 self.write_keyword("OR REPLACE");
12139 }
12140
12141 if cv.temporary {
12142 self.write_space();
12143 self.write_keyword("TEMPORARY");
12144 }
12145
12146 if cv.materialized {
12147 self.write_space();
12148 self.write_keyword("MATERIALIZED");
12149 }
12150
12151 if cv.secure {
12153 self.write_space();
12154 self.write_keyword("SECURE");
12155 }
12156
12157 self.write_space();
12158 self.write_keyword("VIEW");
12159
12160 if cv.if_not_exists {
12161 self.write_space();
12162 self.write_keyword("IF NOT EXISTS");
12163 }
12164
12165 self.write_space();
12166 self.generate_table(&cv.name)?;
12167
12168 if let Some(ref on_cluster) = cv.on_cluster {
12170 self.write_space();
12171 self.generate_on_cluster(on_cluster)?;
12172 }
12173
12174 if let Some(ref to_table) = cv.to_table {
12176 self.write_space();
12177 self.write_keyword("TO");
12178 self.write_space();
12179 self.generate_table(to_table)?;
12180 }
12181
12182 if !cv.materialized {
12185 if let Some(ref schema) = cv.schema {
12187 self.write(" (");
12188 for (i, expr) in schema.expressions.iter().enumerate() {
12189 if i > 0 {
12190 self.write(", ");
12191 }
12192 self.generate_expression(expr)?;
12193 }
12194 self.write(")");
12195 } else if !cv.columns.is_empty() {
12196 self.write(" (");
12197 for (i, col) in cv.columns.iter().enumerate() {
12198 if i > 0 {
12199 self.write(", ");
12200 }
12201 self.generate_identifier(&col.name)?;
12202 if !col.options.is_empty() {
12204 self.write_space();
12205 self.generate_options_clause(&col.options)?;
12206 }
12207 if let Some(ref comment) = col.comment {
12208 self.write_space();
12209 self.write_keyword("COMMENT");
12210 self.write_space();
12211 self.generate_string_literal(comment)?;
12212 }
12213 }
12214 self.write(")");
12215 }
12216
12217 if !cv.security_sql_style || cv.security_after_name {
12220 if let Some(ref security) = cv.security {
12221 self.write_space();
12222 if cv.security_sql_style {
12223 self.write_keyword("SQL SECURITY");
12224 } else {
12225 self.write_keyword("SECURITY");
12226 }
12227 self.write_space();
12228 match security {
12229 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12230 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12231 FunctionSecurity::None => self.write_keyword("NONE"),
12232 }
12233 }
12234 }
12235
12236 if cv.copy_grants {
12238 self.write_space();
12239 self.write_keyword("COPY GRANTS");
12240 }
12241 } else {
12242 if cv.copy_grants {
12244 self.write_space();
12245 self.write_keyword("COPY GRANTS");
12246 }
12247
12248 if let Some(ref schema) = cv.schema {
12250 self.write(" (");
12251 for (i, expr) in schema.expressions.iter().enumerate() {
12252 if i > 0 {
12253 self.write(", ");
12254 }
12255 self.generate_expression(expr)?;
12256 }
12257 self.write(")");
12258 } else if !cv.columns.is_empty() {
12259 self.write(" (");
12261 for (i, col) in cv.columns.iter().enumerate() {
12262 if i > 0 {
12263 self.write(", ");
12264 }
12265 self.generate_identifier(&col.name)?;
12266 if !col.options.is_empty() {
12268 self.write_space();
12269 self.generate_options_clause(&col.options)?;
12270 }
12271 if let Some(ref comment) = col.comment {
12272 self.write_space();
12273 self.write_keyword("COMMENT");
12274 self.write_space();
12275 self.generate_string_literal(comment)?;
12276 }
12277 }
12278 self.write(")");
12279 }
12280
12281 if let Some(ref unique_key) = cv.unique_key {
12283 self.write_space();
12284 self.write_keyword("KEY");
12285 self.write(" (");
12286 for (i, expr) in unique_key.expressions.iter().enumerate() {
12287 if i > 0 {
12288 self.write(", ");
12289 }
12290 self.generate_expression(expr)?;
12291 }
12292 self.write(")");
12293 }
12294 }
12295
12296 if let Some(ref row_access_policy) = cv.row_access_policy {
12297 self.write_space();
12298 self.write_keyword("WITH");
12299 self.write_space();
12300 self.write(row_access_policy);
12301 }
12302
12303 if let Some(ref comment) = cv.comment {
12305 self.write_space();
12306 self.write_keyword("COMMENT");
12307 self.write("=");
12308 self.generate_string_literal(comment)?;
12309 }
12310
12311 if !cv.tags.is_empty() {
12313 self.write_space();
12314 self.write_keyword("TAG");
12315 self.write(" (");
12316 for (i, (name, value)) in cv.tags.iter().enumerate() {
12317 if i > 0 {
12318 self.write(", ");
12319 }
12320 self.write(name);
12321 self.write("='");
12322 self.write(value);
12323 self.write("'");
12324 }
12325 self.write(")");
12326 }
12327
12328 if !cv.options.is_empty() {
12330 self.write_space();
12331 self.generate_options_clause(&cv.options)?;
12332 }
12333
12334 if let Some(ref build) = cv.build {
12336 self.write_space();
12337 self.write_keyword("BUILD");
12338 self.write_space();
12339 self.write_keyword(build);
12340 }
12341
12342 if let Some(ref refresh) = cv.refresh {
12344 self.write_space();
12345 self.generate_refresh_trigger_property(refresh)?;
12346 }
12347
12348 if let Some(auto_refresh) = cv.auto_refresh {
12350 self.write_space();
12351 self.write_keyword("AUTO REFRESH");
12352 self.write_space();
12353 if auto_refresh {
12354 self.write_keyword("YES");
12355 } else {
12356 self.write_keyword("NO");
12357 }
12358 }
12359
12360 for prop in &cv.table_properties {
12362 self.write_space();
12363 self.generate_expression(prop)?;
12364 }
12365
12366 if let Some(ref population) = cv.clickhouse_population {
12368 self.write_space();
12369 self.write_keyword(population);
12370 }
12371
12372 if !matches!(&cv.query, Expression::Null(_)) {
12374 self.write_space();
12375 self.write_keyword("AS");
12376 self.write_space();
12377
12378 if let Some(ref mode) = cv.locking_mode {
12380 self.write_keyword("LOCKING");
12381 self.write_space();
12382 self.write_keyword(mode);
12383 if let Some(ref access) = cv.locking_access {
12384 self.write_space();
12385 self.write_keyword("FOR");
12386 self.write_space();
12387 self.write_keyword(access);
12388 }
12389 self.write_space();
12390 }
12391
12392 if cv.query_parenthesized {
12393 self.write("(");
12394 }
12395 self.generate_expression(&cv.query)?;
12396 if cv.query_parenthesized {
12397 self.write(")");
12398 }
12399 }
12400
12401 if cv.no_schema_binding {
12403 self.write_space();
12404 self.write_keyword("WITH NO SCHEMA BINDING");
12405 }
12406
12407 Ok(())
12408 }
12409
12410 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
12411 self.write_keyword("DROP");
12412
12413 if dv.materialized {
12414 self.write_space();
12415 self.write_keyword("MATERIALIZED");
12416 }
12417
12418 self.write_space();
12419 self.write_keyword("VIEW");
12420
12421 if dv.if_exists {
12422 self.write_space();
12423 self.write_keyword("IF EXISTS");
12424 }
12425
12426 self.write_space();
12427 self.generate_table(&dv.name)?;
12428
12429 Ok(())
12430 }
12431
12432 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
12433 match tr.target {
12434 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
12435 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
12436 }
12437 if tr.if_exists {
12438 self.write_space();
12439 self.write_keyword("IF EXISTS");
12440 }
12441 self.write_space();
12442 self.generate_table(&tr.table)?;
12443
12444 if let Some(ref on_cluster) = tr.on_cluster {
12446 self.write_space();
12447 self.generate_on_cluster(on_cluster)?;
12448 }
12449
12450 if !tr.extra_tables.is_empty() {
12452 let skip_first = if let Some(first) = tr.extra_tables.first() {
12454 first.table.name == tr.table.name && first.star
12455 } else {
12456 false
12457 };
12458
12459 let strip_star = matches!(
12461 self.config.dialect,
12462 Some(crate::dialects::DialectType::PostgreSQL)
12463 | Some(crate::dialects::DialectType::Redshift)
12464 );
12465 if skip_first && !strip_star {
12466 self.write("*");
12467 }
12468
12469 for (i, entry) in tr.extra_tables.iter().enumerate() {
12471 if i == 0 && skip_first {
12472 continue; }
12474 self.write(", ");
12475 self.generate_table(&entry.table)?;
12476 if entry.star && !strip_star {
12477 self.write("*");
12478 }
12479 }
12480 }
12481
12482 if let Some(identity) = &tr.identity {
12484 self.write_space();
12485 match identity {
12486 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
12487 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
12488 }
12489 }
12490
12491 if tr.cascade {
12492 self.write_space();
12493 self.write_keyword("CASCADE");
12494 }
12495
12496 if tr.restrict {
12497 self.write_space();
12498 self.write_keyword("RESTRICT");
12499 }
12500
12501 if let Some(ref partition) = tr.partition {
12503 self.write_space();
12504 self.generate_expression(partition)?;
12505 }
12506
12507 Ok(())
12508 }
12509
12510 fn generate_use(&mut self, u: &Use) -> Result<()> {
12511 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
12513 self.write_keyword("DATABASE");
12514 self.write_space();
12515 self.generate_identifier(&u.this)?;
12516 return Ok(());
12517 }
12518
12519 self.write_keyword("USE");
12520
12521 if let Some(kind) = &u.kind {
12522 self.write_space();
12523 match kind {
12524 UseKind::Database => self.write_keyword("DATABASE"),
12525 UseKind::Schema => self.write_keyword("SCHEMA"),
12526 UseKind::Role => self.write_keyword("ROLE"),
12527 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
12528 UseKind::Catalog => self.write_keyword("CATALOG"),
12529 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
12530 }
12531 }
12532
12533 self.write_space();
12534 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
12537 self.write(&u.this.name);
12538 } else {
12539 self.generate_identifier(&u.this)?;
12540 }
12541 Ok(())
12542 }
12543
12544 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
12545 self.write_keyword("CACHE");
12546 if c.lazy {
12547 self.write_space();
12548 self.write_keyword("LAZY");
12549 }
12550 self.write_space();
12551 self.write_keyword("TABLE");
12552 self.write_space();
12553 self.generate_identifier(&c.table)?;
12554
12555 if !c.options.is_empty() {
12557 self.write_space();
12558 self.write_keyword("OPTIONS");
12559 self.write("(");
12560 for (i, (key, value)) in c.options.iter().enumerate() {
12561 if i > 0 {
12562 self.write(", ");
12563 }
12564 self.generate_expression(key)?;
12565 self.write(" = ");
12566 self.generate_expression(value)?;
12567 }
12568 self.write(")");
12569 }
12570
12571 if let Some(query) = &c.query {
12573 self.write_space();
12574 self.write_keyword("AS");
12575 self.write_space();
12576 self.generate_expression(query)?;
12577 }
12578
12579 Ok(())
12580 }
12581
12582 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
12583 self.write_keyword("UNCACHE TABLE");
12584 if u.if_exists {
12585 self.write_space();
12586 self.write_keyword("IF EXISTS");
12587 }
12588 self.write_space();
12589 self.generate_identifier(&u.table)?;
12590 Ok(())
12591 }
12592
12593 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
12594 self.write_keyword("LOAD DATA");
12595 if l.local {
12596 self.write_space();
12597 self.write_keyword("LOCAL");
12598 }
12599 self.write_space();
12600 self.write_keyword("INPATH");
12601 self.write_space();
12602 self.write("'");
12603 self.write(&l.inpath);
12604 self.write("'");
12605
12606 if l.overwrite {
12607 self.write_space();
12608 self.write_keyword("OVERWRITE");
12609 }
12610
12611 self.write_space();
12612 self.write_keyword("INTO TABLE");
12613 self.write_space();
12614 self.generate_expression(&l.table)?;
12615
12616 if !l.partition.is_empty() {
12618 self.write_space();
12619 self.write_keyword("PARTITION");
12620 self.write("(");
12621 for (i, (col, val)) in l.partition.iter().enumerate() {
12622 if i > 0 {
12623 self.write(", ");
12624 }
12625 self.generate_identifier(col)?;
12626 self.write(" = ");
12627 self.generate_expression(val)?;
12628 }
12629 self.write(")");
12630 }
12631
12632 if let Some(fmt) = &l.input_format {
12634 self.write_space();
12635 self.write_keyword("INPUTFORMAT");
12636 self.write_space();
12637 self.write("'");
12638 self.write(fmt);
12639 self.write("'");
12640 }
12641
12642 if let Some(serde) = &l.serde {
12644 self.write_space();
12645 self.write_keyword("SERDE");
12646 self.write_space();
12647 self.write("'");
12648 self.write(serde);
12649 self.write("'");
12650 }
12651
12652 Ok(())
12653 }
12654
12655 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
12656 self.write_keyword("PRAGMA");
12657 self.write_space();
12658
12659 if let Some(schema) = &p.schema {
12661 self.generate_identifier(schema)?;
12662 self.write(".");
12663 }
12664
12665 self.generate_identifier(&p.name)?;
12667
12668 if p.use_assignment_syntax {
12670 self.write(" = ");
12671 if let Some(value) = &p.value {
12672 self.generate_expression(value)?;
12673 } else if let Some(arg) = p.args.first() {
12674 self.generate_expression(arg)?;
12675 }
12676 } else if !p.args.is_empty() {
12677 self.write("(");
12678 for (i, arg) in p.args.iter().enumerate() {
12679 if i > 0 {
12680 self.write(", ");
12681 }
12682 self.generate_expression(arg)?;
12683 }
12684 self.write(")");
12685 }
12686
12687 Ok(())
12688 }
12689
12690 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
12691 self.write_keyword("GRANT");
12692 self.write_space();
12693
12694 for (i, privilege) in g.privileges.iter().enumerate() {
12696 if i > 0 {
12697 self.write(", ");
12698 }
12699 self.write_keyword(&privilege.name);
12700 if !privilege.columns.is_empty() {
12702 self.write("(");
12703 for (j, col) in privilege.columns.iter().enumerate() {
12704 if j > 0 {
12705 self.write(", ");
12706 }
12707 self.write(col);
12708 }
12709 self.write(")");
12710 }
12711 }
12712
12713 self.write_space();
12714 self.write_keyword("ON");
12715 self.write_space();
12716
12717 if let Some(kind) = &g.kind {
12719 self.write_keyword(kind);
12720 self.write_space();
12721 }
12722
12723 {
12725 use crate::dialects::DialectType;
12726 let should_upper = matches!(
12727 self.config.dialect,
12728 Some(DialectType::PostgreSQL)
12729 | Some(DialectType::CockroachDB)
12730 | Some(DialectType::Materialize)
12731 | Some(DialectType::RisingWave)
12732 ) && (g.kind.as_deref() == Some("FUNCTION")
12733 || g.kind.as_deref() == Some("PROCEDURE"));
12734 if should_upper {
12735 use crate::expressions::Identifier;
12736 let upper_id = Identifier {
12737 name: g.securable.name.to_ascii_uppercase(),
12738 quoted: g.securable.quoted,
12739 ..g.securable.clone()
12740 };
12741 self.generate_identifier(&upper_id)?;
12742 } else {
12743 self.generate_identifier(&g.securable)?;
12744 }
12745 }
12746
12747 if !g.function_params.is_empty() {
12749 self.write("(");
12750 for (i, param) in g.function_params.iter().enumerate() {
12751 if i > 0 {
12752 self.write(", ");
12753 }
12754 self.write(param);
12755 }
12756 self.write(")");
12757 }
12758
12759 self.write_space();
12760 self.write_keyword("TO");
12761 self.write_space();
12762
12763 for (i, principal) in g.principals.iter().enumerate() {
12765 if i > 0 {
12766 self.write(", ");
12767 }
12768 if principal.is_role {
12769 self.write_keyword("ROLE");
12770 self.write_space();
12771 } else if principal.is_group {
12772 self.write_keyword("GROUP");
12773 self.write_space();
12774 } else if principal.is_share {
12775 self.write_keyword("SHARE");
12776 self.write_space();
12777 }
12778 self.generate_identifier(&principal.name)?;
12779 }
12780
12781 if g.grant_option {
12783 self.write_space();
12784 self.write_keyword("WITH GRANT OPTION");
12785 }
12786
12787 if let Some(ref principal) = g.as_principal {
12789 self.write_space();
12790 self.write_keyword("AS");
12791 self.write_space();
12792 self.generate_identifier(principal)?;
12793 }
12794
12795 Ok(())
12796 }
12797
12798 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
12799 self.write_keyword("REVOKE");
12800 self.write_space();
12801
12802 if r.grant_option {
12804 self.write_keyword("GRANT OPTION FOR");
12805 self.write_space();
12806 }
12807
12808 for (i, privilege) in r.privileges.iter().enumerate() {
12810 if i > 0 {
12811 self.write(", ");
12812 }
12813 self.write_keyword(&privilege.name);
12814 if !privilege.columns.is_empty() {
12816 self.write("(");
12817 for (j, col) in privilege.columns.iter().enumerate() {
12818 if j > 0 {
12819 self.write(", ");
12820 }
12821 self.write(col);
12822 }
12823 self.write(")");
12824 }
12825 }
12826
12827 self.write_space();
12828 self.write_keyword("ON");
12829 self.write_space();
12830
12831 if let Some(kind) = &r.kind {
12833 self.write_keyword(kind);
12834 self.write_space();
12835 }
12836
12837 {
12839 use crate::dialects::DialectType;
12840 let should_upper = matches!(
12841 self.config.dialect,
12842 Some(DialectType::PostgreSQL)
12843 | Some(DialectType::CockroachDB)
12844 | Some(DialectType::Materialize)
12845 | Some(DialectType::RisingWave)
12846 ) && (r.kind.as_deref() == Some("FUNCTION")
12847 || r.kind.as_deref() == Some("PROCEDURE"));
12848 if should_upper {
12849 use crate::expressions::Identifier;
12850 let upper_id = Identifier {
12851 name: r.securable.name.to_ascii_uppercase(),
12852 quoted: r.securable.quoted,
12853 ..r.securable.clone()
12854 };
12855 self.generate_identifier(&upper_id)?;
12856 } else {
12857 self.generate_identifier(&r.securable)?;
12858 }
12859 }
12860
12861 if !r.function_params.is_empty() {
12863 self.write("(");
12864 for (i, param) in r.function_params.iter().enumerate() {
12865 if i > 0 {
12866 self.write(", ");
12867 }
12868 self.write(param);
12869 }
12870 self.write(")");
12871 }
12872
12873 self.write_space();
12874 self.write_keyword("FROM");
12875 self.write_space();
12876
12877 for (i, principal) in r.principals.iter().enumerate() {
12879 if i > 0 {
12880 self.write(", ");
12881 }
12882 if principal.is_role {
12883 self.write_keyword("ROLE");
12884 self.write_space();
12885 } else if principal.is_group {
12886 self.write_keyword("GROUP");
12887 self.write_space();
12888 } else if principal.is_share {
12889 self.write_keyword("SHARE");
12890 self.write_space();
12891 }
12892 self.generate_identifier(&principal.name)?;
12893 }
12894
12895 if r.cascade {
12897 self.write_space();
12898 self.write_keyword("CASCADE");
12899 } else if r.restrict {
12900 self.write_space();
12901 self.write_keyword("RESTRICT");
12902 }
12903
12904 Ok(())
12905 }
12906
12907 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
12908 self.write_keyword("COMMENT");
12909
12910 if c.exists {
12912 self.write_space();
12913 self.write_keyword("IF EXISTS");
12914 }
12915
12916 self.write_space();
12917 self.write_keyword("ON");
12918
12919 if c.materialized {
12921 self.write_space();
12922 self.write_keyword("MATERIALIZED");
12923 }
12924
12925 self.write_space();
12926 self.write_keyword(&c.kind);
12927 self.write_space();
12928
12929 self.generate_expression(&c.this)?;
12931
12932 self.write_space();
12933 self.write_keyword("IS");
12934 self.write_space();
12935
12936 self.generate_expression(&c.expression)?;
12938
12939 Ok(())
12940 }
12941
12942 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
12943 self.write_keyword("SET");
12944
12945 for (i, item) in s.items.iter().enumerate() {
12946 if i > 0 {
12947 self.write(",");
12948 }
12949 self.write_space();
12950
12951 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
12953 if let Some(ref kind) = item.kind {
12954 if has_variable_kind {
12958 if matches!(
12959 self.config.dialect,
12960 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
12961 ) {
12962 self.write_keyword("VARIABLE");
12963 self.write_space();
12964 }
12965 } else {
12966 self.write_keyword(kind);
12967 self.write_space();
12968 }
12969 }
12970
12971 let name_str = match &item.name {
12973 Expression::Identifier(id) => Some(id.name.as_str()),
12974 _ => None,
12975 };
12976
12977 let is_transaction = name_str == Some("TRANSACTION");
12978 let is_character_set = name_str == Some("CHARACTER SET");
12979 let is_names = name_str == Some("NAMES");
12980 let is_collate = name_str == Some("COLLATE");
12981 let is_identity_insert = name_str == Some("IDENTITY_INSERT");
12982 let is_value_only =
12983 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
12984
12985 if is_transaction {
12986 self.write_keyword("TRANSACTION");
12988 if let Expression::Identifier(id) = &item.value {
12989 if !id.name.is_empty() {
12990 self.write_space();
12991 self.write(&id.name);
12992 }
12993 }
12994 } else if is_character_set {
12995 self.write_keyword("CHARACTER SET");
12997 self.write_space();
12998 self.generate_set_value(&item.value)?;
12999 } else if is_names {
13000 self.write_keyword("NAMES");
13002 self.write_space();
13003 self.generate_set_value(&item.value)?;
13004 } else if is_collate {
13005 self.write_keyword("COLLATE");
13007 self.write_space();
13008 self.generate_set_value(&item.value)?;
13009 } else if is_identity_insert {
13010 self.write_keyword("IDENTITY_INSERT");
13012 self.write_space();
13013 self.generate_identity_insert_value(&item.value)?;
13014 } else if has_variable_kind {
13015 if let Some(ns) = name_str {
13018 self.write(ns);
13019 } else {
13020 self.generate_expression(&item.name)?;
13021 }
13022 self.write(" = ");
13023 self.generate_set_value(&item.value)?;
13024 } else if is_value_only {
13025 self.generate_expression(&item.name)?;
13027 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
13028 self.generate_expression(&item.name)?;
13030 self.write_space();
13031 self.generate_set_value(&item.value)?;
13032 } else {
13033 match &item.name {
13036 Expression::Identifier(id) => {
13037 self.write(&id.name);
13038 }
13039 _ => {
13040 self.generate_expression(&item.name)?;
13041 }
13042 }
13043 self.write(" = ");
13044 self.generate_set_value(&item.value)?;
13045 }
13046 }
13047
13048 Ok(())
13049 }
13050
13051 fn generate_identity_insert_value(&mut self, value: &Expression) -> Result<()> {
13052 if let Expression::Tuple(tuple) = value {
13053 if tuple.expressions.len() == 2 {
13054 self.generate_expression(&tuple.expressions[0])?;
13055 self.write_space();
13056 self.generate_set_value(&tuple.expressions[1])?;
13057 return Ok(());
13058 }
13059 }
13060
13061 self.generate_set_value(value)
13062 }
13063
13064 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
13067 if let Expression::Identifier(id) = value {
13068 match id.name.as_str() {
13069 "DEFAULT" | "ON" | "OFF" => {
13070 self.write_keyword(&id.name);
13071 return Ok(());
13072 }
13073 _ => {}
13074 }
13075 }
13076 self.generate_expression(value)
13077 }
13078
13079 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
13082 self.write_keyword("ALTER");
13083 if let Some(ref algorithm) = av.algorithm {
13085 self.write_space();
13086 self.write_keyword("ALGORITHM");
13087 self.write(" = ");
13088 self.write_keyword(algorithm);
13089 }
13090 if let Some(ref definer) = av.definer {
13091 self.write_space();
13092 self.write_keyword("DEFINER");
13093 self.write(" = ");
13094 self.write(definer);
13095 }
13096 if let Some(ref sql_security) = av.sql_security {
13097 self.write_space();
13098 self.write_keyword("SQL SECURITY");
13099 self.write(" = ");
13100 self.write_keyword(sql_security);
13101 }
13102 self.write_space();
13103 self.write_keyword("VIEW");
13104 self.write_space();
13105 self.generate_table(&av.name)?;
13106
13107 if !av.columns.is_empty() {
13109 self.write(" (");
13110 for (i, col) in av.columns.iter().enumerate() {
13111 if i > 0 {
13112 self.write(", ");
13113 }
13114 self.generate_identifier(&col.name)?;
13115 if let Some(ref comment) = col.comment {
13116 self.write_space();
13117 self.write_keyword("COMMENT");
13118 self.write(" ");
13119 self.generate_string_literal(comment)?;
13120 }
13121 }
13122 self.write(")");
13123 }
13124
13125 if let Some(ref opt) = av.with_option {
13127 self.write_space();
13128 self.write_keyword("WITH");
13129 self.write_space();
13130 self.write_keyword(opt);
13131 }
13132
13133 for action in &av.actions {
13134 self.write_space();
13135 match action {
13136 AlterViewAction::Rename(new_name) => {
13137 self.write_keyword("RENAME TO");
13138 self.write_space();
13139 self.generate_table(new_name)?;
13140 }
13141 AlterViewAction::OwnerTo(owner) => {
13142 self.write_keyword("OWNER TO");
13143 self.write_space();
13144 self.generate_identifier(owner)?;
13145 }
13146 AlterViewAction::SetSchema(schema) => {
13147 self.write_keyword("SET SCHEMA");
13148 self.write_space();
13149 self.generate_identifier(schema)?;
13150 }
13151 AlterViewAction::SetAuthorization(auth) => {
13152 self.write_keyword("SET AUTHORIZATION");
13153 self.write_space();
13154 self.write(auth);
13155 }
13156 AlterViewAction::AlterColumn { name, action } => {
13157 self.write_keyword("ALTER COLUMN");
13158 self.write_space();
13159 self.generate_identifier(name)?;
13160 self.write_space();
13161 self.generate_alter_column_action(action)?;
13162 }
13163 AlterViewAction::AsSelect(query) => {
13164 self.write_keyword("AS");
13165 self.write_space();
13166 self.generate_expression(query)?;
13167 }
13168 AlterViewAction::SetTblproperties(props) => {
13169 self.write_keyword("SET TBLPROPERTIES");
13170 self.write(" (");
13171 for (i, (key, value)) in props.iter().enumerate() {
13172 if i > 0 {
13173 self.write(", ");
13174 }
13175 self.generate_string_literal(key)?;
13176 self.write("=");
13177 self.generate_string_literal(value)?;
13178 }
13179 self.write(")");
13180 }
13181 AlterViewAction::UnsetTblproperties(keys) => {
13182 self.write_keyword("UNSET TBLPROPERTIES");
13183 self.write(" (");
13184 for (i, key) in keys.iter().enumerate() {
13185 if i > 0 {
13186 self.write(", ");
13187 }
13188 self.generate_string_literal(key)?;
13189 }
13190 self.write(")");
13191 }
13192 }
13193 }
13194
13195 Ok(())
13196 }
13197
13198 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
13199 self.write_keyword("ALTER INDEX");
13200 self.write_space();
13201 self.generate_identifier(&ai.name)?;
13202
13203 if let Some(table) = &ai.table {
13204 self.write_space();
13205 self.write_keyword("ON");
13206 self.write_space();
13207 self.generate_table(table)?;
13208 }
13209
13210 for action in &ai.actions {
13211 self.write_space();
13212 match action {
13213 AlterIndexAction::Rename(new_name) => {
13214 self.write_keyword("RENAME TO");
13215 self.write_space();
13216 self.generate_identifier(new_name)?;
13217 }
13218 AlterIndexAction::SetTablespace(tablespace) => {
13219 self.write_keyword("SET TABLESPACE");
13220 self.write_space();
13221 self.generate_identifier(tablespace)?;
13222 }
13223 AlterIndexAction::Visible(visible) => {
13224 if *visible {
13225 self.write_keyword("VISIBLE");
13226 } else {
13227 self.write_keyword("INVISIBLE");
13228 }
13229 }
13230 }
13231 }
13232
13233 Ok(())
13234 }
13235
13236 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
13237 for comment in &cs.leading_comments {
13239 self.write_formatted_comment(comment);
13240 self.write_space();
13241 }
13242
13243 let saved_athena_hive_context = self.athena_hive_context;
13245 if matches!(
13246 self.config.dialect,
13247 Some(crate::dialects::DialectType::Athena)
13248 ) {
13249 self.athena_hive_context = true;
13250 }
13251
13252 self.write_keyword("CREATE SCHEMA");
13253
13254 if cs.if_not_exists {
13255 self.write_space();
13256 self.write_keyword("IF NOT EXISTS");
13257 }
13258
13259 self.write_space();
13260 for (i, part) in cs.name.iter().enumerate() {
13261 if i > 0 {
13262 self.write(".");
13263 }
13264 self.generate_identifier(part)?;
13265 }
13266
13267 if let Some(ref clone_parts) = cs.clone_from {
13268 self.write_keyword(" CLONE ");
13269 for (i, part) in clone_parts.iter().enumerate() {
13270 if i > 0 {
13271 self.write(".");
13272 }
13273 self.generate_identifier(part)?;
13274 }
13275 }
13276
13277 if let Some(ref at_clause) = cs.at_clause {
13278 self.write_space();
13279 self.generate_expression(at_clause)?;
13280 }
13281
13282 if let Some(auth) = &cs.authorization {
13283 self.write_space();
13284 self.write_keyword("AUTHORIZATION");
13285 self.write_space();
13286 self.generate_identifier(auth)?;
13287 }
13288
13289 let with_properties: Vec<_> = cs
13292 .properties
13293 .iter()
13294 .filter(|p| matches!(p, Expression::Property(_)))
13295 .collect();
13296 let other_properties: Vec<_> = cs
13297 .properties
13298 .iter()
13299 .filter(|p| !matches!(p, Expression::Property(_)))
13300 .collect();
13301
13302 if !with_properties.is_empty() {
13304 self.write_space();
13305 self.write_keyword("WITH");
13306 self.write(" (");
13307 for (i, prop) in with_properties.iter().enumerate() {
13308 if i > 0 {
13309 self.write(", ");
13310 }
13311 self.generate_expression(prop)?;
13312 }
13313 self.write(")");
13314 }
13315
13316 for prop in other_properties {
13318 self.write_space();
13319 self.generate_expression(prop)?;
13320 }
13321
13322 self.athena_hive_context = saved_athena_hive_context;
13324
13325 Ok(())
13326 }
13327
13328 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
13329 self.write_keyword("DROP SCHEMA");
13330
13331 if ds.if_exists {
13332 self.write_space();
13333 self.write_keyword("IF EXISTS");
13334 }
13335
13336 self.write_space();
13337 self.generate_identifier(&ds.name)?;
13338
13339 if ds.cascade {
13340 self.write_space();
13341 self.write_keyword("CASCADE");
13342 }
13343
13344 Ok(())
13345 }
13346
13347 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
13348 self.write_keyword("DROP NAMESPACE");
13349
13350 if dn.if_exists {
13351 self.write_space();
13352 self.write_keyword("IF EXISTS");
13353 }
13354
13355 self.write_space();
13356 self.generate_identifier(&dn.name)?;
13357
13358 if dn.cascade {
13359 self.write_space();
13360 self.write_keyword("CASCADE");
13361 }
13362
13363 Ok(())
13364 }
13365
13366 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
13367 self.write_keyword("CREATE DATABASE");
13368
13369 if cd.if_not_exists {
13370 self.write_space();
13371 self.write_keyword("IF NOT EXISTS");
13372 }
13373
13374 self.write_space();
13375 self.generate_identifier(&cd.name)?;
13376
13377 if let Some(ref clone_src) = cd.clone_from {
13378 self.write_keyword(" CLONE ");
13379 self.generate_identifier(clone_src)?;
13380 }
13381
13382 if let Some(ref at_clause) = cd.at_clause {
13384 self.write_space();
13385 self.generate_expression(at_clause)?;
13386 }
13387
13388 for option in &cd.options {
13389 self.write_space();
13390 match option {
13391 DatabaseOption::CharacterSet(charset) => {
13392 self.write_keyword("CHARACTER SET");
13393 self.write(" = ");
13394 self.write(&format!("'{}'", charset));
13395 }
13396 DatabaseOption::Collate(collate) => {
13397 self.write_keyword("COLLATE");
13398 self.write(" = ");
13399 self.write(&format!("'{}'", collate));
13400 }
13401 DatabaseOption::Owner(owner) => {
13402 self.write_keyword("OWNER");
13403 self.write(" = ");
13404 self.generate_identifier(owner)?;
13405 }
13406 DatabaseOption::Template(template) => {
13407 self.write_keyword("TEMPLATE");
13408 self.write(" = ");
13409 self.generate_identifier(template)?;
13410 }
13411 DatabaseOption::Encoding(encoding) => {
13412 self.write_keyword("ENCODING");
13413 self.write(" = ");
13414 self.write(&format!("'{}'", encoding));
13415 }
13416 DatabaseOption::Location(location) => {
13417 self.write_keyword("LOCATION");
13418 self.write(" = ");
13419 self.write(&format!("'{}'", location));
13420 }
13421 }
13422 }
13423
13424 Ok(())
13425 }
13426
13427 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
13428 self.write_keyword("DROP DATABASE");
13429
13430 if dd.if_exists {
13431 self.write_space();
13432 self.write_keyword("IF EXISTS");
13433 }
13434
13435 self.write_space();
13436 self.generate_identifier(&dd.name)?;
13437
13438 if dd.sync {
13439 self.write_space();
13440 self.write_keyword("SYNC");
13441 }
13442
13443 Ok(())
13444 }
13445
13446 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
13447 self.write_keyword("CREATE");
13448
13449 if cf.or_alter {
13450 self.write_space();
13451 self.write_keyword("OR ALTER");
13452 } else if cf.or_replace {
13453 self.write_space();
13454 self.write_keyword("OR REPLACE");
13455 }
13456
13457 if cf.temporary {
13458 self.write_space();
13459 self.write_keyword("TEMPORARY");
13460 }
13461
13462 self.write_space();
13463 if cf.is_table_function {
13464 self.write_keyword("TABLE FUNCTION");
13465 } else {
13466 self.write_keyword("FUNCTION");
13467 }
13468
13469 if cf.if_not_exists {
13470 self.write_space();
13471 self.write_keyword("IF NOT EXISTS");
13472 }
13473
13474 self.write_space();
13475 self.generate_table(&cf.name)?;
13476 if cf.has_parens {
13477 let func_multiline = self.config.pretty
13478 && matches!(
13479 self.config.dialect,
13480 Some(crate::dialects::DialectType::TSQL)
13481 | Some(crate::dialects::DialectType::Fabric)
13482 )
13483 && !cf.parameters.is_empty();
13484 if func_multiline {
13485 self.write("(\n");
13486 self.indent_level += 2;
13487 self.write_indent();
13488 self.generate_function_parameters(&cf.parameters)?;
13489 self.write("\n");
13490 self.indent_level -= 2;
13491 self.write(")");
13492 } else {
13493 self.write("(");
13494 self.generate_function_parameters(&cf.parameters)?;
13495 self.write(")");
13496 }
13497 }
13498
13499 let use_multiline = self.config.pretty
13502 && matches!(
13503 self.config.dialect,
13504 Some(crate::dialects::DialectType::BigQuery)
13505 | Some(crate::dialects::DialectType::TSQL)
13506 | Some(crate::dialects::DialectType::Fabric)
13507 );
13508
13509 if cf.language_first {
13510 if let Some(lang) = &cf.language {
13512 if use_multiline {
13513 self.write_newline();
13514 } else {
13515 self.write_space();
13516 }
13517 self.write_keyword("LANGUAGE");
13518 self.write_space();
13519 self.write(lang);
13520 }
13521
13522 if let Some(sql_data) = &cf.sql_data_access {
13524 self.write_space();
13525 match sql_data {
13526 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13527 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13528 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13529 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13530 }
13531 }
13532
13533 if let Some(ref rtb) = cf.returns_table_body {
13534 if use_multiline {
13535 self.write_newline();
13536 } else {
13537 self.write_space();
13538 }
13539 self.write_keyword("RETURNS");
13540 self.write_space();
13541 self.write(rtb);
13542 } else if let Some(return_type) = &cf.return_type {
13543 if use_multiline {
13544 self.write_newline();
13545 } else {
13546 self.write_space();
13547 }
13548 self.write_keyword("RETURNS");
13549 self.write_space();
13550 self.generate_function_return_type(return_type)?;
13551 }
13552 } else {
13553 let is_duckdb = matches!(
13556 self.config.dialect,
13557 Some(crate::dialects::DialectType::DuckDB)
13558 );
13559 if let Some(ref rtb) = cf.returns_table_body {
13560 if !(is_duckdb && rtb.is_empty()) {
13561 if use_multiline {
13562 self.write_newline();
13563 } else {
13564 self.write_space();
13565 }
13566 self.write_keyword("RETURNS");
13567 self.write_space();
13568 self.write(rtb);
13569 }
13570 } else if let Some(return_type) = &cf.return_type {
13571 if !is_duckdb {
13573 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
13574 if use_multiline {
13575 self.write_newline();
13576 } else {
13577 self.write_space();
13578 }
13579 self.write_keyword("RETURNS");
13580 self.write_space();
13581 if is_table_return {
13582 self.write_keyword("TABLE");
13583 } else {
13584 self.generate_function_return_type(return_type)?;
13585 }
13586 }
13587 }
13588 }
13589
13590 if !cf.property_order.is_empty() {
13592 let is_bigquery = matches!(
13594 self.config.dialect,
13595 Some(crate::dialects::DialectType::BigQuery)
13596 );
13597 let is_postgres = matches!(
13598 self.config.dialect,
13599 Some(crate::dialects::DialectType::PostgreSQL)
13600 );
13601 let property_order = if is_bigquery {
13602 let mut reordered = Vec::new();
13604 let mut has_as = false;
13605 let mut has_options = false;
13606 for prop in &cf.property_order {
13607 match prop {
13608 FunctionPropertyKind::As => has_as = true,
13609 FunctionPropertyKind::Options => has_options = true,
13610 _ => {}
13611 }
13612 }
13613 if has_as && has_options {
13614 for prop in &cf.property_order {
13616 if *prop != FunctionPropertyKind::As
13617 && *prop != FunctionPropertyKind::Options
13618 {
13619 reordered.push(*prop);
13620 }
13621 }
13622 reordered.push(FunctionPropertyKind::Options);
13623 reordered.push(FunctionPropertyKind::As);
13624 reordered
13625 } else {
13626 cf.property_order.clone()
13627 }
13628 } else if is_postgres
13629 && cf.property_order.contains(&FunctionPropertyKind::As)
13630 && cf.property_order.contains(&FunctionPropertyKind::NullInput)
13631 {
13632 let mut reordered: Vec<_> = cf
13633 .property_order
13634 .iter()
13635 .copied()
13636 .filter(|prop| *prop != FunctionPropertyKind::As)
13637 .collect();
13638 reordered.push(FunctionPropertyKind::As);
13639 reordered
13640 } else {
13641 cf.property_order.clone()
13642 };
13643
13644 for prop in &property_order {
13645 match prop {
13646 FunctionPropertyKind::Set => {
13647 self.generate_function_set_options(cf)?;
13648 }
13649 FunctionPropertyKind::As => {
13650 self.generate_function_body(cf)?;
13651 }
13652 FunctionPropertyKind::Using => {
13653 self.generate_function_using_resources(cf)?;
13654 }
13655 FunctionPropertyKind::Language => {
13656 if !cf.language_first {
13657 if let Some(lang) = &cf.language {
13659 let use_multiline = self.config.pretty
13661 && matches!(
13662 self.config.dialect,
13663 Some(crate::dialects::DialectType::BigQuery)
13664 );
13665 if use_multiline {
13666 self.write_newline();
13667 } else {
13668 self.write_space();
13669 }
13670 self.write_keyword("LANGUAGE");
13671 self.write_space();
13672 self.write(lang);
13673 }
13674 }
13675 }
13676 FunctionPropertyKind::Determinism => {
13677 self.generate_function_determinism(cf)?;
13678 }
13679 FunctionPropertyKind::NullInput => {
13680 self.generate_function_null_input(cf)?;
13681 }
13682 FunctionPropertyKind::Security => {
13683 self.generate_function_security(cf)?;
13684 }
13685 FunctionPropertyKind::SqlDataAccess => {
13686 if !cf.language_first {
13687 self.generate_function_sql_data_access(cf)?;
13689 }
13690 }
13691 FunctionPropertyKind::Options => {
13692 if !cf.options.is_empty() {
13693 self.write_space();
13694 self.generate_options_clause(&cf.options)?;
13695 }
13696 }
13697 FunctionPropertyKind::Environment => {
13698 if !cf.environment.is_empty() {
13699 self.write_space();
13700 self.generate_environment_clause(&cf.environment)?;
13701 }
13702 }
13703 FunctionPropertyKind::Handler => {
13704 if let Some(ref h) = cf.handler {
13705 self.write_space();
13706 self.write_keyword("HANDLER");
13707 if cf.handler_uses_eq {
13708 self.write(" = ");
13709 } else {
13710 self.write_space();
13711 }
13712 self.write("'");
13713 self.write(h);
13714 self.write("'");
13715 }
13716 }
13717 FunctionPropertyKind::RuntimeVersion => {
13718 if let Some(ref runtime_version) = cf.runtime_version {
13719 self.write_space();
13720 self.write_keyword("RUNTIME_VERSION");
13721 self.write("='");
13722 self.write(runtime_version);
13723 self.write("'");
13724 }
13725 }
13726 FunctionPropertyKind::Packages => {
13727 if let Some(ref packages) = cf.packages {
13728 self.write_space();
13729 self.write_keyword("PACKAGES");
13730 self.write("=(");
13731 for (i, package) in packages.iter().enumerate() {
13732 if i > 0 {
13733 self.write(", ");
13734 }
13735 self.write("'");
13736 self.write(package);
13737 self.write("'");
13738 }
13739 self.write(")");
13740 }
13741 }
13742 FunctionPropertyKind::ParameterStyle => {
13743 if let Some(ref ps) = cf.parameter_style {
13744 self.write_space();
13745 self.write_keyword("PARAMETER STYLE");
13746 self.write_space();
13747 self.write_keyword(ps);
13748 }
13749 }
13750 }
13751 }
13752
13753 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
13755 {
13756 self.write_space();
13757 self.generate_options_clause(&cf.options)?;
13758 }
13759
13760 if !cf.environment.is_empty()
13762 && !cf
13763 .property_order
13764 .contains(&FunctionPropertyKind::Environment)
13765 {
13766 self.write_space();
13767 self.generate_environment_clause(&cf.environment)?;
13768 }
13769 } else {
13770 if matches!(
13773 self.config.dialect,
13774 Some(crate::dialects::DialectType::BigQuery)
13775 ) {
13776 self.generate_function_determinism(cf)?;
13777 }
13778
13779 let use_multiline = self.config.pretty
13781 && matches!(
13782 self.config.dialect,
13783 Some(crate::dialects::DialectType::BigQuery)
13784 );
13785
13786 if !cf.language_first {
13787 if let Some(lang) = &cf.language {
13788 if use_multiline {
13789 self.write_newline();
13790 } else {
13791 self.write_space();
13792 }
13793 self.write_keyword("LANGUAGE");
13794 self.write_space();
13795 self.write(lang);
13796 }
13797
13798 self.generate_function_sql_data_access(cf)?;
13800 }
13801
13802 if !matches!(
13804 self.config.dialect,
13805 Some(crate::dialects::DialectType::BigQuery)
13806 ) {
13807 self.generate_function_determinism(cf)?;
13808 }
13809
13810 self.generate_function_null_input(cf)?;
13811 self.generate_function_security(cf)?;
13812 self.generate_function_set_options(cf)?;
13813
13814 if !cf.options.is_empty() {
13816 self.write_space();
13817 self.generate_options_clause(&cf.options)?;
13818 }
13819
13820 if !cf.environment.is_empty() {
13822 self.write_space();
13823 self.generate_environment_clause(&cf.environment)?;
13824 }
13825
13826 if let Some(ref h) = cf.handler {
13827 self.write_space();
13828 self.write_keyword("HANDLER");
13829 if cf.handler_uses_eq {
13830 self.write(" = ");
13831 } else {
13832 self.write_space();
13833 }
13834 self.write("'");
13835 self.write(h);
13836 self.write("'");
13837 }
13838
13839 if let Some(ref runtime_version) = cf.runtime_version {
13840 self.write_space();
13841 self.write_keyword("RUNTIME_VERSION");
13842 self.write("='");
13843 self.write(runtime_version);
13844 self.write("'");
13845 }
13846
13847 if let Some(ref packages) = cf.packages {
13848 self.write_space();
13849 self.write_keyword("PACKAGES");
13850 self.write("=(");
13851 for (i, package) in packages.iter().enumerate() {
13852 if i > 0 {
13853 self.write(", ");
13854 }
13855 self.write("'");
13856 self.write(package);
13857 self.write("'");
13858 }
13859 self.write(")");
13860 }
13861
13862 self.generate_function_body(cf)?;
13863 self.generate_function_using_resources(cf)?;
13864 }
13865
13866 Ok(())
13867 }
13868
13869 fn generate_function_return_type(&mut self, return_type: &DataType) -> Result<()> {
13870 if matches!(
13871 self.config.dialect,
13872 Some(crate::dialects::DialectType::PostgreSQL)
13873 ) {
13874 if let DataType::Custom { name } = return_type {
13875 if name.eq_ignore_ascii_case("integer") {
13876 self.write_keyword("INT");
13877 return Ok(());
13878 }
13879 }
13880 }
13881
13882 self.generate_data_type(return_type)
13883 }
13884
13885 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
13887 for opt in &cf.set_options {
13888 self.write_space();
13889 self.write_keyword("SET");
13890 self.write_space();
13891 self.write(&opt.name);
13892 match &opt.value {
13893 FunctionSetValue::Value { value, use_to } => {
13894 if *use_to {
13895 self.write(" TO ");
13896 } else {
13897 self.write(" = ");
13898 }
13899 self.write(value);
13900 }
13901 FunctionSetValue::FromCurrent => {
13902 self.write_space();
13903 self.write_keyword("FROM CURRENT");
13904 }
13905 }
13906 }
13907 Ok(())
13908 }
13909
13910 fn generate_function_using_resources(&mut self, cf: &CreateFunction) -> Result<()> {
13911 if cf.using_resources.is_empty() {
13912 return Ok(());
13913 }
13914
13915 self.write_space();
13916 self.write_keyword("USING");
13917 for resource in &cf.using_resources {
13918 self.write_space();
13919 self.write_keyword(&resource.kind);
13920 self.write_space();
13921 self.generate_string_literal(&resource.uri)?;
13922 }
13923 Ok(())
13924 }
13925
13926 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
13928 if let Some(body) = &cf.body {
13929 self.write_space();
13931 let use_multiline = self.config.pretty
13933 && matches!(
13934 self.config.dialect,
13935 Some(crate::dialects::DialectType::BigQuery)
13936 );
13937 match body {
13938 FunctionBody::Block(block) => {
13939 self.write_keyword("AS");
13940 if matches!(
13941 self.config.dialect,
13942 Some(crate::dialects::DialectType::TSQL)
13943 ) {
13944 self.write(" BEGIN ");
13945 self.write(block);
13946 self.write(" END");
13947 } else if matches!(
13948 self.config.dialect,
13949 Some(crate::dialects::DialectType::PostgreSQL)
13950 ) {
13951 self.write(" $$");
13952 self.write(block);
13953 self.write("$$");
13954 } else {
13955 let escaped = self.escape_block_for_single_quote(block);
13957 if use_multiline {
13959 self.write_newline();
13960 } else {
13961 self.write(" ");
13962 }
13963 self.write("'");
13964 self.write(&escaped);
13965 self.write("'");
13966 }
13967 }
13968 FunctionBody::StringLiteral(s) => {
13969 self.write_keyword("AS");
13970 if use_multiline {
13972 self.write_newline();
13973 } else {
13974 self.write(" ");
13975 }
13976 self.generate_string_literal(s)?;
13977 }
13978 FunctionBody::Expression(expr) => {
13979 self.write_keyword("AS");
13980 self.write_space();
13981 self.generate_expression(expr)?;
13982 }
13983 FunctionBody::External(name) => {
13984 self.write_keyword("EXTERNAL NAME");
13985 self.write(" '");
13986 self.write(name);
13987 self.write("'");
13988 }
13989 FunctionBody::Return(expr) => {
13990 if matches!(
13991 self.config.dialect,
13992 Some(crate::dialects::DialectType::DuckDB)
13993 ) {
13994 self.write_keyword("AS");
13996 self.write_space();
13997 let is_table_return = cf.returns_table_body.is_some()
13999 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
14000 if is_table_return {
14001 self.write_keyword("TABLE");
14002 self.write_space();
14003 }
14004 self.generate_expression(expr)?;
14005 } else {
14006 if self.config.create_function_return_as {
14007 self.write_keyword("AS");
14008 if self.config.pretty
14010 && matches!(
14011 self.config.dialect,
14012 Some(crate::dialects::DialectType::TSQL)
14013 | Some(crate::dialects::DialectType::Fabric)
14014 )
14015 {
14016 self.write_newline();
14017 } else {
14018 self.write_space();
14019 }
14020 }
14021 self.write_keyword("RETURN");
14022 self.write_space();
14023 self.generate_expression(expr)?;
14024 }
14025 }
14026 FunctionBody::Statements(stmts) => {
14027 self.write_keyword("AS");
14028 self.write(" BEGIN ");
14029 for (i, stmt) in stmts.iter().enumerate() {
14030 if i > 0 {
14031 self.write(" ");
14032 }
14033 self.generate_expression(stmt)?;
14034 self.write(";");
14035 }
14036 self.write(" END");
14037 }
14038 FunctionBody::RawBlock(text) => {
14039 self.write_newline();
14040 self.write(text);
14041 }
14042 FunctionBody::DollarQuoted { content, tag } => {
14043 self.write_keyword("AS");
14044 self.write(" ");
14045 let supports_dollar_quoting = matches!(
14047 self.config.dialect,
14048 Some(crate::dialects::DialectType::PostgreSQL)
14049 | Some(crate::dialects::DialectType::Databricks)
14050 | Some(crate::dialects::DialectType::Redshift)
14051 | Some(crate::dialects::DialectType::DuckDB)
14052 );
14053 if supports_dollar_quoting {
14054 self.write("$");
14056 if let Some(t) = tag {
14057 self.write(t);
14058 }
14059 self.write("$");
14060 self.write(content);
14061 self.write("$");
14062 if let Some(t) = tag {
14063 self.write(t);
14064 }
14065 self.write("$");
14066 } else {
14067 let escaped = self.escape_block_for_single_quote(content);
14069 self.write("'");
14070 self.write(&escaped);
14071 self.write("'");
14072 }
14073 }
14074 }
14075 }
14076 Ok(())
14077 }
14078
14079 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
14081 if let Some(det) = cf.deterministic {
14082 self.write_space();
14083 if matches!(
14084 self.config.dialect,
14085 Some(crate::dialects::DialectType::BigQuery)
14086 ) {
14087 if det {
14089 self.write_keyword("DETERMINISTIC");
14090 } else {
14091 self.write_keyword("NOT DETERMINISTIC");
14092 }
14093 } else {
14094 if det {
14096 self.write_keyword("IMMUTABLE");
14097 } else {
14098 self.write_keyword("VOLATILE");
14099 }
14100 }
14101 }
14102 Ok(())
14103 }
14104
14105 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
14107 if let Some(returns_null) = cf.returns_null_on_null_input {
14108 self.write_space();
14109 if returns_null {
14110 if cf.strict {
14111 self.write_keyword("STRICT");
14112 } else {
14113 self.write_keyword("RETURNS NULL ON NULL INPUT");
14114 }
14115 } else {
14116 self.write_keyword("CALLED ON NULL INPUT");
14117 }
14118 }
14119 Ok(())
14120 }
14121
14122 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
14124 if let Some(security) = &cf.security {
14125 self.write_space();
14126 if matches!(
14128 self.config.dialect,
14129 Some(crate::dialects::DialectType::MySQL)
14130 ) {
14131 self.write_keyword("SQL SECURITY");
14132 } else {
14133 self.write_keyword("SECURITY");
14134 }
14135 self.write_space();
14136 match security {
14137 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
14138 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
14139 FunctionSecurity::None => self.write_keyword("NONE"),
14140 }
14141 }
14142 Ok(())
14143 }
14144
14145 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
14147 if let Some(sql_data) = &cf.sql_data_access {
14148 self.write_space();
14149 match sql_data {
14150 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
14151 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
14152 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
14153 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
14154 }
14155 }
14156 Ok(())
14157 }
14158
14159 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
14160 for (i, param) in params.iter().enumerate() {
14161 if i > 0 {
14162 self.write(", ");
14163 }
14164
14165 if let Some(mode) = ¶m.mode {
14166 if let Some(text) = ¶m.mode_text {
14167 self.write(text);
14168 } else {
14169 match mode {
14170 ParameterMode::In => self.write_keyword("IN"),
14171 ParameterMode::Out => self.write_keyword("OUT"),
14172 ParameterMode::InOut => self.write_keyword("INOUT"),
14173 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
14174 }
14175 }
14176 self.write_space();
14177 }
14178
14179 if let Some(name) = ¶m.name {
14180 self.generate_identifier(name)?;
14181 let skip_type =
14183 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
14184 if !skip_type {
14185 self.write_space();
14186 self.generate_data_type(¶m.data_type)?;
14187 }
14188 } else {
14189 self.generate_data_type(¶m.data_type)?;
14190 }
14191
14192 if let Some(default) = ¶m.default {
14193 if self.config.parameter_default_equals {
14194 self.write(" = ");
14195 } else {
14196 self.write(" DEFAULT ");
14197 }
14198 self.generate_expression(default)?;
14199 }
14200 }
14201
14202 Ok(())
14203 }
14204
14205 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
14206 self.write_keyword("DROP FUNCTION");
14207
14208 if df.if_exists {
14209 self.write_space();
14210 self.write_keyword("IF EXISTS");
14211 }
14212
14213 self.write_space();
14214 self.generate_table(&df.name)?;
14215
14216 if let Some(params) = &df.parameters {
14217 self.write(" (");
14218 for (i, dt) in params.iter().enumerate() {
14219 if i > 0 {
14220 self.write(", ");
14221 }
14222 self.generate_data_type(dt)?;
14223 }
14224 self.write(")");
14225 }
14226
14227 if df.cascade {
14228 self.write_space();
14229 self.write_keyword("CASCADE");
14230 }
14231
14232 Ok(())
14233 }
14234
14235 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
14236 self.write_keyword("CREATE");
14237
14238 if cp.or_alter {
14239 self.write_space();
14240 self.write_keyword("OR ALTER");
14241 } else if cp.or_replace {
14242 self.write_space();
14243 self.write_keyword("OR REPLACE");
14244 }
14245
14246 self.write_space();
14247 if cp.use_proc_keyword {
14248 self.write_keyword("PROC");
14249 } else {
14250 self.write_keyword("PROCEDURE");
14251 }
14252
14253 if cp.if_not_exists {
14254 self.write_space();
14255 self.write_keyword("IF NOT EXISTS");
14256 }
14257
14258 self.write_space();
14259 self.generate_table(&cp.name)?;
14260 if cp.has_parens {
14261 self.write("(");
14262 self.generate_function_parameters(&cp.parameters)?;
14263 self.write(")");
14264 } else if !cp.parameters.is_empty() {
14265 self.write_space();
14267 self.generate_function_parameters(&cp.parameters)?;
14268 }
14269
14270 if let Some(return_type) = &cp.return_type {
14272 self.write_space();
14273 self.write_keyword("RETURNS");
14274 self.write_space();
14275 self.generate_data_type(return_type)?;
14276 }
14277
14278 if let Some(execute_as) = &cp.execute_as {
14280 self.write_space();
14281 self.write_keyword("EXECUTE AS");
14282 self.write_space();
14283 self.write_keyword(execute_as);
14284 }
14285
14286 if let Some(lang) = &cp.language {
14287 self.write_space();
14288 self.write_keyword("LANGUAGE");
14289 self.write_space();
14290 self.write(lang);
14291 }
14292
14293 if let Some(security) = &cp.security {
14294 self.write_space();
14295 self.write_keyword("SECURITY");
14296 self.write_space();
14297 match security {
14298 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
14299 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
14300 FunctionSecurity::None => self.write_keyword("NONE"),
14301 }
14302 }
14303
14304 if !cp.with_options.is_empty() {
14306 self.write_space();
14307 self.write_keyword("WITH");
14308 self.write_space();
14309 for (i, opt) in cp.with_options.iter().enumerate() {
14310 if i > 0 {
14311 self.write(", ");
14312 }
14313 self.write(opt);
14314 }
14315 }
14316
14317 if let Some(body) = &cp.body {
14318 self.write_space();
14319 match body {
14320 FunctionBody::Block(block) => {
14321 self.write_keyword("AS");
14322 if matches!(
14323 self.config.dialect,
14324 Some(crate::dialects::DialectType::TSQL)
14325 ) {
14326 self.write(" BEGIN ");
14327 self.write(block);
14328 self.write(" END");
14329 } else if matches!(
14330 self.config.dialect,
14331 Some(crate::dialects::DialectType::PostgreSQL)
14332 ) {
14333 self.write(" $$");
14334 self.write(block);
14335 self.write("$$");
14336 } else {
14337 let escaped = self.escape_block_for_single_quote(block);
14339 self.write(" '");
14340 self.write(&escaped);
14341 self.write("'");
14342 }
14343 }
14344 FunctionBody::StringLiteral(s) => {
14345 self.write_keyword("AS");
14346 self.write_space();
14347 self.generate_string_literal(s)?;
14348 }
14349 FunctionBody::Expression(expr) => {
14350 self.write_keyword("AS");
14351 self.write_space();
14352 self.generate_expression(expr)?;
14353 }
14354 FunctionBody::External(name) => {
14355 self.write_keyword("EXTERNAL NAME");
14356 self.write(" '");
14357 self.write(name);
14358 self.write("'");
14359 }
14360 FunctionBody::Return(expr) => {
14361 self.write_keyword("RETURN");
14362 self.write_space();
14363 self.generate_expression(expr)?;
14364 }
14365 FunctionBody::Statements(stmts) => {
14366 self.write_keyword("AS");
14367 self.write(" BEGIN ");
14368 for (i, stmt) in stmts.iter().enumerate() {
14369 if i > 0 {
14370 self.write(" ");
14371 }
14372 self.generate_expression(stmt)?;
14373 self.write(";");
14374 }
14375 self.write(" END");
14376 }
14377 FunctionBody::RawBlock(text) => {
14378 self.write_newline();
14379 self.write(text);
14380 }
14381 FunctionBody::DollarQuoted { content, tag } => {
14382 self.write_keyword("AS");
14383 self.write(" ");
14384 let supports_dollar_quoting = matches!(
14386 self.config.dialect,
14387 Some(crate::dialects::DialectType::PostgreSQL)
14388 | Some(crate::dialects::DialectType::Databricks)
14389 | Some(crate::dialects::DialectType::Redshift)
14390 | Some(crate::dialects::DialectType::DuckDB)
14391 );
14392 if supports_dollar_quoting {
14393 self.write("$");
14395 if let Some(t) = tag {
14396 self.write(t);
14397 }
14398 self.write("$");
14399 self.write(content);
14400 self.write("$");
14401 if let Some(t) = tag {
14402 self.write(t);
14403 }
14404 self.write("$");
14405 } else {
14406 let escaped = self.escape_block_for_single_quote(content);
14408 self.write("'");
14409 self.write(&escaped);
14410 self.write("'");
14411 }
14412 }
14413 }
14414 }
14415
14416 Ok(())
14417 }
14418
14419 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
14420 self.write_keyword("DROP PROCEDURE");
14421
14422 if dp.if_exists {
14423 self.write_space();
14424 self.write_keyword("IF EXISTS");
14425 }
14426
14427 self.write_space();
14428 self.generate_table(&dp.name)?;
14429
14430 if let Some(params) = &dp.parameters {
14431 self.write(" (");
14432 for (i, dt) in params.iter().enumerate() {
14433 if i > 0 {
14434 self.write(", ");
14435 }
14436 self.generate_data_type(dt)?;
14437 }
14438 self.write(")");
14439 }
14440
14441 if dp.cascade {
14442 self.write_space();
14443 self.write_keyword("CASCADE");
14444 }
14445
14446 Ok(())
14447 }
14448
14449 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
14450 self.write_keyword("CREATE");
14451
14452 if cs.or_replace {
14453 self.write_space();
14454 self.write_keyword("OR REPLACE");
14455 }
14456
14457 if cs.temporary {
14458 self.write_space();
14459 self.write_keyword("TEMPORARY");
14460 }
14461
14462 self.write_space();
14463 self.write_keyword("SEQUENCE");
14464
14465 if cs.if_not_exists {
14466 self.write_space();
14467 self.write_keyword("IF NOT EXISTS");
14468 }
14469
14470 self.write_space();
14471 self.generate_table(&cs.name)?;
14472
14473 if let Some(as_type) = &cs.as_type {
14475 self.write_space();
14476 self.write_keyword("AS");
14477 self.write_space();
14478 self.generate_data_type(as_type)?;
14479 }
14480
14481 if let Some(comment) = &cs.comment {
14483 self.write_space();
14484 self.write_keyword("COMMENT");
14485 self.write("=");
14486 self.generate_string_literal(comment)?;
14487 }
14488
14489 if !cs.property_order.is_empty() {
14491 for prop in &cs.property_order {
14492 match prop {
14493 SeqPropKind::Start => {
14494 if let Some(start) = cs.start {
14495 self.write_space();
14496 self.write_keyword("START WITH");
14497 self.write(&format!(" {}", start));
14498 }
14499 }
14500 SeqPropKind::Increment => {
14501 if let Some(inc) = cs.increment {
14502 self.write_space();
14503 self.write_keyword("INCREMENT BY");
14504 self.write(&format!(" {}", inc));
14505 }
14506 }
14507 SeqPropKind::Minvalue => {
14508 if let Some(min) = &cs.minvalue {
14509 self.write_space();
14510 match min {
14511 SequenceBound::Value(v) => {
14512 self.write_keyword("MINVALUE");
14513 self.write(&format!(" {}", v));
14514 }
14515 SequenceBound::None => {
14516 self.write_keyword("NO MINVALUE");
14517 }
14518 }
14519 }
14520 }
14521 SeqPropKind::Maxvalue => {
14522 if let Some(max) = &cs.maxvalue {
14523 self.write_space();
14524 match max {
14525 SequenceBound::Value(v) => {
14526 self.write_keyword("MAXVALUE");
14527 self.write(&format!(" {}", v));
14528 }
14529 SequenceBound::None => {
14530 self.write_keyword("NO MAXVALUE");
14531 }
14532 }
14533 }
14534 }
14535 SeqPropKind::Cache => {
14536 if let Some(cache) = cs.cache {
14537 self.write_space();
14538 self.write_keyword("CACHE");
14539 self.write(&format!(" {}", cache));
14540 }
14541 }
14542 SeqPropKind::NoCache => {
14543 self.write_space();
14544 self.write_keyword("NO CACHE");
14545 }
14546 SeqPropKind::NoCacheWord => {
14547 self.write_space();
14548 self.write_keyword("NOCACHE");
14549 }
14550 SeqPropKind::Cycle => {
14551 self.write_space();
14552 self.write_keyword("CYCLE");
14553 }
14554 SeqPropKind::NoCycle => {
14555 self.write_space();
14556 self.write_keyword("NO CYCLE");
14557 }
14558 SeqPropKind::NoCycleWord => {
14559 self.write_space();
14560 self.write_keyword("NOCYCLE");
14561 }
14562 SeqPropKind::OwnedBy => {
14563 if !cs.owned_by_none {
14565 if let Some(owned) = &cs.owned_by {
14566 self.write_space();
14567 self.write_keyword("OWNED BY");
14568 self.write_space();
14569 self.generate_table(owned)?;
14570 }
14571 }
14572 }
14573 SeqPropKind::Order => {
14574 self.write_space();
14575 self.write_keyword("ORDER");
14576 }
14577 SeqPropKind::NoOrder => {
14578 self.write_space();
14579 self.write_keyword("NOORDER");
14580 }
14581 SeqPropKind::Comment => {
14582 }
14584 SeqPropKind::Sharing => {
14585 if let Some(val) = &cs.sharing {
14586 self.write_space();
14587 self.write(&format!("SHARING={}", val));
14588 }
14589 }
14590 SeqPropKind::Keep => {
14591 self.write_space();
14592 self.write_keyword("KEEP");
14593 }
14594 SeqPropKind::NoKeep => {
14595 self.write_space();
14596 self.write_keyword("NOKEEP");
14597 }
14598 SeqPropKind::Scale => {
14599 self.write_space();
14600 self.write_keyword("SCALE");
14601 if let Some(modifier) = &cs.scale_modifier {
14602 if !modifier.is_empty() {
14603 self.write_space();
14604 self.write_keyword(modifier);
14605 }
14606 }
14607 }
14608 SeqPropKind::NoScale => {
14609 self.write_space();
14610 self.write_keyword("NOSCALE");
14611 }
14612 SeqPropKind::Shard => {
14613 self.write_space();
14614 self.write_keyword("SHARD");
14615 if let Some(modifier) = &cs.shard_modifier {
14616 if !modifier.is_empty() {
14617 self.write_space();
14618 self.write_keyword(modifier);
14619 }
14620 }
14621 }
14622 SeqPropKind::NoShard => {
14623 self.write_space();
14624 self.write_keyword("NOSHARD");
14625 }
14626 SeqPropKind::Session => {
14627 self.write_space();
14628 self.write_keyword("SESSION");
14629 }
14630 SeqPropKind::Global => {
14631 self.write_space();
14632 self.write_keyword("GLOBAL");
14633 }
14634 SeqPropKind::NoMinvalueWord => {
14635 self.write_space();
14636 self.write_keyword("NOMINVALUE");
14637 }
14638 SeqPropKind::NoMaxvalueWord => {
14639 self.write_space();
14640 self.write_keyword("NOMAXVALUE");
14641 }
14642 }
14643 }
14644 } else {
14645 if let Some(inc) = cs.increment {
14647 self.write_space();
14648 self.write_keyword("INCREMENT BY");
14649 self.write(&format!(" {}", inc));
14650 }
14651
14652 if let Some(min) = &cs.minvalue {
14653 self.write_space();
14654 match min {
14655 SequenceBound::Value(v) => {
14656 self.write_keyword("MINVALUE");
14657 self.write(&format!(" {}", v));
14658 }
14659 SequenceBound::None => {
14660 self.write_keyword("NO MINVALUE");
14661 }
14662 }
14663 }
14664
14665 if let Some(max) = &cs.maxvalue {
14666 self.write_space();
14667 match max {
14668 SequenceBound::Value(v) => {
14669 self.write_keyword("MAXVALUE");
14670 self.write(&format!(" {}", v));
14671 }
14672 SequenceBound::None => {
14673 self.write_keyword("NO MAXVALUE");
14674 }
14675 }
14676 }
14677
14678 if let Some(start) = cs.start {
14679 self.write_space();
14680 self.write_keyword("START WITH");
14681 self.write(&format!(" {}", start));
14682 }
14683
14684 if let Some(cache) = cs.cache {
14685 self.write_space();
14686 self.write_keyword("CACHE");
14687 self.write(&format!(" {}", cache));
14688 }
14689
14690 if cs.cycle {
14691 self.write_space();
14692 self.write_keyword("CYCLE");
14693 }
14694
14695 if let Some(owned) = &cs.owned_by {
14696 self.write_space();
14697 self.write_keyword("OWNED BY");
14698 self.write_space();
14699 self.generate_table(owned)?;
14700 }
14701 }
14702
14703 Ok(())
14704 }
14705
14706 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
14707 self.write_keyword("DROP SEQUENCE");
14708
14709 if ds.if_exists {
14710 self.write_space();
14711 self.write_keyword("IF EXISTS");
14712 }
14713
14714 self.write_space();
14715 self.generate_table(&ds.name)?;
14716
14717 if ds.cascade {
14718 self.write_space();
14719 self.write_keyword("CASCADE");
14720 }
14721
14722 Ok(())
14723 }
14724
14725 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
14726 self.write_keyword("ALTER SEQUENCE");
14727
14728 if als.if_exists {
14729 self.write_space();
14730 self.write_keyword("IF EXISTS");
14731 }
14732
14733 self.write_space();
14734 self.generate_table(&als.name)?;
14735
14736 if let Some(inc) = als.increment {
14737 self.write_space();
14738 self.write_keyword("INCREMENT BY");
14739 self.write(&format!(" {}", inc));
14740 }
14741
14742 if let Some(min) = &als.minvalue {
14743 self.write_space();
14744 match min {
14745 SequenceBound::Value(v) => {
14746 self.write_keyword("MINVALUE");
14747 self.write(&format!(" {}", v));
14748 }
14749 SequenceBound::None => {
14750 self.write_keyword("NO MINVALUE");
14751 }
14752 }
14753 }
14754
14755 if let Some(max) = &als.maxvalue {
14756 self.write_space();
14757 match max {
14758 SequenceBound::Value(v) => {
14759 self.write_keyword("MAXVALUE");
14760 self.write(&format!(" {}", v));
14761 }
14762 SequenceBound::None => {
14763 self.write_keyword("NO MAXVALUE");
14764 }
14765 }
14766 }
14767
14768 if let Some(start) = als.start {
14769 self.write_space();
14770 self.write_keyword("START WITH");
14771 self.write(&format!(" {}", start));
14772 }
14773
14774 if let Some(restart) = &als.restart {
14775 self.write_space();
14776 self.write_keyword("RESTART");
14777 if let Some(val) = restart {
14778 self.write_keyword(" WITH");
14779 self.write(&format!(" {}", val));
14780 }
14781 }
14782
14783 if let Some(cache) = als.cache {
14784 self.write_space();
14785 self.write_keyword("CACHE");
14786 self.write(&format!(" {}", cache));
14787 }
14788
14789 if let Some(cycle) = als.cycle {
14790 self.write_space();
14791 if cycle {
14792 self.write_keyword("CYCLE");
14793 } else {
14794 self.write_keyword("NO CYCLE");
14795 }
14796 }
14797
14798 if let Some(owned) = &als.owned_by {
14799 self.write_space();
14800 self.write_keyword("OWNED BY");
14801 self.write_space();
14802 if let Some(table) = owned {
14803 self.generate_table(table)?;
14804 } else {
14805 self.write_keyword("NONE");
14806 }
14807 }
14808
14809 Ok(())
14810 }
14811
14812 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
14813 self.write_keyword("CREATE");
14814
14815 if ct.or_alter {
14816 self.write_space();
14817 self.write_keyword("OR ALTER");
14818 } else if ct.or_replace {
14819 self.write_space();
14820 self.write_keyword("OR REPLACE");
14821 }
14822
14823 if ct.constraint {
14824 self.write_space();
14825 self.write_keyword("CONSTRAINT");
14826 }
14827
14828 self.write_space();
14829 self.write_keyword("TRIGGER");
14830 self.write_space();
14831 self.generate_identifier(&ct.name)?;
14832
14833 self.write_space();
14834 match ct.timing {
14835 TriggerTiming::Before => self.write_keyword("BEFORE"),
14836 TriggerTiming::After => self.write_keyword("AFTER"),
14837 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
14838 }
14839
14840 for (i, event) in ct.events.iter().enumerate() {
14842 if i > 0 {
14843 self.write_keyword(" OR");
14844 }
14845 self.write_space();
14846 match event {
14847 TriggerEvent::Insert => self.write_keyword("INSERT"),
14848 TriggerEvent::Update(cols) => {
14849 self.write_keyword("UPDATE");
14850 if let Some(cols) = cols {
14851 self.write_space();
14852 self.write_keyword("OF");
14853 for (j, col) in cols.iter().enumerate() {
14854 if j > 0 {
14855 self.write(",");
14856 }
14857 self.write_space();
14858 self.generate_identifier(col)?;
14859 }
14860 }
14861 }
14862 TriggerEvent::Delete => self.write_keyword("DELETE"),
14863 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
14864 }
14865 }
14866
14867 self.write_space();
14868 self.write_keyword("ON");
14869 self.write_space();
14870 self.generate_table(&ct.table)?;
14871
14872 if let Some(ref_clause) = &ct.referencing {
14874 self.write_space();
14875 self.write_keyword("REFERENCING");
14876 if let Some(old_table) = &ref_clause.old_table {
14877 self.write_space();
14878 self.write_keyword("OLD TABLE AS");
14879 self.write_space();
14880 self.generate_identifier(old_table)?;
14881 }
14882 if let Some(new_table) = &ref_clause.new_table {
14883 self.write_space();
14884 self.write_keyword("NEW TABLE AS");
14885 self.write_space();
14886 self.generate_identifier(new_table)?;
14887 }
14888 if let Some(old_row) = &ref_clause.old_row {
14889 self.write_space();
14890 self.write_keyword("OLD ROW AS");
14891 self.write_space();
14892 self.generate_identifier(old_row)?;
14893 }
14894 if let Some(new_row) = &ref_clause.new_row {
14895 self.write_space();
14896 self.write_keyword("NEW ROW AS");
14897 self.write_space();
14898 self.generate_identifier(new_row)?;
14899 }
14900 }
14901
14902 if let Some(deferrable) = ct.deferrable {
14904 self.write_space();
14905 if deferrable {
14906 self.write_keyword("DEFERRABLE");
14907 } else {
14908 self.write_keyword("NOT DEFERRABLE");
14909 }
14910 }
14911
14912 if let Some(initially) = ct.initially_deferred {
14913 self.write_space();
14914 self.write_keyword("INITIALLY");
14915 self.write_space();
14916 if initially {
14917 self.write_keyword("DEFERRED");
14918 } else {
14919 self.write_keyword("IMMEDIATE");
14920 }
14921 }
14922
14923 if let Some(for_each) = ct.for_each {
14924 self.write_space();
14925 self.write_keyword("FOR EACH");
14926 self.write_space();
14927 match for_each {
14928 TriggerForEach::Row => self.write_keyword("ROW"),
14929 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
14930 }
14931 }
14932
14933 if let Some(when) = &ct.when {
14935 self.write_space();
14936 self.write_keyword("WHEN");
14937 if ct.when_paren {
14938 self.write(" (");
14939 self.generate_expression(when)?;
14940 self.write(")");
14941 } else {
14942 self.write_space();
14943 self.generate_expression(when)?;
14944 }
14945 }
14946
14947 self.write_space();
14949 match &ct.body {
14950 TriggerBody::Execute { function, args } => {
14951 self.write_keyword("EXECUTE FUNCTION");
14952 self.write_space();
14953 self.generate_table(function)?;
14954 self.write("(");
14955 for (i, arg) in args.iter().enumerate() {
14956 if i > 0 {
14957 self.write(", ");
14958 }
14959 self.generate_expression(arg)?;
14960 }
14961 self.write(")");
14962 }
14963 TriggerBody::Block(block) => {
14964 self.write_keyword("BEGIN");
14965 self.write_space();
14966 self.write(block);
14967 self.write_space();
14968 self.write_keyword("END");
14969 }
14970 }
14971
14972 Ok(())
14973 }
14974
14975 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
14976 self.write_keyword("DROP TRIGGER");
14977
14978 if dt.if_exists {
14979 self.write_space();
14980 self.write_keyword("IF EXISTS");
14981 }
14982
14983 self.write_space();
14984 self.generate_identifier(&dt.name)?;
14985
14986 if let Some(table) = &dt.table {
14987 self.write_space();
14988 self.write_keyword("ON");
14989 self.write_space();
14990 self.generate_table(table)?;
14991 }
14992
14993 if dt.cascade {
14994 self.write_space();
14995 self.write_keyword("CASCADE");
14996 }
14997
14998 Ok(())
14999 }
15000
15001 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
15002 self.write_keyword("CREATE TYPE");
15003
15004 if ct.if_not_exists {
15005 self.write_space();
15006 self.write_keyword("IF NOT EXISTS");
15007 }
15008
15009 self.write_space();
15010 self.generate_table(&ct.name)?;
15011
15012 if let TypeDefinition::Base {
15013 input,
15014 output,
15015 internallength,
15016 } = &ct.definition
15017 {
15018 if input.is_empty() && output.is_empty() && internallength.is_none() {
15019 return Ok(());
15020 }
15021 }
15022
15023 self.write_space();
15024 self.write_keyword("AS");
15025 self.write_space();
15026
15027 match &ct.definition {
15028 TypeDefinition::Enum(values) => {
15029 self.write_keyword("ENUM");
15030 self.write(" (");
15031 for (i, val) in values.iter().enumerate() {
15032 if i > 0 {
15033 self.write(", ");
15034 }
15035 self.write(&format!("'{}'", val));
15036 }
15037 self.write(")");
15038 }
15039 TypeDefinition::Composite(attrs) => {
15040 self.write("(");
15041 for (i, attr) in attrs.iter().enumerate() {
15042 if i > 0 {
15043 self.write(", ");
15044 }
15045 self.generate_identifier(&attr.name)?;
15046 self.write_space();
15047 self.generate_data_type(&attr.data_type)?;
15048 if let Some(collate) = &attr.collate {
15049 self.write_space();
15050 self.write_keyword("COLLATE");
15051 self.write_space();
15052 self.generate_identifier(collate)?;
15053 }
15054 }
15055 self.write(")");
15056 }
15057 TypeDefinition::Range {
15058 subtype,
15059 subtype_diff,
15060 canonical,
15061 } => {
15062 self.write_keyword("RANGE");
15063 self.write(" (");
15064 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
15065 self.write("subtype");
15066 } else {
15067 self.write_keyword("SUBTYPE");
15068 }
15069 self.write(" = ");
15070 self.generate_data_type(subtype)?;
15071 if let Some(diff) = subtype_diff {
15072 self.write(", ");
15073 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
15074 self.write("subtype_diff");
15075 } else {
15076 self.write_keyword("SUBTYPE_DIFF");
15077 }
15078 self.write(" = ");
15079 self.write(diff);
15080 }
15081 if let Some(canon) = canonical {
15082 self.write(", ");
15083 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
15084 self.write("canonical");
15085 } else {
15086 self.write_keyword("CANONICAL");
15087 }
15088 self.write(" = ");
15089 self.write(canon);
15090 }
15091 self.write(")");
15092 }
15093 TypeDefinition::Base {
15094 input,
15095 output,
15096 internallength,
15097 } => {
15098 self.write("(");
15099 self.write_keyword("INPUT");
15100 self.write(" = ");
15101 self.write(input);
15102 self.write(", ");
15103 self.write_keyword("OUTPUT");
15104 self.write(" = ");
15105 self.write(output);
15106 if let Some(len) = internallength {
15107 self.write(", ");
15108 self.write_keyword("INTERNALLENGTH");
15109 self.write(" = ");
15110 self.write(&len.to_string());
15111 }
15112 self.write(")");
15113 }
15114 TypeDefinition::Domain {
15115 base_type,
15116 default,
15117 constraints,
15118 } => {
15119 self.generate_data_type(base_type)?;
15120 if let Some(def) = default {
15121 self.write_space();
15122 self.write_keyword("DEFAULT");
15123 self.write_space();
15124 self.generate_expression(def)?;
15125 }
15126 for constr in constraints {
15127 self.write_space();
15128 if let Some(name) = &constr.name {
15129 self.write_keyword("CONSTRAINT");
15130 self.write_space();
15131 self.generate_identifier(name)?;
15132 self.write_space();
15133 }
15134 self.write_keyword("CHECK");
15135 self.write(" (");
15136 self.generate_expression(&constr.check)?;
15137 self.write(")");
15138 }
15139 }
15140 }
15141
15142 Ok(())
15143 }
15144
15145 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
15146 self.write_keyword("CREATE");
15147 if task.or_replace {
15148 self.write_space();
15149 self.write_keyword("OR REPLACE");
15150 }
15151 self.write_space();
15152 self.write_keyword("TASK");
15153 if task.if_not_exists {
15154 self.write_space();
15155 self.write_keyword("IF NOT EXISTS");
15156 }
15157 self.write_space();
15158 self.write(&task.name);
15159 if !task.properties.is_empty() {
15160 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
15162 self.write_space();
15163 }
15164 self.write(&task.properties);
15165 }
15166 self.write_space();
15167 self.write_keyword("AS");
15168 self.write_space();
15169 self.generate_expression(&task.body)?;
15170 Ok(())
15171 }
15172
15173 fn generate_try_catch(&mut self, try_catch: &TryCatch) -> Result<()> {
15174 self.write_keyword("BEGIN TRY");
15175 self.generate_tsql_block_statements(&try_catch.try_body)?;
15176 self.write_keyword("END TRY");
15177
15178 if let Some(catch_body) = &try_catch.catch_body {
15179 if self.config.pretty {
15180 self.write_newline();
15181 self.write_indent();
15182 } else {
15183 self.write_space();
15184 }
15185 self.write_keyword("BEGIN CATCH");
15186 self.generate_tsql_block_statements(catch_body)?;
15187 self.write_keyword("END CATCH");
15188 }
15189
15190 Ok(())
15191 }
15192
15193 fn generate_tsql_block_statements(&mut self, statements: &[Expression]) -> Result<()> {
15194 if statements.is_empty() {
15195 self.write_space();
15196 return Ok(());
15197 }
15198
15199 if self.config.pretty {
15200 self.indent_level += 1;
15201 for stmt in statements {
15202 self.write_newline();
15203 self.write_indent();
15204 self.generate_expression(stmt)?;
15205 self.write(";");
15206 }
15207 self.indent_level -= 1;
15208 self.write_newline();
15209 self.write_indent();
15210 } else {
15211 self.write_space();
15212 for (i, stmt) in statements.iter().enumerate() {
15213 if i > 0 {
15214 self.write_space();
15215 }
15216 self.generate_expression(stmt)?;
15217 self.write(";");
15218 }
15219 self.write_space();
15220 }
15221
15222 Ok(())
15223 }
15224
15225 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
15226 self.write_keyword("DROP TYPE");
15227
15228 if dt.if_exists {
15229 self.write_space();
15230 self.write_keyword("IF EXISTS");
15231 }
15232
15233 self.write_space();
15234 self.generate_table(&dt.name)?;
15235
15236 if dt.cascade {
15237 self.write_space();
15238 self.write_keyword("CASCADE");
15239 }
15240
15241 Ok(())
15242 }
15243
15244 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
15245 let saved_athena_hive_context = self.athena_hive_context;
15247 if matches!(
15248 self.config.dialect,
15249 Some(crate::dialects::DialectType::Athena)
15250 ) {
15251 self.athena_hive_context = true;
15252 }
15253
15254 for comment in &d.leading_comments {
15256 self.write_formatted_comment(comment);
15257 self.write(" ");
15258 }
15259
15260 self.write_keyword("DESCRIBE");
15261
15262 if d.extended {
15263 self.write_space();
15264 self.write_keyword("EXTENDED");
15265 } else if d.formatted {
15266 self.write_space();
15267 self.write_keyword("FORMATTED");
15268 }
15269
15270 if let Some(ref style) = d.style {
15272 self.write_space();
15273 self.write_keyword(style);
15274 }
15275
15276 let should_output_kind = match self.config.dialect {
15278 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
15280 false
15281 }
15282 Some(DialectType::Snowflake) => true,
15284 _ => d.kind.is_some(),
15285 };
15286 if should_output_kind {
15287 if let Some(ref kind) = d.kind {
15288 self.write_space();
15289 self.write_keyword(kind);
15290 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
15291 self.write_space();
15292 self.write_keyword("TABLE");
15293 }
15294 }
15295
15296 self.write_space();
15297 self.generate_expression(&d.target)?;
15298
15299 if !d.params.is_empty() {
15301 self.write("(");
15302 for (i, param) in d.params.iter().enumerate() {
15303 if i > 0 {
15304 self.write(", ");
15305 }
15306 self.write(param);
15307 }
15308 self.write(")");
15309 }
15310
15311 if let Some(ref partition) = d.partition {
15313 self.write_space();
15314 self.generate_expression(partition)?;
15315 }
15316
15317 if d.as_json {
15319 self.write_space();
15320 self.write_keyword("AS JSON");
15321 }
15322
15323 for (name, value) in &d.properties {
15325 self.write_space();
15326 self.write(name);
15327 self.write("=");
15328 self.write(value);
15329 }
15330
15331 self.athena_hive_context = saved_athena_hive_context;
15333
15334 Ok(())
15335 }
15336
15337 fn generate_show(&mut self, s: &Show) -> Result<()> {
15340 self.write_keyword("SHOW");
15341 self.write_space();
15342
15343 let show_terse = s.terse
15346 && !matches!(
15347 s.this.as_str(),
15348 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
15349 );
15350 if show_terse {
15351 self.write_keyword("TERSE");
15352 self.write_space();
15353 }
15354
15355 self.write_keyword(&s.this);
15357
15358 if let Some(ref target_expr) = s.target {
15360 self.write_space();
15361 self.generate_expression(target_expr)?;
15362 }
15363
15364 if s.history {
15366 self.write_space();
15367 self.write_keyword("HISTORY");
15368 }
15369
15370 if let Some(ref for_target) = s.for_target {
15372 self.write_space();
15373 self.write_keyword("FOR");
15374 self.write_space();
15375 self.generate_expression(for_target)?;
15376 }
15377
15378 use crate::dialects::DialectType;
15382 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
15383 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
15384 let mysql_tables_scope_as_from = is_mysql
15385 && matches!(s.this.as_str(), "TABLES" | "FULL TABLES")
15386 && s.scope_kind.as_deref() == Some("SCHEMA")
15387 && s.scope.is_some()
15388 && s.from.is_none();
15389
15390 if !is_snowflake && s.from.is_some() {
15391 if let Some(ref scope_kind) = s.scope_kind {
15395 self.write_space();
15396 self.write_keyword("IN");
15397 self.write_space();
15398 self.write_keyword(scope_kind);
15399 if let Some(ref scope) = s.scope {
15400 self.write_space();
15401 self.generate_expression(scope)?;
15402 }
15403 } else if let Some(ref scope) = s.scope {
15404 self.write_space();
15405 self.write_keyword("IN");
15406 self.write_space();
15407 self.generate_expression(scope)?;
15408 }
15409
15410 if let Some(ref from) = s.from {
15412 self.write_space();
15413 self.write_keyword("FROM");
15414 self.write_space();
15415 self.generate_expression(from)?;
15416 }
15417
15418 if let Some(ref db) = s.db {
15420 self.write_space();
15421 self.write_keyword("FROM");
15422 self.write_space();
15423 self.generate_expression(db)?;
15424 }
15425
15426 if let Some(ref like) = s.like {
15428 self.write_space();
15429 self.write_keyword("LIKE");
15430 self.write_space();
15431 self.generate_expression(like)?;
15432 }
15433 } else {
15434 if let Some(ref like) = s.like {
15438 self.write_space();
15439 self.write_keyword("LIKE");
15440 self.write_space();
15441 self.generate_expression(like)?;
15442 }
15443
15444 if mysql_tables_scope_as_from {
15446 self.write_space();
15447 self.write_keyword("FROM");
15448 self.write_space();
15449 self.generate_expression(s.scope.as_ref().unwrap())?;
15450 } else if let Some(ref scope_kind) = s.scope_kind {
15451 self.write_space();
15452 self.write_keyword("IN");
15453 self.write_space();
15454 self.write_keyword(scope_kind);
15455 if let Some(ref scope) = s.scope {
15456 self.write_space();
15457 self.generate_expression(scope)?;
15458 }
15459 } else if let Some(ref scope) = s.scope {
15460 self.write_space();
15461 self.write_keyword("IN");
15462 self.write_space();
15463 self.generate_expression(scope)?;
15464 }
15465 }
15466
15467 if let Some(ref starts_with) = s.starts_with {
15469 self.write_space();
15470 self.write_keyword("STARTS WITH");
15471 self.write_space();
15472 self.generate_expression(starts_with)?;
15473 }
15474
15475 if let Some(ref limit) = s.limit {
15477 self.write_space();
15478 self.generate_limit(limit)?;
15479 }
15480
15481 if is_snowflake {
15483 if let Some(ref from) = s.from {
15484 self.write_space();
15485 self.write_keyword("FROM");
15486 self.write_space();
15487 self.generate_expression(from)?;
15488 }
15489 }
15490
15491 if let Some(ref where_clause) = s.where_clause {
15493 self.write_space();
15494 self.write_keyword("WHERE");
15495 self.write_space();
15496 self.generate_expression(where_clause)?;
15497 }
15498
15499 if let Some(is_mutex) = s.mutex {
15501 self.write_space();
15502 if is_mutex {
15503 self.write_keyword("MUTEX");
15504 } else {
15505 self.write_keyword("STATUS");
15506 }
15507 }
15508
15509 if !s.privileges.is_empty() {
15511 self.write_space();
15512 self.write_keyword("WITH PRIVILEGES");
15513 self.write_space();
15514 for (i, priv_name) in s.privileges.iter().enumerate() {
15515 if i > 0 {
15516 self.write(", ");
15517 }
15518 self.write_keyword(priv_name);
15519 }
15520 }
15521
15522 Ok(())
15523 }
15524
15525 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
15528 use crate::dialects::DialectType;
15529 match lit {
15530 Literal::String(s) => {
15531 self.generate_string_literal(s)?;
15532 }
15533 Literal::Number(n) => {
15534 if matches!(self.config.dialect, Some(DialectType::MySQL))
15535 && n.len() > 2
15536 && (n.starts_with("0x") || n.starts_with("0X"))
15537 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
15538 {
15539 return self.generate_identifier(&Identifier {
15540 name: n.clone(),
15541 quoted: true,
15542 trailing_comments: Vec::new(),
15543 span: None,
15544 });
15545 }
15546 let n = if n.contains('_')
15550 && !matches!(
15551 self.config.dialect,
15552 Some(DialectType::ClickHouse)
15553 | Some(DialectType::DuckDB)
15554 | Some(DialectType::PostgreSQL)
15555 | Some(DialectType::Hive)
15556 | Some(DialectType::Spark)
15557 | Some(DialectType::Databricks)
15558 ) {
15559 std::borrow::Cow::Owned(n.replace('_', ""))
15560 } else {
15561 std::borrow::Cow::Borrowed(n.as_str())
15562 };
15563 if n.starts_with('.') {
15566 self.write("0");
15567 self.write(&n);
15568 } else if n.starts_with("-.") {
15569 self.write("-0");
15571 self.write(&n[1..]);
15572 } else {
15573 self.write(&n);
15574 }
15575 }
15576 Literal::HexString(h) => {
15577 match self.config.dialect {
15579 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
15580 self.write("0x");
15581 self.write(h);
15582 return Ok(());
15583 }
15584 Some(DialectType::Spark)
15585 | Some(DialectType::Databricks)
15586 | Some(DialectType::Teradata) => self.write("X'"),
15587 _ => self.write("x'"),
15588 }
15589 self.write(h);
15590 self.write("'");
15591 }
15592 Literal::HexNumber(h) => {
15593 match self.config.dialect {
15597 Some(DialectType::BigQuery)
15598 | Some(DialectType::ClickHouse)
15599 | Some(DialectType::TSQL)
15600 | Some(DialectType::Fabric) => {
15601 self.write("0x");
15602 self.write(h);
15603 }
15604 _ => {
15605 if let Ok(val) = u64::from_str_radix(h, 16) {
15607 self.write(&val.to_string());
15608 } else {
15609 self.write("0x");
15611 self.write(h);
15612 }
15613 }
15614 }
15615 }
15616 Literal::BitString(b) => {
15617 self.write("B'");
15619 self.write(b);
15620 self.write("'");
15621 }
15622 Literal::ByteString(b) => {
15623 self.write("b'");
15625 self.write_escaped_byte_string(b);
15627 self.write("'");
15628 }
15629 Literal::NationalString(s) => {
15630 let keep_n_prefix = matches!(
15633 self.config.dialect,
15634 Some(DialectType::TSQL)
15635 | Some(DialectType::Oracle)
15636 | Some(DialectType::MySQL)
15637 | None
15638 );
15639 if keep_n_prefix {
15640 self.write("N'");
15641 } else {
15642 self.write("'");
15643 }
15644 self.write(s);
15645 self.write("'");
15646 }
15647 Literal::Date(d) => {
15648 self.generate_date_literal(d)?;
15649 }
15650 Literal::Time(t) => {
15651 self.generate_time_literal(t)?;
15652 }
15653 Literal::Timestamp(ts) => {
15654 self.generate_timestamp_literal(ts)?;
15655 }
15656 Literal::Datetime(dt) => {
15657 self.generate_datetime_literal(dt)?;
15658 }
15659 Literal::TripleQuotedString(s, _quote_char) => {
15660 if matches!(
15662 self.config.dialect,
15663 Some(crate::dialects::DialectType::BigQuery)
15664 | Some(crate::dialects::DialectType::DuckDB)
15665 | Some(crate::dialects::DialectType::Snowflake)
15666 | Some(crate::dialects::DialectType::Spark)
15667 | Some(crate::dialects::DialectType::Hive)
15668 | Some(crate::dialects::DialectType::Presto)
15669 | Some(crate::dialects::DialectType::Trino)
15670 | Some(crate::dialects::DialectType::PostgreSQL)
15671 | Some(crate::dialects::DialectType::MySQL)
15672 | Some(crate::dialects::DialectType::Redshift)
15673 | Some(crate::dialects::DialectType::TSQL)
15674 | Some(crate::dialects::DialectType::Oracle)
15675 | Some(crate::dialects::DialectType::ClickHouse)
15676 | Some(crate::dialects::DialectType::Databricks)
15677 | Some(crate::dialects::DialectType::SQLite)
15678 ) {
15679 self.generate_string_literal(s)?;
15680 } else {
15681 let quotes = format!("{0}{0}{0}", _quote_char);
15683 self.write("es);
15684 self.write(s);
15685 self.write("es);
15686 }
15687 }
15688 Literal::EscapeString(s) => {
15689 use crate::dialects::DialectType;
15693 let content = if let Some(c) = s.strip_prefix("e:") {
15694 c
15695 } else if let Some(c) = s.strip_prefix("E:") {
15696 c
15697 } else {
15698 s.as_str()
15699 };
15700
15701 if matches!(
15703 self.config.dialect,
15704 Some(DialectType::MySQL) | Some(DialectType::TiDB)
15705 ) {
15706 self.write("'");
15707 self.write(&content.replace('\'', "''"));
15708 self.write("'");
15709 } else {
15710 let prefix = if matches!(
15712 self.config.dialect,
15713 Some(DialectType::SingleStore)
15714 | Some(DialectType::DuckDB)
15715 | Some(DialectType::PostgreSQL)
15716 | Some(DialectType::CockroachDB)
15717 | Some(DialectType::Materialize)
15718 | Some(DialectType::RisingWave)
15719 ) {
15720 "e'"
15721 } else {
15722 "E'"
15723 };
15724
15725 let normalized = content.replace("\\'", "''");
15727 self.write(prefix);
15728 self.write(&normalized);
15729 self.write("'");
15730 }
15731 }
15732 Literal::DollarString(s) => {
15733 use crate::dialects::DialectType;
15736 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
15738 let escape_backslash = matches!(
15740 self.config.dialect,
15741 Some(DialectType::ClickHouse) | Some(DialectType::Snowflake)
15742 );
15743 let use_backslash_quote =
15747 matches!(self.config.dialect, Some(DialectType::Snowflake));
15748
15749 let mut escaped = String::with_capacity(content.len() + 4);
15750 for ch in content.chars() {
15751 if escape_backslash && ch == '\\' {
15752 escaped.push('\\');
15754 escaped.push('\\');
15755 } else if ch == '\'' {
15756 if use_backslash_quote {
15757 escaped.push('\\');
15758 escaped.push('\'');
15759 } else {
15760 escaped.push('\'');
15761 escaped.push('\'');
15762 }
15763 } else {
15764 escaped.push(ch);
15765 }
15766 }
15767 self.write("'");
15768 self.write(&escaped);
15769 self.write("'");
15770 }
15771 Literal::RawString(s) => {
15772 use crate::dialects::DialectType;
15778
15779 let escape_backslash = matches!(
15781 self.config.dialect,
15782 Some(DialectType::BigQuery)
15783 | Some(DialectType::MySQL)
15784 | Some(DialectType::SingleStore)
15785 | Some(DialectType::TiDB)
15786 | Some(DialectType::Hive)
15787 | Some(DialectType::Spark)
15788 | Some(DialectType::Databricks)
15789 | Some(DialectType::Drill)
15790 | Some(DialectType::Snowflake)
15791 | Some(DialectType::Redshift)
15792 | Some(DialectType::ClickHouse)
15793 );
15794
15795 let backslash_escapes_quote = matches!(
15798 self.config.dialect,
15799 Some(DialectType::BigQuery)
15800 | Some(DialectType::Hive)
15801 | Some(DialectType::Spark)
15802 | Some(DialectType::Databricks)
15803 | Some(DialectType::Drill)
15804 | Some(DialectType::Snowflake)
15805 | Some(DialectType::Redshift)
15806 );
15807
15808 let supports_escape_sequences = escape_backslash;
15811
15812 let mut escaped = String::with_capacity(s.len() + 4);
15813 for ch in s.chars() {
15814 if escape_backslash && ch == '\\' {
15815 escaped.push('\\');
15817 escaped.push('\\');
15818 } else if ch == '\'' {
15819 if backslash_escapes_quote {
15820 escaped.push('\\');
15822 escaped.push('\'');
15823 } else {
15824 escaped.push('\'');
15826 escaped.push('\'');
15827 }
15828 } else if supports_escape_sequences {
15829 match ch {
15832 '\n' => {
15833 escaped.push('\\');
15834 escaped.push('n');
15835 }
15836 '\r' => {
15837 escaped.push('\\');
15838 escaped.push('r');
15839 }
15840 '\t' => {
15841 escaped.push('\\');
15842 escaped.push('t');
15843 }
15844 '\x07' => {
15845 escaped.push('\\');
15846 escaped.push('a');
15847 }
15848 '\x08' => {
15849 escaped.push('\\');
15850 escaped.push('b');
15851 }
15852 '\x0C' => {
15853 escaped.push('\\');
15854 escaped.push('f');
15855 }
15856 '\x0B' => {
15857 escaped.push('\\');
15858 escaped.push('v');
15859 }
15860 _ => escaped.push(ch),
15861 }
15862 } else {
15863 escaped.push(ch);
15864 }
15865 }
15866 self.write("'");
15867 self.write(&escaped);
15868 self.write("'");
15869 }
15870 }
15871 Ok(())
15872 }
15873
15874 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
15876 use crate::dialects::DialectType;
15877
15878 match self.config.dialect {
15879 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
15881 self.write("CAST('");
15882 self.write(d);
15883 self.write("' AS DATE)");
15884 }
15885 Some(DialectType::BigQuery) => {
15888 self.write("CAST('");
15889 self.write(d);
15890 self.write("' AS DATE)");
15891 }
15892 Some(DialectType::Exasol) => {
15895 self.write("CAST('");
15896 self.write(d);
15897 self.write("' AS DATE)");
15898 }
15899 Some(DialectType::Snowflake) => {
15902 self.write("CAST('");
15903 self.write(d);
15904 self.write("' AS DATE)");
15905 }
15906 Some(DialectType::PostgreSQL)
15908 | Some(DialectType::MySQL)
15909 | Some(DialectType::SingleStore)
15910 | Some(DialectType::TiDB)
15911 | Some(DialectType::Redshift) => {
15912 self.write("CAST('");
15913 self.write(d);
15914 self.write("' AS DATE)");
15915 }
15916 Some(DialectType::DuckDB)
15918 | Some(DialectType::Presto)
15919 | Some(DialectType::Trino)
15920 | Some(DialectType::Athena)
15921 | Some(DialectType::Spark)
15922 | Some(DialectType::Databricks)
15923 | Some(DialectType::Hive) => {
15924 self.write("CAST('");
15925 self.write(d);
15926 self.write("' AS DATE)");
15927 }
15928 Some(DialectType::Oracle) => {
15930 self.write("TO_DATE('");
15931 self.write(d);
15932 self.write("', 'YYYY-MM-DD')");
15933 }
15934 _ => {
15936 self.write_keyword("DATE");
15937 self.write(" '");
15938 self.write(d);
15939 self.write("'");
15940 }
15941 }
15942 Ok(())
15943 }
15944
15945 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
15947 use crate::dialects::DialectType;
15948
15949 match self.config.dialect {
15950 Some(DialectType::TSQL) => {
15952 self.write("CAST('");
15953 self.write(t);
15954 self.write("' AS TIME)");
15955 }
15956 Some(DialectType::Fabric) => {
15957 self.write("CAST('");
15958 self.write(t);
15959 self.write("' AS TIME(6))");
15960 }
15961 _ => {
15963 self.write_keyword("TIME");
15964 self.write(" '");
15965 self.write(t);
15966 self.write("'");
15967 }
15968 }
15969 Ok(())
15970 }
15971
15972 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
15974 use crate::expressions::Literal;
15975
15976 match expr {
15977 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
15978 let Literal::Date(d) = lit.as_ref() else {
15979 unreachable!()
15980 };
15981 self.write("CAST('");
15983 self.write(d);
15984 self.write("' AS DATE)");
15985 }
15986 _ => {
15987 self.generate_expression(expr)?;
15989 }
15990 }
15991 Ok(())
15992 }
15993
15994 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
15996 use crate::dialects::DialectType;
15997
15998 match self.config.dialect {
15999 Some(DialectType::TSQL) => {
16001 self.write("CAST('");
16002 self.write(ts);
16003 self.write("' AS DATETIME2)");
16004 }
16005 Some(DialectType::BigQuery) => {
16008 self.write("CAST('");
16009 self.write(ts);
16010 self.write("' AS TIMESTAMP)");
16011 }
16012 Some(DialectType::Snowflake) => {
16015 self.write("CAST('");
16016 self.write(ts);
16017 self.write("' AS TIMESTAMP)");
16018 }
16019 Some(DialectType::Dremio) => {
16022 self.write("CAST('");
16023 self.write(ts);
16024 self.write("' AS TIMESTAMP)");
16025 }
16026 Some(DialectType::Exasol) => {
16029 self.write("CAST('");
16030 self.write(ts);
16031 self.write("' AS TIMESTAMP)");
16032 }
16033 Some(DialectType::Oracle) => {
16036 self.write("TO_TIMESTAMP('");
16037 self.write(ts);
16038 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
16039 }
16040 Some(DialectType::Presto) | Some(DialectType::Trino) => {
16042 if Self::timestamp_has_timezone(ts) {
16043 self.write("CAST('");
16044 self.write(ts);
16045 self.write("' AS TIMESTAMP WITH TIME ZONE)");
16046 } else {
16047 self.write("CAST('");
16048 self.write(ts);
16049 self.write("' AS TIMESTAMP)");
16050 }
16051 }
16052 Some(DialectType::ClickHouse) => {
16054 self.write("CAST('");
16055 self.write(ts);
16056 self.write("' AS Nullable(DateTime))");
16057 }
16058 Some(DialectType::Spark) => {
16060 self.write("CAST('");
16061 self.write(ts);
16062 self.write("' AS TIMESTAMP)");
16063 }
16064 Some(DialectType::Redshift) => {
16067 if ts == "epoch" {
16068 self.write_keyword("TIMESTAMP");
16069 self.write(" '");
16070 self.write(ts);
16071 self.write("'");
16072 } else {
16073 self.write("CAST('");
16074 self.write(ts);
16075 self.write("' AS TIMESTAMP)");
16076 }
16077 }
16078 Some(DialectType::PostgreSQL)
16080 | Some(DialectType::Hive)
16081 | Some(DialectType::SQLite)
16082 | Some(DialectType::DuckDB)
16083 | Some(DialectType::Athena)
16084 | Some(DialectType::Drill)
16085 | Some(DialectType::Teradata) => {
16086 self.write("CAST('");
16087 self.write(ts);
16088 self.write("' AS TIMESTAMP)");
16089 }
16090 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
16092 self.write("CAST('");
16093 self.write(ts);
16094 self.write("' AS DATETIME)");
16095 }
16096 Some(DialectType::Databricks) => {
16098 self.write("CAST('");
16099 self.write(ts);
16100 self.write("' AS TIMESTAMP_NTZ)");
16101 }
16102 _ => {
16104 self.write_keyword("TIMESTAMP");
16105 self.write(" '");
16106 self.write(ts);
16107 self.write("'");
16108 }
16109 }
16110 Ok(())
16111 }
16112
16113 fn timestamp_has_timezone(ts: &str) -> bool {
16116 let ts_lower = ts.to_ascii_lowercase();
16120
16121 let continent_prefixes = [
16123 "africa/",
16124 "america/",
16125 "antarctica/",
16126 "arctic/",
16127 "asia/",
16128 "atlantic/",
16129 "australia/",
16130 "europe/",
16131 "indian/",
16132 "pacific/",
16133 "etc/",
16134 "brazil/",
16135 "canada/",
16136 "chile/",
16137 "mexico/",
16138 "us/",
16139 ];
16140
16141 for prefix in &continent_prefixes {
16142 if ts_lower.contains(prefix) {
16143 return true;
16144 }
16145 }
16146
16147 let tz_abbrevs = [
16150 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
16151 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
16152 " sgt", " aest", " aedt", " acst", " acdt", " awst",
16153 ];
16154
16155 for abbrev in &tz_abbrevs {
16156 if ts_lower.ends_with(abbrev) {
16157 return true;
16158 }
16159 }
16160
16161 let trimmed = ts.trim();
16165 if let Some(last_space) = trimmed.rfind(' ') {
16166 let suffix = &trimmed[last_space + 1..];
16167 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
16168 let rest = &suffix[1..];
16170 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
16171 return true;
16172 }
16173 }
16174 }
16175
16176 false
16177 }
16178
16179 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
16181 use crate::dialects::DialectType;
16182
16183 match self.config.dialect {
16184 Some(DialectType::BigQuery) => {
16187 self.write("CAST('");
16188 self.write(dt);
16189 self.write("' AS DATETIME)");
16190 }
16191 Some(DialectType::DuckDB) => {
16193 self.write("CAST('");
16194 self.write(dt);
16195 self.write("' AS TIMESTAMP)");
16196 }
16197 _ => {
16200 self.write_keyword("DATETIME");
16201 self.write(" '");
16202 self.write(dt);
16203 self.write("'");
16204 }
16205 }
16206 Ok(())
16207 }
16208
16209 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
16211 use crate::dialects::DialectType;
16212
16213 match self.config.dialect {
16214 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
16218 self.write("'");
16220 for c in s.chars() {
16221 match c {
16222 '\'' => self.write("\\'"),
16223 '\\' => self.write("\\\\"),
16224 '\n' => self.write("\\n"),
16225 '\r' => self.write("\\r"),
16226 '\t' => self.write("\\t"),
16227 '\0' => self.write("\\0"),
16228 _ => self.output.push(c),
16229 }
16230 }
16231 self.write("'");
16232 }
16233 Some(DialectType::Drill) => {
16234 self.write("'");
16237 for c in s.chars() {
16238 match c {
16239 '\'' => self.write("''"),
16240 '\\' => self.write("\\\\"),
16241 '\n' => self.write("\\n"),
16242 '\r' => self.write("\\r"),
16243 '\t' => self.write("\\t"),
16244 '\0' => self.write("\\0"),
16245 _ => self.output.push(c),
16246 }
16247 }
16248 self.write("'");
16249 }
16250 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
16251 self.write("'");
16252 for c in s.chars() {
16253 match c {
16254 '\'' => self.write("''"),
16256 '\\' => self.write("\\\\"),
16257 '\n' => self.write("\\n"),
16258 '\r' => self.write("\\r"),
16259 '\t' => self.write("\\t"),
16260 '\0' => self.output.push('\0'),
16262 _ => self.output.push(c),
16263 }
16264 }
16265 self.write("'");
16266 }
16267 Some(DialectType::BigQuery) => {
16269 self.write("'");
16270 for c in s.chars() {
16271 match c {
16272 '\'' => self.write("\\'"),
16273 '\\' => self.write("\\\\"),
16274 '\n' => self.write("\\n"),
16275 '\r' => self.write("\\r"),
16276 '\t' => self.write("\\t"),
16277 '\0' => self.write("\\0"),
16278 '\x07' => self.write("\\a"),
16279 '\x08' => self.write("\\b"),
16280 '\x0C' => self.write("\\f"),
16281 '\x0B' => self.write("\\v"),
16282 _ => self.output.push(c),
16283 }
16284 }
16285 self.write("'");
16286 }
16287 Some(DialectType::Athena) => {
16291 if self.athena_hive_context {
16292 self.write("'");
16294 for c in s.chars() {
16295 match c {
16296 '\'' => self.write("\\'"),
16297 '\\' => self.write("\\\\"),
16298 '\n' => self.write("\\n"),
16299 '\r' => self.write("\\r"),
16300 '\t' => self.write("\\t"),
16301 '\0' => self.write("\\0"),
16302 _ => self.output.push(c),
16303 }
16304 }
16305 self.write("'");
16306 } else {
16307 self.write("'");
16309 for c in s.chars() {
16310 match c {
16311 '\'' => self.write("''"),
16312 _ => self.output.push(c),
16314 }
16315 }
16316 self.write("'");
16317 }
16318 }
16319 Some(DialectType::Snowflake) => {
16321 self.write("'");
16322 for c in s.chars() {
16323 match c {
16324 '\'' => self.write("\\'"),
16325 '\\' => self.write("\\\\"),
16326 '\0' => self.write("\\x00"),
16327 '\x08' => self.write("\\b"),
16328 '\x0C' => self.write("\\f"),
16329 '\n' => self.write("\\n"),
16330 '\r' => self.write("\\r"),
16331 '\t' => self.write("\\t"),
16332 _ => self.output.push(c),
16333 }
16334 }
16335 self.write("'");
16336 }
16337 Some(DialectType::PostgreSQL) => {
16339 self.write("'");
16340 for c in s.chars() {
16341 match c {
16342 '\'' => self.write("''"),
16343 _ => self.output.push(c),
16344 }
16345 }
16346 self.write("'");
16347 }
16348 Some(DialectType::Redshift) => {
16350 self.write("'");
16351 for c in s.chars() {
16352 match c {
16353 '\'' => self.write("\\'"),
16354 _ => self.output.push(c),
16355 }
16356 }
16357 self.write("'");
16358 }
16359 Some(DialectType::Oracle) => {
16361 self.write("'");
16362 for ch in s.chars() {
16363 if ch == '\'' {
16364 self.output.push_str("''");
16365 } else {
16366 self.output.push(ch);
16367 }
16368 }
16369 self.write("'");
16370 }
16371 Some(DialectType::ClickHouse) => {
16374 self.write("'");
16375 for c in s.chars() {
16376 match c {
16377 '\'' => self.write("''"),
16378 '\\' => self.write("\\\\"),
16379 '\n' => self.write("\\n"),
16380 '\r' => self.write("\\r"),
16381 '\t' => self.write("\\t"),
16382 '\0' => self.write("\\0"),
16383 '\x07' => self.write("\\a"),
16384 '\x08' => self.write("\\b"),
16385 '\x0C' => self.write("\\f"),
16386 '\x0B' => self.write("\\v"),
16387 c if c.is_control() || (c as u32) < 0x20 => {
16389 let byte = c as u32;
16390 if byte < 256 {
16391 self.write(&format!("\\x{:02X}", byte));
16392 } else {
16393 self.output.push(c);
16394 }
16395 }
16396 _ => self.output.push(c),
16397 }
16398 }
16399 self.write("'");
16400 }
16401 _ => {
16404 self.write("'");
16405 for ch in s.chars() {
16406 if ch == '\'' {
16407 self.output.push_str("''");
16408 } else {
16409 self.output.push(ch);
16410 }
16411 }
16412 self.write("'");
16413 }
16414 }
16415 Ok(())
16416 }
16417
16418 fn write_escaped_byte_string(&mut self, s: &str) {
16421 for c in s.chars() {
16422 match c {
16423 '\'' => self.write("\\'"),
16425 '\\' => self.write("\\\\"),
16427 _ if !c.is_control() => self.output.push(c),
16429 _ => {
16431 let byte = c as u32;
16432 if byte < 256 {
16433 self.write(&format!("\\x{:02x}", byte));
16434 } else {
16435 for b in c.to_string().as_bytes() {
16437 self.write(&format!("\\x{:02x}", b));
16438 }
16439 }
16440 }
16441 }
16442 }
16443 }
16444
16445 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
16446 use crate::dialects::DialectType;
16447
16448 match self.config.dialect {
16450 Some(DialectType::TSQL) => {
16453 self.write(if b.value { "1" } else { "0" });
16454 }
16455 Some(DialectType::Oracle) => {
16457 self.write(if b.value { "1" } else { "0" });
16458 }
16459 Some(DialectType::MySQL) => {
16461 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
16462 }
16463 _ => {
16465 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
16466 }
16467 }
16468 Ok(())
16469 }
16470
16471 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
16474 let name = &id.name;
16475 let quote_style = &self.config.identifier_quote_style;
16476
16477 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
16481
16482 let output_name = if self.config.normalize_identifiers && !id.quoted {
16484 name.to_ascii_lowercase()
16485 } else {
16486 name.to_string()
16487 };
16488
16489 if needs_quoting {
16490 let quote_style = if matches!(self.config.dialect, Some(DialectType::ClickHouse))
16491 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
16492 && quote_style.start == '"'
16493 && output_name.contains('"')
16494 {
16495 &IdentifierQuoteStyle::BACKTICK
16496 } else {
16497 quote_style
16498 };
16499 let escaped_name = if quote_style.start == quote_style.end {
16501 output_name.replace(
16502 quote_style.end,
16503 &format!("{}{}", quote_style.end, quote_style.end),
16504 )
16505 } else {
16506 output_name.replace(
16507 quote_style.end,
16508 &format!("{}{}", quote_style.end, quote_style.end),
16509 )
16510 };
16511 self.write(&format!(
16512 "{}{}{}",
16513 quote_style.start, escaped_name, quote_style.end
16514 ));
16515 } else {
16516 self.write(&output_name);
16517 }
16518
16519 for comment in &id.trailing_comments {
16521 self.write(" ");
16522 self.write_formatted_comment(comment);
16523 }
16524 Ok(())
16525 }
16526
16527 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
16528 use crate::dialects::DialectType;
16529
16530 let name = &id.name;
16531
16532 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
16534 && self.athena_hive_context
16535 {
16536 &IdentifierQuoteStyle::BACKTICK
16537 } else {
16538 &self.config.identifier_quote_style
16539 };
16540
16541 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
16548 let needs_digit_quoting = starts_with_digit
16549 && !self.config.identifiers_can_start_with_digit
16550 && self.config.dialect.is_some();
16551 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
16552 && name.len() > 2
16553 && (name.starts_with("0x") || name.starts_with("0X"))
16554 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
16555 let clickhouse_unsafe_identifier =
16556 matches!(self.config.dialect, Some(DialectType::ClickHouse))
16557 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
16558 && !name.starts_with('{')
16559 && !name.contains('(')
16560 && !name.contains(')')
16561 && name != "?"
16562 && name
16563 .chars()
16564 .any(|c| !(c.is_ascii_alphanumeric() || c == '_'));
16565 let needs_quoting = id.quoted
16566 || self.is_reserved_keyword(name)
16567 || self.config.always_quote_identifiers
16568 || needs_digit_quoting
16569 || mysql_invalid_hex_identifier
16570 || clickhouse_unsafe_identifier;
16571
16572 let (base_name, suffix) = if needs_quoting {
16575 if let Some(paren_pos) = name.find('(') {
16577 let base = &name[..paren_pos];
16578 let rest = &name[paren_pos..];
16579 if rest.starts_with('(')
16581 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
16582 {
16583 let close_paren = rest.find(')').unwrap_or(rest.len());
16585 let inside = &rest[1..close_paren];
16586 if inside.chars().all(|c| c.is_ascii_digit()) {
16587 (base.to_string(), rest.to_string())
16588 } else {
16589 (name.to_string(), String::new())
16590 }
16591 } else {
16592 (name.to_string(), String::new())
16593 }
16594 } else if name.ends_with(" ASC") {
16595 let base = &name[..name.len() - 4];
16596 (base.to_string(), " ASC".to_string())
16597 } else if name.ends_with(" DESC") {
16598 let base = &name[..name.len() - 5];
16599 (base.to_string(), " DESC".to_string())
16600 } else {
16601 (name.to_string(), String::new())
16602 }
16603 } else {
16604 (name.to_string(), String::new())
16605 };
16606
16607 let output_name = if self.config.normalize_identifiers && !id.quoted {
16611 base_name.to_ascii_lowercase()
16612 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
16613 && !id.quoted
16614 && self.is_reserved_keyword(name)
16615 {
16616 base_name.to_ascii_uppercase()
16619 } else {
16620 base_name
16621 };
16622
16623 if needs_quoting {
16624 let escaped_name = if quote_style.start == quote_style.end {
16626 output_name.replace(
16628 quote_style.end,
16629 &format!("{}{}", quote_style.end, quote_style.end),
16630 )
16631 } else {
16632 output_name.replace(
16634 quote_style.end,
16635 &format!("{}{}", quote_style.end, quote_style.end),
16636 )
16637 };
16638 self.write(&format!(
16639 "{}{}{}{}",
16640 quote_style.start, escaped_name, quote_style.end, suffix
16641 ));
16642 } else {
16643 self.write(&output_name);
16644 }
16645
16646 for comment in &id.trailing_comments {
16648 self.write(" ");
16649 self.write_formatted_comment(comment);
16650 }
16651 Ok(())
16652 }
16653
16654 fn generate_column(&mut self, col: &Column) -> Result<()> {
16655 use crate::dialects::DialectType;
16656
16657 if let Some(table) = &col.table {
16658 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
16662 && !table.quoted
16663 && table.name.eq_ignore_ascii_case("LOCAL");
16664
16665 if is_exasol_local_prefix {
16666 self.write("LOCAL");
16668 } else {
16669 self.generate_identifier(table)?;
16670 }
16671 self.write(".");
16672 }
16673 self.generate_identifier(&col.name)?;
16674 if col.join_mark && self.config.supports_column_join_marks {
16677 self.write(" (+)");
16678 }
16679 for comment in &col.trailing_comments {
16681 self.write_space();
16682 self.write_formatted_comment(comment);
16683 }
16684 Ok(())
16685 }
16686
16687 fn generate_prepare(&mut self, prepare: &PrepareStatement) -> Result<()> {
16688 self.write_keyword("PREPARE");
16689 self.write_space();
16690 self.generate_identifier(&prepare.name)?;
16691
16692 if !prepare.parameter_types.is_empty() {
16693 self.write(" (");
16694 for (i, data_type) in prepare.parameter_types.iter().enumerate() {
16695 if i > 0 {
16696 self.write(", ");
16697 }
16698 self.generate_data_type(data_type)?;
16699 }
16700 self.write(")");
16701 }
16702
16703 self.write_space();
16704 self.write_keyword("AS");
16705 self.write_space();
16706 self.generate_expression(&prepare.statement)
16707 }
16708
16709 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
16712 use crate::dialects::DialectType;
16713 use crate::expressions::PseudocolumnType;
16714
16715 if pc.kind == PseudocolumnType::Sysdate
16717 && !matches!(
16718 self.config.dialect,
16719 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
16720 )
16721 {
16722 self.write_keyword("CURRENT_TIMESTAMP");
16723 if matches!(
16725 self.config.dialect,
16726 Some(DialectType::MySQL)
16727 | Some(DialectType::ClickHouse)
16728 | Some(DialectType::Spark)
16729 | Some(DialectType::Databricks)
16730 | Some(DialectType::Hive)
16731 ) {
16732 self.write("()");
16733 }
16734 } else {
16735 self.write(pc.kind.as_str());
16736 }
16737 Ok(())
16738 }
16739
16740 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
16742 use crate::dialects::DialectType;
16743
16744 let supports_connect_by = matches!(
16747 self.config.dialect,
16748 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
16749 );
16750
16751 if !supports_connect_by && self.config.dialect.is_some() {
16752 if self.config.pretty {
16754 self.write_newline();
16755 } else {
16756 self.write_space();
16757 }
16758 self.write_unsupported_comment(
16759 "CONNECT BY requires manual conversion to recursive CTE",
16760 )?;
16761 }
16762
16763 if let Some(start) = &connect.start {
16765 if self.config.pretty {
16766 self.write_newline();
16767 } else {
16768 self.write_space();
16769 }
16770 self.write_keyword("START WITH");
16771 self.write_space();
16772 self.generate_expression(start)?;
16773 }
16774
16775 if self.config.pretty {
16777 self.write_newline();
16778 } else {
16779 self.write_space();
16780 }
16781 self.write_keyword("CONNECT BY");
16782 if connect.nocycle {
16783 self.write_space();
16784 self.write_keyword("NOCYCLE");
16785 }
16786 self.write_space();
16787 self.generate_expression(&connect.connect)?;
16788
16789 Ok(())
16790 }
16791
16792 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
16794 self.generate_connect(connect)
16795 }
16796
16797 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
16799 self.write_keyword("PRIOR");
16800 self.write_space();
16801 self.generate_expression(&prior.this)?;
16802 Ok(())
16803 }
16804
16805 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
16808 self.write_keyword("CONNECT_BY_ROOT");
16809 self.write_space();
16810 self.generate_expression(&cbr.this)?;
16811 Ok(())
16812 }
16813
16814 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
16816 use crate::dialects::DialectType;
16817
16818 let supports_match_recognize = matches!(
16820 self.config.dialect,
16821 Some(DialectType::Oracle)
16822 | Some(DialectType::Snowflake)
16823 | Some(DialectType::Presto)
16824 | Some(DialectType::Trino)
16825 );
16826
16827 if let Some(source) = &mr.this {
16829 self.generate_expression(source)?;
16830 }
16831
16832 if !supports_match_recognize {
16833 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
16834 return Ok(());
16835 }
16836
16837 if self.config.pretty {
16839 self.write_newline();
16840 } else {
16841 self.write_space();
16842 }
16843
16844 self.write_keyword("MATCH_RECOGNIZE");
16845 self.write(" (");
16846
16847 if self.config.pretty {
16848 self.indent_level += 1;
16849 }
16850
16851 let mut needs_separator = false;
16852
16853 if let Some(partition_by) = &mr.partition_by {
16855 if !partition_by.is_empty() {
16856 if self.config.pretty {
16857 self.write_newline();
16858 self.write_indent();
16859 }
16860 self.write_keyword("PARTITION BY");
16861 self.write_space();
16862 for (i, expr) in partition_by.iter().enumerate() {
16863 if i > 0 {
16864 self.write(", ");
16865 }
16866 self.generate_expression(expr)?;
16867 }
16868 needs_separator = true;
16869 }
16870 }
16871
16872 if let Some(order_by) = &mr.order_by {
16874 if !order_by.is_empty() {
16875 if needs_separator {
16876 if self.config.pretty {
16877 self.write_newline();
16878 self.write_indent();
16879 } else {
16880 self.write_space();
16881 }
16882 } else if self.config.pretty {
16883 self.write_newline();
16884 self.write_indent();
16885 }
16886 self.write_keyword("ORDER BY");
16887 if self.config.pretty {
16889 self.indent_level += 1;
16890 for (i, ordered) in order_by.iter().enumerate() {
16891 if i > 0 {
16892 self.write(",");
16893 }
16894 self.write_newline();
16895 self.write_indent();
16896 self.generate_ordered(ordered)?;
16897 }
16898 self.indent_level -= 1;
16899 } else {
16900 self.write_space();
16901 for (i, ordered) in order_by.iter().enumerate() {
16902 if i > 0 {
16903 self.write(", ");
16904 }
16905 self.generate_ordered(ordered)?;
16906 }
16907 }
16908 needs_separator = true;
16909 }
16910 }
16911
16912 if let Some(measures) = &mr.measures {
16914 if !measures.is_empty() {
16915 if needs_separator {
16916 if self.config.pretty {
16917 self.write_newline();
16918 self.write_indent();
16919 } else {
16920 self.write_space();
16921 }
16922 } else if self.config.pretty {
16923 self.write_newline();
16924 self.write_indent();
16925 }
16926 self.write_keyword("MEASURES");
16927 if self.config.pretty {
16929 self.indent_level += 1;
16930 for (i, measure) in measures.iter().enumerate() {
16931 if i > 0 {
16932 self.write(",");
16933 }
16934 self.write_newline();
16935 self.write_indent();
16936 if let Some(semantics) = &measure.window_frame {
16938 match semantics {
16939 MatchRecognizeSemantics::Running => {
16940 self.write_keyword("RUNNING");
16941 self.write_space();
16942 }
16943 MatchRecognizeSemantics::Final => {
16944 self.write_keyword("FINAL");
16945 self.write_space();
16946 }
16947 }
16948 }
16949 self.generate_expression(&measure.this)?;
16950 }
16951 self.indent_level -= 1;
16952 } else {
16953 self.write_space();
16954 for (i, measure) in measures.iter().enumerate() {
16955 if i > 0 {
16956 self.write(", ");
16957 }
16958 if let Some(semantics) = &measure.window_frame {
16960 match semantics {
16961 MatchRecognizeSemantics::Running => {
16962 self.write_keyword("RUNNING");
16963 self.write_space();
16964 }
16965 MatchRecognizeSemantics::Final => {
16966 self.write_keyword("FINAL");
16967 self.write_space();
16968 }
16969 }
16970 }
16971 self.generate_expression(&measure.this)?;
16972 }
16973 }
16974 needs_separator = true;
16975 }
16976 }
16977
16978 if let Some(rows) = &mr.rows {
16980 if needs_separator {
16981 if self.config.pretty {
16982 self.write_newline();
16983 self.write_indent();
16984 } else {
16985 self.write_space();
16986 }
16987 } else if self.config.pretty {
16988 self.write_newline();
16989 self.write_indent();
16990 }
16991 match rows {
16992 MatchRecognizeRows::OneRowPerMatch => {
16993 self.write_keyword("ONE ROW PER MATCH");
16994 }
16995 MatchRecognizeRows::AllRowsPerMatch => {
16996 self.write_keyword("ALL ROWS PER MATCH");
16997 }
16998 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
16999 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
17000 }
17001 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
17002 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
17003 }
17004 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
17005 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
17006 }
17007 }
17008 needs_separator = true;
17009 }
17010
17011 if let Some(after) = &mr.after {
17013 if needs_separator {
17014 if self.config.pretty {
17015 self.write_newline();
17016 self.write_indent();
17017 } else {
17018 self.write_space();
17019 }
17020 } else if self.config.pretty {
17021 self.write_newline();
17022 self.write_indent();
17023 }
17024 match after {
17025 MatchRecognizeAfter::PastLastRow => {
17026 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
17027 }
17028 MatchRecognizeAfter::ToNextRow => {
17029 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
17030 }
17031 MatchRecognizeAfter::ToFirst(ident) => {
17032 self.write_keyword("AFTER MATCH SKIP TO FIRST");
17033 self.write_space();
17034 self.generate_identifier(ident)?;
17035 }
17036 MatchRecognizeAfter::ToLast(ident) => {
17037 self.write_keyword("AFTER MATCH SKIP TO LAST");
17038 self.write_space();
17039 self.generate_identifier(ident)?;
17040 }
17041 }
17042 needs_separator = true;
17043 }
17044
17045 if let Some(pattern) = &mr.pattern {
17047 if needs_separator {
17048 if self.config.pretty {
17049 self.write_newline();
17050 self.write_indent();
17051 } else {
17052 self.write_space();
17053 }
17054 } else if self.config.pretty {
17055 self.write_newline();
17056 self.write_indent();
17057 }
17058 self.write_keyword("PATTERN");
17059 self.write_space();
17060 self.write("(");
17061 self.write(pattern);
17062 self.write(")");
17063 needs_separator = true;
17064 }
17065
17066 if let Some(define) = &mr.define {
17068 if !define.is_empty() {
17069 if needs_separator {
17070 if self.config.pretty {
17071 self.write_newline();
17072 self.write_indent();
17073 } else {
17074 self.write_space();
17075 }
17076 } else if self.config.pretty {
17077 self.write_newline();
17078 self.write_indent();
17079 }
17080 self.write_keyword("DEFINE");
17081 if self.config.pretty {
17083 self.indent_level += 1;
17084 for (i, (name, expr)) in define.iter().enumerate() {
17085 if i > 0 {
17086 self.write(",");
17087 }
17088 self.write_newline();
17089 self.write_indent();
17090 self.generate_identifier(name)?;
17091 self.write(" AS ");
17092 self.generate_expression(expr)?;
17093 }
17094 self.indent_level -= 1;
17095 } else {
17096 self.write_space();
17097 for (i, (name, expr)) in define.iter().enumerate() {
17098 if i > 0 {
17099 self.write(", ");
17100 }
17101 self.generate_identifier(name)?;
17102 self.write(" AS ");
17103 self.generate_expression(expr)?;
17104 }
17105 }
17106 }
17107 }
17108
17109 if self.config.pretty {
17110 self.indent_level -= 1;
17111 self.write_newline();
17112 }
17113 self.write(")");
17114
17115 if let Some(alias) = &mr.alias {
17117 self.write(" ");
17118 if mr.alias_explicit_as {
17119 self.write_keyword("AS");
17120 self.write(" ");
17121 }
17122 self.generate_identifier(alias)?;
17123 }
17124
17125 Ok(())
17126 }
17127
17128 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
17130 use crate::dialects::DialectType;
17131
17132 let supports_hints = matches!(
17134 self.config.dialect,
17135 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
17137 Some(DialectType::Spark) | Some(DialectType::Hive) |
17138 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
17139 );
17140
17141 if !supports_hints || hint.expressions.is_empty() {
17142 return Ok(());
17143 }
17144
17145 let mut hint_strings: Vec<String> = Vec::new();
17148 for expr in &hint.expressions {
17149 match expr {
17150 HintExpression::Raw(text) => {
17151 let parsed = self.parse_raw_hint_text(text);
17153 hint_strings.extend(parsed);
17154 }
17155 _ => {
17156 hint_strings.push(self.hint_expression_to_string(expr)?);
17157 }
17158 }
17159 }
17160
17161 let use_multiline = self.config.pretty && hint_strings.len() > 1;
17165
17166 if use_multiline {
17167 self.write(" /*+ ");
17169 for (i, hint_str) in hint_strings.iter().enumerate() {
17170 if i > 0 {
17171 self.write_newline();
17172 self.write(" "); }
17174 self.write(hint_str);
17175 }
17176 self.write(" */");
17177 } else {
17178 self.write(" /*+ ");
17180 let sep = match self.config.dialect {
17181 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
17182 _ => " ",
17183 };
17184 for (i, hint_str) in hint_strings.iter().enumerate() {
17185 if i > 0 {
17186 self.write(sep);
17187 }
17188 self.write(hint_str);
17189 }
17190 self.write(" */");
17191 }
17192
17193 Ok(())
17194 }
17195
17196 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
17200 let mut results = Vec::new();
17201 let mut chars = text.chars().peekable();
17202 let mut current = String::new();
17203 let mut paren_depth = 0;
17204 let mut has_unparseable_content = false;
17205 let mut position_after_last_function = 0;
17206 let mut char_position = 0;
17207
17208 while let Some(c) = chars.next() {
17209 char_position += c.len_utf8();
17210 match c {
17211 '(' => {
17212 paren_depth += 1;
17213 current.push(c);
17214 }
17215 ')' => {
17216 paren_depth -= 1;
17217 current.push(c);
17218 if paren_depth == 0 {
17220 let trimmed = current.trim().to_string();
17221 if !trimmed.is_empty() {
17222 let formatted = self.format_hint_function(&trimmed);
17224 results.push(formatted);
17225 }
17226 current.clear();
17227 position_after_last_function = char_position;
17228 }
17229 }
17230 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
17231 }
17233 _ if paren_depth == 0 => {
17234 current.push(c);
17236 }
17237 _ => {
17238 current.push(c);
17239 }
17240 }
17241 }
17242
17243 let remaining_text = text[position_after_last_function..].trim();
17245 if !remaining_text.is_empty() {
17246 let words: Vec<&str> = remaining_text.split_whitespace().collect();
17250 let looks_like_hint_functions = words.iter().all(|word| {
17251 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
17253 });
17254
17255 if !looks_like_hint_functions && words.len() > 1 {
17256 has_unparseable_content = true;
17257 }
17258 }
17259
17260 if has_unparseable_content {
17262 return vec![text.trim().to_string()];
17263 }
17264
17265 if results.is_empty() {
17267 results.push(text.trim().to_string());
17268 }
17269
17270 results
17271 }
17272
17273 fn format_hint_function(&self, hint: &str) -> String {
17276 if !self.config.pretty {
17277 return hint.to_string();
17278 }
17279
17280 if let Some(paren_pos) = hint.find('(') {
17282 if hint.ends_with(')') {
17283 let name = &hint[..paren_pos];
17284 let args_str = &hint[paren_pos + 1..hint.len() - 1];
17285
17286 let args: Vec<&str> = args_str.split_whitespace().collect();
17288
17289 let total_args_width: usize =
17291 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() {
17295 let mut result = format!("{}(\n", name);
17296 for arg in &args {
17297 result.push_str(" "); result.push_str(arg);
17299 result.push('\n');
17300 }
17301 result.push_str(" )"); return result;
17303 }
17304 }
17305 }
17306
17307 hint.to_string()
17308 }
17309
17310 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
17312 match expr {
17313 HintExpression::Function { name, args } => {
17314 let arg_strings: Vec<String> = args
17316 .iter()
17317 .map(|arg| {
17318 let mut gen = Generator::with_arc_config(self.config.clone());
17319 gen.generate_expression(arg)?;
17320 Ok(gen.output)
17321 })
17322 .collect::<Result<Vec<_>>>()?;
17323
17324 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
17326 + arg_strings.len().saturating_sub(1); let args_multiline =
17331 self.config.pretty && total_args_width > self.config.max_text_width;
17332
17333 if args_multiline && !arg_strings.is_empty() {
17334 let mut result = format!("{}(\n", name);
17336 for arg_str in &arg_strings {
17337 result.push_str(" "); result.push_str(arg_str);
17339 result.push('\n');
17340 }
17341 result.push_str(" )"); Ok(result)
17343 } else {
17344 let args_str = arg_strings.join(" ");
17346 Ok(format!("{}({})", name, args_str))
17347 }
17348 }
17349 HintExpression::Identifier(name) => Ok(name.clone()),
17350 HintExpression::Raw(text) => {
17351 if self.config.pretty {
17353 Ok(self.format_hint_function(text))
17354 } else {
17355 Ok(text.clone())
17356 }
17357 }
17358 }
17359 }
17360
17361 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
17362 if table.only {
17364 self.write_keyword("ONLY");
17365 self.write_space();
17366 }
17367
17368 if let Some(ref identifier_func) = table.identifier_func {
17370 self.generate_expression(identifier_func)?;
17371 if !table.name.name.is_empty() {
17373 if let Some(catalog) = &table.catalog {
17374 self.write(".");
17375 self.generate_identifier(catalog)?;
17376 }
17377 if let Some(schema) = &table.schema {
17378 self.write(".");
17379 self.generate_identifier(schema)?;
17380 }
17381 self.write(".");
17382 self.generate_identifier(&table.name)?;
17383 }
17384 } else {
17385 if let Some(catalog) = &table.catalog {
17386 self.generate_identifier(catalog)?;
17387 self.write(".");
17388 }
17389 if let Some(schema) = &table.schema {
17390 self.generate_identifier(schema)?;
17391 self.write(".");
17392 }
17393 self.generate_identifier(&table.name)?;
17394 }
17395
17396 if let Some(changes) = &table.changes {
17398 self.write(" ");
17399 self.generate_changes(changes)?;
17400 }
17401
17402 if !table.partitions.is_empty() {
17404 self.write_space();
17405 self.write_keyword("PARTITION");
17406 self.write("(");
17407 for (i, partition) in table.partitions.iter().enumerate() {
17408 if i > 0 {
17409 self.write(", ");
17410 }
17411 self.generate_identifier(partition)?;
17412 }
17413 self.write(")");
17414 }
17415
17416 if table.changes.is_none() {
17419 if let Some(when) = &table.when {
17420 self.write_space();
17421 self.generate_historical_data(when)?;
17422 }
17423 }
17424
17425 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
17427 if !system_time_post_alias {
17428 if let Some(ref system_time) = table.system_time {
17429 self.write_space();
17430 self.write(system_time);
17431 }
17432 }
17433
17434 if let Some(ref version) = table.version {
17436 self.write_space();
17437 self.generate_version(version)?;
17438 }
17439
17440 let alias_post_tablesample = self.config.alias_post_tablesample;
17444
17445 if alias_post_tablesample {
17446 self.generate_table_sample_clause(table)?;
17448 }
17449
17450 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
17453 && table.hints.iter().any(|h| {
17454 if let Expression::Identifier(id) = h {
17455 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
17456 } else {
17457 false
17458 }
17459 });
17460 if !table.hints.is_empty() && !is_sqlite_hint {
17461 for hint in &table.hints {
17462 self.write_space();
17463 self.generate_expression(hint)?;
17464 }
17465 }
17466
17467 if let Some(alias) = &table.alias {
17468 self.write_space();
17469 let always_use_as = self.config.dialect.is_none()
17472 || matches!(
17473 self.config.dialect,
17474 Some(DialectType::Generic)
17475 | Some(DialectType::PostgreSQL)
17476 | Some(DialectType::Redshift)
17477 | Some(DialectType::Snowflake)
17478 | Some(DialectType::BigQuery)
17479 | Some(DialectType::DuckDB)
17480 | Some(DialectType::Presto)
17481 | Some(DialectType::Trino)
17482 | Some(DialectType::TSQL)
17483 | Some(DialectType::Fabric)
17484 | Some(DialectType::MySQL)
17485 | Some(DialectType::Spark)
17486 | Some(DialectType::Hive)
17487 | Some(DialectType::SQLite)
17488 | Some(DialectType::Drill)
17489 );
17490 let is_stage_ref = table.name.name.starts_with('@');
17491 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
17493 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
17494 self.write_keyword("AS");
17495 self.write_space();
17496 }
17497 self.generate_identifier(alias)?;
17498
17499 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
17502 self.write("(");
17503 for (i, col_alias) in table.column_aliases.iter().enumerate() {
17504 if i > 0 {
17505 self.write(", ");
17506 }
17507 self.generate_identifier(col_alias)?;
17508 }
17509 self.write(")");
17510 }
17511 }
17512
17513 if system_time_post_alias {
17515 if let Some(ref system_time) = table.system_time {
17516 self.write_space();
17517 self.write(system_time);
17518 }
17519 }
17520
17521 if !alias_post_tablesample {
17523 self.generate_table_sample_clause(table)?;
17524 }
17525
17526 if is_sqlite_hint {
17528 for hint in &table.hints {
17529 self.write_space();
17530 self.generate_expression(hint)?;
17531 }
17532 }
17533
17534 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
17536 self.write_space();
17537 self.write_keyword("FINAL");
17538 }
17539
17540 for comment in &table.trailing_comments {
17542 self.write_space();
17543 self.write_formatted_comment(comment);
17544 }
17545 Ok(())
17549 }
17550
17551 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
17553 if let Some(ref ts) = table.table_sample {
17554 self.write_space();
17555 if ts.is_using_sample {
17556 self.write_keyword("USING SAMPLE");
17557 } else {
17558 self.write_keyword(self.config.tablesample_keywords);
17560 }
17561 self.generate_sample_body(ts)?;
17562 if let Some(ref seed) = ts.seed {
17564 self.write_space();
17565 self.write_keyword(self.config.tablesample_seed_keyword);
17566 self.write(" (");
17567 self.generate_expression(seed)?;
17568 self.write(")");
17569 }
17570 }
17571 Ok(())
17572 }
17573
17574 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
17575 if sr.quoted {
17579 self.write("'");
17580 }
17581
17582 self.write(&sr.name);
17583 if let Some(path) = &sr.path {
17584 self.write(path);
17585 }
17586
17587 if sr.quoted {
17588 self.write("'");
17589 }
17590
17591 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
17593 if has_options {
17594 self.write(" (");
17595 let mut first = true;
17596
17597 if let Some(file_format) = &sr.file_format {
17598 if !first {
17599 self.write(", ");
17600 }
17601 self.write_keyword("FILE_FORMAT");
17602 self.write(" => ");
17603 self.generate_expression(file_format)?;
17604 first = false;
17605 }
17606
17607 if let Some(pattern) = &sr.pattern {
17608 if !first {
17609 self.write(", ");
17610 }
17611 self.write_keyword("PATTERN");
17612 self.write(" => '");
17613 self.write(pattern);
17614 self.write("'");
17615 }
17616
17617 self.write(")");
17618 }
17619 Ok(())
17620 }
17621
17622 fn generate_star(&mut self, star: &Star) -> Result<()> {
17623 use crate::dialects::DialectType;
17624
17625 if let Some(table) = &star.table {
17626 self.generate_identifier(table)?;
17627 self.write(".");
17628 }
17629 self.write("*");
17630
17631 if let Some(except) = &star.except {
17633 if !except.is_empty() {
17634 self.write_space();
17635 match self.config.dialect {
17637 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
17638 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
17639 self.write_keyword("EXCLUDE")
17640 }
17641 _ => self.write_keyword("EXCEPT"), }
17643 self.write(" (");
17644 for (i, col) in except.iter().enumerate() {
17645 if i > 0 {
17646 self.write(", ");
17647 }
17648 self.generate_identifier(col)?;
17649 }
17650 self.write(")");
17651 }
17652 }
17653
17654 if let Some(replace) = &star.replace {
17656 if !replace.is_empty() {
17657 self.write_space();
17658 self.write_keyword("REPLACE");
17659 self.write(" (");
17660 for (i, alias) in replace.iter().enumerate() {
17661 if i > 0 {
17662 self.write(", ");
17663 }
17664 self.generate_expression(&alias.this)?;
17665 self.write_space();
17666 self.write_keyword("AS");
17667 self.write_space();
17668 self.generate_identifier(&alias.alias)?;
17669 }
17670 self.write(")");
17671 }
17672 }
17673
17674 if let Some(rename) = &star.rename {
17676 if !rename.is_empty() {
17677 self.write_space();
17678 self.write_keyword("RENAME");
17679 self.write(" (");
17680 for (i, (old_name, new_name)) in rename.iter().enumerate() {
17681 if i > 0 {
17682 self.write(", ");
17683 }
17684 self.generate_identifier(old_name)?;
17685 self.write_space();
17686 self.write_keyword("AS");
17687 self.write_space();
17688 self.generate_identifier(new_name)?;
17689 }
17690 self.write(")");
17691 }
17692 }
17693
17694 for comment in &star.trailing_comments {
17696 self.write_space();
17697 self.write_formatted_comment(comment);
17698 }
17699
17700 Ok(())
17701 }
17702
17703 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
17705 self.write("{");
17706 match expr {
17707 Expression::Star(star) => {
17708 self.generate_star(star)?;
17710 }
17711 Expression::ILike(ilike) => {
17712 self.generate_expression(&ilike.left)?;
17714 self.write_space();
17715 self.write_keyword("ILIKE");
17716 self.write_space();
17717 self.generate_expression(&ilike.right)?;
17718 }
17719 _ => {
17720 self.generate_expression(expr)?;
17721 }
17722 }
17723 self.write("}");
17724 Ok(())
17725 }
17726
17727 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
17728 match &alias.this {
17732 Expression::Column(col) => {
17733 if let Some(table) = &col.table {
17735 self.generate_identifier(table)?;
17736 self.write(".");
17737 }
17738 self.generate_identifier(&col.name)?;
17739 }
17740 _ => {
17741 self.generate_expression(&alias.this)?;
17742 }
17743 }
17744
17745 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
17749 for comment in &alias.pre_alias_comments {
17750 self.write_space();
17751 self.write_formatted_comment(comment);
17752 }
17753 }
17754
17755 use crate::dialects::DialectType;
17756
17757 let is_table_source = matches!(
17763 &alias.this,
17764 Expression::JSONTable(_)
17765 | Expression::XMLTable(_)
17766 | Expression::TableFromRows(_)
17767 | Expression::Unnest(_)
17768 | Expression::MatchRecognize(_)
17769 | Expression::Select(_)
17770 | Expression::Subquery(_)
17771 | Expression::Paren(_)
17772 | Expression::JoinedTable(_)
17773 );
17774 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
17775 let skip_as = is_table_source && dialect_skips_table_alias_as;
17776
17777 self.write_space();
17778 if !skip_as {
17779 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
17780 if let Some(ref alias_keyword) = alias.alias_keyword {
17781 self.write(alias_keyword);
17782 } else {
17783 self.write_keyword("AS");
17784 }
17785 } else {
17786 self.write_keyword("AS");
17787 }
17788 self.write_space();
17789 }
17790
17791 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
17793
17794 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
17796 self.write("(");
17798 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17799 if i > 0 {
17800 self.write(", ");
17801 }
17802 self.generate_alias_identifier(col_alias)?;
17803 }
17804 self.write(")");
17805 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
17806 self.generate_alias_identifier(&alias.alias)?;
17808 self.write("(");
17809 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17810 if i > 0 {
17811 self.write(", ");
17812 }
17813 self.generate_alias_identifier(col_alias)?;
17814 }
17815 self.write(")");
17816 } else {
17817 self.generate_alias_identifier(&alias.alias)?;
17819 }
17820
17821 for comment in &alias.trailing_comments {
17823 self.write_space();
17824 self.write_formatted_comment(comment);
17825 }
17826
17827 if alias.trailing_comments.is_empty() {
17832 for comment in &alias.pre_alias_comments {
17833 self.write_space();
17834 self.write_formatted_comment(comment);
17835 }
17836 }
17837
17838 Ok(())
17839 }
17840
17841 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
17842 use crate::dialects::DialectType;
17843
17844 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
17846 self.generate_expression(&cast.this)?;
17847 self.write(" :> ");
17848 self.generate_data_type(&cast.to)?;
17849 return Ok(());
17850 }
17851
17852 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
17854 let is_unknown_type = matches!(cast.to, DataType::Unknown)
17855 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
17856 if is_unknown_type {
17857 if let Some(format) = &cast.format {
17858 self.write_keyword("CAST");
17859 self.write("(");
17860 self.generate_expression(&cast.this)?;
17861 self.write_space();
17862 self.write_keyword("AS");
17863 self.write_space();
17864 self.write_keyword("FORMAT");
17865 self.write_space();
17866 self.generate_expression(format)?;
17867 self.write(")");
17868 return Ok(());
17869 }
17870 }
17871 }
17872
17873 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
17876 if let Some(format) = &cast.format {
17877 let is_date = matches!(cast.to, DataType::Date);
17879 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
17880
17881 if is_date || is_timestamp {
17882 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
17883 self.write_keyword(func_name);
17884 self.write("(");
17885 self.generate_expression(&cast.this)?;
17886 self.write(", ");
17887
17888 if let Expression::Literal(lit) = format.as_ref() {
17891 if let Literal::String(fmt_str) = lit.as_ref() {
17892 let normalized = self.normalize_oracle_format(fmt_str);
17893 self.write("'");
17894 self.write(&normalized);
17895 self.write("'");
17896 }
17897 } else {
17898 self.generate_expression(format)?;
17899 }
17900
17901 self.write(")");
17902 return Ok(());
17903 }
17904 }
17905 }
17906
17907 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
17910 if let Expression::Array(arr) = &cast.this {
17911 self.generate_data_type(&cast.to)?;
17912 self.write("[");
17914 for (i, expr) in arr.expressions.iter().enumerate() {
17915 if i > 0 {
17916 self.write(", ");
17917 }
17918 self.generate_expression(expr)?;
17919 }
17920 self.write("]");
17921 return Ok(());
17922 }
17923 if matches!(&cast.this, Expression::ArrayFunc(_)) {
17924 self.generate_data_type(&cast.to)?;
17925 self.generate_expression(&cast.this)?;
17926 return Ok(());
17927 }
17928 }
17929
17930 if matches!(
17933 self.config.dialect,
17934 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
17935 ) {
17936 if let Expression::Struct(ref s) = cast.this {
17937 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
17938 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
17939 self.write_keyword("CAST");
17940 self.write("(");
17941 self.generate_struct_as_row(s)?;
17942 self.write_space();
17943 self.write_keyword("AS");
17944 self.write_space();
17945 self.generate_data_type(&cast.to)?;
17946 self.write(")");
17947 return Ok(());
17948 }
17949 }
17950 }
17951
17952 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
17955
17956 if use_double_colon {
17957 self.generate_expression(&cast.this)?;
17959 self.write("::");
17960 self.generate_data_type(&cast.to)?;
17961 } else {
17962 self.write_keyword("CAST");
17964 self.write("(");
17965 self.generate_expression(&cast.this)?;
17966 self.write_space();
17967 self.write_keyword("AS");
17968 self.write_space();
17969 if matches!(
17972 self.config.dialect,
17973 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
17974 ) {
17975 match &cast.to {
17976 DataType::Custom { ref name } => {
17977 if name.eq_ignore_ascii_case("LONGTEXT")
17978 || name.eq_ignore_ascii_case("MEDIUMTEXT")
17979 || name.eq_ignore_ascii_case("TINYTEXT")
17980 || name.eq_ignore_ascii_case("LONGBLOB")
17981 || name.eq_ignore_ascii_case("MEDIUMBLOB")
17982 || name.eq_ignore_ascii_case("TINYBLOB")
17983 {
17984 self.write_keyword("CHAR");
17985 } else {
17986 self.generate_data_type(&cast.to)?;
17987 }
17988 }
17989 DataType::VarChar { length, .. } => {
17990 self.write_keyword("CHAR");
17992 if let Some(n) = length {
17993 self.write(&format!("({})", n));
17994 }
17995 }
17996 DataType::Text => {
17997 self.write_keyword("CHAR");
17999 }
18000 DataType::Timestamp {
18001 precision,
18002 timezone: false,
18003 } => {
18004 self.write_keyword("DATETIME");
18006 if let Some(p) = precision {
18007 self.write(&format!("({})", p));
18008 }
18009 }
18010 _ => {
18011 self.generate_data_type(&cast.to)?;
18012 }
18013 }
18014 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
18015 match &cast.to {
18017 DataType::String { length } => {
18018 self.write_keyword("VARCHAR");
18019 if let Some(n) = length {
18020 self.write(&format!("({})", n));
18021 }
18022 }
18023 _ => {
18024 self.generate_data_type(&cast.to)?;
18025 }
18026 }
18027 } else {
18028 self.generate_data_type(&cast.to)?;
18029 }
18030
18031 if let Some(default) = &cast.default {
18033 self.write_space();
18034 self.write_keyword("DEFAULT");
18035 self.write_space();
18036 self.generate_expression(default)?;
18037 self.write_space();
18038 self.write_keyword("ON");
18039 self.write_space();
18040 self.write_keyword("CONVERSION");
18041 self.write_space();
18042 self.write_keyword("ERROR");
18043 }
18044
18045 if let Some(format) = &cast.format {
18048 if matches!(
18050 self.config.dialect,
18051 Some(crate::dialects::DialectType::Oracle)
18052 ) {
18053 self.write(", ");
18054 } else {
18055 self.write_space();
18056 self.write_keyword("FORMAT");
18057 self.write_space();
18058 }
18059 self.generate_expression(format)?;
18060 }
18061
18062 self.write(")");
18063 for comment in &cast.trailing_comments {
18065 self.write_space();
18066 self.write_formatted_comment(comment);
18067 }
18068 }
18069 Ok(())
18070 }
18071
18072 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
18075 self.write_keyword("ROW");
18076 self.write("(");
18077 for (i, (_, expr)) in s.fields.iter().enumerate() {
18078 if i > 0 {
18079 self.write(", ");
18080 }
18081 if let Expression::Struct(ref inner_s) = expr {
18083 self.generate_struct_as_row(inner_s)?;
18084 } else {
18085 self.generate_expression(expr)?;
18086 }
18087 }
18088 self.write(")");
18089 Ok(())
18090 }
18091
18092 fn normalize_oracle_format(&self, format: &str) -> String {
18095 let mut result = String::new();
18098 let chars: Vec<char> = format.chars().collect();
18099 let mut i = 0;
18100
18101 while i < chars.len() {
18102 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
18103 if i + 2 < chars.len() {
18105 let next = chars[i + 2];
18106 if next == '1' || next == '2' {
18107 result.push('H');
18109 result.push('H');
18110 i += 2;
18111 continue;
18112 }
18113 }
18114 result.push_str("HH12");
18116 i += 2;
18117 } else {
18118 result.push(chars[i]);
18119 i += 1;
18120 }
18121 }
18122
18123 result
18124 }
18125
18126 fn dialect_prefers_double_colon(&self) -> bool {
18129 matches!(self.config.dialect, Some(DialectType::ClickHouse))
18130 }
18131
18132 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
18134 use crate::dialects::DialectType;
18135
18136 let use_percent_operator = matches!(
18138 self.config.dialect,
18139 Some(DialectType::Snowflake)
18140 | Some(DialectType::MySQL)
18141 | Some(DialectType::Presto)
18142 | Some(DialectType::Trino)
18143 | Some(DialectType::PostgreSQL)
18144 | Some(DialectType::DuckDB)
18145 | Some(DialectType::Hive)
18146 | Some(DialectType::Spark)
18147 | Some(DialectType::Databricks)
18148 | Some(DialectType::Athena)
18149 | Some(DialectType::TSQL)
18150 | Some(DialectType::Fabric)
18151 );
18152
18153 if use_percent_operator {
18154 let needs_paren = |e: &Expression| {
18157 matches!(
18158 e,
18159 Expression::Add(_)
18160 | Expression::Sub(_)
18161 | Expression::Mul(_)
18162 | Expression::Div(_)
18163 | Expression::Mod(_)
18164 | Expression::ModFunc(_)
18165 )
18166 };
18167 if needs_paren(&f.this) {
18168 self.write("(");
18169 self.generate_expression(&f.this)?;
18170 self.write(")");
18171 } else {
18172 self.generate_expression(&f.this)?;
18173 }
18174 self.write(" % ");
18175 if needs_paren(&f.expression) {
18176 self.write("(");
18177 self.generate_expression(&f.expression)?;
18178 self.write(")");
18179 } else {
18180 self.generate_expression(&f.expression)?;
18181 }
18182 Ok(())
18183 } else {
18184 self.generate_binary_func("MOD", &f.this, &f.expression)
18185 }
18186 }
18187
18188 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
18190 use crate::dialects::DialectType;
18191
18192 let func_name = match self.config.dialect {
18194 Some(DialectType::Snowflake) => "COALESCE",
18195 _ => "IFNULL",
18196 };
18197
18198 self.generate_binary_func(func_name, &f.this, &f.expression)
18199 }
18200
18201 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
18203 if let Some(ref original_name) = f.original_name {
18205 return self.generate_binary_func(original_name, &f.this, &f.expression);
18206 }
18207
18208 use crate::dialects::DialectType;
18210 let func_name = match self.config.dialect {
18211 Some(DialectType::Snowflake)
18212 | Some(DialectType::ClickHouse)
18213 | Some(DialectType::PostgreSQL)
18214 | Some(DialectType::Presto)
18215 | Some(DialectType::Trino)
18216 | Some(DialectType::Athena)
18217 | Some(DialectType::DuckDB)
18218 | Some(DialectType::BigQuery)
18219 | Some(DialectType::Spark)
18220 | Some(DialectType::Databricks)
18221 | Some(DialectType::Hive) => "COALESCE",
18222 Some(DialectType::MySQL)
18223 | Some(DialectType::Doris)
18224 | Some(DialectType::StarRocks)
18225 | Some(DialectType::SingleStore)
18226 | Some(DialectType::TiDB) => "IFNULL",
18227 _ => "NVL",
18228 };
18229
18230 self.generate_binary_func(func_name, &f.this, &f.expression)
18231 }
18232
18233 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
18235 use crate::dialects::DialectType;
18236
18237 let func_name = match self.config.dialect {
18239 Some(DialectType::Snowflake) => "STDDEV",
18240 _ => "STDDEV_SAMP",
18241 };
18242
18243 self.generate_agg_func(func_name, f)
18244 }
18245
18246 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
18247 self.generate_expression(&coll.this)?;
18248 self.write_space();
18249 self.write_keyword("COLLATE");
18250 self.write_space();
18251 if coll.quoted {
18252 self.write("'");
18254 self.write(&coll.collation);
18255 self.write("'");
18256 } else if coll.double_quoted {
18257 self.write("\"");
18259 self.write(&coll.collation);
18260 self.write("\"");
18261 } else {
18262 self.write(&coll.collation);
18264 }
18265 Ok(())
18266 }
18267
18268 fn generate_case(&mut self, case: &Case) -> Result<()> {
18269 let multiline_case = if self.config.pretty {
18271 let mut statements: Vec<String> = Vec::new();
18273 let operand_str = if let Some(operand) = &case.operand {
18274 let s = self.generate_to_string(operand)?;
18275 statements.push(format!("CASE {}", s));
18276 s
18277 } else {
18278 statements.push("CASE".to_string());
18279 String::new()
18280 };
18281 let _ = operand_str;
18282 for (condition, result) in &case.whens {
18283 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
18284 statements.push(format!("THEN {}", self.generate_to_string(result)?));
18285 }
18286 if let Some(else_) = &case.else_ {
18287 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
18288 }
18289 statements.push("END".to_string());
18290 self.too_wide(&statements)
18291 } else {
18292 false
18293 };
18294
18295 self.write_keyword("CASE");
18296 if let Some(operand) = &case.operand {
18297 self.write_space();
18298 self.generate_expression(operand)?;
18299 }
18300 if multiline_case {
18301 self.indent_level += 1;
18302 }
18303 for (condition, result) in &case.whens {
18304 if multiline_case {
18305 self.write_newline();
18306 self.write_indent();
18307 } else {
18308 self.write_space();
18309 }
18310 self.write_keyword("WHEN");
18311 self.write_space();
18312 self.generate_expression(condition)?;
18313 if multiline_case {
18314 self.write_newline();
18315 self.write_indent();
18316 } else {
18317 self.write_space();
18318 }
18319 self.write_keyword("THEN");
18320 self.write_space();
18321 self.generate_expression(result)?;
18322 }
18323 if let Some(else_) = &case.else_ {
18324 if multiline_case {
18325 self.write_newline();
18326 self.write_indent();
18327 } else {
18328 self.write_space();
18329 }
18330 self.write_keyword("ELSE");
18331 self.write_space();
18332 self.generate_expression(else_)?;
18333 }
18334 if multiline_case {
18335 self.indent_level -= 1;
18336 self.write_newline();
18337 self.write_indent();
18338 } else {
18339 self.write_space();
18340 }
18341 self.write_keyword("END");
18342 for comment in &case.comments {
18344 self.write(" ");
18345 self.write_formatted_comment(comment);
18346 }
18347 Ok(())
18348 }
18349
18350 fn generate_function(&mut self, func: &Function) -> Result<()> {
18351 let normalized_name = if func.name.eq_ignore_ascii_case("GROUPING")
18353 && func.args.len() > 1
18354 && matches!(
18355 self.config.dialect,
18356 Some(DialectType::TSQL | DialectType::Fabric)
18357 ) {
18358 Cow::Borrowed("GROUPING_ID")
18359 } else if matches!(self.config.dialect, Some(DialectType::Snowflake))
18360 && func.name.to_ascii_uppercase().starts_with("IDENTIFIER(")
18361 {
18362 Cow::Borrowed(func.name.as_str())
18363 } else {
18364 self.normalize_func_name(&func.name)
18365 };
18366
18367 if matches!(self.config.dialect, Some(DialectType::DuckDB))
18369 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
18370 {
18371 self.write("LIST_FILTER(");
18372 self.write("[");
18373 for (i, arg) in func.args.iter().enumerate() {
18374 if i > 0 {
18375 self.write(", ");
18376 }
18377 self.generate_expression(arg)?;
18378 }
18379 self.write("], _u -> NOT _u IS NULL)");
18380 return Ok(());
18381 }
18382
18383 if matches!(self.config.dialect, Some(DialectType::Snowflake))
18386 && func.name.eq_ignore_ascii_case("TO_VARIANT")
18387 && func.args.len() == 1
18388 {
18389 let array_expressions = match &func.args[0] {
18390 Expression::ArrayFunc(arr) => Some(&arr.expressions),
18391 Expression::Array(arr) => Some(&arr.expressions),
18392 _ => None,
18393 };
18394 if let Some(expressions) = array_expressions {
18395 self.write_keyword("TO_VARIANT");
18396 self.write("(");
18397 self.write_keyword("ARRAY_CONSTRUCT");
18398 self.write("(");
18399 for (i, arg) in expressions.iter().enumerate() {
18400 if i > 0 {
18401 self.write(", ");
18402 }
18403 self.generate_expression(arg)?;
18404 }
18405 self.write(")");
18406 self.write(")");
18407 return Ok(());
18408 }
18409 }
18410
18411 if func.name.eq_ignore_ascii_case("STRUCT")
18413 && !matches!(
18414 self.config.dialect,
18415 Some(DialectType::BigQuery)
18416 | Some(DialectType::Spark)
18417 | Some(DialectType::Databricks)
18418 | Some(DialectType::Hive)
18419 | None
18420 )
18421 {
18422 return self.generate_struct_function_cross_dialect(func);
18423 }
18424
18425 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
18428 self.generate_expression(&func.args[0])?;
18429 self.write("::?");
18430 if let Expression::Literal(lit) = &func.args[1] {
18432 if let crate::expressions::Literal::String(key) = lit.as_ref() {
18433 self.write(key);
18434 }
18435 } else {
18436 self.generate_expression(&func.args[1])?;
18437 }
18438 return Ok(());
18439 }
18440
18441 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
18443 self.generate_expression(&func.args[0])?;
18444 self.write(" # ");
18445 self.generate_expression(&func.args[1])?;
18446 return Ok(());
18447 }
18448
18449 if matches!(
18451 self.config.dialect,
18452 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
18453 ) && func.name.eq_ignore_ascii_case("TRY")
18454 && func.args.len() == 1
18455 {
18456 self.generate_expression(&func.args[0])?;
18457 return Ok(());
18458 }
18459
18460 if self.config.dialect == Some(DialectType::ClickHouse)
18462 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
18463 && func.args.len() == 1
18464 {
18465 self.write("dateTrunc('DAY', ");
18466 self.generate_expression(&func.args[0])?;
18467 self.write(")");
18468 return Ok(());
18469 }
18470
18471 if self.config.dialect == Some(DialectType::ClickHouse)
18473 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
18474 && func.args.len() == 2
18475 {
18476 self.write("dateTrunc(");
18477 self.generate_expression(&func.args[0])?;
18478 self.write(", ");
18479 self.generate_expression(&func.args[1])?;
18480 self.write(")");
18481 return Ok(());
18482 }
18483
18484 if matches!(
18486 self.config.dialect,
18487 Some(DialectType::Presto | DialectType::Trino | DialectType::Athena)
18488 ) && func.name.eq_ignore_ascii_case("SUBSTRING")
18489 {
18490 self.write_keyword("SUBSTR");
18491 self.write("(");
18492 for (i, arg) in func.args.iter().enumerate() {
18493 if i > 0 {
18494 self.write(", ");
18495 }
18496 self.generate_expression(arg)?;
18497 }
18498 self.write(")");
18499 return Ok(());
18500 }
18501
18502 if self.config.dialect == Some(DialectType::Snowflake)
18503 && func.name.eq_ignore_ascii_case("LIST_DISTINCT")
18504 && func.args.len() == 1
18505 {
18506 self.write_keyword("ARRAY_DISTINCT");
18507 self.write("(");
18508 self.write_keyword("ARRAY_COMPACT");
18509 self.write("(");
18510 self.generate_expression(&func.args[0])?;
18511 self.write("))");
18512 return Ok(());
18513 }
18514
18515 if self.config.dialect == Some(DialectType::Snowflake)
18516 && func.name.eq_ignore_ascii_case("LIST")
18517 && func.args.len() == 1
18518 && !matches!(func.args.first(), Some(Expression::Select(_)))
18519 {
18520 self.write_keyword("ARRAY_AGG");
18521 self.write("(");
18522 self.generate_expression(&func.args[0])?;
18523 self.write(")");
18524 return Ok(());
18525 }
18526
18527 if self.config.dialect == Some(DialectType::Redshift)
18529 && func.name.eq_ignore_ascii_case("CONCAT")
18530 && func.args.len() >= 2
18531 {
18532 for (i, arg) in func.args.iter().enumerate() {
18533 if i > 0 {
18534 self.write(" || ");
18535 }
18536 self.generate_expression(arg)?;
18537 }
18538 return Ok(());
18539 }
18540
18541 if self.config.dialect == Some(DialectType::Redshift)
18543 && func.name.eq_ignore_ascii_case("CONCAT_WS")
18544 && func.args.len() >= 2
18545 {
18546 let sep = &func.args[0];
18547 for (i, arg) in func.args.iter().skip(1).enumerate() {
18548 if i > 0 {
18549 self.write(" || ");
18550 self.generate_expression(sep)?;
18551 self.write(" || ");
18552 }
18553 self.generate_expression(arg)?;
18554 }
18555 return Ok(());
18556 }
18557
18558 if self.config.dialect == Some(DialectType::Redshift)
18561 && (func.name.eq_ignore_ascii_case("DATEDIFF")
18562 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
18563 && func.args.len() == 3
18564 {
18565 self.write_keyword("DATEDIFF");
18566 self.write("(");
18567 self.write_redshift_date_part(&func.args[0]);
18569 self.write(", ");
18570 self.generate_expression(&func.args[1])?;
18571 self.write(", ");
18572 self.generate_expression(&func.args[2])?;
18573 self.write(")");
18574 return Ok(());
18575 }
18576
18577 if self.config.dialect == Some(DialectType::Redshift)
18580 && (func.name.eq_ignore_ascii_case("DATEADD")
18581 || func.name.eq_ignore_ascii_case("DATE_ADD"))
18582 && func.args.len() == 3
18583 {
18584 self.write_keyword("DATEADD");
18585 self.write("(");
18586 self.write_redshift_date_part(&func.args[0]);
18588 self.write(", ");
18589 self.generate_expression(&func.args[1])?;
18590 self.write(", ");
18591 self.generate_expression(&func.args[2])?;
18592 self.write(")");
18593 return Ok(());
18594 }
18595
18596 if func.name.eq_ignore_ascii_case("UUID_STRING")
18598 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
18599 {
18600 if matches!(
18601 self.config.dialect,
18602 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
18603 ) {
18604 self.write_keyword("CAST");
18605 self.write("(");
18606 self.write_keyword("UUID");
18607 self.write("() ");
18608 self.write_keyword("AS");
18609 self.write(" ");
18610 self.write_keyword("STRING");
18611 self.write(")");
18612 return Ok(());
18613 }
18614
18615 if matches!(
18616 self.config.dialect,
18617 Some(DialectType::Presto | DialectType::Trino)
18618 ) {
18619 self.write_keyword("CAST");
18620 self.write("(");
18621 self.write_keyword("UUID");
18622 self.write("() ");
18623 self.write_keyword("AS");
18624 self.write(" ");
18625 self.write_keyword("VARCHAR");
18626 self.write(")");
18627 return Ok(());
18628 }
18629
18630 if self.config.dialect == Some(DialectType::DuckDB) && func.args.len() == 2 {
18631 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(");
18632 self.generate_expression(&func.args[0])?;
18633 self.write(", '-', '')) || ENCODE(");
18634 self.generate_expression(&func.args[1])?;
18635 self.write(")), 1, 32) AS h))");
18636 return Ok(());
18637 }
18638
18639 let func_name = match self.config.dialect {
18640 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
18641 Some(DialectType::BigQuery) => "GENERATE_UUID",
18642 _ => "UUID",
18643 };
18644 self.write_keyword(func_name);
18645 self.write("()");
18646 return Ok(());
18647 }
18648
18649 if matches!(self.config.dialect, Some(DialectType::Snowflake))
18653 && func.name.eq_ignore_ascii_case("GENERATOR")
18654 {
18655 let has_positional_args =
18656 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
18657 if has_positional_args {
18658 let param_names = ["ROWCOUNT", "TIMELIMIT"];
18659 self.write_keyword("GENERATOR");
18660 self.write("(");
18661 for (i, arg) in func.args.iter().enumerate() {
18662 if i > 0 {
18663 self.write(", ");
18664 }
18665 if i < param_names.len() {
18666 self.write_keyword(param_names[i]);
18667 self.write(" => ");
18668 self.generate_expression(arg)?;
18669 } else {
18670 self.generate_expression(arg)?;
18671 }
18672 }
18673 self.write(")");
18674 return Ok(());
18675 }
18676 }
18677
18678 if self.config.dialect == Some(DialectType::Redshift)
18681 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
18682 && func.args.len() == 2
18683 {
18684 self.write_keyword("DATE_TRUNC");
18685 self.write("(");
18686 self.write_redshift_date_part_quoted(&func.args[0]);
18688 self.write(", ");
18689 self.generate_expression(&func.args[1])?;
18690 self.write(")");
18691 return Ok(());
18692 }
18693
18694 if matches!(
18696 self.config.dialect,
18697 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18698 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
18699 || func.name.eq_ignore_ascii_case("DATEPART"))
18700 && func.args.len() == 2
18701 {
18702 if let Some(part) = self.extract_date_part_string(&func.args[0]) {
18703 let date_part = self.classify_tsql_date_part_name(&part);
18704 self.generate_tsql_date_part(date_part, &func.args[1])?;
18705 } else {
18706 self.write_keyword("DATEPART");
18707 self.write("(");
18708 self.generate_expression(&func.args[0])?;
18709 self.write(", ");
18710 self.generate_expression(&func.args[1])?;
18711 self.write(")");
18712 }
18713 return Ok(());
18714 }
18715
18716 if matches!(
18718 self.config.dialect,
18719 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18720 ) && (func.name.eq_ignore_ascii_case("DATETRUNC")
18721 || func.name.eq_ignore_ascii_case("DATE_TRUNC"))
18722 && func.args.len() == 2
18723 {
18724 if let Some(part) = self.extract_date_part_string(&func.args[0]) {
18725 let date_part = self.classify_tsql_date_trunc_name(&part);
18726 self.generate_tsql_date_trunc(date_part, &func.args[1])?;
18727 } else {
18728 self.write_keyword("DATETRUNC");
18729 self.write("(");
18730 self.generate_expression(&func.args[0])?;
18731 self.write(", ");
18732 self.generate_expression(&func.args[1])?;
18733 self.write(")");
18734 }
18735 return Ok(());
18736 }
18737
18738 if matches!(
18740 self.config.dialect,
18741 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
18742 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
18743 || func.name.eq_ignore_ascii_case("DATEPART"))
18744 && func.args.len() == 2
18745 {
18746 self.write_keyword("EXTRACT");
18747 self.write("(");
18748 match &func.args[0] {
18750 Expression::Literal(lit)
18751 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18752 {
18753 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18754 unreachable!()
18755 };
18756 self.write(&s.to_ascii_lowercase());
18757 }
18758 _ => self.generate_expression(&func.args[0])?,
18759 }
18760 self.write_space();
18761 self.write_keyword("FROM");
18762 self.write_space();
18763 self.generate_expression(&func.args[1])?;
18764 self.write(")");
18765 return Ok(());
18766 }
18767
18768 if self.config.dialect == Some(DialectType::PostgreSQL)
18770 && matches!(
18771 func.name.to_ascii_uppercase().as_str(),
18772 "DATE_ADD" | "DATE_SUB"
18773 )
18774 && func.args.len() == 2
18775 && matches!(func.args[1], Expression::Interval(_))
18776 {
18777 self.generate_expression(&func.args[0])?;
18778 self.write_space();
18779 if func.name.eq_ignore_ascii_case("DATE_SUB") {
18780 self.write("-");
18781 } else {
18782 self.write("+");
18783 }
18784 self.write_space();
18785 self.generate_expression(&func.args[1])?;
18786 return Ok(());
18787 }
18788
18789 if self.config.dialect == Some(DialectType::Dremio)
18792 && (func.name.eq_ignore_ascii_case("DATE_PART")
18793 || func.name.eq_ignore_ascii_case("DATEPART"))
18794 && func.args.len() == 2
18795 {
18796 self.write_keyword("EXTRACT");
18797 self.write("(");
18798 self.generate_expression(&func.args[0])?;
18799 self.write_space();
18800 self.write_keyword("FROM");
18801 self.write_space();
18802 self.generate_dremio_date_expression(&func.args[1])?;
18804 self.write(")");
18805 return Ok(());
18806 }
18807
18808 if self.config.dialect == Some(DialectType::Dremio)
18810 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
18811 && func.args.is_empty()
18812 {
18813 self.write_keyword("CURRENT_DATE_UTC");
18814 return Ok(());
18815 }
18816
18817 if self.config.dialect == Some(DialectType::Dremio)
18821 && func.name.eq_ignore_ascii_case("DATETYPE")
18822 && func.args.len() == 3
18823 {
18824 fn get_int_literal(expr: &Expression) -> Option<i64> {
18826 if let Expression::Literal(lit) = expr {
18827 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
18828 s.parse::<i64>().ok()
18829 } else {
18830 None
18831 }
18832 } else {
18833 None
18834 }
18835 }
18836
18837 if let (Some(year), Some(month), Some(day)) = (
18839 get_int_literal(&func.args[0]),
18840 get_int_literal(&func.args[1]),
18841 get_int_literal(&func.args[2]),
18842 ) {
18843 self.write_keyword("DATE");
18845 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
18846 return Ok(());
18847 }
18848
18849 self.write_keyword("CAST");
18851 self.write("(");
18852 self.write_keyword("CONCAT");
18853 self.write("(");
18854 self.generate_expression(&func.args[0])?;
18855 self.write(", '-', ");
18856 self.generate_expression(&func.args[1])?;
18857 self.write(", '-', ");
18858 self.generate_expression(&func.args[2])?;
18859 self.write(")");
18860 self.write_space();
18861 self.write_keyword("AS");
18862 self.write_space();
18863 self.write_keyword("DATE");
18864 self.write(")");
18865 return Ok(());
18866 }
18867
18868 let is_presto_like = matches!(
18871 self.config.dialect,
18872 Some(DialectType::Presto) | Some(DialectType::Trino)
18873 );
18874 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
18875 self.write_keyword("DATE_ADD");
18876 self.write("(");
18877 self.generate_expression(&func.args[0])?;
18879 self.write(", ");
18880 let interval = &func.args[1];
18882 let needs_cast = !self.returns_integer_type(interval);
18883 if needs_cast {
18884 self.write_keyword("CAST");
18885 self.write("(");
18886 }
18887 self.generate_expression(interval)?;
18888 if needs_cast {
18889 self.write_space();
18890 self.write_keyword("AS");
18891 self.write_space();
18892 self.write_keyword("BIGINT");
18893 self.write(")");
18894 }
18895 self.write(", ");
18896 self.generate_expression(&func.args[2])?;
18898 self.write(")");
18899 return Ok(());
18900 }
18901
18902 let use_brackets = func.use_bracket_syntax;
18904
18905 let has_ordinality = func.name.len() >= 16
18910 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
18911 let output_name = if has_ordinality {
18912 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
18913 self.normalize_func_name(base_name)
18914 } else {
18915 normalized_name.clone()
18916 };
18917
18918 let quote_source_clickhouse_function =
18921 matches!(self.config.dialect, Some(DialectType::ClickHouse))
18922 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
18923 && func.quoted;
18924
18925 if quote_source_clickhouse_function {
18926 self.generate_identifier(&Identifier {
18927 name: func.name.clone(),
18928 quoted: true,
18929 trailing_comments: Vec::new(),
18930 span: None,
18931 })?;
18932 } else if func.name.contains('.') && !has_ordinality {
18933 if func.quoted {
18936 self.write("`");
18937 self.write(&func.name);
18938 self.write("`");
18939 } else {
18940 self.write(&func.name);
18941 }
18942 } else {
18943 self.write(&output_name);
18944 }
18945
18946 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
18949 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
18950 || func.name.eq_ignore_ascii_case("SESSION_USER")
18951 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
18952 {
18953 matches!(
18954 self.config.dialect,
18955 Some(DialectType::Snowflake)
18956 | Some(DialectType::Spark)
18957 | Some(DialectType::Databricks)
18958 | Some(DialectType::Hive)
18959 )
18960 } else {
18961 false
18962 };
18963 !needs_parens
18964 };
18965 if force_parens {
18966 for comment in &func.trailing_comments {
18968 self.write_space();
18969 self.write_formatted_comment(comment);
18970 }
18971 return Ok(());
18972 }
18973
18974 if func.name.eq_ignore_ascii_case("CUBE")
18976 || func.name.eq_ignore_ascii_case("ROLLUP")
18977 || func.name.eq_ignore_ascii_case("GROUPING SETS")
18978 {
18979 self.write(" (");
18980 } else if use_brackets {
18981 self.write("[");
18982 } else {
18983 self.write("(");
18984 }
18985 if func.distinct {
18986 self.write_keyword("DISTINCT");
18987 self.write_space();
18988 }
18989
18990 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
18992 && (func.name.eq_ignore_ascii_case("TABLE")
18993 || func.name.eq_ignore_ascii_case("FLATTEN"));
18994 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
18996 || func.name.eq_ignore_ascii_case("CUBE")
18997 || func.name.eq_ignore_ascii_case("ROLLUP");
18998 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
18999 if is_grouping_func {
19000 true
19001 } else {
19002 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
19004 for arg in &func.args {
19005 let mut temp_gen = Generator::with_arc_config(self.config.clone());
19006 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
19008 expr_strings.push(temp_gen.output);
19009 }
19010 self.too_wide(&expr_strings)
19011 }
19012 } else {
19013 false
19014 };
19015
19016 if should_split {
19017 self.write_newline();
19019 self.indent_level += 1;
19020 for (i, arg) in func.args.iter().enumerate() {
19021 self.write_indent();
19022 self.generate_expression(arg)?;
19023 if i + 1 < func.args.len() {
19024 self.write(",");
19025 }
19026 self.write_newline();
19027 }
19028 self.indent_level -= 1;
19029 self.write_indent();
19030 } else {
19031 for (i, arg) in func.args.iter().enumerate() {
19033 if i > 0 {
19034 self.write(", ");
19035 }
19036 self.generate_expression(arg)?;
19037 }
19038 }
19039
19040 if use_brackets {
19041 self.write("]");
19042 } else {
19043 self.write(")");
19044 }
19045 if has_ordinality {
19047 self.write_space();
19048 self.write_keyword("WITH ORDINALITY");
19049 }
19050 for comment in &func.trailing_comments {
19052 self.write_space();
19053 self.write_formatted_comment(comment);
19054 }
19055 Ok(())
19056 }
19057
19058 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
19059 self.generate_expression(&fe.this)?;
19060 self.write_keyword(" EMITS ");
19061 self.generate_expression(&fe.emits)?;
19062 Ok(())
19063 }
19064
19065 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
19066 let mut normalized_name = self.normalize_func_name(&func.name);
19068
19069 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
19071 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
19072 match self.config.dialect {
19073 Some(DialectType::ClickHouse) => {
19074 normalized_name = if is_max {
19075 Cow::Borrowed("argMax")
19076 } else {
19077 Cow::Borrowed("argMin")
19078 };
19079 }
19080 Some(DialectType::DuckDB) => {
19081 normalized_name = if is_max {
19082 Cow::Borrowed("ARG_MAX")
19083 } else {
19084 Cow::Borrowed("ARG_MIN")
19085 };
19086 }
19087 _ => {}
19088 }
19089 }
19090 self.write(normalized_name.as_ref());
19091 self.write("(");
19092 if func.distinct {
19093 self.write_keyword("DISTINCT");
19094 self.write_space();
19095 }
19096
19097 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
19101 let needs_multi_arg_transform =
19102 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
19103
19104 if needs_multi_arg_transform {
19105 self.write_keyword("CASE");
19107 for arg in &func.args {
19108 self.write_space();
19109 self.write_keyword("WHEN");
19110 self.write_space();
19111 self.generate_expression(arg)?;
19112 self.write_space();
19113 self.write_keyword("IS NULL THEN NULL");
19114 }
19115 self.write_space();
19116 self.write_keyword("ELSE");
19117 self.write(" (");
19118 for (i, arg) in func.args.iter().enumerate() {
19119 if i > 0 {
19120 self.write(", ");
19121 }
19122 self.generate_expression(arg)?;
19123 }
19124 self.write(")");
19125 self.write_space();
19126 self.write_keyword("END");
19127 } else {
19128 for (i, arg) in func.args.iter().enumerate() {
19129 if i > 0 {
19130 self.write(", ");
19131 }
19132 self.generate_expression(arg)?;
19133 }
19134 }
19135
19136 let clickhouse_ignore_nulls_outside =
19138 matches!(self.config.dialect, Some(DialectType::ClickHouse));
19139 if self.config.ignore_nulls_in_func
19140 && !matches!(
19141 self.config.dialect,
19142 Some(DialectType::DuckDB) | Some(DialectType::ClickHouse)
19143 )
19144 {
19145 if let Some(ignore) = func.ignore_nulls {
19146 self.write_space();
19147 if ignore {
19148 self.write_keyword("IGNORE NULLS");
19149 } else {
19150 self.write_keyword("RESPECT NULLS");
19151 }
19152 }
19153 }
19154
19155 if !func.order_by.is_empty() {
19157 self.write_space();
19158 self.write_keyword("ORDER BY");
19159 self.write_space();
19160 for (i, ord) in func.order_by.iter().enumerate() {
19161 if i > 0 {
19162 self.write(", ");
19163 }
19164 self.generate_ordered(ord)?;
19165 }
19166 }
19167
19168 if let Some(limit) = &func.limit {
19170 self.write_space();
19171 self.write_keyword("LIMIT");
19172 self.write_space();
19173 if let Expression::Tuple(t) = limit.as_ref() {
19175 if t.expressions.len() == 2 {
19176 self.generate_expression(&t.expressions[0])?;
19177 self.write(", ");
19178 self.generate_expression(&t.expressions[1])?;
19179 } else {
19180 self.generate_expression(limit)?;
19181 }
19182 } else {
19183 self.generate_expression(limit)?;
19184 }
19185 }
19186
19187 self.write(")");
19188
19189 if (!self.config.ignore_nulls_in_func || clickhouse_ignore_nulls_outside)
19191 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19192 {
19193 if let Some(ignore) = func.ignore_nulls {
19194 self.write_space();
19195 if ignore {
19196 self.write_keyword("IGNORE NULLS");
19197 } else {
19198 self.write_keyword("RESPECT NULLS");
19199 }
19200 }
19201 }
19202
19203 if let Some(filter) = &func.filter {
19204 self.write_space();
19205 self.write_keyword("FILTER");
19206 self.write("(");
19207 self.write_keyword("WHERE");
19208 self.write_space();
19209 self.generate_expression(filter)?;
19210 self.write(")");
19211 }
19212
19213 Ok(())
19214 }
19215
19216 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
19217 self.generate_expression(&wf.this)?;
19218
19219 if let Some(keep) = &wf.keep {
19221 self.write_space();
19222 self.write_keyword("KEEP");
19223 self.write(" (");
19224 self.write_keyword("DENSE_RANK");
19225 self.write_space();
19226 if keep.first {
19227 self.write_keyword("FIRST");
19228 } else {
19229 self.write_keyword("LAST");
19230 }
19231 self.write_space();
19232 self.write_keyword("ORDER BY");
19233 self.write_space();
19234 for (i, ord) in keep.order_by.iter().enumerate() {
19235 if i > 0 {
19236 self.write(", ");
19237 }
19238 self.generate_ordered(ord)?;
19239 }
19240 self.write(")");
19241 }
19242
19243 let has_over = !wf.over.partition_by.is_empty()
19245 || !wf.over.order_by.is_empty()
19246 || wf.over.frame.is_some()
19247 || wf.over.window_name.is_some();
19248
19249 if has_over {
19251 self.write_space();
19252 self.write_keyword("OVER");
19253
19254 let has_specs = !wf.over.partition_by.is_empty()
19256 || !wf.over.order_by.is_empty()
19257 || wf.over.frame.is_some();
19258
19259 if wf.over.window_name.is_some() && !has_specs {
19260 self.write_space();
19262 self.write(&wf.over.window_name.as_ref().unwrap().name);
19263 } else {
19264 self.write(" (");
19266 self.generate_over(&wf.over)?;
19267 self.write(")");
19268 }
19269 } else if wf.keep.is_none() {
19270 self.write_space();
19272 self.write_keyword("OVER");
19273 self.write(" ()");
19274 }
19275
19276 Ok(())
19277 }
19278
19279 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
19281 self.generate_expression(&wg.this)?;
19282 self.write_space();
19283 self.write_keyword("WITHIN GROUP");
19284 self.write(" (");
19285 self.write_keyword("ORDER BY");
19286 self.write_space();
19287 for (i, ord) in wg.order_by.iter().enumerate() {
19288 if i > 0 {
19289 self.write(", ");
19290 }
19291 self.generate_ordered(ord)?;
19292 }
19293 self.write(")");
19294 Ok(())
19295 }
19296
19297 fn generate_over(&mut self, over: &Over) -> Result<()> {
19299 let mut has_content = false;
19300
19301 if let Some(name) = &over.window_name {
19303 self.write(&name.name);
19304 has_content = true;
19305 }
19306
19307 if !over.partition_by.is_empty() {
19309 if has_content {
19310 self.write_space();
19311 }
19312 self.write_keyword("PARTITION BY");
19313 self.write_space();
19314 for (i, expr) in over.partition_by.iter().enumerate() {
19315 if i > 0 {
19316 self.write(", ");
19317 }
19318 self.generate_expression(expr)?;
19319 }
19320 has_content = true;
19321 }
19322
19323 if !over.order_by.is_empty() {
19325 if has_content {
19326 self.write_space();
19327 }
19328 self.write_keyword("ORDER BY");
19329 self.write_space();
19330 for (i, ordered) in over.order_by.iter().enumerate() {
19331 if i > 0 {
19332 self.write(", ");
19333 }
19334 self.generate_ordered(ordered)?;
19335 }
19336 has_content = true;
19337 }
19338
19339 if let Some(frame) = &over.frame {
19341 if has_content {
19342 self.write_space();
19343 }
19344 self.generate_window_frame(frame)?;
19345 }
19346
19347 Ok(())
19348 }
19349
19350 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
19351 let lowercase_frame = self.config.lowercase_window_frame_keywords;
19353
19354 if !lowercase_frame {
19356 if let Some(kind_text) = &frame.kind_text {
19357 self.write(kind_text);
19358 } else {
19359 match frame.kind {
19360 WindowFrameKind::Rows => self.write_keyword("ROWS"),
19361 WindowFrameKind::Range => self.write_keyword("RANGE"),
19362 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
19363 }
19364 }
19365 } else {
19366 match frame.kind {
19367 WindowFrameKind::Rows => self.write("rows"),
19368 WindowFrameKind::Range => self.write("range"),
19369 WindowFrameKind::Groups => self.write("groups"),
19370 }
19371 }
19372
19373 self.write_space();
19376 let should_normalize = self.config.normalize_window_frame_between
19377 && frame.end.is_none()
19378 && matches!(
19379 frame.start,
19380 WindowFrameBound::Preceding(_)
19381 | WindowFrameBound::Following(_)
19382 | WindowFrameBound::UnboundedPreceding
19383 | WindowFrameBound::UnboundedFollowing
19384 );
19385
19386 if let Some(end) = &frame.end {
19387 self.write_keyword("BETWEEN");
19389 self.write_space();
19390 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
19391 self.write_space();
19392 self.write_keyword("AND");
19393 self.write_space();
19394 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
19395 } else if should_normalize {
19396 self.write_keyword("BETWEEN");
19398 self.write_space();
19399 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
19400 self.write_space();
19401 self.write_keyword("AND");
19402 self.write_space();
19403 self.write_keyword("CURRENT ROW");
19404 } else {
19405 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
19407 }
19408
19409 if let Some(exclude) = &frame.exclude {
19411 self.write_space();
19412 self.write_keyword("EXCLUDE");
19413 self.write_space();
19414 match exclude {
19415 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
19416 WindowFrameExclude::Group => self.write_keyword("GROUP"),
19417 WindowFrameExclude::Ties => self.write_keyword("TIES"),
19418 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
19419 }
19420 }
19421
19422 Ok(())
19423 }
19424
19425 fn generate_window_frame_bound(
19426 &mut self,
19427 bound: &WindowFrameBound,
19428 side_text: Option<&str>,
19429 ) -> Result<()> {
19430 let lowercase_frame = self.config.lowercase_window_frame_keywords;
19432
19433 match bound {
19434 WindowFrameBound::CurrentRow => {
19435 self.write_keyword("CURRENT ROW");
19436 }
19437 WindowFrameBound::UnboundedPreceding => {
19438 self.write_keyword("UNBOUNDED");
19439 self.write_space();
19440 if lowercase_frame {
19441 self.write("preceding");
19442 } else if let Some(text) = side_text {
19443 self.write(text);
19444 } else {
19445 self.write_keyword("PRECEDING");
19446 }
19447 }
19448 WindowFrameBound::UnboundedFollowing => {
19449 self.write_keyword("UNBOUNDED");
19450 self.write_space();
19451 if lowercase_frame {
19452 self.write("following");
19453 } else if let Some(text) = side_text {
19454 self.write(text);
19455 } else {
19456 self.write_keyword("FOLLOWING");
19457 }
19458 }
19459 WindowFrameBound::Preceding(expr) => {
19460 self.generate_expression(expr)?;
19461 self.write_space();
19462 if lowercase_frame {
19463 self.write("preceding");
19464 } else if let Some(text) = side_text {
19465 self.write(text);
19466 } else {
19467 self.write_keyword("PRECEDING");
19468 }
19469 }
19470 WindowFrameBound::Following(expr) => {
19471 self.generate_expression(expr)?;
19472 self.write_space();
19473 if lowercase_frame {
19474 self.write("following");
19475 } else if let Some(text) = side_text {
19476 self.write(text);
19477 } else {
19478 self.write_keyword("FOLLOWING");
19479 }
19480 }
19481 WindowFrameBound::BarePreceding => {
19482 if lowercase_frame {
19483 self.write("preceding");
19484 } else if let Some(text) = side_text {
19485 self.write(text);
19486 } else {
19487 self.write_keyword("PRECEDING");
19488 }
19489 }
19490 WindowFrameBound::BareFollowing => {
19491 if lowercase_frame {
19492 self.write("following");
19493 } else if let Some(text) = side_text {
19494 self.write(text);
19495 } else {
19496 self.write_keyword("FOLLOWING");
19497 }
19498 }
19499 WindowFrameBound::Value(expr) => {
19500 self.generate_expression(expr)?;
19502 }
19503 }
19504 Ok(())
19505 }
19506
19507 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
19508 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
19511 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
19512 && !matches!(&interval.this, Some(Expression::Literal(_)));
19513
19514 if self.config.single_string_interval {
19517 if let (
19518 Some(Expression::Literal(lit)),
19519 Some(IntervalUnitSpec::Simple {
19520 ref unit,
19521 ref use_plural,
19522 }),
19523 ) = (&interval.this, &interval.unit)
19524 {
19525 if let Literal::String(ref val) = lit.as_ref() {
19526 self.write_keyword("INTERVAL");
19527 self.write_space();
19528 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
19529 let unit_str = self.interval_unit_str(unit, effective_plural);
19530 self.write("'");
19531 self.write(val);
19532 self.write(" ");
19533 self.write(&unit_str);
19534 self.write("'");
19535 return Ok(());
19536 }
19537 }
19538 }
19539
19540 if !skip_interval_keyword {
19541 self.write_keyword("INTERVAL");
19542 }
19543
19544 if let Some(ref value) = interval.this {
19546 if !skip_interval_keyword {
19547 self.write_space();
19548 }
19549 let needs_parens = interval.unit.is_some()
19553 && matches!(
19554 value,
19555 Expression::Add(_)
19556 | Expression::Sub(_)
19557 | Expression::Mul(_)
19558 | Expression::Div(_)
19559 | Expression::Mod(_)
19560 | Expression::BitwiseAnd(_)
19561 | Expression::BitwiseOr(_)
19562 | Expression::BitwiseXor(_)
19563 );
19564 if needs_parens {
19565 self.write("(");
19566 }
19567 self.generate_expression(value)?;
19568 if needs_parens {
19569 self.write(")");
19570 }
19571 }
19572
19573 if let Some(ref unit_spec) = interval.unit {
19575 self.write_space();
19576 self.write_interval_unit_spec(unit_spec)?;
19577 }
19578
19579 Ok(())
19580 }
19581
19582 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
19584 match (unit, use_plural) {
19585 (IntervalUnit::Year, false) => "YEAR",
19586 (IntervalUnit::Year, true) => "YEARS",
19587 (IntervalUnit::Quarter, false) => "QUARTER",
19588 (IntervalUnit::Quarter, true) => "QUARTERS",
19589 (IntervalUnit::Month, false) => "MONTH",
19590 (IntervalUnit::Month, true) => "MONTHS",
19591 (IntervalUnit::Week, false) => "WEEK",
19592 (IntervalUnit::Week, true) => "WEEKS",
19593 (IntervalUnit::Day, false) => "DAY",
19594 (IntervalUnit::Day, true) => "DAYS",
19595 (IntervalUnit::Hour, false) => "HOUR",
19596 (IntervalUnit::Hour, true) => "HOURS",
19597 (IntervalUnit::Minute, false) => "MINUTE",
19598 (IntervalUnit::Minute, true) => "MINUTES",
19599 (IntervalUnit::Second, false) => "SECOND",
19600 (IntervalUnit::Second, true) => "SECONDS",
19601 (IntervalUnit::Millisecond, false) => "MILLISECOND",
19602 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
19603 (IntervalUnit::Microsecond, false) => "MICROSECOND",
19604 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
19605 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
19606 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
19607 }
19608 }
19609
19610 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
19611 match unit_spec {
19612 IntervalUnitSpec::Simple { unit, use_plural } => {
19613 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
19615 self.write_simple_interval_unit(unit, effective_plural);
19616 }
19617 IntervalUnitSpec::Span(span) => {
19618 self.write_simple_interval_unit(&span.this, false);
19619 self.write_space();
19620 self.write_keyword("TO");
19621 self.write_space();
19622 self.write_simple_interval_unit(&span.expression, false);
19623 }
19624 IntervalUnitSpec::ExprSpan(span) => {
19625 self.generate_expression(&span.this)?;
19627 self.write_space();
19628 self.write_keyword("TO");
19629 self.write_space();
19630 self.generate_expression(&span.expression)?;
19631 }
19632 IntervalUnitSpec::Expr(expr) => {
19633 self.generate_expression(expr)?;
19634 }
19635 }
19636 Ok(())
19637 }
19638
19639 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
19640 match (unit, use_plural) {
19642 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
19643 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
19644 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
19645 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
19646 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
19647 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
19648 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
19649 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
19650 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
19651 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
19652 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
19653 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
19654 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
19655 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
19656 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
19657 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
19658 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
19659 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
19660 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
19661 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
19662 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
19663 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
19664 }
19665 }
19666
19667 fn write_redshift_date_part(&mut self, expr: &Expression) {
19670 let part_str = self.extract_date_part_string(expr);
19671 if let Some(part) = part_str {
19672 let normalized = self.normalize_date_part(&part);
19673 self.write_keyword(&normalized);
19674 } else {
19675 let _ = self.generate_expression(expr);
19677 }
19678 }
19679
19680 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
19683 let part_str = self.extract_date_part_string(expr);
19684 if let Some(part) = part_str {
19685 let normalized = self.normalize_date_part(&part);
19686 self.write("'");
19687 self.write(&normalized);
19688 self.write("'");
19689 } else {
19690 let _ = self.generate_expression(expr);
19692 }
19693 }
19694
19695 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
19697 match expr {
19698 Expression::Literal(lit)
19699 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
19700 {
19701 let crate::expressions::Literal::String(s) = lit.as_ref() else {
19702 unreachable!()
19703 };
19704 Some(s.clone())
19705 }
19706 Expression::Identifier(id) => Some(id.name.clone()),
19707 Expression::Var(v) => Some(v.this.clone()),
19708 Expression::Column(col) if col.table.is_none() => {
19709 Some(col.name.name.clone())
19711 }
19712 Expression::Cast(cast)
19713 if cast.format.is_none()
19714 && cast.default.is_none()
19715 && Self::is_string_data_type(&cast.to)
19716 && matches!(
19717 &cast.this,
19718 Expression::Literal(lit)
19719 if matches!(lit.as_ref(), crate::expressions::Literal::String(_))
19720 ) =>
19721 {
19722 self.extract_date_part_string(&cast.this)
19723 }
19724 _ => None,
19725 }
19726 }
19727
19728 fn classify_tsql_datetime_field(&self, field: &DateTimeField) -> TsqlDatePart {
19729 match field {
19730 DateTimeField::Year => TsqlDatePart::Native("YEAR".to_string()),
19731 DateTimeField::Month => TsqlDatePart::Native("MONTH".to_string()),
19732 DateTimeField::Day => TsqlDatePart::Native("DAY".to_string()),
19733 DateTimeField::Hour => TsqlDatePart::Native("HOUR".to_string()),
19734 DateTimeField::Minute => TsqlDatePart::Native("MINUTE".to_string()),
19735 DateTimeField::Second => TsqlDatePart::Native("SECOND".to_string()),
19736 DateTimeField::Millisecond => TsqlDatePart::Native("MILLISECOND".to_string()),
19737 DateTimeField::Microsecond => TsqlDatePart::Native("MICROSECOND".to_string()),
19738 DateTimeField::DayOfWeek => TsqlDatePart::Native("WEEKDAY".to_string()),
19739 DateTimeField::DayOfYear => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19740 DateTimeField::Week => TsqlDatePart::Native("WEEK".to_string()),
19741 DateTimeField::WeekWithModifier(modifier) => {
19742 TsqlDatePart::Unsupported(format!("WEEK({modifier})"))
19743 }
19744 DateTimeField::Quarter => TsqlDatePart::Native("QUARTER".to_string()),
19745 DateTimeField::Epoch => TsqlDatePart::Epoch,
19746 DateTimeField::TimezoneMinute => TsqlDatePart::Native("TZOFFSET".to_string()),
19747 DateTimeField::Timezone => TsqlDatePart::Unsupported("TIMEZONE".to_string()),
19748 DateTimeField::TimezoneHour => TsqlDatePart::Unsupported("TIMEZONE_HOUR".to_string()),
19749 DateTimeField::Date => TsqlDatePart::Unsupported("DATE".to_string()),
19750 DateTimeField::Time => TsqlDatePart::Unsupported("TIME".to_string()),
19751 DateTimeField::Custom(name) => self.classify_tsql_date_part_name(name),
19752 }
19753 }
19754
19755 fn classify_tsql_date_part_name(&self, part: &str) -> TsqlDatePart {
19756 let trimmed = part.trim();
19757 let upper = trimmed.to_ascii_uppercase();
19758 match upper.as_str() {
19759 "YEAR" => TsqlDatePart::Native(trimmed.to_string()),
19760 "YY" | "YYY" | "YYYY" | "YR" | "YEARS" | "YRS" => {
19761 TsqlDatePart::Native("YEAR".to_string())
19762 }
19763 "QUARTER" => TsqlDatePart::Native(trimmed.to_string()),
19764 "Q" | "QQ" | "QTR" | "QTRS" | "QUARTERS" => TsqlDatePart::Native("QUARTER".to_string()),
19765 "MONTH" => TsqlDatePart::Native(trimmed.to_string()),
19766 "MM" | "M" | "MON" | "MONS" | "MONTHS" => TsqlDatePart::Native("MONTH".to_string()),
19767 "DAYOFYEAR" => TsqlDatePart::Native(trimmed.to_string()),
19768 "DOY" | "DY" | "Y" => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19769 "DAY" => TsqlDatePart::Native(trimmed.to_string()),
19770 "D" | "DD" | "DAYS" | "DAYOFMONTH" => TsqlDatePart::Native("DAY".to_string()),
19771 "WEEK" | "W" | "WK" | "WW" | "WEEKOFYEAR" | "WOY" | "WY" | "WEEKS" => {
19772 if upper == "WEEK" {
19773 TsqlDatePart::Native(trimmed.to_string())
19774 } else {
19775 TsqlDatePart::Native("WEEK".to_string())
19776 }
19777 }
19778 "WEEKDAY" => TsqlDatePart::Native(trimmed.to_string()),
19779 "DAYOFWEEK" | "DOW" | "DW" => TsqlDatePart::Native("WEEKDAY".to_string()),
19780 "ISODOW" | "ISO_DOW" | "DOW_ISO" | "DW_ISO" | "ISO_DAYOFWEEK" | "ISO_WEEKDAY"
19781 | "DAYOFWEEKISO" | "DAYOFWEEK_ISO" | "WEEKDAY_ISO" => TsqlDatePart::IsoDayOfWeek,
19782 "HOUR" => TsqlDatePart::Native(trimmed.to_string()),
19783 "H" | "HH" | "HR" | "HOURS" | "HRS" => TsqlDatePart::Native("HOUR".to_string()),
19784 "MINUTE" => TsqlDatePart::Native(trimmed.to_string()),
19785 "MI" | "MIN" | "MINUTES" | "MINS" | "N" => TsqlDatePart::Native("MINUTE".to_string()),
19786 "SECOND" => TsqlDatePart::Native(trimmed.to_string()),
19787 "S" | "SEC" | "SECONDS" | "SECS" | "SS" => TsqlDatePart::Native("SECOND".to_string()),
19788 "MILLISECOND" | "MS" | "MSEC" | "MSECS" | "MSECOND" | "MSECONDS" | "MILLISEC"
19789 | "MILLISECS" | "MILLISECON" | "MILLISECONDS" => {
19790 if upper == "MILLISECOND" {
19791 TsqlDatePart::Native(trimmed.to_string())
19792 } else {
19793 TsqlDatePart::Native("MILLISECOND".to_string())
19794 }
19795 }
19796 "MICROSECOND" | "US" | "USEC" | "USECS" | "MICROSEC" | "MICROSECS" | "USECOND"
19797 | "USECONDS" | "MICROSECONDS" | "MCS" => {
19798 if upper == "MICROSECOND" {
19799 TsqlDatePart::Native(trimmed.to_string())
19800 } else {
19801 TsqlDatePart::Native("MICROSECOND".to_string())
19802 }
19803 }
19804 "NANOSECOND" | "NS" | "NSEC" | "NANOSEC" | "NSECOND" | "NSECONDS" | "NANOSECS" => {
19805 if upper == "NANOSECOND" {
19806 TsqlDatePart::Native(trimmed.to_string())
19807 } else {
19808 TsqlDatePart::Native("NANOSECOND".to_string())
19809 }
19810 }
19811 "TZOFFSET" => TsqlDatePart::Native(trimmed.to_string()),
19812 "TZ" | "TZM" | "TIMEZONE_MINUTE" => TsqlDatePart::Native("TZOFFSET".to_string()),
19813 "ISO_WEEK" | "ISOWEEK" | "ISOWK" | "ISOWW" | "WEEKISO" | "WEEKOFYEARISO"
19814 | "WEEKOFYEAR_ISO" | "WEEK_ISO" => {
19815 if upper == "ISO_WEEK" {
19816 TsqlDatePart::Native(trimmed.to_string())
19817 } else {
19818 TsqlDatePart::Native("ISO_WEEK".to_string())
19819 }
19820 }
19821 "EPOCH" | "EPOCH_SECOND" | "EPOCH_SECONDS" => TsqlDatePart::Epoch,
19822 "DECADE" | "DECADES" | "DEC" | "DECS" | "CENTURY" | "CENTURIES" | "CENT" | "CENTS"
19823 | "MILLENNIUM" | "MILLENIA" | "MIL" | "MILS" | "TIMEZONE" | "TIMEZONE_HOUR" | "TZH"
19824 | "DATE" | "TIME" => TsqlDatePart::Unsupported(upper),
19825 _ => TsqlDatePart::Unsupported(upper),
19826 }
19827 }
19828
19829 fn classify_tsql_date_trunc_field(&self, field: &DateTimeField) -> TsqlDatePart {
19830 match field {
19831 DateTimeField::Year => TsqlDatePart::Native("YEAR".to_string()),
19832 DateTimeField::Month => TsqlDatePart::Native("MONTH".to_string()),
19833 DateTimeField::Day => TsqlDatePart::Native("DAY".to_string()),
19834 DateTimeField::Hour => TsqlDatePart::Native("HOUR".to_string()),
19835 DateTimeField::Minute => TsqlDatePart::Native("MINUTE".to_string()),
19836 DateTimeField::Second => TsqlDatePart::Native("SECOND".to_string()),
19837 DateTimeField::Millisecond => TsqlDatePart::Native("MILLISECOND".to_string()),
19838 DateTimeField::Microsecond => TsqlDatePart::Native("MICROSECOND".to_string()),
19839 DateTimeField::DayOfYear => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19840 DateTimeField::Week => TsqlDatePart::Native("WEEK".to_string()),
19841 DateTimeField::WeekWithModifier(modifier) => {
19842 match modifier.to_ascii_uppercase().as_str() {
19843 "MONDAY" | "ISO" | "ISO_WEEK" => TsqlDatePart::Native("ISO_WEEK".to_string()),
19844 "SUNDAY" => TsqlDatePart::Native("WEEK".to_string()),
19845 _ => TsqlDatePart::Unsupported(format!("WEEK({modifier})")),
19846 }
19847 }
19848 DateTimeField::Quarter => TsqlDatePart::Native("QUARTER".to_string()),
19849 DateTimeField::DayOfWeek => TsqlDatePart::Unsupported("WEEKDAY".to_string()),
19850 DateTimeField::Epoch => TsqlDatePart::Unsupported("EPOCH".to_string()),
19851 DateTimeField::Timezone => TsqlDatePart::Unsupported("TIMEZONE".to_string()),
19852 DateTimeField::TimezoneHour => TsqlDatePart::Unsupported("TIMEZONE_HOUR".to_string()),
19853 DateTimeField::TimezoneMinute => {
19854 TsqlDatePart::Unsupported("TIMEZONE_MINUTE".to_string())
19855 }
19856 DateTimeField::Date => TsqlDatePart::Unsupported("DATE".to_string()),
19857 DateTimeField::Time => TsqlDatePart::Unsupported("TIME".to_string()),
19858 DateTimeField::Custom(name) => self.classify_tsql_date_trunc_name(name),
19859 }
19860 }
19861
19862 fn classify_tsql_date_trunc_name(&self, part: &str) -> TsqlDatePart {
19863 let upper = part.trim().to_ascii_uppercase();
19864 match upper.as_str() {
19865 "YEAR" | "YY" | "YYY" | "YYYY" | "YR" | "YEARS" | "YRS" => {
19866 TsqlDatePart::Native("YEAR".to_string())
19867 }
19868 "QUARTER" | "Q" | "QQ" | "QTR" | "QTRS" | "QUARTERS" => {
19869 TsqlDatePart::Native("QUARTER".to_string())
19870 }
19871 "MONTH" | "MM" | "M" | "MON" | "MONS" | "MONTHS" => {
19872 TsqlDatePart::Native("MONTH".to_string())
19873 }
19874 "DAYOFYEAR" | "DOY" | "DY" | "Y" => TsqlDatePart::Native("DAYOFYEAR".to_string()),
19875 "DAY" | "D" | "DD" | "DAYS" | "DAYOFMONTH" => TsqlDatePart::Native("DAY".to_string()),
19876 "WEEK" | "W" | "WK" | "WW" | "WEEKS" | "WEEKOFYEAR" | "WOY" | "WY" => {
19877 TsqlDatePart::Native("WEEK".to_string())
19878 }
19879 "ISO_WEEK" | "ISOWEEK" | "ISOWK" | "ISOWW" | "WEEKISO" | "WEEKOFYEARISO"
19880 | "WEEKOFYEAR_ISO" | "WEEK_ISO" => TsqlDatePart::Native("ISO_WEEK".to_string()),
19881 "HOUR" | "H" | "HH" | "HR" | "HOURS" | "HRS" => {
19882 TsqlDatePart::Native("HOUR".to_string())
19883 }
19884 "MINUTE" | "MI" | "MIN" | "MINUTES" | "MINS" | "N" => {
19885 TsqlDatePart::Native("MINUTE".to_string())
19886 }
19887 "SECOND" | "S" | "SEC" | "SECONDS" | "SECS" | "SS" => {
19888 TsqlDatePart::Native("SECOND".to_string())
19889 }
19890 "MILLISECOND" | "MS" | "MSEC" | "MSECS" | "MSECOND" | "MSECONDS" | "MILLISEC"
19891 | "MILLISECS" | "MILLISECON" | "MILLISECONDS" => {
19892 TsqlDatePart::Native("MILLISECOND".to_string())
19893 }
19894 "MICROSECOND" | "US" | "USEC" | "USECS" | "MICROSEC" | "MICROSECS" | "USECOND"
19895 | "USECONDS" | "MICROSECONDS" | "MCS" => {
19896 TsqlDatePart::Native("MICROSECOND".to_string())
19897 }
19898 "WEEKDAY" | "DAYOFWEEK" | "DOW" | "DW" | "ISODOW" | "ISO_DOW" | "DOW_ISO"
19899 | "DW_ISO" | "ISO_DAYOFWEEK" | "ISO_WEEKDAY" | "DAYOFWEEKISO" | "DAYOFWEEK_ISO"
19900 | "WEEKDAY_ISO" | "NANOSECOND" | "NS" | "NSEC" | "NANOSEC" | "NSECOND" | "NSECONDS"
19901 | "NANOSECS" | "TZOFFSET" | "TZ" | "TZM" | "TIMEZONE" | "TIMEZONE_HOUR"
19902 | "TIMEZONE_MINUTE" | "TZH" | "EPOCH" | "EPOCH_SECOND" | "EPOCH_SECONDS" | "DECADE"
19903 | "DECADES" | "DEC" | "DECS" | "CENTURY" | "CENTURIES" | "CENT" | "CENTS"
19904 | "MILLENNIUM" | "MILLENIA" | "MIL" | "MILS" | "DATE" | "TIME" => {
19905 TsqlDatePart::Unsupported(upper)
19906 }
19907 _ => TsqlDatePart::Unsupported(upper),
19908 }
19909 }
19910
19911 fn generate_tsql_date_part(&mut self, part: TsqlDatePart, expr: &Expression) -> Result<()> {
19912 match part {
19913 TsqlDatePart::Native(name) => self.generate_tsql_native_datepart(&name, expr),
19914 TsqlDatePart::Epoch => self.generate_tsql_epoch_seconds(expr),
19915 TsqlDatePart::IsoDayOfWeek => self.generate_tsql_iso_day_of_week(expr),
19916 TsqlDatePart::Unsupported(name) => {
19917 self.unsupported(format!("DATEPART {name} is not supported by T-SQL/Fabric"))?;
19918 self.write_keyword("DATEPART");
19919 self.write("(");
19920 self.write_keyword(&name);
19921 self.write(", ");
19922 self.generate_expression(expr)?;
19923 self.write(")");
19924 Ok(())
19925 }
19926 }
19927 }
19928
19929 fn generate_tsql_native_datepart(&mut self, name: &str, expr: &Expression) -> Result<()> {
19930 self.write_keyword("DATEPART");
19931 self.write("(");
19932 self.write_keyword(name);
19933 self.write(", ");
19934 self.generate_expression(expr)?;
19935 self.write(")");
19936 Ok(())
19937 }
19938
19939 fn generate_tsql_epoch_seconds(&mut self, expr: &Expression) -> Result<()> {
19940 self.write_keyword("DATEDIFF");
19941 self.write("(SECOND, ");
19942 self.write_keyword("CAST");
19943 self.write("('1970-01-01' AS ");
19944 self.write_keyword("DATETIME2");
19945 self.write("), ");
19946 self.generate_expression(expr)?;
19947 self.write(")");
19948 Ok(())
19949 }
19950
19951 fn generate_tsql_iso_day_of_week(&mut self, expr: &Expression) -> Result<()> {
19952 self.write("(((DATEPART(WEEKDAY, ");
19953 self.generate_expression(expr)?;
19954 self.write(") + @@DATEFIRST - 2) % 7) + 1)");
19955 Ok(())
19956 }
19957
19958 fn generate_tsql_date_trunc(&mut self, part: TsqlDatePart, expr: &Expression) -> Result<()> {
19959 match part {
19960 TsqlDatePart::Native(name) => {
19961 self.write_keyword("DATETRUNC");
19962 self.write("(");
19963 self.write_keyword(&name);
19964 self.write(", ");
19965 self.generate_expression(expr)?;
19966 self.write(")");
19967 Ok(())
19968 }
19969 TsqlDatePart::Epoch => {
19970 self.generate_tsql_unsupported_date_trunc("EPOCH".to_string(), expr)
19971 }
19972 TsqlDatePart::IsoDayOfWeek => {
19973 self.generate_tsql_unsupported_date_trunc("ISODOW".to_string(), expr)
19974 }
19975 TsqlDatePart::Unsupported(name) => {
19976 self.generate_tsql_unsupported_date_trunc(name, expr)
19977 }
19978 }
19979 }
19980
19981 fn generate_tsql_unsupported_date_trunc(
19982 &mut self,
19983 name: String,
19984 expr: &Expression,
19985 ) -> Result<()> {
19986 self.unsupported(format!("DATETRUNC {name} is not supported by T-SQL/Fabric"))?;
19987 self.write_keyword("DATETRUNC");
19988 self.write("(");
19989 self.write_keyword(&name);
19990 self.write(", ");
19991 self.generate_expression(expr)?;
19992 self.write(")");
19993 Ok(())
19994 }
19995
19996 fn normalize_date_part(&self, part: &str) -> String {
19999 let mut buf = [0u8; 64];
20000 let lower: &str = if part.len() <= 64 {
20001 for (i, b) in part.bytes().enumerate() {
20002 buf[i] = b.to_ascii_lowercase();
20003 }
20004 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
20005 } else {
20006 return part.to_ascii_uppercase();
20007 };
20008 match lower {
20009 "day" | "days" | "d" => "DAY".to_string(),
20010 "month" | "months" | "mon" | "mons" | "mm" => "MONTH".to_string(),
20011 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
20012 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
20013 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
20014 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
20015 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
20016 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
20017 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
20018 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
20019 _ => part.to_ascii_uppercase(),
20020 }
20021 }
20022
20023 fn write_datetime_field(&mut self, field: &DateTimeField) {
20024 match field {
20025 DateTimeField::Year => self.write_keyword("YEAR"),
20026 DateTimeField::Month => self.write_keyword("MONTH"),
20027 DateTimeField::Day => self.write_keyword("DAY"),
20028 DateTimeField::Hour => self.write_keyword("HOUR"),
20029 DateTimeField::Minute => self.write_keyword("MINUTE"),
20030 DateTimeField::Second => self.write_keyword("SECOND"),
20031 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
20032 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
20033 DateTimeField::DayOfWeek => {
20034 let name = match self.config.dialect {
20035 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
20036 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
20037 _ => "DOW",
20038 };
20039 self.write_keyword(name);
20040 }
20041 DateTimeField::DayOfYear => {
20042 let name = match self.config.dialect {
20043 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
20044 _ => "DOY",
20045 };
20046 self.write_keyword(name);
20047 }
20048 DateTimeField::Week => self.write_keyword("WEEK"),
20049 DateTimeField::WeekWithModifier(modifier) => {
20050 self.write_keyword("WEEK");
20051 self.write("(");
20052 self.write(modifier);
20053 self.write(")");
20054 }
20055 DateTimeField::Quarter => self.write_keyword("QUARTER"),
20056 DateTimeField::Epoch => self.write_keyword("EPOCH"),
20057 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
20058 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
20059 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
20060 DateTimeField::Date => self.write_keyword("DATE"),
20061 DateTimeField::Time => self.write_keyword("TIME"),
20062 DateTimeField::Custom(name) => self.write(name),
20063 }
20064 }
20065
20066 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
20068 match field {
20069 DateTimeField::Year => self.write("year"),
20070 DateTimeField::Month => self.write("month"),
20071 DateTimeField::Day => self.write("day"),
20072 DateTimeField::Hour => self.write("hour"),
20073 DateTimeField::Minute => self.write("minute"),
20074 DateTimeField::Second => self.write("second"),
20075 DateTimeField::Millisecond => self.write("millisecond"),
20076 DateTimeField::Microsecond => self.write("microsecond"),
20077 DateTimeField::DayOfWeek => self.write("dow"),
20078 DateTimeField::DayOfYear => self.write("doy"),
20079 DateTimeField::Week => self.write("week"),
20080 DateTimeField::WeekWithModifier(modifier) => {
20081 self.write("week(");
20082 self.write(modifier);
20083 self.write(")");
20084 }
20085 DateTimeField::Quarter => self.write("quarter"),
20086 DateTimeField::Epoch => self.write("epoch"),
20087 DateTimeField::Timezone => self.write("timezone"),
20088 DateTimeField::TimezoneHour => self.write("timezone_hour"),
20089 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
20090 DateTimeField::Date => self.write("date"),
20091 DateTimeField::Time => self.write("time"),
20092 DateTimeField::Custom(name) => self.write(name),
20093 }
20094 }
20095
20096 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
20099 self.write_keyword(name);
20100 self.write("(");
20101 self.generate_expression(arg)?;
20102 self.write(")");
20103 Ok(())
20104 }
20105
20106 fn generate_unary_func(
20108 &mut self,
20109 default_name: &str,
20110 f: &crate::expressions::UnaryFunc,
20111 ) -> Result<()> {
20112 let name = f.original_name.as_deref().unwrap_or(default_name);
20113 self.write_keyword(name);
20114 self.write("(");
20115 self.generate_expression(&f.this)?;
20116 self.write(")");
20117 Ok(())
20118 }
20119
20120 fn generate_sqrt_cbrt(
20122 &mut self,
20123 f: &crate::expressions::UnaryFunc,
20124 func_name: &str,
20125 _op: &str,
20126 ) -> Result<()> {
20127 self.write_keyword(func_name);
20130 self.write("(");
20131 self.generate_expression(&f.this)?;
20132 self.write(")");
20133 Ok(())
20134 }
20135
20136 fn generate_binary_func(
20137 &mut self,
20138 name: &str,
20139 arg1: &Expression,
20140 arg2: &Expression,
20141 ) -> Result<()> {
20142 self.write_keyword(name);
20143 self.write("(");
20144 self.generate_expression(arg1)?;
20145 self.write(", ");
20146 self.generate_expression(arg2)?;
20147 self.write(")");
20148 Ok(())
20149 }
20150
20151 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
20155 let func_name = f.name.as_deref().unwrap_or("CHAR");
20157 self.write_keyword(func_name);
20158 self.write("(");
20159 for (i, arg) in f.args.iter().enumerate() {
20160 if i > 0 {
20161 self.write(", ");
20162 }
20163 self.generate_expression(arg)?;
20164 }
20165 if let Some(ref charset) = f.charset {
20166 self.write(" ");
20167 self.write_keyword("USING");
20168 self.write(" ");
20169 self.write(charset);
20170 }
20171 self.write(")");
20172 Ok(())
20173 }
20174
20175 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
20176 use crate::dialects::DialectType;
20177
20178 match self.config.dialect {
20179 Some(DialectType::Teradata) => {
20180 self.generate_expression(&f.this)?;
20182 self.write(" ** ");
20183 self.generate_expression(&f.expression)?;
20184 Ok(())
20185 }
20186 _ => {
20187 self.generate_binary_func("POWER", &f.this, &f.expression)
20189 }
20190 }
20191 }
20192
20193 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
20194 self.write_func_name(name);
20195 self.write("(");
20196 for (i, arg) in args.iter().enumerate() {
20197 if i > 0 {
20198 self.write(", ");
20199 }
20200 self.generate_expression(arg)?;
20201 }
20202 self.write(")");
20203 Ok(())
20204 }
20205
20206 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
20209 self.write_keyword("CONCAT_WS");
20210 self.write("(");
20211 self.generate_expression(&f.separator)?;
20212 for expr in &f.expressions {
20213 self.write(", ");
20214 self.generate_expression(expr)?;
20215 }
20216 self.write(")");
20217 Ok(())
20218 }
20219
20220 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
20221 if let Expression::Concat(op) = expr {
20222 Self::collect_concat_operands(&op.left, out);
20223 Self::collect_concat_operands(&op.right, out);
20224 } else {
20225 out.push(expr);
20226 }
20227 }
20228
20229 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
20230 let mut operands = Vec::new();
20231 Self::collect_concat_operands(&op.left, &mut operands);
20232 Self::collect_concat_operands(&op.right, &mut operands);
20233
20234 self.write_keyword("CONCAT");
20235 self.write("(");
20236 for (i, operand) in operands.iter().enumerate() {
20237 if i > 0 {
20238 self.write(", ");
20239 }
20240 self.generate_expression(operand)?;
20241 }
20242 self.write(")");
20243 Ok(())
20244 }
20245
20246 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
20247 if let Expression::DPipe(dpipe) = expr {
20248 Self::collect_dpipe_operands(&dpipe.this, out);
20249 Self::collect_dpipe_operands(&dpipe.expression, out);
20250 } else {
20251 out.push(expr);
20252 }
20253 }
20254
20255 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
20256 let mut operands = Vec::new();
20257 Self::collect_dpipe_operands(&e.this, &mut operands);
20258 Self::collect_dpipe_operands(&e.expression, &mut operands);
20259
20260 self.write_keyword("CONCAT");
20261 self.write("(");
20262 for (i, operand) in operands.iter().enumerate() {
20263 if i > 0 {
20264 self.write(", ");
20265 }
20266 self.generate_expression(operand)?;
20267 }
20268 self.write(")");
20269 Ok(())
20270 }
20271
20272 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
20273 let use_substr = matches!(
20275 self.config.dialect,
20276 Some(
20277 DialectType::Oracle
20278 | DialectType::Presto
20279 | DialectType::Trino
20280 | DialectType::Athena
20281 )
20282 );
20283 if use_substr {
20284 self.write_keyword("SUBSTR");
20285 } else {
20286 self.write_keyword("SUBSTRING");
20287 }
20288 self.write("(");
20289 self.generate_expression(&f.this)?;
20290 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
20292 let use_comma_syntax = matches!(
20294 self.config.dialect,
20295 Some(DialectType::Spark)
20296 | Some(DialectType::Hive)
20297 | Some(DialectType::Databricks)
20298 | Some(DialectType::TSQL)
20299 | Some(DialectType::Fabric)
20300 );
20301 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
20302 self.write_space();
20304 self.write_keyword("FROM");
20305 self.write_space();
20306 self.generate_expression(&f.start)?;
20307 if let Some(length) = &f.length {
20308 self.write_space();
20309 self.write_keyword("FOR");
20310 self.write_space();
20311 self.generate_expression(length)?;
20312 }
20313 } else {
20314 self.write(", ");
20316 self.generate_expression(&f.start)?;
20317 if let Some(length) = &f.length {
20318 self.write(", ");
20319 self.generate_expression(length)?;
20320 }
20321 }
20322 self.write(")");
20323 Ok(())
20324 }
20325
20326 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
20327 self.write_keyword("OVERLAY");
20328 self.write("(");
20329 self.generate_expression(&f.this)?;
20330 self.write_space();
20331 self.write_keyword("PLACING");
20332 self.write_space();
20333 self.generate_expression(&f.replacement)?;
20334 self.write_space();
20335 self.write_keyword("FROM");
20336 self.write_space();
20337 self.generate_expression(&f.from)?;
20338 if let Some(length) = &f.length {
20339 self.write_space();
20340 self.write_keyword("FOR");
20341 self.write_space();
20342 self.generate_expression(length)?;
20343 }
20344 self.write(")");
20345 Ok(())
20346 }
20347
20348 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
20349 if f.position_explicit && f.characters.is_none() {
20352 match f.position {
20353 TrimPosition::Leading => {
20354 self.write_keyword("LTRIM");
20355 self.write("(");
20356 self.generate_expression(&f.this)?;
20357 self.write(")");
20358 return Ok(());
20359 }
20360 TrimPosition::Trailing => {
20361 self.write_keyword("RTRIM");
20362 self.write("(");
20363 self.generate_expression(&f.this)?;
20364 self.write(")");
20365 return Ok(());
20366 }
20367 TrimPosition::Both => {
20368 }
20371 }
20372 }
20373
20374 self.write_keyword("TRIM");
20375 self.write("(");
20376 let force_standard = f.characters.is_some()
20379 && !f.sql_standard_syntax
20380 && matches!(
20381 self.config.dialect,
20382 Some(DialectType::Hive)
20383 | Some(DialectType::Spark)
20384 | Some(DialectType::Databricks)
20385 | Some(DialectType::ClickHouse)
20386 );
20387 let use_standard = (f.sql_standard_syntax || force_standard)
20388 && !(f.position_explicit
20389 && f.characters.is_none()
20390 && matches!(f.position, TrimPosition::Both));
20391 if use_standard {
20392 if f.position_explicit {
20395 match f.position {
20396 TrimPosition::Both => self.write_keyword("BOTH"),
20397 TrimPosition::Leading => self.write_keyword("LEADING"),
20398 TrimPosition::Trailing => self.write_keyword("TRAILING"),
20399 }
20400 self.write_space();
20401 }
20402 if let Some(chars) = &f.characters {
20403 self.generate_expression(chars)?;
20404 self.write_space();
20405 }
20406 self.write_keyword("FROM");
20407 self.write_space();
20408 self.generate_expression(&f.this)?;
20409 } else {
20410 self.generate_expression(&f.this)?;
20412 if let Some(chars) = &f.characters {
20413 self.write(", ");
20414 self.generate_expression(chars)?;
20415 }
20416 }
20417 self.write(")");
20418 Ok(())
20419 }
20420
20421 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
20422 self.write_keyword("REPLACE");
20423 self.write("(");
20424 self.generate_expression(&f.this)?;
20425 self.write(", ");
20426 self.generate_expression(&f.old)?;
20427 self.write(", ");
20428 self.generate_expression(&f.new)?;
20429 self.write(")");
20430 Ok(())
20431 }
20432
20433 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
20434 self.write_keyword(name);
20435 self.write("(");
20436 self.generate_expression(&f.this)?;
20437 self.write(", ");
20438 self.generate_expression(&f.length)?;
20439 self.write(")");
20440 Ok(())
20441 }
20442
20443 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
20444 self.write_keyword("REPEAT");
20445 self.write("(");
20446 self.generate_expression(&f.this)?;
20447 self.write(", ");
20448 self.generate_expression(&f.times)?;
20449 self.write(")");
20450 Ok(())
20451 }
20452
20453 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
20454 self.write_keyword(name);
20455 self.write("(");
20456 self.generate_expression(&f.this)?;
20457 self.write(", ");
20458 self.generate_expression(&f.length)?;
20459 if let Some(fill) = &f.fill {
20460 self.write(", ");
20461 self.generate_expression(fill)?;
20462 }
20463 self.write(")");
20464 Ok(())
20465 }
20466
20467 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
20468 self.write_keyword("SPLIT");
20469 self.write("(");
20470 self.generate_expression(&f.this)?;
20471 self.write(", ");
20472 self.generate_expression(&f.delimiter)?;
20473 self.write(")");
20474 Ok(())
20475 }
20476
20477 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
20478 use crate::dialects::DialectType;
20479 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
20481 self.generate_expression(&f.this)?;
20482 self.write(" ~ ");
20483 self.generate_expression(&f.pattern)?;
20484 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && f.flags.is_none()
20485 {
20486 self.write("match(");
20488 self.generate_expression(&f.this)?;
20489 self.write(", ");
20490 self.generate_expression(&f.pattern)?;
20491 self.write(")");
20492 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
20493 self.generate_expression(&f.this)?;
20495 self.write_keyword(" REGEXP_LIKE ");
20496 self.generate_expression(&f.pattern)?;
20497 } else if matches!(
20498 self.config.dialect,
20499 Some(DialectType::SingleStore)
20500 | Some(DialectType::Spark)
20501 | Some(DialectType::Hive)
20502 | Some(DialectType::Databricks)
20503 ) && f.flags.is_none()
20504 {
20505 self.generate_expression(&f.this)?;
20507 self.write_keyword(" RLIKE ");
20508 self.generate_expression(&f.pattern)?;
20509 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
20510 self.write_keyword("REGEXP");
20512 self.write("(");
20513 self.generate_expression(&f.this)?;
20514 self.write(", ");
20515 self.generate_expression(&f.pattern)?;
20516 if let Some(flags) = &f.flags {
20517 self.write(", ");
20518 self.generate_expression(flags)?;
20519 }
20520 self.write(")");
20521 } else {
20522 self.write_keyword("REGEXP_LIKE");
20523 self.write("(");
20524 self.generate_expression(&f.this)?;
20525 self.write(", ");
20526 self.generate_expression(&f.pattern)?;
20527 if let Some(flags) = &f.flags {
20528 self.write(", ");
20529 self.generate_expression(flags)?;
20530 }
20531 self.write(")");
20532 }
20533 Ok(())
20534 }
20535
20536 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
20537 self.write_keyword("REGEXP_REPLACE");
20538 self.write("(");
20539 self.generate_expression(&f.this)?;
20540 self.write(", ");
20541 self.generate_expression(&f.pattern)?;
20542 self.write(", ");
20543 self.generate_expression(&f.replacement)?;
20544 if let Some(flags) = &f.flags {
20545 self.write(", ");
20546 self.generate_expression(flags)?;
20547 }
20548 self.write(")");
20549 Ok(())
20550 }
20551
20552 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
20553 self.write_keyword("REGEXP_EXTRACT");
20554 self.write("(");
20555 self.generate_expression(&f.this)?;
20556 self.write(", ");
20557 self.generate_expression(&f.pattern)?;
20558 if let Some(group) = &f.group {
20559 self.write(", ");
20560 self.generate_expression(group)?;
20561 }
20562 self.write(")");
20563 Ok(())
20564 }
20565
20566 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
20569 self.write_keyword("ROUND");
20570 self.write("(");
20571 self.generate_expression(&f.this)?;
20572 if let Some(decimals) = &f.decimals {
20573 self.write(", ");
20574 self.generate_expression(decimals)?;
20575 }
20576 self.write(")");
20577 Ok(())
20578 }
20579
20580 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
20581 self.write_keyword("FLOOR");
20582 self.write("(");
20583 self.generate_expression(&f.this)?;
20584 if let Some(to) = &f.to {
20586 self.write(" ");
20587 self.write_keyword("TO");
20588 self.write(" ");
20589 self.generate_expression(to)?;
20590 } else if let Some(scale) = &f.scale {
20591 self.write(", ");
20592 self.generate_expression(scale)?;
20593 }
20594 self.write(")");
20595 Ok(())
20596 }
20597
20598 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
20599 self.write_keyword("CEIL");
20600 self.write("(");
20601 self.generate_expression(&f.this)?;
20602 if let Some(to) = &f.to {
20604 self.write(" ");
20605 self.write_keyword("TO");
20606 self.write(" ");
20607 self.generate_expression(to)?;
20608 } else if let Some(decimals) = &f.decimals {
20609 self.write(", ");
20610 self.generate_expression(decimals)?;
20611 }
20612 self.write(")");
20613 Ok(())
20614 }
20615
20616 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
20617 use crate::expressions::Literal;
20618
20619 if let Some(base) = &f.base {
20620 if self.is_log_base_none() {
20623 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
20624 {
20625 self.write_func_name("LOG2");
20626 self.write("(");
20627 self.generate_expression(&f.this)?;
20628 self.write(")");
20629 return Ok(());
20630 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
20631 {
20632 self.write_func_name("LOG10");
20633 self.write("(");
20634 self.generate_expression(&f.this)?;
20635 self.write(")");
20636 return Ok(());
20637 }
20638 }
20640
20641 self.write_func_name("LOG");
20642 self.write("(");
20643 if self.is_log_value_first() {
20644 self.generate_expression(&f.this)?;
20646 self.write(", ");
20647 self.generate_expression(base)?;
20648 } else {
20649 self.generate_expression(base)?;
20651 self.write(", ");
20652 self.generate_expression(&f.this)?;
20653 }
20654 self.write(")");
20655 } else {
20656 self.write_func_name("LOG");
20658 self.write("(");
20659 self.generate_expression(&f.this)?;
20660 self.write(")");
20661 }
20662 Ok(())
20663 }
20664
20665 fn is_log_value_first(&self) -> bool {
20668 use crate::dialects::DialectType;
20669 matches!(
20670 self.config.dialect,
20671 Some(DialectType::BigQuery)
20672 | Some(DialectType::TSQL)
20673 | Some(DialectType::Tableau)
20674 | Some(DialectType::Fabric)
20675 )
20676 }
20677
20678 fn is_log_base_none(&self) -> bool {
20681 use crate::dialects::DialectType;
20682 matches!(
20683 self.config.dialect,
20684 Some(DialectType::Presto)
20685 | Some(DialectType::Trino)
20686 | Some(DialectType::ClickHouse)
20687 | Some(DialectType::Athena)
20688 )
20689 }
20690
20691 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
20694 self.write_keyword("CURRENT_TIME");
20695 if let Some(precision) = f.precision {
20696 self.write(&format!("({})", precision));
20697 } else if matches!(
20698 self.config.dialect,
20699 Some(crate::dialects::DialectType::MySQL)
20700 | Some(crate::dialects::DialectType::SingleStore)
20701 | Some(crate::dialects::DialectType::TiDB)
20702 ) {
20703 self.write("()");
20704 }
20705 Ok(())
20706 }
20707
20708 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
20709 use crate::dialects::DialectType;
20710
20711 if f.sysdate {
20713 match self.config.dialect {
20714 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
20715 self.write_keyword("SYSDATE");
20716 return Ok(());
20717 }
20718 Some(DialectType::Snowflake) => {
20719 self.write_keyword("SYSDATE");
20721 self.write("()");
20722 return Ok(());
20723 }
20724 _ => {
20725 }
20727 }
20728 }
20729
20730 self.write_keyword("CURRENT_TIMESTAMP");
20731 if let Some(precision) = f.precision {
20733 self.write(&format!("({})", precision));
20734 } else if matches!(
20735 self.config.dialect,
20736 Some(crate::dialects::DialectType::MySQL)
20737 | Some(crate::dialects::DialectType::SingleStore)
20738 | Some(crate::dialects::DialectType::TiDB)
20739 | Some(crate::dialects::DialectType::Spark)
20740 | Some(crate::dialects::DialectType::Hive)
20741 | Some(crate::dialects::DialectType::Databricks)
20742 | Some(crate::dialects::DialectType::ClickHouse)
20743 | Some(crate::dialects::DialectType::BigQuery)
20744 | Some(crate::dialects::DialectType::Snowflake)
20745 | Some(crate::dialects::DialectType::Exasol)
20746 ) {
20747 self.write("()");
20748 }
20749 Ok(())
20750 }
20751
20752 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
20753 if self.config.dialect == Some(DialectType::Exasol) {
20755 self.write_keyword("CONVERT_TZ");
20756 self.write("(");
20757 self.generate_expression(&f.this)?;
20758 self.write(", 'UTC', ");
20759 self.generate_expression(&f.zone)?;
20760 self.write(")");
20761 return Ok(());
20762 }
20763
20764 self.generate_expression(&f.this)?;
20765 self.write_space();
20766 self.write_keyword("AT TIME ZONE");
20767 self.write_space();
20768 self.generate_expression(&f.zone)?;
20769 Ok(())
20770 }
20771
20772 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
20773 use crate::dialects::DialectType;
20774
20775 let is_presto_like = matches!(
20778 self.config.dialect,
20779 Some(DialectType::Presto) | Some(DialectType::Trino)
20780 );
20781
20782 if is_presto_like {
20783 self.write_keyword(name);
20784 self.write("(");
20785 self.write("'");
20787 self.write_simple_interval_unit(&f.unit, false);
20788 self.write("'");
20789 self.write(", ");
20790 let needs_cast = !self.returns_integer_type(&f.interval);
20792 if needs_cast {
20793 self.write_keyword("CAST");
20794 self.write("(");
20795 }
20796 self.generate_expression(&f.interval)?;
20797 if needs_cast {
20798 self.write_space();
20799 self.write_keyword("AS");
20800 self.write_space();
20801 self.write_keyword("BIGINT");
20802 self.write(")");
20803 }
20804 self.write(", ");
20805 self.generate_expression(&f.this)?;
20806 self.write(")");
20807 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20808 self.generate_expression(&f.this)?;
20809 self.write_space();
20810 if name.eq_ignore_ascii_case("DATE_SUB") {
20811 self.write("-");
20812 } else {
20813 self.write("+");
20814 }
20815 self.write_space();
20816 self.write_keyword("INTERVAL");
20817 self.write_space();
20818 self.write("'");
20819 let mut interval_gen = Generator::with_arc_config(self.config.clone());
20820 let interval_sql = interval_gen.generate(&f.interval)?;
20821 self.write(&interval_sql);
20822 self.write(" ");
20823 self.write_simple_interval_unit(&f.unit, false);
20824 self.write("'");
20825 } else {
20826 self.write_keyword(name);
20827 self.write("(");
20828 self.generate_expression(&f.this)?;
20829 self.write(", ");
20830 self.write_keyword("INTERVAL");
20831 self.write_space();
20832 self.generate_expression(&f.interval)?;
20833 self.write_space();
20834 self.write_simple_interval_unit(&f.unit, false); self.write(")");
20836 }
20837 Ok(())
20838 }
20839
20840 fn returns_integer_type(&self, expr: &Expression) -> bool {
20843 use crate::expressions::{DataType, Literal};
20844 match expr {
20845 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
20847 let Literal::Number(n) = lit.as_ref() else {
20848 unreachable!()
20849 };
20850 !n.contains('.')
20851 }
20852
20853 Expression::Floor(f) => self.returns_integer_type(&f.this),
20855
20856 Expression::Round(f) => {
20858 f.decimals.is_none() && self.returns_integer_type(&f.this)
20860 }
20861
20862 Expression::Sign(f) => self.returns_integer_type(&f.this),
20864
20865 Expression::Abs(f) => self.returns_integer_type(&f.this),
20867
20868 Expression::Mul(op) => {
20870 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20871 }
20872 Expression::Add(op) => {
20873 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20874 }
20875 Expression::Sub(op) => {
20876 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
20877 }
20878 Expression::Mod(op) => self.returns_integer_type(&op.left),
20879
20880 Expression::Cast(c) => matches!(
20882 &c.to,
20883 DataType::BigInt { .. }
20884 | DataType::Int { .. }
20885 | DataType::SmallInt { .. }
20886 | DataType::TinyInt { .. }
20887 ),
20888
20889 Expression::Neg(op) => self.returns_integer_type(&op.this),
20891
20892 Expression::Paren(p) => self.returns_integer_type(&p.this),
20894
20895 _ => false,
20898 }
20899 }
20900
20901 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
20902 self.write_keyword("DATEDIFF");
20903 self.write("(");
20904 if let Some(unit) = &f.unit {
20905 self.write_simple_interval_unit(unit, false); self.write(", ");
20907 }
20908 if self.config.dialect == Some(DialectType::Snowflake) {
20909 self.generate_expression(&f.expression)?;
20910 self.write(", ");
20911 self.generate_expression(&f.this)?;
20912 } else {
20913 self.generate_expression(&f.this)?;
20914 self.write(", ");
20915 self.generate_expression(&f.expression)?;
20916 }
20917 self.write(")");
20918 Ok(())
20919 }
20920
20921 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
20922 if matches!(
20923 self.config.dialect,
20924 Some(DialectType::TSQL) | Some(DialectType::Fabric)
20925 ) {
20926 let date_part = self.classify_tsql_date_trunc_field(&f.unit);
20927 self.generate_tsql_date_trunc(date_part, &f.this)?;
20928 return Ok(());
20929 }
20930 if self.config.dialect == Some(DialectType::ClickHouse) {
20931 self.write("dateTrunc");
20932 } else {
20933 self.write_keyword("DATE_TRUNC");
20934 }
20935 self.write("('");
20936 self.write_datetime_field(&f.unit);
20937 self.write("', ");
20938 self.generate_expression(&f.this)?;
20939 self.write(")");
20940 Ok(())
20941 }
20942
20943 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
20944 use crate::dialects::DialectType;
20945 use crate::expressions::DateTimeField;
20946
20947 self.write_keyword("LAST_DAY");
20948 self.write("(");
20949 self.generate_expression(&f.this)?;
20950 if let Some(unit) = &f.unit {
20951 self.write(", ");
20952 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
20955 if let DateTimeField::WeekWithModifier(_) = unit {
20956 self.write_keyword("WEEK");
20957 } else {
20958 self.write_datetime_field(unit);
20959 }
20960 } else {
20961 self.write_datetime_field(unit);
20962 }
20963 }
20964 self.write(")");
20965 Ok(())
20966 }
20967
20968 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
20969 if matches!(
20971 self.config.dialect,
20972 Some(DialectType::TSQL) | Some(DialectType::Fabric)
20973 ) {
20974 let date_part = self.classify_tsql_datetime_field(&f.field);
20975 self.generate_tsql_date_part(date_part, &f.this)?;
20976 return Ok(());
20977 }
20978 self.write_keyword("EXTRACT");
20979 self.write("(");
20980 if matches!(
20982 self.config.dialect,
20983 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
20984 ) {
20985 self.write_datetime_field_lower(&f.field);
20986 } else {
20987 self.write_datetime_field(&f.field);
20988 }
20989 self.write_space();
20990 self.write_keyword("FROM");
20991 self.write_space();
20992 self.generate_expression(&f.this)?;
20993 self.write(")");
20994 Ok(())
20995 }
20996
20997 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
20998 self.write_keyword("TO_DATE");
20999 self.write("(");
21000 self.generate_expression(&f.this)?;
21001 if let Some(format) = &f.format {
21002 self.write(", ");
21003 self.generate_expression(format)?;
21004 }
21005 self.write(")");
21006 Ok(())
21007 }
21008
21009 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
21010 self.write_keyword("TO_TIMESTAMP");
21011 self.write("(");
21012 self.generate_expression(&f.this)?;
21013 if let Some(format) = &f.format {
21014 self.write(", ");
21015 self.generate_expression(format)?;
21016 }
21017 self.write(")");
21018 Ok(())
21019 }
21020
21021 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
21024 use crate::dialects::DialectType;
21025
21026 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
21028 self.write_keyword("CASE WHEN");
21029 self.write_space();
21030 self.generate_expression(&f.condition)?;
21031 self.write_space();
21032 self.write_keyword("THEN");
21033 self.write_space();
21034 self.generate_expression(&f.true_value)?;
21035 if let Some(false_val) = &f.false_value {
21036 self.write_space();
21037 self.write_keyword("ELSE");
21038 self.write_space();
21039 self.generate_expression(false_val)?;
21040 }
21041 self.write_space();
21042 self.write_keyword("END");
21043 return Ok(());
21044 }
21045
21046 if self.config.dialect == Some(DialectType::Exasol) {
21048 self.write_keyword("IF");
21049 self.write_space();
21050 self.generate_expression(&f.condition)?;
21051 self.write_space();
21052 self.write_keyword("THEN");
21053 self.write_space();
21054 self.generate_expression(&f.true_value)?;
21055 if let Some(false_val) = &f.false_value {
21056 self.write_space();
21057 self.write_keyword("ELSE");
21058 self.write_space();
21059 self.generate_expression(false_val)?;
21060 }
21061 self.write_space();
21062 self.write_keyword("ENDIF");
21063 return Ok(());
21064 }
21065
21066 let func_name = match self.config.dialect {
21068 Some(DialectType::ClickHouse) => f.original_name.as_deref().unwrap_or("IF"),
21069 Some(DialectType::Snowflake) => "IFF",
21070 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
21071 Some(DialectType::Drill) => "`IF`",
21072 _ => "IF",
21073 };
21074 self.write(func_name);
21075 self.write("(");
21076 self.generate_expression(&f.condition)?;
21077 self.write(", ");
21078 self.generate_expression(&f.true_value)?;
21079 if let Some(false_val) = &f.false_value {
21080 self.write(", ");
21081 self.generate_expression(false_val)?;
21082 }
21083 self.write(")");
21084 Ok(())
21085 }
21086
21087 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
21088 self.write_keyword("NVL2");
21089 self.write("(");
21090 self.generate_expression(&f.this)?;
21091 self.write(", ");
21092 self.generate_expression(&f.true_value)?;
21093 self.write(", ");
21094 self.generate_expression(&f.false_value)?;
21095 self.write(")");
21096 Ok(())
21097 }
21098
21099 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
21102 let count_name = match self.config.normalize_functions {
21104 NormalizeFunctions::Upper => "COUNT".to_string(),
21105 NormalizeFunctions::Lower => "count".to_string(),
21106 NormalizeFunctions::None => f
21107 .original_name
21108 .clone()
21109 .unwrap_or_else(|| "COUNT".to_string()),
21110 };
21111 self.write(&count_name);
21112 self.write("(");
21113 if f.distinct {
21114 self.write_keyword("DISTINCT");
21115 self.write_space();
21116 }
21117 if f.star {
21118 self.write("*");
21119 } else if let Some(ref expr) = f.this {
21120 if let Expression::Tuple(tuple) = expr {
21122 let needs_transform =
21126 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
21127
21128 if needs_transform {
21129 self.write_keyword("CASE");
21131 for e in &tuple.expressions {
21132 self.write_space();
21133 self.write_keyword("WHEN");
21134 self.write_space();
21135 self.generate_expression(e)?;
21136 self.write_space();
21137 self.write_keyword("IS NULL THEN NULL");
21138 }
21139 self.write_space();
21140 self.write_keyword("ELSE");
21141 self.write(" (");
21142 for (i, e) in tuple.expressions.iter().enumerate() {
21143 if i > 0 {
21144 self.write(", ");
21145 }
21146 self.generate_expression(e)?;
21147 }
21148 self.write(")");
21149 self.write_space();
21150 self.write_keyword("END");
21151 } else {
21152 for (i, e) in tuple.expressions.iter().enumerate() {
21153 if i > 0 {
21154 self.write(", ");
21155 }
21156 self.generate_expression(e)?;
21157 }
21158 }
21159 } else {
21160 self.generate_expression(expr)?;
21161 }
21162 }
21163 let clickhouse_ignore_nulls_outside =
21164 matches!(self.config.dialect, Some(DialectType::ClickHouse));
21165 if let Some(ignore) = f.ignore_nulls.filter(|_| !clickhouse_ignore_nulls_outside) {
21166 self.write_space();
21167 if ignore {
21168 self.write_keyword("IGNORE NULLS");
21169 } else {
21170 self.write_keyword("RESPECT NULLS");
21171 }
21172 }
21173 self.write(")");
21174 if let Some(ignore) = f.ignore_nulls.filter(|_| clickhouse_ignore_nulls_outside) {
21175 self.write_space();
21176 if ignore {
21177 self.write_keyword("IGNORE NULLS");
21178 } else {
21179 self.write_keyword("RESPECT NULLS");
21180 }
21181 }
21182 if let Some(ref filter) = f.filter {
21183 self.write_space();
21184 self.write_keyword("FILTER");
21185 self.write("(");
21186 self.write_keyword("WHERE");
21187 self.write_space();
21188 self.generate_expression(filter)?;
21189 self.write(")");
21190 }
21191 Ok(())
21192 }
21193
21194 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
21195 let func_name: Cow<'_, str> = match self.config.normalize_functions {
21197 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
21198 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
21199 NormalizeFunctions::None => {
21200 if let Some(ref original) = f.name {
21203 Cow::Owned(original.clone())
21204 } else {
21205 Cow::Owned(name.to_ascii_lowercase())
21206 }
21207 }
21208 };
21209 self.write(func_name.as_ref());
21210 self.write("(");
21211 if f.distinct {
21212 self.write_keyword("DISTINCT");
21213 self.write_space();
21214 }
21215 let is_zero_arg_mode =
21218 name.eq_ignore_ascii_case("MODE") && matches!(f.this, Expression::Null(_));
21219 if !is_zero_arg_mode {
21220 self.generate_expression(&f.this)?;
21221 }
21222 if self.config.ignore_nulls_in_func
21225 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
21226 {
21227 match f.ignore_nulls {
21228 Some(true) => {
21229 self.write_space();
21230 self.write_keyword("IGNORE NULLS");
21231 }
21232 Some(false) => {
21233 self.write_space();
21234 self.write_keyword("RESPECT NULLS");
21235 }
21236 None => {}
21237 }
21238 }
21239 if let Some((ref expr, is_max)) = f.having_max {
21242 self.write_space();
21243 self.write_keyword("HAVING");
21244 self.write_space();
21245 if is_max {
21246 self.write_keyword("MAX");
21247 } else {
21248 self.write_keyword("MIN");
21249 }
21250 self.write_space();
21251 self.generate_expression(expr)?;
21252 }
21253 if !f.order_by.is_empty() {
21255 self.write_space();
21256 self.write_keyword("ORDER BY");
21257 self.write_space();
21258 for (i, ord) in f.order_by.iter().enumerate() {
21259 if i > 0 {
21260 self.write(", ");
21261 }
21262 self.generate_ordered(ord)?;
21263 }
21264 }
21265 if let Some(ref limit) = f.limit {
21267 self.write_space();
21268 self.write_keyword("LIMIT");
21269 self.write_space();
21270 if let Expression::Tuple(t) = limit.as_ref() {
21272 if t.expressions.len() == 2 {
21273 self.generate_expression(&t.expressions[0])?;
21274 self.write(", ");
21275 self.generate_expression(&t.expressions[1])?;
21276 } else {
21277 self.generate_expression(limit)?;
21278 }
21279 } else {
21280 self.generate_expression(limit)?;
21281 }
21282 }
21283 self.write(")");
21284 if !self.config.ignore_nulls_in_func
21287 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
21288 {
21289 match f.ignore_nulls {
21290 Some(true) => {
21291 self.write_space();
21292 self.write_keyword("IGNORE NULLS");
21293 }
21294 Some(false) => {
21295 self.write_space();
21296 self.write_keyword("RESPECT NULLS");
21297 }
21298 None => {}
21299 }
21300 }
21301 if let Some(ref filter) = f.filter {
21302 self.write_space();
21303 self.write_keyword("FILTER");
21304 self.write("(");
21305 self.write_keyword("WHERE");
21306 self.write_space();
21307 self.generate_expression(filter)?;
21308 self.write(")");
21309 }
21310 Ok(())
21311 }
21312
21313 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
21316 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
21318 let func_name: Cow<'_, str> = match self.config.normalize_functions {
21320 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
21321 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
21322 NormalizeFunctions::None => {
21323 if let Some(ref original) = f.name {
21324 Cow::Owned(original.clone())
21325 } else {
21326 Cow::Owned(name.to_ascii_lowercase())
21327 }
21328 }
21329 };
21330 self.write(func_name.as_ref());
21331 self.write("(");
21332 if f.distinct {
21333 self.write_keyword("DISTINCT");
21334 self.write_space();
21335 }
21336 if !matches!(f.this, Expression::Null(_)) {
21337 self.generate_expression(&f.this)?;
21338 }
21339 self.write(", ");
21340 self.write_keyword("TRUE");
21341 self.write(")");
21342 return Ok(());
21343 }
21344 self.generate_agg_func(name, f)
21345 }
21346
21347 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
21348 self.write_keyword("GROUP_CONCAT");
21349 self.write("(");
21350 if f.distinct {
21351 self.write_keyword("DISTINCT");
21352 self.write_space();
21353 }
21354 self.generate_expression(&f.this)?;
21355 if let Some(ref order_by) = f.order_by {
21356 self.write_space();
21357 self.write_keyword("ORDER BY");
21358 self.write_space();
21359 for (i, ord) in order_by.iter().enumerate() {
21360 if i > 0 {
21361 self.write(", ");
21362 }
21363 self.generate_ordered(ord)?;
21364 }
21365 }
21366 if let Some(ref sep) = f.separator {
21367 if matches!(
21370 self.config.dialect,
21371 Some(crate::dialects::DialectType::SQLite)
21372 ) {
21373 self.write(", ");
21374 self.generate_expression(sep)?;
21375 } else {
21376 self.write_space();
21377 self.write_keyword("SEPARATOR");
21378 self.write_space();
21379 self.generate_expression(sep)?;
21380 }
21381 }
21382 if let Some(ref limit) = f.limit {
21383 self.write_space();
21384 self.write_keyword("LIMIT");
21385 self.write_space();
21386 self.generate_expression(limit)?;
21387 }
21388 self.write(")");
21389 if let Some(ref filter) = f.filter {
21390 self.write_space();
21391 self.write_keyword("FILTER");
21392 self.write("(");
21393 self.write_keyword("WHERE");
21394 self.write_space();
21395 self.generate_expression(filter)?;
21396 self.write(")");
21397 }
21398 Ok(())
21399 }
21400
21401 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
21402 let uses_within_group_order = matches!(
21403 self.config.dialect,
21404 Some(crate::dialects::DialectType::TSQL | crate::dialects::DialectType::Fabric)
21405 );
21406 self.write_keyword("STRING_AGG");
21407 self.write("(");
21408 if f.distinct {
21409 self.write_keyword("DISTINCT");
21410 self.write_space();
21411 }
21412 self.generate_expression(&f.this)?;
21413 if let Some(ref separator) = f.separator {
21414 self.write(", ");
21415 self.generate_string_agg_separator(separator)?;
21416 }
21417 if !uses_within_group_order {
21419 if let Some(ref order_by) = f.order_by {
21420 self.write_space();
21421 self.write_keyword("ORDER BY");
21422 self.write_space();
21423 for (i, ord) in order_by.iter().enumerate() {
21424 if i > 0 {
21425 self.write(", ");
21426 }
21427 self.generate_ordered(ord)?;
21428 }
21429 }
21430 }
21431 if let Some(ref limit) = f.limit {
21432 self.write_space();
21433 self.write_keyword("LIMIT");
21434 self.write_space();
21435 self.generate_expression(limit)?;
21436 }
21437 self.write(")");
21438 if uses_within_group_order {
21439 if let Some(ref order_by) = f.order_by {
21440 self.write_space();
21441 self.write_keyword("WITHIN GROUP");
21442 self.write(" (");
21443 self.write_keyword("ORDER BY");
21444 self.write_space();
21445 for (i, ord) in order_by.iter().enumerate() {
21446 if i > 0 {
21447 self.write(", ");
21448 }
21449 self.generate_ordered(ord)?;
21450 }
21451 self.write(")");
21452 }
21453 }
21454 if let Some(ref filter) = f.filter {
21455 self.write_space();
21456 self.write_keyword("FILTER");
21457 self.write("(");
21458 self.write_keyword("WHERE");
21459 self.write_space();
21460 self.generate_expression(filter)?;
21461 self.write(")");
21462 }
21463 Ok(())
21464 }
21465
21466 fn generate_string_agg_separator(&mut self, separator: &Expression) -> Result<()> {
21467 if matches!(
21468 self.config.dialect,
21469 Some(crate::dialects::DialectType::TSQL | crate::dialects::DialectType::Fabric)
21470 ) {
21471 if let Some(inner) = Self::tsql_string_agg_literal_separator_cast_inner(separator) {
21472 return self.generate_expression(inner);
21473 }
21474 }
21475
21476 self.generate_expression(separator)
21477 }
21478
21479 fn tsql_string_agg_literal_separator_cast_inner(separator: &Expression) -> Option<&Expression> {
21480 let Expression::Cast(cast) = separator else {
21481 return None;
21482 };
21483
21484 if cast.format.is_some() || cast.default.is_some() {
21485 return None;
21486 }
21487
21488 if !Self::is_string_data_type(&cast.to) {
21489 return None;
21490 }
21491
21492 match &cast.this {
21493 Expression::Literal(literal) if literal.is_string() => Some(&cast.this),
21494 _ => None,
21495 }
21496 }
21497
21498 fn is_string_data_type(data_type: &DataType) -> bool {
21499 matches!(
21500 data_type,
21501 DataType::Char { .. }
21502 | DataType::VarChar { .. }
21503 | DataType::String { .. }
21504 | DataType::Text
21505 | DataType::TextWithLength { .. }
21506 ) || matches!(
21507 data_type,
21508 DataType::Custom { name, .. }
21509 if name.eq_ignore_ascii_case("VARCHAR")
21510 || name.eq_ignore_ascii_case("NVARCHAR")
21511 || name.eq_ignore_ascii_case("VARCHAR(MAX)")
21512 || name.eq_ignore_ascii_case("NVARCHAR(MAX)")
21513 )
21514 }
21515
21516 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
21517 use crate::dialects::DialectType;
21518 let order_inside_args = matches!(self.config.dialect, Some(DialectType::DuckDB));
21519 self.write_keyword("LISTAGG");
21520 self.write("(");
21521 if f.distinct {
21522 self.write_keyword("DISTINCT");
21523 self.write_space();
21524 }
21525 self.generate_expression(&f.this)?;
21526 if let Some(ref sep) = f.separator {
21527 self.write(", ");
21528 self.generate_expression(sep)?;
21529 } else if matches!(
21530 self.config.dialect,
21531 Some(DialectType::Trino) | Some(DialectType::Presto)
21532 ) {
21533 self.write(", ','");
21535 }
21536 if let Some(ref overflow) = f.on_overflow {
21537 self.write_space();
21538 self.write_keyword("ON OVERFLOW");
21539 self.write_space();
21540 match overflow {
21541 ListAggOverflow::Error => self.write_keyword("ERROR"),
21542 ListAggOverflow::Truncate { filler, with_count } => {
21543 self.write_keyword("TRUNCATE");
21544 if let Some(ref fill) = filler {
21545 self.write_space();
21546 self.generate_expression(fill)?;
21547 }
21548 if *with_count {
21549 self.write_space();
21550 self.write_keyword("WITH COUNT");
21551 } else {
21552 self.write_space();
21553 self.write_keyword("WITHOUT COUNT");
21554 }
21555 }
21556 }
21557 }
21558 if order_inside_args {
21559 if let Some(ref order_by) = f.order_by {
21560 self.write_space();
21561 self.write_keyword("ORDER BY");
21562 self.write_space();
21563 for (i, ord) in order_by.iter().enumerate() {
21564 if i > 0 {
21565 self.write(", ");
21566 }
21567 self.generate_ordered(ord)?;
21568 }
21569 }
21570 }
21571 self.write(")");
21572 if !order_inside_args {
21573 if let Some(ref order_by) = f.order_by {
21574 self.write_space();
21575 self.write_keyword("WITHIN GROUP");
21576 self.write(" (");
21577 self.write_keyword("ORDER BY");
21578 self.write_space();
21579 for (i, ord) in order_by.iter().enumerate() {
21580 if i > 0 {
21581 self.write(", ");
21582 }
21583 self.generate_ordered(ord)?;
21584 }
21585 self.write(")");
21586 }
21587 }
21588 if let Some(ref filter) = f.filter {
21589 self.write_space();
21590 self.write_keyword("FILTER");
21591 self.write("(");
21592 self.write_keyword("WHERE");
21593 self.write_space();
21594 self.generate_expression(filter)?;
21595 self.write(")");
21596 }
21597 Ok(())
21598 }
21599
21600 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
21601 self.write_keyword("SUM_IF");
21602 self.write("(");
21603 self.generate_expression(&f.this)?;
21604 self.write(", ");
21605 self.generate_expression(&f.condition)?;
21606 self.write(")");
21607 if let Some(ref filter) = f.filter {
21608 self.write_space();
21609 self.write_keyword("FILTER");
21610 self.write("(");
21611 self.write_keyword("WHERE");
21612 self.write_space();
21613 self.generate_expression(filter)?;
21614 self.write(")");
21615 }
21616 Ok(())
21617 }
21618
21619 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
21620 self.write_keyword("APPROX_PERCENTILE");
21621 self.write("(");
21622 self.generate_expression(&f.this)?;
21623 self.write(", ");
21624 self.generate_expression(&f.percentile)?;
21625 if let Some(ref acc) = f.accuracy {
21626 self.write(", ");
21627 self.generate_expression(acc)?;
21628 }
21629 self.write(")");
21630 if let Some(ref filter) = f.filter {
21631 self.write_space();
21632 self.write_keyword("FILTER");
21633 self.write("(");
21634 self.write_keyword("WHERE");
21635 self.write_space();
21636 self.generate_expression(filter)?;
21637 self.write(")");
21638 }
21639 Ok(())
21640 }
21641
21642 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
21643 self.write_keyword(name);
21644 self.write("(");
21645 self.generate_expression(&f.percentile)?;
21646 self.write(")");
21647 if let Some(ref order_by) = f.order_by {
21648 self.write_space();
21649 self.write_keyword("WITHIN GROUP");
21650 self.write(" (");
21651 self.write_keyword("ORDER BY");
21652 self.write_space();
21653 self.generate_expression(&f.this)?;
21654 for ord in order_by.iter() {
21655 if ord.desc {
21656 self.write_space();
21657 self.write_keyword("DESC");
21658 }
21659 }
21660 self.write(")");
21661 }
21662 if let Some(ref filter) = f.filter {
21663 self.write_space();
21664 self.write_keyword("FILTER");
21665 self.write("(");
21666 self.write_keyword("WHERE");
21667 self.write_space();
21668 self.generate_expression(filter)?;
21669 self.write(")");
21670 }
21671 Ok(())
21672 }
21673
21674 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
21677 self.write_keyword("NTILE");
21678 self.write("(");
21679 if let Some(num_buckets) = &f.num_buckets {
21680 self.generate_expression(num_buckets)?;
21681 }
21682 if let Some(order_by) = &f.order_by {
21683 self.write_keyword(" ORDER BY ");
21684 for (i, ob) in order_by.iter().enumerate() {
21685 if i > 0 {
21686 self.write(", ");
21687 }
21688 self.generate_ordered(ob)?;
21689 }
21690 }
21691 self.write(")");
21692 Ok(())
21693 }
21694
21695 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
21696 self.write_keyword(name);
21697 self.write("(");
21698 self.generate_expression(&f.this)?;
21699 if let Some(ref offset) = f.offset {
21700 self.write(", ");
21701 self.generate_expression(offset)?;
21702 if let Some(ref default) = f.default {
21703 self.write(", ");
21704 self.generate_expression(default)?;
21705 }
21706 }
21707 if self.config.ignore_nulls_in_func {
21709 match f.ignore_nulls {
21710 Some(true) => {
21711 self.write_space();
21712 self.write_keyword("IGNORE NULLS");
21713 }
21714 Some(false) => {
21715 self.write_space();
21716 self.write_keyword("RESPECT NULLS");
21717 }
21718 None => {}
21719 }
21720 }
21721 self.write(")");
21722 if !self.config.ignore_nulls_in_func {
21724 match f.ignore_nulls {
21725 Some(true) => {
21726 self.write_space();
21727 self.write_keyword("IGNORE NULLS");
21728 }
21729 Some(false) => {
21730 self.write_space();
21731 self.write_keyword("RESPECT NULLS");
21732 }
21733 None => {}
21734 }
21735 }
21736 Ok(())
21737 }
21738
21739 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
21740 self.write_keyword(name);
21741 self.write("(");
21742 self.generate_expression(&f.this)?;
21743 if !f.order_by.is_empty() {
21745 self.write_space();
21746 self.write_keyword("ORDER BY");
21747 self.write_space();
21748 for (i, ordered) in f.order_by.iter().enumerate() {
21749 if i > 0 {
21750 self.write(", ");
21751 }
21752 self.generate_ordered(ordered)?;
21753 }
21754 }
21755 if self.config.ignore_nulls_in_func {
21757 match f.ignore_nulls {
21758 Some(true) => {
21759 self.write_space();
21760 self.write_keyword("IGNORE NULLS");
21761 }
21762 Some(false) => {
21763 self.write_space();
21764 self.write_keyword("RESPECT NULLS");
21765 }
21766 None => {}
21767 }
21768 }
21769 self.write(")");
21770 if !self.config.ignore_nulls_in_func {
21772 match f.ignore_nulls {
21773 Some(true) => {
21774 self.write_space();
21775 self.write_keyword("IGNORE NULLS");
21776 }
21777 Some(false) => {
21778 self.write_space();
21779 self.write_keyword("RESPECT NULLS");
21780 }
21781 None => {}
21782 }
21783 }
21784 Ok(())
21785 }
21786
21787 fn generate_value_func_with_ignore_nulls_bool(
21790 &mut self,
21791 name: &str,
21792 f: &ValueFunc,
21793 ) -> Result<()> {
21794 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
21795 self.write_keyword(name);
21796 self.write("(");
21797 self.generate_expression(&f.this)?;
21798 self.write(", ");
21799 self.write_keyword("TRUE");
21800 self.write(")");
21801 return Ok(());
21802 }
21803 self.generate_value_func(name, f)
21804 }
21805
21806 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
21807 self.write_keyword("NTH_VALUE");
21808 self.write("(");
21809 self.generate_expression(&f.this)?;
21810 self.write(", ");
21811 self.generate_expression(&f.offset)?;
21812 if self.config.ignore_nulls_in_func {
21814 match f.ignore_nulls {
21815 Some(true) => {
21816 self.write_space();
21817 self.write_keyword("IGNORE NULLS");
21818 }
21819 Some(false) => {
21820 self.write_space();
21821 self.write_keyword("RESPECT NULLS");
21822 }
21823 None => {}
21824 }
21825 }
21826 self.write(")");
21827 if matches!(
21829 self.config.dialect,
21830 Some(crate::dialects::DialectType::Snowflake)
21831 ) {
21832 match f.from_first {
21833 Some(true) => {
21834 self.write_space();
21835 self.write_keyword("FROM FIRST");
21836 }
21837 Some(false) => {
21838 self.write_space();
21839 self.write_keyword("FROM LAST");
21840 }
21841 None => {}
21842 }
21843 }
21844 if !self.config.ignore_nulls_in_func {
21846 match f.ignore_nulls {
21847 Some(true) => {
21848 self.write_space();
21849 self.write_keyword("IGNORE NULLS");
21850 }
21851 Some(false) => {
21852 self.write_space();
21853 self.write_keyword("RESPECT NULLS");
21854 }
21855 None => {}
21856 }
21857 }
21858 Ok(())
21859 }
21860
21861 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
21864 if matches!(
21867 self.config.dialect,
21868 Some(crate::dialects::DialectType::ClickHouse)
21869 ) {
21870 self.write_keyword("POSITION");
21871 self.write("(");
21872 self.generate_expression(&f.string)?;
21873 self.write(", ");
21874 self.generate_expression(&f.substring)?;
21875 if let Some(ref start) = f.start {
21876 self.write(", ");
21877 self.generate_expression(start)?;
21878 }
21879 self.write(")");
21880 return Ok(());
21881 }
21882
21883 self.write_keyword("POSITION");
21884 self.write("(");
21885 self.generate_expression(&f.substring)?;
21886 self.write_space();
21887 self.write_keyword("IN");
21888 self.write_space();
21889 self.generate_expression(&f.string)?;
21890 if let Some(ref start) = f.start {
21891 self.write(", ");
21892 self.generate_expression(start)?;
21893 }
21894 self.write(")");
21895 Ok(())
21896 }
21897
21898 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
21901 if f.lower.is_some() || f.upper.is_some() {
21903 self.write_keyword("RANDOM");
21904 self.write("(");
21905 if let Some(ref lower) = f.lower {
21906 self.generate_expression(lower)?;
21907 }
21908 if let Some(ref upper) = f.upper {
21909 self.write(", ");
21910 self.generate_expression(upper)?;
21911 }
21912 self.write(")");
21913 return Ok(());
21914 }
21915 let func_name = match self.config.dialect {
21917 Some(crate::dialects::DialectType::Snowflake)
21918 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
21919 _ => "RAND",
21920 };
21921 self.write_keyword(func_name);
21922 self.write("(");
21923 if !matches!(
21925 self.config.dialect,
21926 Some(crate::dialects::DialectType::DuckDB)
21927 ) {
21928 if let Some(ref seed) = f.seed {
21929 self.generate_expression(seed)?;
21930 }
21931 }
21932 self.write(")");
21933 Ok(())
21934 }
21935
21936 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
21937 self.write_keyword("TRUNCATE");
21938 self.write("(");
21939 self.generate_expression(&f.this)?;
21940 if let Some(ref decimals) = f.decimals {
21941 self.write(", ");
21942 self.generate_expression(decimals)?;
21943 }
21944 self.write(")");
21945 Ok(())
21946 }
21947
21948 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
21951 self.write_keyword("DECODE");
21952 self.write("(");
21953 self.generate_expression(&f.this)?;
21954 for (search, result) in &f.search_results {
21955 self.write(", ");
21956 self.generate_expression(search)?;
21957 self.write(", ");
21958 self.generate_expression(result)?;
21959 }
21960 if let Some(ref default) = f.default {
21961 self.write(", ");
21962 self.generate_expression(default)?;
21963 }
21964 self.write(")");
21965 Ok(())
21966 }
21967
21968 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
21971 self.write_keyword(name);
21972 self.write("(");
21973 self.generate_expression(&f.this)?;
21974 self.write(", ");
21975 self.generate_expression(&f.format)?;
21976 self.write(")");
21977 Ok(())
21978 }
21979
21980 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
21981 self.write_keyword("FROM_UNIXTIME");
21982 self.write("(");
21983 self.generate_expression(&f.this)?;
21984 if let Some(ref format) = f.format {
21985 self.write(", ");
21986 self.generate_expression(format)?;
21987 }
21988 self.write(")");
21989 Ok(())
21990 }
21991
21992 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
21993 self.write_keyword("UNIX_TIMESTAMP");
21994 self.write("(");
21995 if let Some(ref expr) = f.this {
21996 self.generate_expression(expr)?;
21997 if let Some(ref format) = f.format {
21998 self.write(", ");
21999 self.generate_expression(format)?;
22000 }
22001 } else if matches!(
22002 self.config.dialect,
22003 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
22004 ) {
22005 self.write_keyword("CURRENT_TIMESTAMP");
22007 self.write("()");
22008 }
22009 self.write(")");
22010 Ok(())
22011 }
22012
22013 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
22014 self.write_keyword("MAKE_DATE");
22015 self.write("(");
22016 self.generate_expression(&f.year)?;
22017 self.write(", ");
22018 self.generate_expression(&f.month)?;
22019 self.write(", ");
22020 self.generate_expression(&f.day)?;
22021 self.write(")");
22022 Ok(())
22023 }
22024
22025 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
22026 self.write_keyword("MAKE_TIMESTAMP");
22027 self.write("(");
22028 self.generate_expression(&f.year)?;
22029 self.write(", ");
22030 self.generate_expression(&f.month)?;
22031 self.write(", ");
22032 self.generate_expression(&f.day)?;
22033 self.write(", ");
22034 self.generate_expression(&f.hour)?;
22035 self.write(", ");
22036 self.generate_expression(&f.minute)?;
22037 self.write(", ");
22038 self.generate_expression(&f.second)?;
22039 if let Some(ref tz) = f.timezone {
22040 self.write(", ");
22041 self.generate_expression(tz)?;
22042 }
22043 self.write(")");
22044 Ok(())
22045 }
22046
22047 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
22049 match expr {
22050 Expression::Struct(s) => {
22051 if s.fields.iter().all(|(name, _)| name.is_some()) {
22052 Some(
22053 s.fields
22054 .iter()
22055 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
22056 .collect(),
22057 )
22058 } else {
22059 None
22060 }
22061 }
22062 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
22063 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
22065 Some(
22066 f.args
22067 .iter()
22068 .filter_map(|a| {
22069 if let Expression::Alias(alias) = a {
22070 Some(alias.alias.name.clone())
22071 } else {
22072 None
22073 }
22074 })
22075 .collect(),
22076 )
22077 } else {
22078 None
22079 }
22080 }
22081 _ => None,
22082 }
22083 }
22084
22085 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
22087 match expr {
22088 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
22089 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
22090 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
22091 }
22092 _ => false,
22093 }
22094 }
22095
22096 fn struct_field_count(expr: &Expression) -> usize {
22098 match expr {
22099 Expression::Struct(s) => s.fields.len(),
22100 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
22101 _ => 0,
22102 }
22103 }
22104
22105 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
22107 match expr {
22108 Expression::Struct(s) => {
22109 let mut new_fields = Vec::with_capacity(s.fields.len());
22110 for (i, (name, value)) in s.fields.iter().enumerate() {
22111 if name.is_none() && i < field_names.len() {
22112 new_fields.push((Some(field_names[i].clone()), value.clone()));
22113 } else {
22114 new_fields.push((name.clone(), value.clone()));
22115 }
22116 }
22117 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
22118 }
22119 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
22120 let mut new_args = Vec::with_capacity(f.args.len());
22121 for (i, arg) in f.args.iter().enumerate() {
22122 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
22123 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
22125 this: arg.clone(),
22126 alias: crate::expressions::Identifier::new(field_names[i].clone()),
22127 column_aliases: Vec::new(),
22128 alias_explicit_as: false,
22129 alias_keyword: None,
22130 pre_alias_comments: Vec::new(),
22131 trailing_comments: Vec::new(),
22132 inferred_type: None,
22133 })));
22134 } else {
22135 new_args.push(arg.clone());
22136 }
22137 }
22138 Expression::Function(Box::new(crate::expressions::Function {
22139 name: f.name.clone(),
22140 args: new_args,
22141 distinct: f.distinct,
22142 trailing_comments: f.trailing_comments.clone(),
22143 use_bracket_syntax: f.use_bracket_syntax,
22144 no_parens: f.no_parens,
22145 quoted: f.quoted,
22146 span: None,
22147 inferred_type: None,
22148 }))
22149 }
22150 _ => expr.clone(),
22151 }
22152 }
22153
22154 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
22158 let first = match expressions.first() {
22159 Some(e) => e,
22160 None => return expressions.to_vec(),
22161 };
22162
22163 let field_names = match Self::extract_struct_field_names(first) {
22164 Some(names) if !names.is_empty() => names,
22165 _ => return expressions.to_vec(),
22166 };
22167
22168 let mut result = Vec::with_capacity(expressions.len());
22169 for (idx, expr) in expressions.iter().enumerate() {
22170 if idx == 0 {
22171 result.push(expr.clone());
22172 continue;
22173 }
22174 if Self::struct_field_count(expr) == field_names.len()
22176 && Self::struct_has_unnamed_fields(expr)
22177 {
22178 result.push(Self::apply_struct_field_names(expr, &field_names));
22179 } else {
22180 result.push(expr.clone());
22181 }
22182 }
22183 result
22184 }
22185
22186 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
22189 let needs_inheritance = matches!(
22192 self.config.dialect,
22193 Some(DialectType::DuckDB)
22194 | Some(DialectType::Spark)
22195 | Some(DialectType::Databricks)
22196 | Some(DialectType::Hive)
22197 | Some(DialectType::Snowflake)
22198 | Some(DialectType::Presto)
22199 | Some(DialectType::Trino)
22200 );
22201 let propagated: Vec<Expression>;
22202 let expressions = if needs_inheritance && f.expressions.len() > 1 {
22203 propagated = Self::inherit_struct_field_names(&f.expressions);
22204 &propagated
22205 } else {
22206 &f.expressions
22207 };
22208
22209 let should_split = if self.config.pretty && !expressions.is_empty() {
22211 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
22212 for expr in expressions {
22213 let mut temp_gen = Generator::with_arc_config(self.config.clone());
22214 Arc::make_mut(&mut temp_gen.config).pretty = false;
22215 temp_gen.generate_expression(expr)?;
22216 expr_strings.push(temp_gen.output);
22217 }
22218 self.too_wide(&expr_strings)
22219 } else {
22220 false
22221 };
22222
22223 if f.bracket_notation {
22224 let (open, close) = match self.config.dialect {
22228 None
22229 | Some(DialectType::Generic)
22230 | Some(DialectType::Spark)
22231 | Some(DialectType::Databricks)
22232 | Some(DialectType::Hive) => {
22233 self.write_keyword("ARRAY");
22234 ("(", ")")
22235 }
22236 Some(DialectType::Presto)
22237 | Some(DialectType::Trino)
22238 | Some(DialectType::PostgreSQL)
22239 | Some(DialectType::Redshift)
22240 | Some(DialectType::Materialize)
22241 | Some(DialectType::RisingWave)
22242 | Some(DialectType::CockroachDB) => {
22243 self.write_keyword("ARRAY");
22244 ("[", "]")
22245 }
22246 _ => ("[", "]"),
22247 };
22248 self.write(open);
22249 if should_split {
22250 self.write_newline();
22251 self.indent_level += 1;
22252 for (i, expr) in expressions.iter().enumerate() {
22253 self.write_indent();
22254 self.generate_expression(expr)?;
22255 if i + 1 < expressions.len() {
22256 self.write(",");
22257 }
22258 self.write_newline();
22259 }
22260 self.indent_level -= 1;
22261 self.write_indent();
22262 } else {
22263 for (i, expr) in expressions.iter().enumerate() {
22264 if i > 0 {
22265 self.write(", ");
22266 }
22267 self.generate_expression(expr)?;
22268 }
22269 }
22270 self.write(close);
22271 } else {
22272 if f.use_list_keyword {
22274 self.write_keyword("LIST");
22275 } else {
22276 self.write_keyword("ARRAY");
22277 }
22278 let has_subquery = expressions
22281 .iter()
22282 .any(|e| matches!(e, Expression::Select(_)));
22283 let (open, close) = if matches!(
22284 self.config.dialect,
22285 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
22286 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
22287 && has_subquery)
22288 {
22289 ("(", ")")
22290 } else {
22291 ("[", "]")
22292 };
22293 self.write(open);
22294 if should_split {
22295 self.write_newline();
22296 self.indent_level += 1;
22297 for (i, expr) in expressions.iter().enumerate() {
22298 self.write_indent();
22299 self.generate_expression(expr)?;
22300 if i + 1 < expressions.len() {
22301 self.write(",");
22302 }
22303 self.write_newline();
22304 }
22305 self.indent_level -= 1;
22306 self.write_indent();
22307 } else {
22308 for (i, expr) in expressions.iter().enumerate() {
22309 if i > 0 {
22310 self.write(", ");
22311 }
22312 self.generate_expression(expr)?;
22313 }
22314 }
22315 self.write(close);
22316 }
22317 Ok(())
22318 }
22319
22320 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
22321 self.write_keyword("ARRAY_SORT");
22322 self.write("(");
22323 self.generate_expression(&f.this)?;
22324 if let Some(ref comp) = f.comparator {
22325 self.write(", ");
22326 self.generate_expression(comp)?;
22327 }
22328 self.write(")");
22329 Ok(())
22330 }
22331
22332 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
22333 self.write_keyword(name);
22334 self.write("(");
22335 self.generate_expression(&f.this)?;
22336 self.write(", ");
22337 self.generate_expression(&f.separator)?;
22338 if let Some(ref null_rep) = f.null_replacement {
22339 self.write(", ");
22340 self.generate_expression(null_rep)?;
22341 }
22342 self.write(")");
22343 Ok(())
22344 }
22345
22346 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
22347 self.write_keyword("UNNEST");
22348 self.write("(");
22349 self.generate_expression(&f.this)?;
22350 for extra in &f.expressions {
22351 self.write(", ");
22352 self.generate_expression(extra)?;
22353 }
22354 self.write(")");
22355 if f.with_ordinality {
22356 self.write_space();
22357 if self.config.unnest_with_ordinality {
22358 self.write_keyword("WITH ORDINALITY");
22360 } else if f.offset_alias.is_some() {
22361 if let Some(ref alias) = f.alias {
22364 self.write_keyword("AS");
22365 self.write_space();
22366 self.generate_identifier(alias)?;
22367 self.write_space();
22368 }
22369 self.write_keyword("WITH OFFSET");
22370 if let Some(ref offset_alias) = f.offset_alias {
22371 self.write_space();
22372 self.write_keyword("AS");
22373 self.write_space();
22374 self.generate_identifier(offset_alias)?;
22375 }
22376 } else {
22377 self.write_keyword("WITH OFFSET");
22379 if f.alias.is_none() {
22380 self.write(" AS offset");
22381 }
22382 }
22383 }
22384 if let Some(ref alias) = f.alias {
22385 let should_add_alias = if !f.with_ordinality {
22387 true
22388 } else if self.config.unnest_with_ordinality {
22389 true
22391 } else if f.offset_alias.is_some() {
22392 false
22394 } else {
22395 true
22397 };
22398 if should_add_alias {
22399 self.write_space();
22400 self.write_keyword("AS");
22401 self.write_space();
22402 self.generate_identifier(alias)?;
22403 }
22404 }
22405 Ok(())
22406 }
22407
22408 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
22409 self.write_keyword("FILTER");
22410 self.write("(");
22411 self.generate_expression(&f.this)?;
22412 self.write(", ");
22413 self.generate_expression(&f.filter)?;
22414 self.write(")");
22415 Ok(())
22416 }
22417
22418 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
22419 self.write_keyword("TRANSFORM");
22420 self.write("(");
22421 self.generate_expression(&f.this)?;
22422 self.write(", ");
22423 self.generate_expression(&f.transform)?;
22424 self.write(")");
22425 Ok(())
22426 }
22427
22428 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
22429 self.write_keyword(name);
22430 self.write("(");
22431 self.generate_expression(&f.start)?;
22432 self.write(", ");
22433 self.generate_expression(&f.stop)?;
22434 if let Some(ref step) = f.step {
22435 self.write(", ");
22436 self.generate_expression(step)?;
22437 }
22438 self.write(")");
22439 Ok(())
22440 }
22441
22442 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
22445 self.write_keyword("STRUCT");
22446 self.write("(");
22447 for (i, (name, expr)) in f.fields.iter().enumerate() {
22448 if i > 0 {
22449 self.write(", ");
22450 }
22451 if let Some(ref id) = name {
22452 self.generate_identifier(id)?;
22453 self.write(" ");
22454 self.write_keyword("AS");
22455 self.write(" ");
22456 }
22457 self.generate_expression(expr)?;
22458 }
22459 self.write(")");
22460 Ok(())
22461 }
22462
22463 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
22465 let mut names: Vec<Option<String>> = Vec::new();
22468 let mut values: Vec<&Expression> = Vec::new();
22469 let mut all_named = true;
22470
22471 for arg in &func.args {
22472 match arg {
22473 Expression::Alias(a) => {
22474 names.push(Some(a.alias.name.clone()));
22475 values.push(&a.this);
22476 }
22477 _ => {
22478 names.push(None);
22479 values.push(arg);
22480 all_named = false;
22481 }
22482 }
22483 }
22484
22485 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
22486 self.write("{");
22488 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
22489 if i > 0 {
22490 self.write(", ");
22491 }
22492 if let Some(n) = name {
22493 self.write("'");
22494 self.write(n);
22495 self.write("'");
22496 } else {
22497 self.write("'_");
22498 self.write(&i.to_string());
22499 self.write("'");
22500 }
22501 self.write(": ");
22502 self.generate_expression(value)?;
22503 }
22504 self.write("}");
22505 return Ok(());
22506 }
22507
22508 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
22509 self.write_keyword("OBJECT_CONSTRUCT");
22511 self.write("(");
22512 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
22513 if i > 0 {
22514 self.write(", ");
22515 }
22516 if let Some(n) = name {
22517 self.write("'");
22518 self.write(n);
22519 self.write("'");
22520 } else {
22521 self.write("'_");
22522 self.write(&i.to_string());
22523 self.write("'");
22524 }
22525 self.write(", ");
22526 self.generate_expression(value)?;
22527 }
22528 self.write(")");
22529 return Ok(());
22530 }
22531
22532 if matches!(
22533 self.config.dialect,
22534 Some(DialectType::Presto) | Some(DialectType::Trino)
22535 ) {
22536 if all_named && !names.is_empty() {
22537 self.write_keyword("CAST");
22540 self.write("(");
22541 self.write_keyword("ROW");
22542 self.write("(");
22543 for (i, value) in values.iter().enumerate() {
22544 if i > 0 {
22545 self.write(", ");
22546 }
22547 self.generate_expression(value)?;
22548 }
22549 self.write(")");
22550 self.write(" ");
22551 self.write_keyword("AS");
22552 self.write(" ");
22553 self.write_keyword("ROW");
22554 self.write("(");
22555 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
22556 if i > 0 {
22557 self.write(", ");
22558 }
22559 if let Some(n) = name {
22560 self.write(n);
22561 }
22562 self.write(" ");
22563 let type_str = Self::infer_sql_type_for_presto(value);
22564 self.write_keyword(&type_str);
22565 }
22566 self.write(")");
22567 self.write(")");
22568 } else {
22569 self.write_keyword("ROW");
22571 self.write("(");
22572 for (i, value) in values.iter().enumerate() {
22573 if i > 0 {
22574 self.write(", ");
22575 }
22576 self.generate_expression(value)?;
22577 }
22578 self.write(")");
22579 }
22580 return Ok(());
22581 }
22582
22583 self.write_keyword("ROW");
22585 self.write("(");
22586 for (i, value) in values.iter().enumerate() {
22587 if i > 0 {
22588 self.write(", ");
22589 }
22590 self.generate_expression(value)?;
22591 }
22592 self.write(")");
22593 Ok(())
22594 }
22595
22596 fn infer_sql_type_for_presto(expr: &Expression) -> String {
22598 match expr {
22599 Expression::Literal(lit)
22600 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
22601 {
22602 "VARCHAR".to_string()
22603 }
22604 Expression::Literal(lit)
22605 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
22606 {
22607 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
22608 unreachable!()
22609 };
22610 if n.contains('.') {
22611 "DOUBLE".to_string()
22612 } else {
22613 "INTEGER".to_string()
22614 }
22615 }
22616 Expression::Boolean(_) => "BOOLEAN".to_string(),
22617 Expression::Literal(lit)
22618 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
22619 {
22620 "DATE".to_string()
22621 }
22622 Expression::Literal(lit)
22623 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
22624 {
22625 "TIMESTAMP".to_string()
22626 }
22627 Expression::Literal(lit)
22628 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
22629 {
22630 "TIMESTAMP".to_string()
22631 }
22632 Expression::Array(_) | Expression::ArrayFunc(_) => {
22633 "ARRAY(VARCHAR)".to_string()
22635 }
22636 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
22638 Expression::Function(f) => {
22639 if f.name.eq_ignore_ascii_case("STRUCT") {
22640 "ROW".to_string()
22641 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
22642 "DATE".to_string()
22643 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
22644 || f.name.eq_ignore_ascii_case("NOW")
22645 {
22646 "TIMESTAMP".to_string()
22647 } else {
22648 "VARCHAR".to_string()
22649 }
22650 }
22651 _ => "VARCHAR".to_string(),
22652 }
22653 }
22654
22655 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
22656 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
22658 self.write_keyword("STRUCT_EXTRACT");
22659 self.write("(");
22660 self.generate_expression(&f.this)?;
22661 self.write(", ");
22662 self.write("'");
22664 self.write(&f.field.name);
22665 self.write("'");
22666 self.write(")");
22667 return Ok(());
22668 }
22669 self.generate_expression(&f.this)?;
22670 self.write(".");
22671 self.generate_identifier(&f.field)
22672 }
22673
22674 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
22675 if matches!(
22676 self.config.dialect,
22677 Some(DialectType::Spark | DialectType::Databricks)
22678 ) {
22679 self.write_keyword("STRUCT");
22680 self.write("(");
22681 for (i, (name, value)) in f.pairs.iter().enumerate() {
22682 if i > 0 {
22683 self.write(", ");
22684 }
22685 self.generate_expression(value)?;
22686 self.write(" ");
22687 self.write_keyword("AS");
22688 self.write(" ");
22689 if let Expression::Literal(lit) = name {
22690 if let Literal::String(field_name) = lit.as_ref() {
22691 self.generate_identifier(&Identifier::new(field_name))?;
22692 } else {
22693 self.generate_expression(name)?;
22694 }
22695 } else {
22696 self.generate_expression(name)?;
22697 }
22698 }
22699 self.write(")");
22700 return Ok(());
22701 }
22702
22703 self.write_keyword("NAMED_STRUCT");
22704 self.write("(");
22705 for (i, (name, value)) in f.pairs.iter().enumerate() {
22706 if i > 0 {
22707 self.write(", ");
22708 }
22709 self.generate_expression(name)?;
22710 self.write(", ");
22711 self.generate_expression(value)?;
22712 }
22713 self.write(")");
22714 Ok(())
22715 }
22716
22717 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
22720 if f.curly_brace_syntax {
22721 if f.with_map_keyword {
22723 self.write_keyword("MAP");
22724 self.write(" ");
22725 }
22726 self.write("{");
22727 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
22728 if i > 0 {
22729 self.write(", ");
22730 }
22731 self.generate_expression(key)?;
22732 self.write(": ");
22733 self.generate_expression(val)?;
22734 }
22735 self.write("}");
22736 } else {
22737 self.write_keyword("MAP");
22739 self.write("(");
22740 self.write_keyword("ARRAY");
22741 self.write("[");
22742 for (i, key) in f.keys.iter().enumerate() {
22743 if i > 0 {
22744 self.write(", ");
22745 }
22746 self.generate_expression(key)?;
22747 }
22748 self.write("], ");
22749 self.write_keyword("ARRAY");
22750 self.write("[");
22751 for (i, val) in f.values.iter().enumerate() {
22752 if i > 0 {
22753 self.write(", ");
22754 }
22755 self.generate_expression(val)?;
22756 }
22757 self.write("])");
22758 }
22759 Ok(())
22760 }
22761
22762 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
22763 self.write_keyword(name);
22764 self.write("(");
22765 self.generate_expression(&f.this)?;
22766 self.write(", ");
22767 self.generate_expression(&f.transform)?;
22768 self.write(")");
22769 Ok(())
22770 }
22771
22772 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
22775 use crate::dialects::DialectType;
22776
22777 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
22779
22780 if use_arrow {
22781 self.generate_expression(&f.this)?;
22783 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
22784 self.write(" ->> ");
22785 } else {
22786 self.write(" -> ");
22787 }
22788 self.generate_expression(&f.path)?;
22789 return Ok(());
22790 }
22791
22792 if f.hash_arrow_syntax
22794 && matches!(
22795 self.config.dialect,
22796 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22797 )
22798 {
22799 self.generate_expression(&f.this)?;
22800 self.write(" #>> ");
22801 self.generate_expression(&f.path)?;
22802 return Ok(());
22803 }
22804
22805 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
22808 match name {
22809 "JSON_EXTRACT_SCALAR"
22810 | "JSON_EXTRACT_PATH_TEXT"
22811 | "JSON_EXTRACT"
22812 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
22813 _ => name,
22814 }
22815 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
22816 match name {
22817 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
22818 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
22819 _ => name,
22820 }
22821 } else {
22822 name
22823 };
22824
22825 self.write_keyword(func_name);
22826 self.write("(");
22827 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
22829 if let Expression::Cast(ref cast) = f.this {
22830 if matches!(cast.to, crate::expressions::DataType::Json) {
22831 self.generate_expression(&cast.this)?;
22832 } else {
22833 self.generate_expression(&f.this)?;
22834 }
22835 } else {
22836 self.generate_expression(&f.this)?;
22837 }
22838 } else {
22839 self.generate_expression(&f.this)?;
22840 }
22841 if matches!(
22844 self.config.dialect,
22845 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22846 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
22847 {
22848 if let Expression::Literal(ref lit) = f.path {
22849 if let Literal::String(ref s) = lit.as_ref() {
22850 let parts = Self::decompose_json_path(s);
22851 for part in &parts {
22852 self.write(", '");
22853 self.write(part);
22854 self.write("'");
22855 }
22856 }
22857 } else {
22858 self.write(", ");
22859 self.generate_expression(&f.path)?;
22860 }
22861 } else {
22862 self.write(", ");
22863 self.generate_expression(&f.path)?;
22864 }
22865
22866 if let Some(ref wrapper) = f.wrapper_option {
22869 self.write_space();
22870 self.write_keyword(wrapper);
22871 }
22872 if let Some(ref quotes) = f.quotes_option {
22873 self.write_space();
22874 self.write_keyword(quotes);
22875 if f.on_scalar_string {
22876 self.write_space();
22877 self.write_keyword("ON SCALAR STRING");
22878 }
22879 }
22880 if let Some(ref on_err) = f.on_error {
22881 self.write_space();
22882 self.write_keyword(on_err);
22883 }
22884 if let Some(ref ret_type) = f.returning {
22885 self.write_space();
22886 self.write_keyword("RETURNING");
22887 self.write_space();
22888 self.generate_data_type(ret_type)?;
22889 }
22890
22891 self.write(")");
22892 Ok(())
22893 }
22894
22895 fn dialect_supports_json_arrow(&self) -> bool {
22897 use crate::dialects::DialectType;
22898 match self.config.dialect {
22899 Some(DialectType::PostgreSQL) => true,
22901 Some(DialectType::MySQL) => true,
22902 Some(DialectType::DuckDB) => true,
22903 Some(DialectType::CockroachDB) => true,
22904 Some(DialectType::StarRocks) => true,
22905 Some(DialectType::SQLite) => true,
22906 _ => false,
22908 }
22909 }
22910
22911 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
22912 use crate::dialects::DialectType;
22913
22914 if matches!(
22916 self.config.dialect,
22917 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
22918 ) && name == "JSON_EXTRACT_PATH"
22919 {
22920 self.generate_expression(&f.this)?;
22921 self.write(" #> ");
22922 if f.paths.len() == 1 {
22923 self.generate_expression(&f.paths[0])?;
22924 } else {
22925 self.write_keyword("ARRAY");
22927 self.write("[");
22928 for (i, path) in f.paths.iter().enumerate() {
22929 if i > 0 {
22930 self.write(", ");
22931 }
22932 self.generate_expression(path)?;
22933 }
22934 self.write("]");
22935 }
22936 return Ok(());
22937 }
22938
22939 self.write_keyword(name);
22940 self.write("(");
22941 self.generate_expression(&f.this)?;
22942 for path in &f.paths {
22943 self.write(", ");
22944 self.generate_expression(path)?;
22945 }
22946 self.write(")");
22947 Ok(())
22948 }
22949
22950 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
22951 use crate::dialects::DialectType;
22952
22953 self.write_keyword("JSON_OBJECT");
22954 self.write("(");
22955 if f.star {
22956 self.write("*");
22957 } else {
22958 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
22962 || matches!(
22963 self.config.dialect,
22964 Some(DialectType::BigQuery)
22965 | Some(DialectType::MySQL)
22966 | Some(DialectType::SQLite)
22967 );
22968
22969 for (i, (key, value)) in f.pairs.iter().enumerate() {
22970 if i > 0 {
22971 self.write(", ");
22972 }
22973 self.generate_expression(key)?;
22974 if use_comma_syntax {
22975 self.write(", ");
22976 } else {
22977 self.write(": ");
22978 }
22979 self.generate_expression(value)?;
22980 }
22981 }
22982 if let Some(null_handling) = f.null_handling {
22983 self.write_space();
22984 match null_handling {
22985 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
22986 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
22987 }
22988 }
22989 if f.with_unique_keys {
22990 self.write_space();
22991 self.write_keyword("WITH UNIQUE KEYS");
22992 }
22993 if let Some(ref ret_type) = f.returning_type {
22994 self.write_space();
22995 self.write_keyword("RETURNING");
22996 self.write_space();
22997 self.generate_data_type(ret_type)?;
22998 if f.format_json {
22999 self.write_space();
23000 self.write_keyword("FORMAT JSON");
23001 }
23002 if let Some(ref enc) = f.encoding {
23003 self.write_space();
23004 self.write_keyword("ENCODING");
23005 self.write_space();
23006 self.write(enc);
23007 }
23008 }
23009 self.write(")");
23010 Ok(())
23011 }
23012
23013 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
23014 self.write_keyword(name);
23015 self.write("(");
23016 self.generate_expression(&f.this)?;
23017 for (path, value) in &f.path_values {
23018 self.write(", ");
23019 self.generate_expression(path)?;
23020 self.write(", ");
23021 self.generate_expression(value)?;
23022 }
23023 self.write(")");
23024 Ok(())
23025 }
23026
23027 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
23028 self.write_keyword("JSON_ARRAYAGG");
23029 self.write("(");
23030 self.generate_expression(&f.this)?;
23031 if let Some(ref order_by) = f.order_by {
23032 self.write_space();
23033 self.write_keyword("ORDER BY");
23034 self.write_space();
23035 for (i, ord) in order_by.iter().enumerate() {
23036 if i > 0 {
23037 self.write(", ");
23038 }
23039 self.generate_ordered(ord)?;
23040 }
23041 }
23042 if let Some(null_handling) = f.null_handling {
23043 self.write_space();
23044 match null_handling {
23045 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
23046 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
23047 }
23048 }
23049 self.write(")");
23050 if let Some(ref filter) = f.filter {
23051 self.write_space();
23052 self.write_keyword("FILTER");
23053 self.write("(");
23054 self.write_keyword("WHERE");
23055 self.write_space();
23056 self.generate_expression(filter)?;
23057 self.write(")");
23058 }
23059 Ok(())
23060 }
23061
23062 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
23063 self.write_keyword("JSON_OBJECTAGG");
23064 self.write("(");
23065 self.generate_expression(&f.key)?;
23066 self.write(": ");
23067 self.generate_expression(&f.value)?;
23068 if let Some(null_handling) = f.null_handling {
23069 self.write_space();
23070 match null_handling {
23071 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
23072 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
23073 }
23074 }
23075 self.write(")");
23076 if let Some(ref filter) = f.filter {
23077 self.write_space();
23078 self.write_keyword("FILTER");
23079 self.write("(");
23080 self.write_keyword("WHERE");
23081 self.write_space();
23082 self.generate_expression(filter)?;
23083 self.write(")");
23084 }
23085 Ok(())
23086 }
23087
23088 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
23091 use crate::dialects::DialectType;
23092
23093 if self.config.dialect == Some(DialectType::Redshift) {
23095 self.write_keyword("CAST");
23096 self.write("(");
23097 self.generate_expression(&f.this)?;
23098 self.write_space();
23099 self.write_keyword("AS");
23100 self.write_space();
23101 self.generate_data_type(&f.to)?;
23102 self.write(")");
23103 return Ok(());
23104 }
23105
23106 self.write_keyword("CONVERT");
23107 self.write("(");
23108 self.generate_data_type(&f.to)?;
23109 self.write(", ");
23110 self.generate_expression(&f.this)?;
23111 if let Some(ref style) = f.style {
23112 self.write(", ");
23113 self.generate_expression(style)?;
23114 }
23115 self.write(")");
23116 Ok(())
23117 }
23118
23119 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
23122 if f.colon {
23123 self.write_keyword("LAMBDA");
23125 self.write_space();
23126 for (i, param) in f.parameters.iter().enumerate() {
23127 if i > 0 {
23128 self.write(", ");
23129 }
23130 self.generate_identifier(param)?;
23131 }
23132 self.write(" : ");
23133 } else {
23134 if f.parameters.len() == 1 {
23136 self.generate_identifier(&f.parameters[0])?;
23137 } else {
23138 self.write("(");
23139 for (i, param) in f.parameters.iter().enumerate() {
23140 if i > 0 {
23141 self.write(", ");
23142 }
23143 self.generate_identifier(param)?;
23144 }
23145 self.write(")");
23146 }
23147 self.write(" -> ");
23148 }
23149 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23150 if let Expression::Lambda(inner) = &f.body {
23151 self.generate_lambda_with_parenthesized_single_param(inner)?;
23152 return Ok(());
23153 }
23154 }
23155
23156 self.generate_expression(&f.body)
23157 }
23158
23159 fn generate_lambda_with_parenthesized_single_param(&mut self, f: &LambdaExpr) -> Result<()> {
23160 if f.colon {
23161 return self.generate_lambda(f);
23162 }
23163
23164 self.write("(");
23165 for (i, param) in f.parameters.iter().enumerate() {
23166 if i > 0 {
23167 self.write(", ");
23168 }
23169 self.generate_identifier(param)?;
23170 }
23171 self.write(") -> ");
23172 self.generate_expression(&f.body)
23173 }
23174
23175 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
23176 self.generate_identifier(&f.name)?;
23177 match f.separator {
23178 NamedArgSeparator::DArrow => self.write(" => "),
23179 NamedArgSeparator::ColonEq => self.write(" := "),
23180 NamedArgSeparator::Eq => self.write(" = "),
23181 }
23182 self.generate_expression(&f.value)
23183 }
23184
23185 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
23186 self.write_keyword(&f.prefix);
23187 self.write(" ");
23188 self.generate_expression(&f.this)
23189 }
23190
23191 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
23192 match f.style {
23193 ParameterStyle::Question => self.write("?"),
23194 ParameterStyle::Dollar => {
23195 if let Some(idx) = f.index {
23196 if matches!(
23197 self.config.dialect,
23198 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23199 ) {
23200 self.write("@P");
23201 self.write(&idx.to_string());
23202 } else {
23203 self.write("$");
23204 self.write(&idx.to_string());
23205 }
23206 } else {
23207 self.write("$");
23208 if let Some(ref name) = f.name {
23209 self.write(name);
23211 }
23212 }
23213 }
23214 ParameterStyle::DollarBrace => {
23215 self.write("${");
23217 if let Some(ref name) = f.name {
23218 self.write(name);
23219 }
23220 if let Some(ref expr) = f.expression {
23221 self.write(":");
23222 self.write(expr);
23223 }
23224 self.write("}");
23225 }
23226 ParameterStyle::Colon => {
23227 self.write(":");
23228 if let Some(idx) = f.index {
23229 self.write(&idx.to_string());
23230 } else if let Some(ref name) = f.name {
23231 self.write(name);
23232 }
23233 }
23234 ParameterStyle::At => {
23235 self.write("@");
23236 if let Some(ref name) = f.name {
23237 if f.string_quoted {
23238 self.write("'");
23239 self.write(name);
23240 self.write("'");
23241 } else if f.quoted {
23242 self.write("\"");
23243 self.write(name);
23244 self.write("\"");
23245 } else {
23246 self.write(name);
23247 }
23248 }
23249 }
23250 ParameterStyle::DoubleAt => {
23251 self.write("@@");
23252 if let Some(ref name) = f.name {
23253 self.write(name);
23254 }
23255 }
23256 ParameterStyle::DoubleDollar => {
23257 self.write("$$");
23258 if let Some(ref name) = f.name {
23259 self.write(name);
23260 }
23261 }
23262 ParameterStyle::Percent => {
23263 if let Some(ref name) = f.name {
23264 self.write("%(");
23266 self.write(name);
23267 self.write(")s");
23268 } else {
23269 self.write("%s");
23271 }
23272 }
23273 ParameterStyle::Brace => {
23274 self.write("{");
23277 if let Some(ref name) = f.name {
23278 self.write(name);
23279 }
23280 if let Some(ref expr) = f.expression {
23281 self.write(": ");
23282 self.write(expr);
23283 }
23284 self.write("}");
23285 }
23286 }
23287 Ok(())
23288 }
23289
23290 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
23291 self.write("?");
23292 if let Some(idx) = f.index {
23293 self.write(&idx.to_string());
23294 }
23295 Ok(())
23296 }
23297
23298 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
23299 if f.is_block {
23300 self.write("/*");
23301 self.write(&f.text);
23302 self.write("*/");
23303 } else {
23304 self.write("--");
23305 self.write(&f.text);
23306 }
23307 Ok(())
23308 }
23309
23310 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
23313 self.generate_expression(&f.this)?;
23314 if f.not {
23315 self.write_space();
23316 self.write_keyword("NOT");
23317 }
23318 self.write_space();
23319 self.write_keyword("SIMILAR TO");
23320 self.write_space();
23321 self.generate_expression(&f.pattern)?;
23322 if let Some(ref escape) = f.escape {
23323 self.write_space();
23324 self.write_keyword("ESCAPE");
23325 self.write_space();
23326 self.generate_expression(escape)?;
23327 }
23328 Ok(())
23329 }
23330
23331 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
23332 self.generate_expression(&f.this)?;
23333 self.write_space();
23334 if let Some(op) = &f.op {
23336 match op {
23337 QuantifiedOp::Eq => self.write("="),
23338 QuantifiedOp::Neq => self.write("<>"),
23339 QuantifiedOp::Lt => self.write("<"),
23340 QuantifiedOp::Lte => self.write("<="),
23341 QuantifiedOp::Gt => self.write(">"),
23342 QuantifiedOp::Gte => self.write(">="),
23343 }
23344 self.write_space();
23345 }
23346 self.write_keyword(name);
23347
23348 if matches!(&f.subquery, Expression::Subquery(_)) {
23350 self.write_space();
23351 self.generate_expression(&f.subquery)?;
23352 } else {
23353 let is_statement = matches!(
23354 &f.subquery,
23355 Expression::Select(_)
23356 | Expression::Union(_)
23357 | Expression::Intersect(_)
23358 | Expression::Except(_)
23359 );
23360 if is_statement
23361 && !self.config.quantified_no_paren_space
23362 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
23363 {
23364 self.write_space();
23365 }
23366 self.write("(");
23367
23368 if self.config.pretty && is_statement {
23369 self.write_newline();
23370 self.indent_level += 1;
23371 self.write_indent();
23372 }
23373 self.generate_expression(&f.subquery)?;
23374 if self.config.pretty && is_statement {
23375 self.write_newline();
23376 self.indent_level -= 1;
23377 self.write_indent();
23378 }
23379 self.write(")");
23380 }
23381 Ok(())
23382 }
23383
23384 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
23385 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
23387 self.generate_expression(this)?;
23388 self.write_space();
23389 self.write_keyword("OVERLAPS");
23390 self.write_space();
23391 self.generate_expression(expr)?;
23392 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
23393 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
23394 {
23395 self.write("(");
23397 self.generate_expression(ls)?;
23398 self.write(", ");
23399 self.generate_expression(le)?;
23400 self.write(")");
23401 self.write_space();
23402 self.write_keyword("OVERLAPS");
23403 self.write_space();
23404 self.write("(");
23405 self.generate_expression(rs)?;
23406 self.write(", ");
23407 self.generate_expression(re)?;
23408 self.write(")");
23409 }
23410 Ok(())
23411 }
23412
23413 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
23416 use crate::dialects::DialectType;
23417
23418 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
23420 self.generate_expression(&cast.this)?;
23421 self.write(" !:> ");
23422 self.generate_data_type(&cast.to)?;
23423 return Ok(());
23424 }
23425
23426 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
23428 self.write_keyword("TRYCAST");
23429 self.write("(");
23430 self.generate_expression(&cast.this)?;
23431 self.write_space();
23432 self.write_keyword("AS");
23433 self.write_space();
23434 self.generate_data_type(&cast.to)?;
23435 self.write(")");
23436 return Ok(());
23437 }
23438
23439 let keyword = if matches!(
23441 self.config.dialect,
23442 Some(DialectType::Hive)
23443 | Some(DialectType::MySQL)
23444 | Some(DialectType::SQLite)
23445 | Some(DialectType::Oracle)
23446 | Some(DialectType::ClickHouse)
23447 | Some(DialectType::Redshift)
23448 | Some(DialectType::PostgreSQL)
23449 | Some(DialectType::StarRocks)
23450 | Some(DialectType::Doris)
23451 ) {
23452 "CAST"
23453 } else {
23454 "TRY_CAST"
23455 };
23456
23457 self.write_keyword(keyword);
23458 self.write("(");
23459 self.generate_expression(&cast.this)?;
23460 self.write_space();
23461 self.write_keyword("AS");
23462 self.write_space();
23463 self.generate_data_type(&cast.to)?;
23464
23465 if let Some(format) = &cast.format {
23467 self.write_space();
23468 self.write_keyword("FORMAT");
23469 self.write_space();
23470 self.generate_expression(format)?;
23471 }
23472
23473 self.write(")");
23474 Ok(())
23475 }
23476
23477 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
23478 self.write_keyword("SAFE_CAST");
23479 self.write("(");
23480 self.generate_expression(&cast.this)?;
23481 self.write_space();
23482 self.write_keyword("AS");
23483 self.write_space();
23484 self.generate_data_type(&cast.to)?;
23485
23486 if let Some(format) = &cast.format {
23488 self.write_space();
23489 self.write_keyword("FORMAT");
23490 self.write_space();
23491 self.generate_expression(format)?;
23492 }
23493
23494 self.write(")");
23495 Ok(())
23496 }
23497
23498 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
23501 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
23505 if needs_parens {
23506 self.write("(");
23507 }
23508 self.generate_expression(&s.this)?;
23509 if needs_parens {
23510 self.write(")");
23511 }
23512 self.write("[");
23513 self.generate_expression(&s.index)?;
23514 self.write("]");
23515 Ok(())
23516 }
23517
23518 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
23519 self.generate_expression(&d.this)?;
23520 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
23523 && matches!(
23524 &d.this,
23525 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
23526 );
23527 if use_colon {
23528 self.write(":");
23529 } else {
23530 self.write(".");
23531 }
23532 self.generate_identifier(&d.field)
23533 }
23534
23535 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
23536 self.generate_expression(&m.this)?;
23537 self.write(".");
23538 if m.method.quoted {
23541 let q = self.config.identifier_quote;
23542 self.write(&format!("{}{}{}", q, m.method.name, q));
23543 } else {
23544 self.write(&m.method.name);
23545 }
23546 self.write("(");
23547 for (i, arg) in m.args.iter().enumerate() {
23548 if i > 0 {
23549 self.write(", ");
23550 }
23551 self.generate_expression(arg)?;
23552 }
23553 self.write(")");
23554 Ok(())
23555 }
23556
23557 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
23558 let needs_parens = matches!(
23561 &s.this,
23562 Expression::JsonExtract(f) if f.arrow_syntax
23563 ) || matches!(
23564 &s.this,
23565 Expression::JsonExtractScalar(f) if f.arrow_syntax
23566 );
23567
23568 if needs_parens {
23569 self.write("(");
23570 }
23571 self.generate_expression(&s.this)?;
23572 if needs_parens {
23573 self.write(")");
23574 }
23575 self.write("[");
23576 if let Some(start) = &s.start {
23577 self.generate_expression(start)?;
23578 }
23579 self.write(":");
23580 if let Some(end) = &s.end {
23581 self.generate_expression(end)?;
23582 }
23583 self.write("]");
23584 Ok(())
23585 }
23586
23587 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
23588 match &op.left {
23592 Expression::Column(col) => {
23593 if let Some(table) = &col.table {
23596 self.generate_identifier(table)?;
23597 self.write(".");
23598 }
23599 self.generate_identifier(&col.name)?;
23600 if col.join_mark && self.config.supports_column_join_marks {
23602 self.write(" (+)");
23603 }
23604 if op.left_comments.is_empty() {
23606 for comment in &col.trailing_comments {
23607 self.write_space();
23608 self.write_formatted_comment(comment);
23609 }
23610 }
23611 }
23612 Expression::Add(inner_op)
23613 | Expression::Sub(inner_op)
23614 | Expression::Mul(inner_op)
23615 | Expression::Div(inner_op)
23616 | Expression::Concat(inner_op) => {
23617 self.generate_binary_op_no_trailing(inner_op, match &op.left {
23619 Expression::Add(_) => "+",
23620 Expression::Sub(_) => "-",
23621 Expression::Mul(_) => "*",
23622 Expression::Div(_) => "/",
23623 Expression::Concat(_) => "||",
23624 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
23625 })?;
23626 }
23627 _ => {
23628 self.generate_expression(&op.left)?;
23629 }
23630 }
23631 for comment in &op.left_comments {
23633 self.write_space();
23634 self.write_formatted_comment(comment);
23635 }
23636 if self.config.pretty
23637 && matches!(self.config.dialect, Some(DialectType::Snowflake))
23638 && (operator == "AND" || operator == "OR")
23639 {
23640 self.write_newline();
23641 self.write_indent();
23642 self.write_keyword(operator);
23643 } else {
23644 self.write_space();
23645 if operator.chars().all(|c| c.is_alphabetic()) {
23646 self.write_keyword(operator);
23647 } else {
23648 self.write(operator);
23649 }
23650 }
23651 for comment in &op.operator_comments {
23653 self.write_space();
23654 self.write_formatted_comment(comment);
23655 }
23656 self.write_space();
23657 self.generate_expression(&op.right)?;
23658 for comment in &op.trailing_comments {
23660 self.write_space();
23661 self.write_formatted_comment(comment);
23662 }
23663 Ok(())
23664 }
23665
23666 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
23667 let keyword = connector.keyword();
23668 let Some(terms) = self.flatten_connector_terms(op, connector) else {
23669 return self.generate_binary_op(op, keyword);
23670 };
23671
23672 let wrap_clickhouse_or_term = |generator: &mut Self, term: &Expression| -> Result<()> {
23673 let should_wrap = matches!(connector, ConnectorOperator::Or)
23674 && matches!(generator.config.dialect, Some(DialectType::ClickHouse))
23675 && matches!(
23676 generator.config.source_dialect,
23677 Some(DialectType::ClickHouse)
23678 )
23679 && matches!(term, Expression::And(_));
23680 if should_wrap {
23681 generator.write("(");
23682 generator.generate_expression(term)?;
23683 generator.write(")");
23684 } else {
23685 generator.generate_expression(term)?;
23686 }
23687 Ok(())
23688 };
23689
23690 wrap_clickhouse_or_term(self, terms[0])?;
23691 for term in terms.iter().skip(1) {
23692 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
23693 self.write_newline();
23694 self.write_indent();
23695 self.write_keyword(keyword);
23696 } else {
23697 self.write_space();
23698 self.write_keyword(keyword);
23699 }
23700 self.write_space();
23701 wrap_clickhouse_or_term(self, term)?;
23702 }
23703
23704 Ok(())
23705 }
23706
23707 fn flatten_connector_terms<'a>(
23708 &self,
23709 root: &'a BinaryOp,
23710 connector: ConnectorOperator,
23711 ) -> Option<Vec<&'a Expression>> {
23712 if !root.left_comments.is_empty()
23713 || !root.operator_comments.is_empty()
23714 || !root.trailing_comments.is_empty()
23715 {
23716 return None;
23717 }
23718
23719 let mut terms = Vec::new();
23720 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
23721
23722 while let Some(expr) = stack.pop() {
23723 match (connector, expr) {
23724 (ConnectorOperator::And, Expression::And(inner))
23725 if inner.left_comments.is_empty()
23726 && inner.operator_comments.is_empty()
23727 && inner.trailing_comments.is_empty() =>
23728 {
23729 stack.push(&inner.right);
23730 stack.push(&inner.left);
23731 }
23732 (ConnectorOperator::Or, Expression::Or(inner))
23733 if inner.left_comments.is_empty()
23734 && inner.operator_comments.is_empty()
23735 && inner.trailing_comments.is_empty() =>
23736 {
23737 stack.push(&inner.right);
23738 stack.push(&inner.left);
23739 }
23740 _ => terms.push(expr),
23741 }
23742 }
23743
23744 if terms.len() > 1 {
23745 Some(terms)
23746 } else {
23747 None
23748 }
23749 }
23750
23751 fn missing_closing_parens_outside_quotes(sql: &str) -> usize {
23752 let mut depth = 0usize;
23753 let mut quote: Option<char> = None;
23754 let mut chars = sql.chars().peekable();
23755
23756 while let Some(ch) = chars.next() {
23757 if let Some(quote_char) = quote {
23758 if ch == '\\' {
23759 chars.next();
23760 } else if ch == quote_char {
23761 if quote_char == '\'' && chars.peek() == Some(&'\'') {
23762 chars.next();
23763 } else {
23764 quote = None;
23765 }
23766 }
23767 continue;
23768 }
23769
23770 match ch {
23771 '\'' | '"' | '`' => quote = Some(ch),
23772 '(' => depth += 1,
23773 ')' => depth = depth.saturating_sub(1),
23774 _ => {}
23775 }
23776 }
23777
23778 depth
23779 }
23780
23781 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
23783 self.generate_like_op_inner(op, operator, false)
23784 }
23785
23786 fn generate_like_op_negated(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
23787 self.generate_like_op_inner(op, operator, true)
23788 }
23789
23790 fn generate_like_op_inner(&mut self, op: &LikeOp, operator: &str, negated: bool) -> Result<()> {
23791 if negated
23792 && matches!(
23793 self.config.dialect,
23794 Some(DialectType::ClickHouse)
23795 | Some(DialectType::DataFusion)
23796 | Some(DialectType::TSQL)
23797 | Some(DialectType::Fabric)
23798 )
23799 {
23800 self.write_keyword("NOT");
23801 self.write_space();
23802 return self.generate_like_op_inner(op, operator, false);
23803 }
23804
23805 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23806 if let Expression::Star(star) = &op.left {
23807 if star
23808 .except
23809 .as_ref()
23810 .is_some_and(|except| !except.is_empty())
23811 {
23812 if let Some(table) = &star.table {
23813 self.generate_identifier(table)?;
23814 self.write(".");
23815 }
23816 self.write("*");
23817 self.write_space();
23818 self.write_keyword(operator);
23819 if let Some(quantifier) = &op.quantifier {
23820 self.write_space();
23821 self.write_keyword(quantifier);
23822 self.write_space();
23823 } else {
23824 self.write_space();
23825 }
23826 self.generate_expression(&op.right)?;
23827 if let Some(escape) = &op.escape {
23828 self.write_space();
23829 self.write_keyword("ESCAPE");
23830 self.write_space();
23831 self.generate_expression(escape)?;
23832 }
23833 if let Some(except) = &star.except {
23834 self.write_space();
23835 self.write_keyword("EXCEPT");
23836 self.write(" (");
23837 for (i, col) in except.iter().enumerate() {
23838 if i > 0 {
23839 self.write(", ");
23840 }
23841 self.generate_identifier(col)?;
23842 }
23843 self.write(")");
23844 }
23845 return Ok(());
23846 }
23847 }
23848 }
23849
23850 self.generate_expression(&op.left)?;
23851 self.write_space();
23852 if negated {
23853 self.write_keyword("NOT");
23854 self.write_space();
23855 }
23856 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
23858 self.write("`ILIKE`");
23859 } else {
23860 self.write_keyword(operator);
23861 }
23862 if let Some(quantifier) = &op.quantifier {
23863 self.write_space();
23864 self.write_keyword(quantifier);
23865 let is_any =
23870 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
23871 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
23872 self.write_space();
23873 }
23874 } else {
23875 self.write_space();
23876 }
23877 self.generate_expression(&op.right)?;
23878 if let Some(escape) = &op.escape {
23879 self.write_space();
23880 self.write_keyword("ESCAPE");
23881 self.write_space();
23882 self.generate_expression(escape)?;
23883 }
23884 Ok(())
23885 }
23886
23887 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
23890 use crate::dialects::DialectType;
23891 self.generate_expression(&op.left)?;
23892 self.write_space();
23893 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
23894 self.write("<=>");
23895 } else {
23896 self.write_keyword("IS NOT DISTINCT FROM");
23897 }
23898 self.write_space();
23899 self.generate_expression(&op.right)?;
23900 Ok(())
23901 }
23902
23903 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
23905 self.generate_expression(&op.left)?;
23906 self.write_space();
23907 self.write_keyword("IS DISTINCT FROM");
23908 self.write_space();
23909 self.generate_expression(&op.right)?;
23910 Ok(())
23911 }
23912
23913 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
23915 match &op.left {
23917 Expression::Column(col) => {
23918 if let Some(table) = &col.table {
23919 self.generate_identifier(table)?;
23920 self.write(".");
23921 }
23922 self.generate_identifier(&col.name)?;
23923 if col.join_mark && self.config.supports_column_join_marks {
23925 self.write(" (+)");
23926 }
23927 }
23928 Expression::Add(inner_op)
23929 | Expression::Sub(inner_op)
23930 | Expression::Mul(inner_op)
23931 | Expression::Div(inner_op)
23932 | Expression::Concat(inner_op) => {
23933 self.generate_binary_op_no_trailing(inner_op, match &op.left {
23934 Expression::Add(_) => "+",
23935 Expression::Sub(_) => "-",
23936 Expression::Mul(_) => "*",
23937 Expression::Div(_) => "/",
23938 Expression::Concat(_) => "||",
23939 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
23940 })?;
23941 }
23942 _ => {
23943 self.generate_expression(&op.left)?;
23944 }
23945 }
23946 for comment in &op.left_comments {
23948 self.write_space();
23949 self.write_formatted_comment(comment);
23950 }
23951 self.write_space();
23952 if operator.chars().all(|c| c.is_alphabetic()) {
23953 self.write_keyword(operator);
23954 } else {
23955 self.write(operator);
23956 }
23957 for comment in &op.operator_comments {
23959 self.write_space();
23960 self.write_formatted_comment(comment);
23961 }
23962 self.write_space();
23963 match &op.right {
23966 Expression::Column(col) => {
23967 if let Some(table) = &col.table {
23968 self.generate_identifier(table)?;
23969 self.write(".");
23970 }
23971 self.generate_identifier(&col.name)?;
23972 if col.join_mark && self.config.supports_column_join_marks {
23974 self.write(" (+)");
23975 }
23976 }
23977 _ => {
23978 self.generate_expression(&op.right)?;
23979 }
23980 }
23981 Ok(())
23983 }
23984
23985 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
23986 if operator.chars().all(|c| c.is_alphabetic()) {
23987 self.write_keyword(operator);
23988 self.write_space();
23989 } else {
23990 self.write(operator);
23991 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
23993 self.write_space();
23994 }
23995 }
23996 self.generate_expression(&op.this)
23997 }
23998
23999 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
24000 let is_generic =
24004 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
24005 let use_prefix_not =
24006 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
24007 if use_prefix_not {
24008 self.write_keyword("NOT");
24009 self.write_space();
24010 }
24011 self.generate_expression(&in_expr.this)?;
24012 if in_expr.global {
24013 self.write_space();
24014 self.write_keyword("GLOBAL");
24015 }
24016 if in_expr.not && !use_prefix_not {
24017 self.write_space();
24018 self.write_keyword("NOT");
24019 }
24020 self.write_space();
24021 self.write_keyword("IN");
24022
24023 if let Some(unnest_expr) = &in_expr.unnest {
24025 self.write_space();
24026 self.write_keyword("UNNEST");
24027 self.write("(");
24028 self.generate_expression(unnest_expr)?;
24029 self.write(")");
24030 return Ok(());
24031 }
24032
24033 if let Some(query) = &in_expr.query {
24034 let is_bare = in_expr.expressions.is_empty()
24037 && !matches!(
24038 query,
24039 Expression::Select(_)
24040 | Expression::Union(_)
24041 | Expression::Intersect(_)
24042 | Expression::Except(_)
24043 | Expression::Subquery(_)
24044 );
24045 if is_bare {
24046 self.write_space();
24048 self.generate_expression(query)?;
24049 } else {
24050 self.write(" (");
24052 let is_statement = matches!(
24053 query,
24054 Expression::Select(_)
24055 | Expression::Union(_)
24056 | Expression::Intersect(_)
24057 | Expression::Except(_)
24058 | Expression::Subquery(_)
24059 );
24060 if self.config.pretty && is_statement {
24061 self.write_newline();
24062 self.indent_level += 1;
24063 self.write_indent();
24064 }
24065 self.generate_expression(query)?;
24066 if self.config.pretty && is_statement {
24067 self.write_newline();
24068 self.indent_level -= 1;
24069 self.write_indent();
24070 }
24071 self.write(")");
24072 }
24073 } else {
24074 let is_duckdb = matches!(
24078 self.config.dialect,
24079 Some(crate::dialects::DialectType::DuckDB)
24080 );
24081 let is_clickhouse = matches!(
24082 self.config.dialect,
24083 Some(crate::dialects::DialectType::ClickHouse)
24084 );
24085 let single_expr = in_expr.expressions.len() == 1;
24086 if is_clickhouse && single_expr {
24087 if let Expression::Array(arr) = &in_expr.expressions[0] {
24088 self.write(" (");
24090 for (i, expr) in arr.expressions.iter().enumerate() {
24091 if i > 0 {
24092 self.write(", ");
24093 }
24094 self.generate_expression(expr)?;
24095 }
24096 self.write(")");
24097 } else if in_expr.is_field {
24098 self.write_space();
24099 self.generate_expression(&in_expr.expressions[0])?;
24100 } else {
24101 self.write(" (");
24102 self.generate_expression(&in_expr.expressions[0])?;
24103 self.write(")");
24104 }
24105 } else {
24106 let is_bare_ref = single_expr
24107 && matches!(
24108 &in_expr.expressions[0],
24109 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
24110 );
24111 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
24112 self.write_space();
24115 self.generate_expression(&in_expr.expressions[0])?;
24116 } else {
24117 self.write(" (");
24119 for (i, expr) in in_expr.expressions.iter().enumerate() {
24120 if i > 0 {
24121 self.write(", ");
24122 }
24123 self.generate_expression(expr)?;
24124 }
24125 self.write(")");
24126 }
24127 }
24128 }
24129
24130 Ok(())
24131 }
24132
24133 fn generate_between(&mut self, between: &Between) -> Result<()> {
24134 let use_prefix_not = between.not
24136 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
24137 if use_prefix_not {
24138 self.write_keyword("NOT");
24139 self.write_space();
24140 }
24141 self.generate_expression(&between.this)?;
24142 if between.not && !use_prefix_not {
24143 self.write_space();
24144 self.write_keyword("NOT");
24145 }
24146 self.write_space();
24147 self.write_keyword("BETWEEN");
24148 if let Some(sym) = between.symmetric {
24150 if sym {
24151 self.write(" SYMMETRIC");
24152 } else {
24153 self.write(" ASYMMETRIC");
24154 }
24155 }
24156 self.write_space();
24157 self.generate_expression(&between.low)?;
24158 self.write_space();
24159 self.write_keyword("AND");
24160 self.write_space();
24161 self.generate_expression(&between.high)
24162 }
24163
24164 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
24165 let use_prefix_not = is_null.not
24167 && (self.config.dialect.is_none()
24168 || self.config.dialect == Some(DialectType::Generic)
24169 || is_null.postfix_form);
24170 if use_prefix_not {
24171 self.write_keyword("NOT");
24173 self.write_space();
24174 self.generate_expression(&is_null.this)?;
24175 self.write_space();
24176 self.write_keyword("IS");
24177 self.write_space();
24178 self.write_keyword("NULL");
24179 } else {
24180 self.generate_expression(&is_null.this)?;
24181 self.write_space();
24182 self.write_keyword("IS");
24183 if is_null.not {
24184 self.write_space();
24185 self.write_keyword("NOT");
24186 }
24187 self.write_space();
24188 self.write_keyword("NULL");
24189 }
24190 Ok(())
24191 }
24192
24193 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
24194 self.generate_expression(&is_true.this)?;
24195 self.write_space();
24196 self.write_keyword("IS");
24197 if is_true.not {
24198 self.write_space();
24199 self.write_keyword("NOT");
24200 }
24201 self.write_space();
24202 self.write_keyword("TRUE");
24203 Ok(())
24204 }
24205
24206 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
24207 self.generate_expression(&is_false.this)?;
24208 self.write_space();
24209 self.write_keyword("IS");
24210 if is_false.not {
24211 self.write_space();
24212 self.write_keyword("NOT");
24213 }
24214 self.write_space();
24215 self.write_keyword("FALSE");
24216 Ok(())
24217 }
24218
24219 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
24220 self.generate_expression(&is_json.this)?;
24221 self.write_space();
24222 self.write_keyword("IS");
24223 if is_json.negated {
24224 self.write_space();
24225 self.write_keyword("NOT");
24226 }
24227 self.write_space();
24228 self.write_keyword("JSON");
24229
24230 if let Some(ref json_type) = is_json.json_type {
24232 self.write_space();
24233 self.write_keyword(json_type);
24234 }
24235
24236 match &is_json.unique_keys {
24238 Some(JsonUniqueKeys::With) => {
24239 self.write_space();
24240 self.write_keyword("WITH UNIQUE KEYS");
24241 }
24242 Some(JsonUniqueKeys::Without) => {
24243 self.write_space();
24244 self.write_keyword("WITHOUT UNIQUE KEYS");
24245 }
24246 Some(JsonUniqueKeys::Shorthand) => {
24247 self.write_space();
24248 self.write_keyword("UNIQUE KEYS");
24249 }
24250 None => {}
24251 }
24252
24253 Ok(())
24254 }
24255
24256 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
24257 self.generate_expression(&is_expr.left)?;
24258 self.write_space();
24259 self.write_keyword("IS");
24260 self.write_space();
24261 self.generate_expression(&is_expr.right)
24262 }
24263
24264 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
24265 if exists.not {
24266 self.write_keyword("NOT");
24267 self.write_space();
24268 }
24269 self.write_keyword("EXISTS");
24270 self.write("(");
24271 let is_statement = matches!(
24272 &exists.this,
24273 Expression::Select(_)
24274 | Expression::Union(_)
24275 | Expression::Intersect(_)
24276 | Expression::Except(_)
24277 );
24278 if self.config.pretty && is_statement {
24279 self.write_newline();
24280 self.indent_level += 1;
24281 self.write_indent();
24282 self.generate_expression(&exists.this)?;
24283 self.write_newline();
24284 self.indent_level -= 1;
24285 self.write_indent();
24286 self.write(")");
24287 } else {
24288 self.generate_expression(&exists.this)?;
24289 self.write(")");
24290 }
24291 Ok(())
24292 }
24293
24294 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
24295 self.generate_expression(&op.left)?;
24296 self.write_space();
24297 self.write_keyword("MEMBER OF");
24298 self.write("(");
24299 self.generate_expression(&op.right)?;
24300 self.write(")");
24301 Ok(())
24302 }
24303
24304 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
24305 if subquery.lateral {
24306 self.write_keyword("LATERAL");
24307 self.write_space();
24308 }
24309
24310 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
24314 matches!(
24315 &p.this,
24316 Expression::Select(_)
24317 | Expression::Union(_)
24318 | Expression::Intersect(_)
24319 | Expression::Except(_)
24320 | Expression::Subquery(_)
24321 )
24322 } else {
24323 false
24324 };
24325
24326 let is_statement = matches!(
24328 &subquery.this,
24329 Expression::Select(_)
24330 | Expression::Union(_)
24331 | Expression::Intersect(_)
24332 | Expression::Except(_)
24333 | Expression::Merge(_)
24334 );
24335
24336 if !skip_outer_parens {
24337 self.write("(");
24338 if self.config.pretty && is_statement {
24339 self.write_newline();
24340 self.indent_level += 1;
24341 self.write_indent();
24342 }
24343 }
24344 self.generate_expression(&subquery.this)?;
24345
24346 if subquery.modifiers_inside {
24348 if let Some(order_by) = &subquery.order_by {
24350 self.write_space();
24351 self.write_keyword("ORDER BY");
24352 self.write_space();
24353 for (i, ord) in order_by.expressions.iter().enumerate() {
24354 if i > 0 {
24355 self.write(", ");
24356 }
24357 self.generate_ordered(ord)?;
24358 }
24359 }
24360
24361 if let Some(limit) = &subquery.limit {
24362 self.write_space();
24363 self.write_keyword("LIMIT");
24364 self.write_space();
24365 self.generate_expression(&limit.this)?;
24366 if limit.percent {
24367 self.write_space();
24368 self.write_keyword("PERCENT");
24369 }
24370 }
24371
24372 if let Some(offset) = &subquery.offset {
24373 self.write_space();
24374 self.write_keyword("OFFSET");
24375 self.write_space();
24376 self.generate_expression(&offset.this)?;
24377 }
24378 }
24379
24380 if !skip_outer_parens {
24381 if self.config.pretty && is_statement {
24382 self.write_newline();
24383 self.indent_level -= 1;
24384 self.write_indent();
24385 }
24386 self.write(")");
24387 }
24388
24389 if !subquery.modifiers_inside {
24391 if let Some(order_by) = &subquery.order_by {
24392 self.write_space();
24393 self.write_keyword("ORDER BY");
24394 self.write_space();
24395 for (i, ord) in order_by.expressions.iter().enumerate() {
24396 if i > 0 {
24397 self.write(", ");
24398 }
24399 self.generate_ordered(ord)?;
24400 }
24401 }
24402
24403 if let Some(limit) = &subquery.limit {
24404 self.write_space();
24405 self.write_keyword("LIMIT");
24406 self.write_space();
24407 self.generate_expression(&limit.this)?;
24408 if limit.percent {
24409 self.write_space();
24410 self.write_keyword("PERCENT");
24411 }
24412 }
24413
24414 if let Some(offset) = &subquery.offset {
24415 self.write_space();
24416 self.write_keyword("OFFSET");
24417 self.write_space();
24418 self.generate_expression(&offset.this)?;
24419 }
24420
24421 if let Some(distribute_by) = &subquery.distribute_by {
24423 self.write_space();
24424 self.write_keyword("DISTRIBUTE BY");
24425 self.write_space();
24426 for (i, expr) in distribute_by.expressions.iter().enumerate() {
24427 if i > 0 {
24428 self.write(", ");
24429 }
24430 self.generate_expression(expr)?;
24431 }
24432 }
24433
24434 if let Some(sort_by) = &subquery.sort_by {
24436 self.write_space();
24437 self.write_keyword("SORT BY");
24438 self.write_space();
24439 for (i, ord) in sort_by.expressions.iter().enumerate() {
24440 if i > 0 {
24441 self.write(", ");
24442 }
24443 self.generate_ordered(ord)?;
24444 }
24445 }
24446
24447 if let Some(cluster_by) = &subquery.cluster_by {
24449 self.write_space();
24450 self.write_keyword("CLUSTER BY");
24451 self.write_space();
24452 for (i, ord) in cluster_by.expressions.iter().enumerate() {
24453 if i > 0 {
24454 self.write(", ");
24455 }
24456 self.generate_ordered(ord)?;
24457 }
24458 }
24459 }
24460
24461 if let Some(alias) = &subquery.alias {
24462 self.write_space();
24463 let skip_as = matches!(self.config.dialect, Some(DialectType::Oracle))
24464 || (matches!(self.config.dialect, Some(DialectType::ClickHouse))
24465 && !subquery.alias_explicit_as);
24466 if !skip_as {
24467 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24468 self.write(subquery.alias_keyword.as_deref().unwrap_or("AS"));
24469 } else {
24470 self.write_keyword("AS");
24471 }
24472 self.write_space();
24473 }
24474 self.generate_identifier(alias)?;
24475 if !subquery.column_aliases.is_empty() {
24476 self.write("(");
24477 for (i, col) in subquery.column_aliases.iter().enumerate() {
24478 if i > 0 {
24479 self.write(", ");
24480 }
24481 self.generate_identifier(col)?;
24482 }
24483 self.write(")");
24484 }
24485 }
24486 for comment in &subquery.trailing_comments {
24488 self.write(" ");
24489 self.write_formatted_comment(comment);
24490 }
24491 Ok(())
24492 }
24493
24494 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
24495 if let Some(ref with) = pivot.with {
24497 self.generate_with(with)?;
24498 self.write_space();
24499 }
24500
24501 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
24502
24503 let is_redshift_unpivot = pivot.unpivot
24507 && pivot.expressions.is_empty()
24508 && pivot.fields.is_empty()
24509 && pivot.using.is_empty()
24510 && pivot.into.is_none()
24511 && !matches!(&pivot.this, Expression::Null(_));
24512
24513 if is_redshift_unpivot {
24514 self.write_keyword("UNPIVOT");
24516 self.write_space();
24517 self.generate_expression(&pivot.this)?;
24518 if let Some(alias) = &pivot.alias {
24520 self.write_space();
24521 self.write_keyword("AS");
24522 self.write_space();
24523 self.write(&alias.name);
24525 }
24526 return Ok(());
24527 }
24528
24529 let is_simplified = !pivot.using.is_empty()
24531 || pivot.into.is_some()
24532 || (pivot.fields.is_empty()
24533 && !pivot.expressions.is_empty()
24534 && !matches!(&pivot.this, Expression::Null(_)));
24535
24536 if is_simplified {
24537 self.write_keyword(direction);
24541 self.write_space();
24542 self.generate_expression(&pivot.this)?;
24543
24544 if !pivot.expressions.is_empty() {
24545 self.write_space();
24546 self.write_keyword("ON");
24547 self.write_space();
24548 for (i, expr) in pivot.expressions.iter().enumerate() {
24549 if i > 0 {
24550 self.write(", ");
24551 }
24552 self.generate_expression(expr)?;
24553 }
24554 }
24555
24556 if let Some(into) = &pivot.into {
24558 self.write_space();
24559 self.write_keyword("INTO");
24560 self.write_space();
24561 self.generate_expression(into)?;
24562 }
24563
24564 if !pivot.using.is_empty() {
24566 self.write_space();
24567 self.write_keyword("USING");
24568 self.write_space();
24569 for (i, expr) in pivot.using.iter().enumerate() {
24570 if i > 0 {
24571 self.write(", ");
24572 }
24573 self.generate_expression(expr)?;
24574 }
24575 }
24576
24577 if let Some(group) = &pivot.group {
24579 self.write_space();
24580 self.generate_expression(group)?;
24581 }
24582 } else {
24583 if !matches!(&pivot.this, Expression::Null(_)) {
24588 self.generate_expression(&pivot.this)?;
24589 self.write_space();
24590 }
24591 self.write_keyword(direction);
24592 self.write("(");
24593
24594 for (i, expr) in pivot.expressions.iter().enumerate() {
24596 if i > 0 {
24597 self.write(", ");
24598 }
24599 self.generate_expression(expr)?;
24600 }
24601
24602 if !pivot.fields.is_empty() {
24604 if !pivot.expressions.is_empty() {
24605 self.write_space();
24606 }
24607 self.write_keyword("FOR");
24608 self.write_space();
24609 for (i, field) in pivot.fields.iter().enumerate() {
24610 if i > 0 {
24611 self.write_space();
24612 }
24613 self.generate_expression(field)?;
24615 }
24616 }
24617
24618 if let Some(default_val) = &pivot.default_on_null {
24620 self.write_space();
24621 self.write_keyword("DEFAULT ON NULL");
24622 self.write(" (");
24623 self.generate_expression(default_val)?;
24624 self.write(")");
24625 }
24626
24627 if let Some(group) = &pivot.group {
24629 self.write_space();
24630 self.generate_expression(group)?;
24631 }
24632
24633 self.write(")");
24634 }
24635
24636 if let Some(alias) = &pivot.alias {
24638 self.write_space();
24639 self.write_keyword("AS");
24640 self.write_space();
24641 self.generate_identifier(alias)?;
24642 self.generate_alias_column_list(&pivot.alias_columns)?;
24643 }
24644
24645 Ok(())
24646 }
24647
24648 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
24649 self.generate_expression(&unpivot.this)?;
24650 self.write_space();
24651 self.write_keyword("UNPIVOT");
24652 if let Some(include) = unpivot.include_nulls {
24654 self.write_space();
24655 if include {
24656 self.write_keyword("INCLUDE NULLS");
24657 } else {
24658 self.write_keyword("EXCLUDE NULLS");
24659 }
24660 self.write_space();
24661 }
24662 self.write("(");
24663 if unpivot.value_column_parenthesized {
24664 self.write("(");
24665 }
24666 self.generate_identifier(&unpivot.value_column)?;
24667 for extra_col in &unpivot.extra_value_columns {
24669 self.write(", ");
24670 self.generate_identifier(extra_col)?;
24671 }
24672 if unpivot.value_column_parenthesized {
24673 self.write(")");
24674 }
24675 self.write_space();
24676 self.write_keyword("FOR");
24677 self.write_space();
24678 self.generate_identifier(&unpivot.name_column)?;
24679 self.write_space();
24680 self.write_keyword("IN");
24681 self.write(" (");
24682 for (i, col) in unpivot.columns.iter().enumerate() {
24683 if i > 0 {
24684 self.write(", ");
24685 }
24686 self.generate_expression(col)?;
24687 }
24688 self.write("))");
24689 if let Some(alias) = &unpivot.alias {
24690 self.write_space();
24691 self.write_keyword("AS");
24692 self.write_space();
24693 self.generate_identifier(alias)?;
24694 self.generate_alias_column_list(&unpivot.alias_columns)?;
24695 }
24696 Ok(())
24697 }
24698
24699 fn generate_alias_column_list(&mut self, columns: &[Identifier]) -> Result<()> {
24700 if columns.is_empty() {
24701 return Ok(());
24702 }
24703
24704 self.write("(");
24705 for (i, column) in columns.iter().enumerate() {
24706 if i > 0 {
24707 self.write(", ");
24708 }
24709 self.generate_identifier(column)?;
24710 }
24711 self.write(")");
24712 Ok(())
24713 }
24714
24715 fn generate_values(&mut self, values: &Values) -> Result<()> {
24716 self.write_keyword("VALUES");
24717 for (i, row) in values.expressions.iter().enumerate() {
24718 if i > 0 {
24719 self.write(",");
24720 }
24721 self.write(" (");
24722 for (j, expr) in row.expressions.iter().enumerate() {
24723 if j > 0 {
24724 self.write(", ");
24725 }
24726 self.generate_expression(expr)?;
24727 }
24728 self.write(")");
24729 }
24730 if let Some(alias) = &values.alias {
24731 self.write_space();
24732 self.write_keyword("AS");
24733 self.write_space();
24734 self.generate_identifier(alias)?;
24735 if !values.column_aliases.is_empty() {
24736 self.write("(");
24737 for (i, col) in values.column_aliases.iter().enumerate() {
24738 if i > 0 {
24739 self.write(", ");
24740 }
24741 self.generate_identifier(col)?;
24742 }
24743 self.write(")");
24744 }
24745 }
24746 Ok(())
24747 }
24748
24749 fn generate_array(&mut self, arr: &Array) -> Result<()> {
24750 let needs_inheritance = matches!(
24752 self.config.dialect,
24753 Some(DialectType::DuckDB)
24754 | Some(DialectType::Spark)
24755 | Some(DialectType::Databricks)
24756 | Some(DialectType::Hive)
24757 | Some(DialectType::Snowflake)
24758 | Some(DialectType::Presto)
24759 | Some(DialectType::Trino)
24760 );
24761 let propagated: Vec<Expression>;
24762 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
24763 propagated = Self::inherit_struct_field_names(&arr.expressions);
24764 &propagated
24765 } else {
24766 &arr.expressions
24767 };
24768
24769 let use_parens =
24772 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
24773 if !self.config.array_bracket_only {
24774 self.write_keyword("ARRAY");
24775 }
24776 if use_parens {
24777 self.write("(");
24778 } else {
24779 self.write("[");
24780 }
24781 for (i, expr) in expressions.iter().enumerate() {
24782 if i > 0 {
24783 self.write(", ");
24784 }
24785 self.generate_expression(expr)?;
24786 }
24787 if use_parens {
24788 self.write(")");
24789 } else {
24790 self.write("]");
24791 }
24792 Ok(())
24793 }
24794
24795 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
24796 if tuple.expressions.len() == 2 {
24799 if let Expression::TableAlias(_) = &tuple.expressions[1] {
24800 self.generate_expression(&tuple.expressions[0])?;
24802 self.write_space();
24803 self.write_keyword("AS");
24804 self.write_space();
24805 self.generate_expression(&tuple.expressions[1])?;
24806 return Ok(());
24807 }
24808 }
24809
24810 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
24813 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
24814 for expr in &tuple.expressions {
24815 expr_strings.push(self.generate_to_string(expr)?);
24816 }
24817 self.too_wide(&expr_strings)
24818 } else {
24819 false
24820 };
24821
24822 if expand_tuple {
24823 self.write("(");
24824 self.write_newline();
24825 self.indent_level += 1;
24826 for (i, expr) in tuple.expressions.iter().enumerate() {
24827 if i > 0 {
24828 self.write(",");
24829 self.write_newline();
24830 }
24831 self.write_indent();
24832 self.generate_expression(expr)?;
24833 }
24834 self.indent_level -= 1;
24835 self.write_newline();
24836 self.write_indent();
24837 self.write(")");
24838 } else {
24839 self.write("(");
24840 for (i, expr) in tuple.expressions.iter().enumerate() {
24841 if i > 0 {
24842 self.write(", ");
24843 }
24844 self.generate_expression(expr)?;
24845 }
24846 self.write(")");
24847 }
24848 Ok(())
24849 }
24850
24851 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
24852 self.generate_expression(&pipe.this)?;
24853 self.write(" |> ");
24854 self.generate_expression(&pipe.expression)?;
24855 Ok(())
24856 }
24857
24858 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
24859 let unsupported_tsql_null_ordering = ordered.nulls_first.is_some()
24860 && !self.config.null_ordering_supported
24861 && matches!(
24862 self.config.dialect,
24863 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24864 );
24865 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
24866 let emulate_tsql_null_ordering = if let Some(nulls_first) = ordered.nulls_first {
24867 let target_default_nulls_first = !ordered.desc;
24868
24869 unsupported_tsql_null_ordering
24870 && nulls_first != target_default_nulls_first
24871 && !random_ordering
24872 } else {
24873 false
24874 };
24875
24876 if emulate_tsql_null_ordering {
24877 if Self::is_integer_ordering_literal(&ordered.this) {
24878 let nulls_order = if ordered.nulls_first == Some(true) {
24879 "NULLS FIRST"
24880 } else {
24881 "NULLS LAST"
24882 };
24883 self.unsupported(format!(
24884 "'{nulls_order}' translation not supported with positional ordering"
24885 ))?;
24886 } else {
24887 self.write_keyword("CASE WHEN");
24888 self.write_space();
24889 self.generate_expression(&ordered.this)?;
24890 self.write_space();
24891 self.write_keyword("IS NULL THEN 1 ELSE 0 END");
24892 if ordered.nulls_first == Some(true) {
24893 self.write_space();
24894 self.write_keyword("DESC");
24895 }
24896 self.write(", ");
24897 }
24898 }
24899
24900 self.generate_expression(&ordered.this)?;
24901 if ordered.desc {
24902 self.write_space();
24903 self.write_keyword("DESC");
24904 } else if ordered.explicit_asc {
24905 self.write_space();
24906 self.write_keyword("ASC");
24907 }
24908 if let Some(nulls_first) = ordered.nulls_first {
24909 if !unsupported_tsql_null_ordering
24910 && (self.config.null_ordering_supported
24911 || !matches!(self.config.dialect, Some(DialectType::Fabric)))
24912 {
24913 let is_asc = !ordered.desc;
24927 let is_nulls_are_large = matches!(
24928 self.config.dialect,
24929 Some(DialectType::Oracle)
24930 | Some(DialectType::PostgreSQL)
24931 | Some(DialectType::Redshift)
24932 | Some(DialectType::Snowflake)
24933 );
24934 let is_nulls_are_last = matches!(
24935 self.config.dialect,
24936 Some(DialectType::Dremio)
24937 | Some(DialectType::DuckDB)
24938 | Some(DialectType::Presto)
24939 | Some(DialectType::Trino)
24940 | Some(DialectType::Athena)
24941 | Some(DialectType::ClickHouse)
24942 | Some(DialectType::Drill)
24943 | Some(DialectType::Exasol)
24944 );
24945
24946 let is_default_nulls = if is_nulls_are_large {
24948 (is_asc && !nulls_first) || (!is_asc && nulls_first)
24950 } else if is_nulls_are_last {
24951 !nulls_first
24953 } else {
24954 false
24955 };
24956
24957 if !is_default_nulls {
24958 self.write_space();
24959 self.write_keyword("NULLS");
24960 self.write_space();
24961 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
24962 }
24963 }
24964 }
24965 if let Some(ref with_fill) = ordered.with_fill {
24967 self.write_space();
24968 self.generate_with_fill(with_fill)?;
24969 }
24970 Ok(())
24971 }
24972
24973 fn is_integer_ordering_literal(expr: &Expression) -> bool {
24974 matches!(
24975 expr,
24976 Expression::Literal(lit)
24977 if matches!(lit.as_ref(), Literal::Number(n) if n.parse::<u64>().is_ok())
24978 )
24979 }
24980
24981 fn write_clickhouse_type(&mut self, type_str: &str) {
24983 if self.clickhouse_nullable_depth < 0 {
24984 self.write(type_str);
24986 } else {
24987 self.write(&format!("Nullable({})", type_str));
24988 }
24989 }
24990
24991 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
24992 use crate::dialects::DialectType;
24993
24994 match dt {
24995 DataType::Boolean => {
24996 match self.config.dialect {
24998 Some(DialectType::TSQL) => self.write_keyword("BIT"),
24999 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
25001 self.write_keyword("NUMBER(1)")
25003 }
25004 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
25006 }
25007 }
25008 DataType::TinyInt { length } => {
25009 match self.config.dialect {
25013 Some(DialectType::PostgreSQL)
25014 | Some(DialectType::Redshift)
25015 | Some(DialectType::Oracle)
25016 | Some(DialectType::Exasol) => {
25017 self.write_keyword("SMALLINT");
25018 }
25019 Some(DialectType::Teradata) => {
25020 self.write_keyword("BYTEINT");
25022 }
25023 Some(DialectType::Dremio) => {
25024 self.write_keyword("INT");
25026 }
25027 Some(DialectType::ClickHouse) => {
25028 self.write_clickhouse_type("Int8");
25029 }
25030 _ => {
25031 self.write_keyword("TINYINT");
25032 }
25033 }
25034 if let Some(n) = length {
25035 if !matches!(
25036 self.config.dialect,
25037 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
25038 ) {
25039 self.write(&format!("({})", n));
25040 }
25041 }
25042 }
25043 DataType::SmallInt { length } => {
25044 match self.config.dialect {
25046 Some(DialectType::Dremio) => {
25047 self.write_keyword("INT");
25048 }
25049 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
25050 self.write_keyword("INTEGER");
25051 }
25052 Some(DialectType::BigQuery) => {
25053 self.write_keyword("INT64");
25054 }
25055 Some(DialectType::ClickHouse) => {
25056 self.write_clickhouse_type("Int16");
25057 }
25058 _ => {
25059 self.write_keyword("SMALLINT");
25060 if let Some(n) = length {
25061 self.write(&format!("({})", n));
25062 }
25063 }
25064 }
25065 }
25066 DataType::Int {
25067 length,
25068 integer_spelling: _,
25069 } => {
25070 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
25072 self.write_keyword("INT64");
25073 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25074 self.write_clickhouse_type("Int32");
25075 } else {
25076 let use_integer = match self.config.dialect {
25078 Some(DialectType::TSQL)
25079 | Some(DialectType::Fabric)
25080 | Some(DialectType::Presto)
25081 | Some(DialectType::Trino)
25082 | Some(DialectType::SQLite)
25083 | Some(DialectType::Redshift) => true,
25084 _ => false,
25085 };
25086 if use_integer {
25087 self.write_keyword("INTEGER");
25088 } else {
25089 self.write_keyword("INT");
25090 }
25091 if let Some(n) = length {
25092 self.write(&format!("({})", n));
25093 }
25094 }
25095 }
25096 DataType::BigInt { length } => {
25097 match self.config.dialect {
25099 Some(DialectType::Oracle) => {
25100 self.write_keyword("INT");
25102 }
25103 Some(DialectType::ClickHouse) => {
25104 self.write_clickhouse_type("Int64");
25105 }
25106 _ => {
25107 self.write_keyword("BIGINT");
25108 if let Some(n) = length {
25109 self.write(&format!("({})", n));
25110 }
25111 }
25112 }
25113 }
25114 DataType::Float {
25115 precision,
25116 scale,
25117 real_spelling,
25118 } => {
25119 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25123 self.write_clickhouse_type("Float32");
25124 } else if *real_spelling
25125 && !matches!(
25126 self.config.dialect,
25127 Some(DialectType::Spark)
25128 | Some(DialectType::Databricks)
25129 | Some(DialectType::Hive)
25130 | Some(DialectType::Snowflake)
25131 | Some(DialectType::MySQL)
25132 | Some(DialectType::BigQuery)
25133 )
25134 {
25135 self.write_keyword("REAL")
25136 } else {
25137 match self.config.dialect {
25138 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
25139 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
25140 _ => self.write_keyword("FLOAT"),
25141 }
25142 }
25143 if !matches!(
25146 self.config.dialect,
25147 Some(DialectType::Spark)
25148 | Some(DialectType::Databricks)
25149 | Some(DialectType::Hive)
25150 | Some(DialectType::Presto)
25151 | Some(DialectType::Trino)
25152 ) {
25153 if let Some(p) = precision {
25154 self.write(&format!("({}", p));
25155 if let Some(s) = scale {
25156 self.write(&format!(", {})", s));
25157 } else {
25158 self.write(")");
25159 }
25160 }
25161 }
25162 }
25163 DataType::Double { precision, scale } => {
25164 match self.config.dialect {
25166 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25167 self.write_keyword("FLOAT")
25168 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
25170 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
25171 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
25172 Some(DialectType::SQLite) => self.write_keyword("REAL"),
25173 Some(DialectType::PostgreSQL)
25174 | Some(DialectType::Redshift)
25175 | Some(DialectType::Teradata)
25176 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
25177 _ => self.write_keyword("DOUBLE"),
25178 }
25179 if let Some(p) = precision {
25181 self.write(&format!("({}", p));
25182 if let Some(s) = scale {
25183 self.write(&format!(", {})", s));
25184 } else {
25185 self.write(")");
25186 }
25187 }
25188 }
25189 DataType::Decimal { precision, scale } => {
25190 match self.config.dialect {
25192 Some(DialectType::ClickHouse) => {
25193 self.write("Decimal");
25194 if let Some(p) = precision {
25195 self.write(&format!("({}", p));
25196 if let Some(s) = scale {
25197 self.write(&format!(", {}", s));
25198 }
25199 self.write(")");
25200 }
25201 }
25202 Some(DialectType::Oracle) => {
25203 self.write_keyword("NUMBER");
25205 if let Some(p) = precision {
25206 self.write(&format!("({}", p));
25207 if let Some(s) = scale {
25208 self.write(&format!(", {}", s));
25209 }
25210 self.write(")");
25211 }
25212 }
25213 Some(DialectType::BigQuery) => {
25214 self.write_keyword("NUMERIC");
25216 if let Some(p) = precision {
25217 self.write(&format!("({}", p));
25218 if let Some(s) = scale {
25219 self.write(&format!(", {}", s));
25220 }
25221 self.write(")");
25222 }
25223 }
25224 _ => {
25225 self.write_keyword("DECIMAL");
25226 if let Some(p) = precision {
25227 self.write(&format!("({}", p));
25228 if let Some(s) = scale {
25229 self.write(&format!(", {}", s));
25230 }
25231 self.write(")");
25232 }
25233 }
25234 }
25235 }
25236 DataType::Char { length } => {
25237 match self.config.dialect {
25239 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25240 self.write_keyword("TEXT");
25242 }
25243 Some(DialectType::Hive)
25244 | Some(DialectType::Spark)
25245 | Some(DialectType::Databricks) => {
25246 if length.is_some()
25249 && !matches!(self.config.dialect, Some(DialectType::Hive))
25250 {
25251 self.write_keyword("CHAR");
25252 if let Some(n) = length {
25253 self.write(&format!("({})", n));
25254 }
25255 } else {
25256 self.write_keyword("STRING");
25257 }
25258 }
25259 Some(DialectType::Dremio) => {
25260 self.write_keyword("VARCHAR");
25262 if let Some(n) = length {
25263 self.write(&format!("({})", n));
25264 }
25265 }
25266 _ => {
25267 self.write_keyword("CHAR");
25268 if let Some(n) = length {
25269 self.write(&format!("({})", n));
25270 }
25271 }
25272 }
25273 }
25274 DataType::VarChar {
25275 length,
25276 parenthesized_length,
25277 } => {
25278 match self.config.dialect {
25280 Some(DialectType::Oracle) => {
25281 self.write_keyword("VARCHAR2");
25282 if let Some(n) = length {
25283 self.write(&format!("({})", n));
25284 }
25285 }
25286 Some(DialectType::DuckDB) => {
25287 self.write_keyword("TEXT");
25289 if let Some(n) = length {
25290 self.write(&format!("({})", n));
25291 }
25292 }
25293 Some(DialectType::SQLite) => {
25294 self.write_keyword("TEXT");
25296 if let Some(n) = length {
25297 self.write(&format!("({})", n));
25298 }
25299 }
25300 Some(DialectType::MySQL) if length.is_none() => {
25301 self.write_keyword("TEXT");
25303 }
25304 Some(DialectType::Hive)
25305 | Some(DialectType::Spark)
25306 | Some(DialectType::Databricks)
25307 if length.is_none() =>
25308 {
25309 self.write_keyword("STRING");
25311 }
25312 _ => {
25313 self.write_keyword("VARCHAR");
25314 if let Some(n) = length {
25315 if *parenthesized_length {
25317 self.write(&format!("(({}))", n));
25318 } else {
25319 self.write(&format!("({})", n));
25320 }
25321 }
25322 }
25323 }
25324 }
25325 DataType::Text => {
25326 match self.config.dialect {
25328 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
25329 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25330 self.write_keyword("VARCHAR(MAX)")
25331 }
25332 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
25333 Some(DialectType::Snowflake)
25334 | Some(DialectType::Dremio)
25335 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
25336 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
25337 Some(DialectType::Presto)
25338 | Some(DialectType::Trino)
25339 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
25340 Some(DialectType::Spark)
25341 | Some(DialectType::Databricks)
25342 | Some(DialectType::Hive) => self.write_keyword("STRING"),
25343 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
25344 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
25345 self.write_keyword("STRING")
25346 }
25347 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
25348 _ => self.write_keyword("TEXT"),
25349 }
25350 }
25351 DataType::TextWithLength { length } => {
25352 match self.config.dialect {
25354 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
25355 Some(DialectType::Hive)
25356 | Some(DialectType::Spark)
25357 | Some(DialectType::Databricks) => {
25358 self.write(&format!("VARCHAR({})", length));
25359 }
25360 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
25361 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
25362 Some(DialectType::Snowflake)
25363 | Some(DialectType::Presto)
25364 | Some(DialectType::Trino)
25365 | Some(DialectType::Athena)
25366 | Some(DialectType::Drill)
25367 | Some(DialectType::Dremio) => {
25368 self.write(&format!("VARCHAR({})", length));
25369 }
25370 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25371 self.write(&format!("VARCHAR({})", length))
25372 }
25373 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
25374 self.write(&format!("STRING({})", length))
25375 }
25376 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
25377 _ => self.write(&format!("TEXT({})", length)),
25378 }
25379 }
25380 DataType::String { length } => {
25381 match self.config.dialect {
25383 Some(DialectType::ClickHouse) => {
25384 self.write("String");
25386 if let Some(n) = length {
25387 self.write(&format!("({})", n));
25388 }
25389 }
25390 Some(DialectType::BigQuery)
25391 | Some(DialectType::Hive)
25392 | Some(DialectType::Spark)
25393 | Some(DialectType::Databricks)
25394 | Some(DialectType::StarRocks)
25395 | Some(DialectType::Doris) => {
25396 self.write_keyword("STRING");
25397 if let Some(n) = length {
25398 self.write(&format!("({})", n));
25399 }
25400 }
25401 Some(DialectType::PostgreSQL) => {
25402 if let Some(n) = length {
25404 self.write_keyword("VARCHAR");
25405 self.write(&format!("({})", n));
25406 } else {
25407 self.write_keyword("TEXT");
25408 }
25409 }
25410 Some(DialectType::Redshift) => {
25411 if let Some(n) = length {
25413 self.write_keyword("VARCHAR");
25414 self.write(&format!("({})", n));
25415 } else {
25416 self.write_keyword("VARCHAR(MAX)");
25417 }
25418 }
25419 Some(DialectType::MySQL) => {
25420 if let Some(n) = length {
25422 self.write_keyword("VARCHAR");
25423 self.write(&format!("({})", n));
25424 } else {
25425 self.write_keyword("TEXT");
25426 }
25427 }
25428 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25429 if let Some(n) = length {
25431 self.write_keyword("VARCHAR");
25432 self.write(&format!("({})", n));
25433 } else {
25434 self.write_keyword("VARCHAR(MAX)");
25435 }
25436 }
25437 Some(DialectType::Oracle) => {
25438 self.write_keyword("CLOB");
25440 }
25441 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
25442 self.write_keyword("TEXT");
25444 if let Some(n) = length {
25445 self.write(&format!("({})", n));
25446 }
25447 }
25448 Some(DialectType::Presto)
25449 | Some(DialectType::Trino)
25450 | Some(DialectType::Drill)
25451 | Some(DialectType::Dremio) => {
25452 self.write_keyword("VARCHAR");
25454 if let Some(n) = length {
25455 self.write(&format!("({})", n));
25456 }
25457 }
25458 Some(DialectType::Snowflake) => {
25459 self.write_keyword("STRING");
25462 if let Some(n) = length {
25463 self.write(&format!("({})", n));
25464 }
25465 }
25466 _ => {
25467 self.write_keyword("STRING");
25469 if let Some(n) = length {
25470 self.write(&format!("({})", n));
25471 }
25472 }
25473 }
25474 }
25475 DataType::Binary { length } => {
25476 match self.config.dialect {
25478 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25479 self.write_keyword("BYTEA");
25480 if let Some(n) = length {
25481 self.write(&format!("({})", n));
25482 }
25483 }
25484 Some(DialectType::Redshift) => {
25485 self.write_keyword("VARBYTE");
25486 if let Some(n) = length {
25487 self.write(&format!("({})", n));
25488 }
25489 }
25490 Some(DialectType::DuckDB)
25491 | Some(DialectType::SQLite)
25492 | Some(DialectType::Oracle) => {
25493 self.write_keyword("BLOB");
25495 if let Some(n) = length {
25496 self.write(&format!("({})", n));
25497 }
25498 }
25499 Some(DialectType::Presto)
25500 | Some(DialectType::Trino)
25501 | Some(DialectType::Athena)
25502 | Some(DialectType::Drill)
25503 | Some(DialectType::Dremio) => {
25504 self.write_keyword("VARBINARY");
25506 if let Some(n) = length {
25507 self.write(&format!("({})", n));
25508 }
25509 }
25510 Some(DialectType::ClickHouse) => {
25511 if self.clickhouse_nullable_depth < 0 {
25513 self.write("BINARY");
25514 } else {
25515 self.write("Nullable(BINARY");
25516 }
25517 if let Some(n) = length {
25518 self.write(&format!("({})", n));
25519 }
25520 if self.clickhouse_nullable_depth >= 0 {
25521 self.write(")");
25522 }
25523 }
25524 _ => {
25525 self.write_keyword("BINARY");
25526 if let Some(n) = length {
25527 self.write(&format!("({})", n));
25528 }
25529 }
25530 }
25531 }
25532 DataType::VarBinary { length } => {
25533 match self.config.dialect {
25535 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
25536 self.write_keyword("BYTEA");
25537 if let Some(n) = length {
25538 self.write(&format!("({})", n));
25539 }
25540 }
25541 Some(DialectType::Redshift) => {
25542 self.write_keyword("VARBYTE");
25543 if let Some(n) = length {
25544 self.write(&format!("({})", n));
25545 }
25546 }
25547 Some(DialectType::DuckDB)
25548 | Some(DialectType::SQLite)
25549 | Some(DialectType::Oracle) => {
25550 self.write_keyword("BLOB");
25552 if let Some(n) = length {
25553 self.write(&format!("({})", n));
25554 }
25555 }
25556 Some(DialectType::Exasol) => {
25557 self.write_keyword("VARCHAR");
25559 }
25560 Some(DialectType::Spark)
25561 | Some(DialectType::Hive)
25562 | Some(DialectType::Databricks) => {
25563 self.write_keyword("BINARY");
25565 if let Some(n) = length {
25566 self.write(&format!("({})", n));
25567 }
25568 }
25569 Some(DialectType::ClickHouse) => {
25570 self.write_clickhouse_type("String");
25572 }
25573 _ => {
25574 self.write_keyword("VARBINARY");
25575 if let Some(n) = length {
25576 self.write(&format!("({})", n));
25577 }
25578 }
25579 }
25580 }
25581 DataType::Blob => {
25582 match self.config.dialect {
25584 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
25585 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
25586 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
25587 self.write_keyword("VARBINARY")
25588 }
25589 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
25590 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
25591 Some(DialectType::Presto)
25592 | Some(DialectType::Trino)
25593 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
25594 Some(DialectType::DuckDB) => {
25595 self.write_keyword("VARBINARY");
25598 }
25599 Some(DialectType::Spark)
25600 | Some(DialectType::Databricks)
25601 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
25602 Some(DialectType::ClickHouse) => {
25603 self.write("Nullable(String)");
25607 }
25608 _ => self.write_keyword("BLOB"),
25609 }
25610 }
25611 DataType::Bit { length } => {
25612 match self.config.dialect {
25614 Some(DialectType::Dremio)
25615 | Some(DialectType::Spark)
25616 | Some(DialectType::Databricks)
25617 | Some(DialectType::Hive)
25618 | Some(DialectType::Snowflake)
25619 | Some(DialectType::BigQuery)
25620 | Some(DialectType::Presto)
25621 | Some(DialectType::Trino)
25622 | Some(DialectType::ClickHouse)
25623 | Some(DialectType::Redshift) => {
25624 self.write_keyword("BOOLEAN");
25626 }
25627 _ => {
25628 self.write_keyword("BIT");
25629 if let Some(n) = length {
25630 self.write(&format!("({})", n));
25631 }
25632 }
25633 }
25634 }
25635 DataType::VarBit { length } => {
25636 self.write_keyword("VARBIT");
25637 if let Some(n) = length {
25638 self.write(&format!("({})", n));
25639 }
25640 }
25641 DataType::Date => self.write_keyword("DATE"),
25642 DataType::Time {
25643 precision,
25644 timezone,
25645 } => {
25646 if *timezone {
25647 match self.config.dialect {
25649 Some(DialectType::DuckDB) => {
25650 self.write_keyword("TIMETZ");
25652 }
25653 Some(DialectType::PostgreSQL) => {
25654 self.write_keyword("TIMETZ");
25656 if let Some(p) = precision {
25657 self.write(&format!("({})", p));
25658 }
25659 }
25660 _ => {
25661 self.write_keyword("TIME");
25663 if let Some(p) = precision {
25664 self.write(&format!("({})", p));
25665 }
25666 self.write_keyword(" WITH TIME ZONE");
25667 }
25668 }
25669 } else {
25670 if matches!(
25672 self.config.dialect,
25673 Some(DialectType::Spark)
25674 | Some(DialectType::Databricks)
25675 | Some(DialectType::Hive)
25676 ) {
25677 self.write_keyword("TIMESTAMP");
25678 } else {
25679 self.write_keyword("TIME");
25680 if let Some(p) = precision {
25681 self.write(&format!("({})", p));
25682 }
25683 }
25684 }
25685 }
25686 DataType::Timestamp {
25687 precision,
25688 timezone,
25689 } => {
25690 match self.config.dialect {
25692 Some(DialectType::Snowflake) if *timezone => {
25693 self.write_keyword("TIMESTAMPTZ");
25694 if let Some(p) = precision {
25695 self.write(&format!("({})", p));
25696 }
25697 }
25698 Some(DialectType::ClickHouse) => {
25699 self.write("DateTime");
25700 if let Some(p) = precision {
25701 self.write(&format!("({})", p));
25702 }
25703 }
25704 Some(DialectType::TSQL) => {
25705 if *timezone {
25706 self.write_keyword("DATETIMEOFFSET");
25707 } else {
25708 self.write_keyword("DATETIME2");
25709 }
25710 if let Some(p) = precision {
25711 self.write(&format!("({})", p));
25712 }
25713 }
25714 Some(DialectType::MySQL) => {
25715 self.write_keyword("TIMESTAMP");
25717 if let Some(p) = precision {
25718 self.write(&format!("({})", p));
25719 }
25720 }
25721 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
25722 self.write_keyword("DATETIME");
25724 if let Some(p) = precision {
25725 self.write(&format!("({})", p));
25726 }
25727 }
25728 Some(DialectType::BigQuery) => {
25729 if *timezone {
25731 self.write_keyword("TIMESTAMP");
25732 } else {
25733 self.write_keyword("DATETIME");
25734 }
25735 }
25736 Some(DialectType::DuckDB) => {
25737 if *timezone {
25739 self.write_keyword("TIMESTAMPTZ");
25740 } else {
25741 self.write_keyword("TIMESTAMP");
25742 if let Some(p) = precision {
25743 self.write(&format!("({})", p));
25744 }
25745 }
25746 }
25747 _ => {
25748 if *timezone && !self.config.tz_to_with_time_zone {
25749 self.write_keyword("TIMESTAMPTZ");
25751 if let Some(p) = precision {
25752 self.write(&format!("({})", p));
25753 }
25754 } else {
25755 self.write_keyword("TIMESTAMP");
25756 if let Some(p) = precision {
25757 self.write(&format!("({})", p));
25758 }
25759 if *timezone {
25760 self.write_space();
25761 self.write_keyword("WITH TIME ZONE");
25762 }
25763 }
25764 }
25765 }
25766 }
25767 DataType::Interval { unit, to } => {
25768 self.write_keyword("INTERVAL");
25769 if let Some(u) = unit {
25770 self.write_space();
25771 self.write_keyword(u);
25772 }
25773 if let Some(t) = to {
25775 self.write_space();
25776 self.write_keyword("TO");
25777 self.write_space();
25778 self.write_keyword(t);
25779 }
25780 }
25781 DataType::Json => {
25782 match self.config.dialect {
25784 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
25787 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
25788 _ => self.write_keyword("JSON"),
25789 }
25790 }
25791 DataType::JsonB => {
25792 match self.config.dialect {
25794 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
25795 Some(DialectType::Doris) => self.write_keyword("JSONB"),
25796 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
25797 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
25798 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
25801 }
25802 DataType::Uuid => {
25803 match self.config.dialect {
25805 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
25806 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
25807 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
25808 Some(DialectType::BigQuery)
25809 | Some(DialectType::Spark)
25810 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
25811 _ => self.write_keyword("UUID"),
25812 }
25813 }
25814 DataType::Array {
25815 element_type,
25816 dimension,
25817 } => {
25818 match self.config.dialect {
25820 Some(DialectType::PostgreSQL)
25821 | Some(DialectType::Redshift)
25822 | Some(DialectType::DuckDB) => {
25823 self.generate_data_type(element_type)?;
25825 if let Some(dim) = dimension {
25826 self.write(&format!("[{}]", dim));
25827 } else {
25828 self.write("[]");
25829 }
25830 }
25831 Some(DialectType::BigQuery) => {
25832 self.write_keyword("ARRAY<");
25833 self.generate_data_type(element_type)?;
25834 self.write(">");
25835 }
25836 Some(DialectType::Snowflake)
25837 | Some(DialectType::Presto)
25838 | Some(DialectType::Trino)
25839 | Some(DialectType::ClickHouse) => {
25840 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25842 self.write("Array(");
25843 } else {
25844 self.write_keyword("ARRAY(");
25845 }
25846 self.generate_data_type(element_type)?;
25847 self.write(")");
25848 }
25849 Some(DialectType::TSQL)
25850 | Some(DialectType::MySQL)
25851 | Some(DialectType::Oracle) => {
25852 match self.config.dialect {
25855 Some(DialectType::MySQL) => self.write_keyword("JSON"),
25856 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
25857 _ => self.write_keyword("JSON"),
25858 }
25859 }
25860 _ => {
25861 self.write_keyword("ARRAY<");
25863 self.generate_data_type(element_type)?;
25864 self.write(">");
25865 }
25866 }
25867 }
25868 DataType::List { element_type } => {
25869 self.generate_data_type(element_type)?;
25871 self.write_keyword(" LIST");
25872 }
25873 DataType::Map {
25874 key_type,
25875 value_type,
25876 } => {
25877 match self.config.dialect {
25879 Some(DialectType::Materialize) => {
25880 self.write_keyword("MAP[");
25882 self.generate_data_type(key_type)?;
25883 self.write(" => ");
25884 self.generate_data_type(value_type)?;
25885 self.write("]");
25886 }
25887 Some(DialectType::Snowflake)
25888 | Some(DialectType::RisingWave)
25889 | Some(DialectType::DuckDB)
25890 | Some(DialectType::Presto)
25891 | Some(DialectType::Trino)
25892 | Some(DialectType::Athena) => {
25893 self.write_keyword("MAP(");
25894 self.generate_data_type(key_type)?;
25895 self.write(", ");
25896 self.generate_data_type(value_type)?;
25897 self.write(")");
25898 }
25899 Some(DialectType::ClickHouse) => {
25900 self.write("Map(");
25903 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
25905 self.clickhouse_nullable_depth = 0;
25906 self.write(", ");
25907 self.generate_data_type(value_type)?;
25908 self.write(")");
25909 }
25910 _ => {
25911 self.write_keyword("MAP<");
25912 self.generate_data_type(key_type)?;
25913 self.write(", ");
25914 self.generate_data_type(value_type)?;
25915 self.write(">");
25916 }
25917 }
25918 }
25919 DataType::Vector {
25920 element_type,
25921 dimension,
25922 } => {
25923 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
25924 self.write_keyword("VECTOR(");
25926 if let Some(dim) = dimension {
25927 self.write(&dim.to_string());
25928 }
25929 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
25931 DataType::TinyInt { .. } => Some("I8"),
25932 DataType::SmallInt { .. } => Some("I16"),
25933 DataType::Int { .. } => Some("I32"),
25934 DataType::BigInt { .. } => Some("I64"),
25935 DataType::Float { .. } => Some("F32"),
25936 DataType::Double { .. } => Some("F64"),
25937 _ => None,
25938 });
25939 if let Some(alias) = type_alias {
25940 if dimension.is_some() {
25941 self.write(", ");
25942 }
25943 self.write(alias);
25944 }
25945 self.write(")");
25946 } else {
25947 self.write_keyword("VECTOR(");
25949 if let Some(ref et) = element_type {
25950 self.generate_data_type(et)?;
25951 if dimension.is_some() {
25952 self.write(", ");
25953 }
25954 }
25955 if let Some(dim) = dimension {
25956 self.write(&dim.to_string());
25957 }
25958 self.write(")");
25959 }
25960 }
25961 DataType::Object { fields, modifier } => {
25962 self.write_keyword("OBJECT(");
25963 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
25964 if i > 0 {
25965 self.write(", ");
25966 }
25967 self.write(name);
25968 self.write(" ");
25969 self.generate_data_type(dt)?;
25970 if *not_null {
25971 self.write_keyword(" NOT NULL");
25972 }
25973 }
25974 self.write(")");
25975 if let Some(mod_str) = modifier {
25976 self.write(" ");
25977 self.write_keyword(mod_str);
25978 }
25979 }
25980 DataType::Struct { fields, nested } => {
25981 match self.config.dialect {
25983 Some(DialectType::Snowflake) => {
25984 self.write_keyword("OBJECT(");
25986 for (i, field) in fields.iter().enumerate() {
25987 if i > 0 {
25988 self.write(", ");
25989 }
25990 if !field.name.is_empty() {
25991 self.write(&field.name);
25992 self.write(" ");
25993 }
25994 self.generate_data_type(&field.data_type)?;
25995 }
25996 self.write(")");
25997 }
25998 Some(DialectType::Presto) | Some(DialectType::Trino) => {
25999 self.write_keyword("ROW(");
26001 for (i, field) in fields.iter().enumerate() {
26002 if i > 0 {
26003 self.write(", ");
26004 }
26005 if !field.name.is_empty() {
26006 self.write(&field.name);
26007 self.write(" ");
26008 }
26009 self.generate_data_type(&field.data_type)?;
26010 }
26011 self.write(")");
26012 }
26013 Some(DialectType::DuckDB) => {
26014 self.write_keyword("STRUCT(");
26016 for (i, field) in fields.iter().enumerate() {
26017 if i > 0 {
26018 self.write(", ");
26019 }
26020 if !field.name.is_empty() {
26021 self.write(&field.name);
26022 self.write(" ");
26023 }
26024 self.generate_data_type(&field.data_type)?;
26025 }
26026 self.write(")");
26027 }
26028 Some(DialectType::ClickHouse) => {
26029 self.write("Tuple(");
26031 for (i, field) in fields.iter().enumerate() {
26032 if i > 0 {
26033 self.write(", ");
26034 }
26035 if !field.name.is_empty() {
26036 self.write(&field.name);
26037 self.write(" ");
26038 }
26039 self.generate_data_type(&field.data_type)?;
26040 }
26041 self.write(")");
26042 }
26043 Some(DialectType::SingleStore) => {
26044 self.write_keyword("RECORD(");
26046 for (i, field) in fields.iter().enumerate() {
26047 if i > 0 {
26048 self.write(", ");
26049 }
26050 if !field.name.is_empty() {
26051 self.write(&field.name);
26052 self.write(" ");
26053 }
26054 self.generate_data_type(&field.data_type)?;
26055 }
26056 self.write(")");
26057 }
26058 _ => {
26059 let force_angle_brackets = matches!(
26061 self.config.dialect,
26062 Some(DialectType::Hive)
26063 | Some(DialectType::Spark)
26064 | Some(DialectType::Databricks)
26065 );
26066 if *nested && !force_angle_brackets {
26067 self.write_keyword("STRUCT(");
26068 for (i, field) in fields.iter().enumerate() {
26069 if i > 0 {
26070 self.write(", ");
26071 }
26072 if !field.name.is_empty() {
26073 self.write(&field.name);
26074 self.write(" ");
26075 }
26076 self.generate_data_type(&field.data_type)?;
26077 }
26078 self.write(")");
26079 } else {
26080 self.write_keyword("STRUCT<");
26081 for (i, field) in fields.iter().enumerate() {
26082 if i > 0 {
26083 self.write(", ");
26084 }
26085 if !field.name.is_empty() {
26086 self.write(&field.name);
26088 self.write(self.config.struct_field_sep);
26089 }
26090 self.generate_data_type(&field.data_type)?;
26092 if let Some(comment) = &field.comment {
26094 self.write(" COMMENT '");
26095 self.write(comment);
26096 self.write("'");
26097 }
26098 if !field.options.is_empty() {
26100 self.write(" ");
26101 self.generate_options_clause(&field.options)?;
26102 }
26103 }
26104 self.write(">");
26105 }
26106 }
26107 }
26108 }
26109 DataType::Enum {
26110 values,
26111 assignments,
26112 } => {
26113 if self.config.dialect == Some(DialectType::ClickHouse) {
26116 self.write("Enum(");
26117 } else {
26118 self.write_keyword("ENUM(");
26119 }
26120 for (i, val) in values.iter().enumerate() {
26121 if i > 0 {
26122 self.write(", ");
26123 }
26124 self.write("'");
26125 self.write(val);
26126 self.write("'");
26127 if let Some(Some(assignment)) = assignments.get(i) {
26128 self.write(" = ");
26129 self.write(assignment);
26130 }
26131 }
26132 self.write(")");
26133 }
26134 DataType::Set { values } => {
26135 self.write_keyword("SET(");
26137 for (i, val) in values.iter().enumerate() {
26138 if i > 0 {
26139 self.write(", ");
26140 }
26141 self.write("'");
26142 self.write(val);
26143 self.write("'");
26144 }
26145 self.write(")");
26146 }
26147 DataType::Union { fields } => {
26148 self.write_keyword("UNION(");
26150 for (i, (name, dt)) in fields.iter().enumerate() {
26151 if i > 0 {
26152 self.write(", ");
26153 }
26154 if !name.is_empty() {
26155 self.write(name);
26156 self.write(" ");
26157 }
26158 self.generate_data_type(dt)?;
26159 }
26160 self.write(")");
26161 }
26162 DataType::Nullable { inner } => {
26163 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26165 self.write("Nullable(");
26166 let saved_depth = self.clickhouse_nullable_depth;
26168 self.clickhouse_nullable_depth = -1;
26169 self.generate_data_type(inner)?;
26170 self.clickhouse_nullable_depth = saved_depth;
26171 self.write(")");
26172 } else {
26173 match inner.as_ref() {
26175 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
26176 self.generate_data_type(&DataType::Timestamp {
26177 precision: None,
26178 timezone: false,
26179 })?;
26180 }
26181 _ => {
26182 self.generate_data_type(inner)?;
26183 }
26184 }
26185 }
26186 }
26187 DataType::Custom { name } => {
26188 let name_upper = name.to_ascii_uppercase();
26190 match self.config.dialect {
26191 Some(DialectType::ClickHouse) => {
26192 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
26193 (name_upper[..idx].to_string(), &name[idx..])
26194 } else {
26195 (name_upper.clone(), "")
26196 };
26197 let mapped = match base_upper.as_str() {
26198 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
26199 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
26200 "DATETIME64" => "DateTime64",
26201 "DATE32" => "Date32",
26202 "INT" => "Int32",
26203 "MEDIUMINT" => "Int32",
26204 "INT8" => "Int8",
26205 "INT16" => "Int16",
26206 "INT32" => "Int32",
26207 "INT64" => "Int64",
26208 "INT128" => "Int128",
26209 "INT256" => "Int256",
26210 "UINT8" => "UInt8",
26211 "UINT16" => "UInt16",
26212 "UINT32" => "UInt32",
26213 "UINT64" => "UInt64",
26214 "UINT128" => "UInt128",
26215 "UINT256" => "UInt256",
26216 "FLOAT32" => "Float32",
26217 "FLOAT64" => "Float64",
26218 "DECIMAL32" => "Decimal32",
26219 "DECIMAL64" => "Decimal64",
26220 "DECIMAL128" => "Decimal128",
26221 "DECIMAL256" => "Decimal256",
26222 "ENUM" => "Enum",
26223 "ENUM8" => "Enum8",
26224 "ENUM16" => "Enum16",
26225 "FIXEDSTRING" => "FixedString",
26226 "NESTED" => "Nested",
26227 "LOWCARDINALITY" => "LowCardinality",
26228 "NULLABLE" => "Nullable",
26229 "IPV4" => "IPv4",
26230 "IPV6" => "IPv6",
26231 "POINT" => "Point",
26232 "RING" => "Ring",
26233 "LINESTRING" => "LineString",
26234 "MULTILINESTRING" => "MultiLineString",
26235 "POLYGON" => "Polygon",
26236 "MULTIPOLYGON" => "MultiPolygon",
26237 "AGGREGATEFUNCTION" => "AggregateFunction",
26238 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
26239 "DYNAMIC" => "Dynamic",
26240 _ => "",
26241 };
26242 if mapped.is_empty() {
26243 self.write(name);
26244 } else {
26245 self.write(mapped);
26246 if matches!(base_upper.as_str(), "ENUM8" | "ENUM16")
26247 && !suffix.is_empty()
26248 {
26249 let escaped_suffix = suffix
26250 .replace('\\', "\\\\")
26251 .replace('\t', "\\t")
26252 .replace('\n', "\\n")
26253 .replace('\r', "\\r");
26254 self.write(&escaped_suffix);
26255 } else {
26256 self.write(suffix);
26257 }
26258 }
26259 }
26260 Some(DialectType::MySQL)
26261 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
26262 {
26263 self.write_keyword("TIMESTAMP");
26265 }
26266 Some(DialectType::Snowflake) => {
26267 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
26268 (name_upper[..idx].to_string(), &name[idx..])
26269 } else {
26270 (name_upper.clone(), "")
26271 };
26272
26273 match base_upper.as_str() {
26274 "TIMESTAMPNTZ" | "TIMESTAMP_NTZ" => {
26275 self.write_keyword("TIMESTAMPNTZ");
26276 self.write(suffix);
26277 }
26278 "TIMESTAMPLTZ" | "TIMESTAMP_LTZ" => {
26279 self.write_keyword("TIMESTAMPLTZ");
26280 self.write(suffix);
26281 }
26282 "TIMESTAMPTZ" | "TIMESTAMP_TZ" => {
26283 self.write_keyword("TIMESTAMPTZ");
26284 self.write(suffix);
26285 }
26286 _ => self.write(name),
26287 }
26288 }
26289 Some(DialectType::Fabric) => {
26290 let (base_upper, args_str) = if let Some(idx) = name.find('(') {
26291 (name_upper[..idx].to_string(), Some(&name[idx..]))
26292 } else {
26293 (name_upper.clone(), None)
26294 };
26295
26296 match base_upper.as_str() {
26297 "NVARCHAR" => {
26298 self.write_keyword("VARCHAR");
26299 if let Some(args) = args_str {
26300 self.write(args);
26301 }
26302 }
26303 "NCHAR" => {
26304 self.write_keyword("CHAR");
26305 if let Some(args) = args_str {
26306 self.write(args);
26307 }
26308 }
26309 _ => self.write(name),
26310 }
26311 }
26312 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
26313 self.write_keyword("SQL_VARIANT");
26314 }
26315 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
26316 self.write_keyword("DECIMAL(38, 5)");
26317 }
26318 Some(DialectType::Exasol) => {
26319 match name_upper.as_str() {
26321 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
26323 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
26325 "MEDIUMINT" => self.write_keyword("INT"),
26327 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
26329 self.write_keyword("DECIMAL")
26330 }
26331 "DATETIME" => self.write_keyword("TIMESTAMP"),
26333 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
26334 _ => self.write(name),
26335 }
26336 }
26337 Some(DialectType::Dremio) => {
26338 match name_upper.as_str() {
26340 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
26341 "ARRAY" => self.write_keyword("LIST"),
26342 "NCHAR" => self.write_keyword("VARCHAR"),
26343 _ => self.write(name),
26344 }
26345 }
26346 _ => {
26348 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
26350 (name_upper[..idx].to_string(), Some(&name[idx..]))
26351 } else {
26352 (name_upper.clone(), None)
26353 };
26354
26355 match base_upper.as_str() {
26356 "INT64"
26357 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26358 {
26359 self.write_keyword("BIGINT");
26360 }
26361 "FLOAT64"
26362 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26363 {
26364 self.write_keyword("DOUBLE");
26365 }
26366 "BOOL"
26367 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26368 {
26369 self.write_keyword("BOOLEAN");
26370 }
26371 "BYTES"
26372 if matches!(
26373 self.config.dialect,
26374 Some(DialectType::Spark)
26375 | Some(DialectType::Hive)
26376 | Some(DialectType::Databricks)
26377 ) =>
26378 {
26379 self.write_keyword("BINARY");
26380 }
26381 "BYTES"
26382 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
26383 {
26384 self.write_keyword("VARBINARY");
26385 }
26386 "DATETIME2" | "SMALLDATETIME"
26388 if !matches!(
26389 self.config.dialect,
26390 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26391 ) =>
26392 {
26393 if matches!(
26395 self.config.dialect,
26396 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
26397 ) {
26398 self.write_keyword("TIMESTAMP");
26399 if let Some(args) = _args_str {
26400 self.write(args);
26401 }
26402 } else {
26403 self.write_keyword("TIMESTAMP");
26404 }
26405 }
26406 "DATETIMEOFFSET"
26408 if !matches!(
26409 self.config.dialect,
26410 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26411 ) =>
26412 {
26413 if matches!(
26414 self.config.dialect,
26415 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
26416 ) {
26417 self.write_keyword("TIMESTAMPTZ");
26418 if let Some(args) = _args_str {
26419 self.write(args);
26420 }
26421 } else {
26422 self.write_keyword("TIMESTAMPTZ");
26423 }
26424 }
26425 "UNIQUEIDENTIFIER"
26427 if !matches!(
26428 self.config.dialect,
26429 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26430 ) =>
26431 {
26432 match self.config.dialect {
26433 Some(DialectType::Spark)
26434 | Some(DialectType::Databricks)
26435 | Some(DialectType::Hive) => self.write_keyword("STRING"),
26436 _ => self.write_keyword("UUID"),
26437 }
26438 }
26439 "BIT"
26441 if !matches!(
26442 self.config.dialect,
26443 Some(DialectType::TSQL)
26444 | Some(DialectType::Fabric)
26445 | Some(DialectType::PostgreSQL)
26446 | Some(DialectType::MySQL)
26447 | Some(DialectType::DuckDB)
26448 ) =>
26449 {
26450 self.write_keyword("BOOLEAN");
26451 }
26452 "NVARCHAR"
26454 if !matches!(
26455 self.config.dialect,
26456 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26457 ) =>
26458 {
26459 match self.config.dialect {
26460 Some(DialectType::Oracle) => {
26461 self.write_keyword("NVARCHAR2");
26463 if let Some(args) = _args_str {
26464 self.write(args);
26465 }
26466 }
26467 Some(DialectType::BigQuery) => {
26468 self.write_keyword("STRING");
26470 }
26471 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
26472 self.write_keyword("TEXT");
26473 if let Some(args) = _args_str {
26474 self.write(args);
26475 }
26476 }
26477 Some(DialectType::Hive) => {
26478 self.write_keyword("STRING");
26480 }
26481 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
26482 if _args_str.is_some() {
26483 self.write_keyword("VARCHAR");
26484 self.write(_args_str.unwrap());
26485 } else {
26486 self.write_keyword("STRING");
26487 }
26488 }
26489 _ => {
26490 self.write_keyword("VARCHAR");
26491 if let Some(args) = _args_str {
26492 self.write(args);
26493 }
26494 }
26495 }
26496 }
26497 "NCHAR"
26499 if !matches!(
26500 self.config.dialect,
26501 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26502 ) =>
26503 {
26504 match self.config.dialect {
26505 Some(DialectType::Oracle) => {
26506 self.write_keyword("NCHAR");
26508 if let Some(args) = _args_str {
26509 self.write(args);
26510 }
26511 }
26512 Some(DialectType::BigQuery) => {
26513 self.write_keyword("STRING");
26515 }
26516 Some(DialectType::Hive) => {
26517 self.write_keyword("STRING");
26519 }
26520 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
26521 self.write_keyword("TEXT");
26522 if let Some(args) = _args_str {
26523 self.write(args);
26524 }
26525 }
26526 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
26527 if _args_str.is_some() {
26528 self.write_keyword("CHAR");
26529 self.write(_args_str.unwrap());
26530 } else {
26531 self.write_keyword("STRING");
26532 }
26533 }
26534 _ => {
26535 self.write_keyword("CHAR");
26536 if let Some(args) = _args_str {
26537 self.write(args);
26538 }
26539 }
26540 }
26541 }
26542 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
26545 Some(DialectType::MySQL)
26546 | Some(DialectType::SingleStore)
26547 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
26548 Some(DialectType::Spark)
26549 | Some(DialectType::Databricks)
26550 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
26551 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
26552 Some(DialectType::Presto)
26553 | Some(DialectType::Trino)
26554 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
26555 Some(DialectType::Snowflake)
26556 | Some(DialectType::Redshift)
26557 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
26558 _ => self.write_keyword("TEXT"),
26559 },
26560 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
26563 Some(DialectType::MySQL)
26564 | Some(DialectType::SingleStore)
26565 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
26566 Some(DialectType::Spark)
26567 | Some(DialectType::Databricks)
26568 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
26569 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
26570 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
26571 Some(DialectType::Presto)
26572 | Some(DialectType::Trino)
26573 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
26574 Some(DialectType::Snowflake)
26575 | Some(DialectType::Redshift)
26576 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
26577 _ => self.write_keyword("BLOB"),
26578 },
26579 "LONGVARCHAR" => match self.config.dialect {
26581 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
26582 _ => self.write_keyword("VARCHAR"),
26583 },
26584 "DATETIME" => {
26586 match self.config.dialect {
26587 Some(DialectType::MySQL)
26588 | Some(DialectType::Doris)
26589 | Some(DialectType::StarRocks)
26590 | Some(DialectType::TSQL)
26591 | Some(DialectType::Fabric)
26592 | Some(DialectType::BigQuery)
26593 | Some(DialectType::SQLite)
26594 | Some(DialectType::Snowflake) => {
26595 self.write_keyword("DATETIME");
26596 if let Some(args) = _args_str {
26597 self.write(args);
26598 }
26599 }
26600 Some(_) => {
26601 self.write_keyword("TIMESTAMP");
26603 if let Some(args) = _args_str {
26604 self.write(args);
26605 }
26606 }
26607 None => {
26608 self.write(name);
26610 }
26611 }
26612 }
26613 "VARCHAR2"
26615 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
26616 {
26617 match self.config.dialect {
26618 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
26619 self.write_keyword("TEXT");
26620 }
26621 Some(DialectType::Hive)
26622 | Some(DialectType::Spark)
26623 | Some(DialectType::Databricks)
26624 | Some(DialectType::BigQuery)
26625 | Some(DialectType::ClickHouse)
26626 | Some(DialectType::StarRocks)
26627 | Some(DialectType::Doris) => {
26628 self.write_keyword("STRING");
26629 }
26630 _ => {
26631 self.write_keyword("VARCHAR");
26632 if let Some(args) = _args_str {
26633 self.write(args);
26634 }
26635 }
26636 }
26637 }
26638 "NVARCHAR2"
26639 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
26640 {
26641 match self.config.dialect {
26642 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
26643 self.write_keyword("TEXT");
26644 }
26645 Some(DialectType::Hive)
26646 | Some(DialectType::Spark)
26647 | Some(DialectType::Databricks)
26648 | Some(DialectType::BigQuery)
26649 | Some(DialectType::ClickHouse)
26650 | Some(DialectType::StarRocks)
26651 | Some(DialectType::Doris) => {
26652 self.write_keyword("STRING");
26653 }
26654 _ => {
26655 self.write_keyword("VARCHAR");
26656 if let Some(args) = _args_str {
26657 self.write(args);
26658 }
26659 }
26660 }
26661 }
26662 _ => self.write(name),
26663 }
26664 }
26665 }
26666 }
26667 DataType::Geometry { subtype, srid } => {
26668 match self.config.dialect {
26670 Some(DialectType::MySQL) => {
26671 if let Some(sub) = subtype {
26673 self.write_keyword(sub);
26674 if let Some(s) = srid {
26675 self.write(" SRID ");
26676 self.write(&s.to_string());
26677 }
26678 } else {
26679 self.write_keyword("GEOMETRY");
26680 }
26681 }
26682 Some(DialectType::BigQuery) => {
26683 self.write_keyword("GEOGRAPHY");
26685 }
26686 Some(DialectType::Teradata) => {
26687 self.write_keyword("ST_GEOMETRY");
26689 if subtype.is_some() || srid.is_some() {
26690 self.write("(");
26691 if let Some(sub) = subtype {
26692 self.write_keyword(sub);
26693 }
26694 if let Some(s) = srid {
26695 if subtype.is_some() {
26696 self.write(", ");
26697 }
26698 self.write(&s.to_string());
26699 }
26700 self.write(")");
26701 }
26702 }
26703 _ => {
26704 self.write_keyword("GEOMETRY");
26706 if subtype.is_some() || srid.is_some() {
26707 self.write("(");
26708 if let Some(sub) = subtype {
26709 self.write_keyword(sub);
26710 }
26711 if let Some(s) = srid {
26712 if subtype.is_some() {
26713 self.write(", ");
26714 }
26715 self.write(&s.to_string());
26716 }
26717 self.write(")");
26718 }
26719 }
26720 }
26721 }
26722 DataType::Geography { subtype, srid } => {
26723 match self.config.dialect {
26725 Some(DialectType::MySQL) => {
26726 if let Some(sub) = subtype {
26728 self.write_keyword(sub);
26729 } else {
26730 self.write_keyword("GEOMETRY");
26731 }
26732 let effective_srid = srid.unwrap_or(4326);
26734 self.write(" SRID ");
26735 self.write(&effective_srid.to_string());
26736 }
26737 Some(DialectType::BigQuery) => {
26738 self.write_keyword("GEOGRAPHY");
26740 }
26741 Some(DialectType::Snowflake) => {
26742 self.write_keyword("GEOGRAPHY");
26744 }
26745 _ => {
26746 self.write_keyword("GEOGRAPHY");
26748 if subtype.is_some() || srid.is_some() {
26749 self.write("(");
26750 if let Some(sub) = subtype {
26751 self.write_keyword(sub);
26752 }
26753 if let Some(s) = srid {
26754 if subtype.is_some() {
26755 self.write(", ");
26756 }
26757 self.write(&s.to_string());
26758 }
26759 self.write(")");
26760 }
26761 }
26762 }
26763 }
26764 DataType::CharacterSet { name } => {
26765 self.write_keyword("CHAR CHARACTER SET ");
26767 self.write(name);
26768 }
26769 _ => self.write("UNKNOWN"),
26770 }
26771 Ok(())
26772 }
26773
26774 #[inline]
26777 fn write(&mut self, s: &str) {
26778 self.output.push_str(s);
26779 }
26780
26781 #[inline]
26782 fn write_space(&mut self) {
26783 self.output.push(' ');
26784 }
26785
26786 #[inline]
26787 fn write_keyword(&mut self, keyword: &str) {
26788 if self.config.uppercase_keywords {
26789 self.output.push_str(keyword);
26790 } else {
26791 for b in keyword.bytes() {
26792 self.output.push(b.to_ascii_lowercase() as char);
26793 }
26794 }
26795 }
26796
26797 fn write_func_name(&mut self, name: &str) {
26799 let normalized = self.normalize_func_name(name);
26800 self.output.push_str(normalized.as_ref());
26801 }
26802
26803 fn convert_strptime_to_exasol_format(format: &str) -> String {
26807 let mut result = String::new();
26808 let chars: Vec<char> = format.chars().collect();
26809 let mut i = 0;
26810 while i < chars.len() {
26811 if chars[i] == '%' && i + 1 < chars.len() {
26812 let spec = chars[i + 1];
26813 let exasol_spec = match spec {
26814 'Y' => "YYYY",
26815 'y' => "YY",
26816 'm' => "MM",
26817 'd' => "DD",
26818 'H' => "HH",
26819 'M' => "MI",
26820 'S' => "SS",
26821 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
26833 result.push('%');
26835 result.push(spec);
26836 i += 2;
26837 continue;
26838 }
26839 };
26840 result.push_str(exasol_spec);
26841 i += 2;
26842 } else {
26843 result.push(chars[i]);
26844 i += 1;
26845 }
26846 }
26847 result
26848 }
26849
26850 fn convert_strptime_to_postgres_format(format: &str) -> String {
26854 let mut result = String::new();
26855 let chars: Vec<char> = format.chars().collect();
26856 let mut i = 0;
26857 while i < chars.len() {
26858 if chars[i] == '%' && i + 1 < chars.len() {
26859 if chars[i + 1] == '-' && i + 2 < chars.len() {
26861 let spec = chars[i + 2];
26862 let pg_spec = match spec {
26863 'd' => "FMDD",
26864 'm' => "FMMM",
26865 'H' => "FMHH24",
26866 'M' => "FMMI",
26867 'S' => "FMSS",
26868 _ => {
26869 result.push('%');
26870 result.push('-');
26871 result.push(spec);
26872 i += 3;
26873 continue;
26874 }
26875 };
26876 result.push_str(pg_spec);
26877 i += 3;
26878 continue;
26879 }
26880 let spec = chars[i + 1];
26881 let pg_spec = match spec {
26882 'Y' => "YYYY",
26883 'y' => "YY",
26884 'm' => "MM",
26885 'd' => "DD",
26886 'H' => "HH24",
26887 'I' => "HH12",
26888 'M' => "MI",
26889 'S' => "SS",
26890 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
26901 result.push('%');
26903 result.push(spec);
26904 i += 2;
26905 continue;
26906 }
26907 };
26908 result.push_str(pg_spec);
26909 i += 2;
26910 } else {
26911 result.push(chars[i]);
26912 i += 1;
26913 }
26914 }
26915 result
26916 }
26917
26918 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
26920 if self.config.limit_only_literals {
26921 if let Some(value) = Self::try_evaluate_constant(expr) {
26922 self.write(&value.to_string());
26923 return Ok(());
26924 }
26925 }
26926 self.generate_expression(expr)
26927 }
26928
26929 fn is_noop_limit_expr(expr: &Expression) -> bool {
26930 match expr {
26931 Expression::Null(_) => true,
26932 Expression::Identifier(identifier) => identifier.name.eq_ignore_ascii_case("ALL"),
26933 Expression::Column(column) => {
26934 column.table.is_none() && column.name.name.eq_ignore_ascii_case("ALL")
26935 }
26936 Expression::Var(var) => var.this.eq_ignore_ascii_case("ALL"),
26937 Expression::Paren(paren) => Self::is_noop_limit_expr(&paren.this),
26938 _ => false,
26939 }
26940 }
26941
26942 fn write_formatted_comment(&mut self, comment: &str) {
26946 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
26949 &comment[2..comment.len() - 2]
26952 } else if comment.starts_with("--") {
26953 &comment[2..]
26956 } else {
26957 comment
26959 };
26960 if content.trim().is_empty() {
26962 return;
26963 }
26964 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
26967 let content = &sanitized;
26968 self.output.push_str("/*");
26970 if !content.starts_with(' ') {
26971 self.output.push(' ');
26972 }
26973 self.output.push_str(content);
26974 if !content.ends_with(' ') {
26975 self.output.push(' ');
26976 }
26977 self.output.push_str("*/");
26978 }
26979
26980 fn escape_block_for_single_quote(&self, block: &str) -> String {
26983 let escape_backslash = matches!(
26984 self.config.dialect,
26985 Some(crate::dialects::DialectType::Snowflake)
26986 );
26987 let mut escaped = String::with_capacity(block.len() + 4);
26988 for ch in block.chars() {
26989 if ch == '\'' {
26990 escaped.push('\\');
26991 escaped.push('\'');
26992 } else if escape_backslash && ch == '\\' {
26993 escaped.push('\\');
26994 escaped.push('\\');
26995 } else {
26996 escaped.push(ch);
26997 }
26998 }
26999 escaped
27000 }
27001
27002 fn write_newline(&mut self) {
27003 self.output.push('\n');
27004 }
27005
27006 fn write_indent(&mut self) {
27007 for _ in 0..self.indent_level {
27008 self.output.push_str(self.config.indent);
27009 }
27010 }
27011
27012 fn too_wide(&self, args: &[String]) -> bool {
27018 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
27019 }
27020
27021 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
27024 let config = GeneratorConfig {
27025 pretty: false,
27026 dialect: self.config.dialect,
27027 ..Default::default()
27028 };
27029 let mut gen = Generator::with_config(config);
27030 gen.generate_expression(expr)?;
27031 Ok(gen.output)
27032 }
27033
27034 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
27037 if self.config.pretty {
27038 self.write_newline();
27039 self.write_indent();
27040 self.write_keyword(keyword);
27041 self.write_newline();
27042 self.indent_level += 1;
27043 self.write_indent();
27044 self.generate_expression(condition)?;
27045 self.indent_level -= 1;
27046 } else {
27047 self.write_space();
27048 self.write_keyword(keyword);
27049 self.write_space();
27050 self.generate_expression(condition)?;
27051 }
27052 Ok(())
27053 }
27054
27055 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
27058 if exprs.is_empty() {
27059 return Ok(());
27060 }
27061
27062 if self.config.pretty {
27063 self.write_newline();
27064 self.write_indent();
27065 self.write_keyword(keyword);
27066 self.write_newline();
27067 self.indent_level += 1;
27068 for (i, expr) in exprs.iter().enumerate() {
27069 if i > 0 {
27070 self.write(",");
27071 self.write_newline();
27072 }
27073 self.write_indent();
27074 self.generate_expression(expr)?;
27075 }
27076 self.indent_level -= 1;
27077 } else {
27078 self.write_space();
27079 self.write_keyword(keyword);
27080 self.write_space();
27081 for (i, expr) in exprs.iter().enumerate() {
27082 if i > 0 {
27083 self.write(", ");
27084 }
27085 self.generate_expression(expr)?;
27086 }
27087 }
27088 Ok(())
27089 }
27090
27091 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
27093 if orderings.is_empty() {
27094 return Ok(());
27095 }
27096
27097 if self.config.pretty {
27098 self.write_newline();
27099 self.write_indent();
27100 self.write_keyword(keyword);
27101 self.write_newline();
27102 self.indent_level += 1;
27103 for (i, ordered) in orderings.iter().enumerate() {
27104 if i > 0 {
27105 self.write(",");
27106 self.write_newline();
27107 }
27108 self.write_indent();
27109 self.generate_ordered(ordered)?;
27110 }
27111 self.indent_level -= 1;
27112 } else {
27113 self.write_space();
27114 self.write_keyword(keyword);
27115 self.write_space();
27116 for (i, ordered) in orderings.iter().enumerate() {
27117 if i > 0 {
27118 self.write(", ");
27119 }
27120 self.generate_ordered(ordered)?;
27121 }
27122 }
27123 Ok(())
27124 }
27125
27126 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
27128 if windows.is_empty() {
27129 return Ok(());
27130 }
27131
27132 if self.config.pretty {
27133 self.write_newline();
27134 self.write_indent();
27135 self.write_keyword("WINDOW");
27136 self.write_newline();
27137 self.indent_level += 1;
27138 for (i, named_window) in windows.iter().enumerate() {
27139 if i > 0 {
27140 self.write(",");
27141 self.write_newline();
27142 }
27143 self.write_indent();
27144 self.generate_identifier(&named_window.name)?;
27145 self.write_space();
27146 self.write_keyword("AS");
27147 self.write(" (");
27148 self.generate_over(&named_window.spec)?;
27149 self.write(")");
27150 }
27151 self.indent_level -= 1;
27152 } else {
27153 self.write_space();
27154 self.write_keyword("WINDOW");
27155 self.write_space();
27156 for (i, named_window) in windows.iter().enumerate() {
27157 if i > 0 {
27158 self.write(", ");
27159 }
27160 self.generate_identifier(&named_window.name)?;
27161 self.write_space();
27162 self.write_keyword("AS");
27163 self.write(" (");
27164 self.generate_over(&named_window.spec)?;
27165 self.write(")");
27166 }
27167 }
27168 Ok(())
27169 }
27170
27171 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
27173 self.write_keyword("AI_AGG");
27175 self.write("(");
27176 self.generate_expression(&e.this)?;
27177 self.write(", ");
27178 self.generate_expression(&e.expression)?;
27179 self.write(")");
27180 Ok(())
27181 }
27182
27183 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
27184 self.write_keyword("AI_CLASSIFY");
27186 self.write("(");
27187 self.generate_expression(&e.this)?;
27188 if let Some(categories) = &e.categories {
27189 self.write(", ");
27190 self.generate_expression(categories)?;
27191 }
27192 if let Some(config) = &e.config {
27193 self.write(", ");
27194 self.generate_expression(config)?;
27195 }
27196 self.write(")");
27197 Ok(())
27198 }
27199
27200 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
27201 self.write_keyword("ADD");
27203 self.write_space();
27204 if e.exists {
27205 self.write_keyword("IF NOT EXISTS");
27206 self.write_space();
27207 }
27208 self.generate_expression(&e.this)?;
27209 if let Some(location) = &e.location {
27210 self.write_space();
27211 self.generate_expression(location)?;
27212 }
27213 Ok(())
27214 }
27215
27216 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
27217 self.write_keyword("ALGORITHM");
27219 self.write("=");
27220 self.generate_expression(&e.this)?;
27221 Ok(())
27222 }
27223
27224 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
27225 self.generate_expression(&e.this)?;
27227 self.write_space();
27228 self.write_keyword("AS");
27229 self.write(" (");
27230 for (i, expr) in e.expressions.iter().enumerate() {
27231 if i > 0 {
27232 self.write(", ");
27233 }
27234 self.generate_expression(expr)?;
27235 }
27236 self.write(")");
27237 Ok(())
27238 }
27239
27240 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
27241 self.write_keyword("ALLOWED_VALUES");
27243 self.write_space();
27244 for (i, expr) in e.expressions.iter().enumerate() {
27245 if i > 0 {
27246 self.write(", ");
27247 }
27248 self.generate_expression(expr)?;
27249 }
27250 Ok(())
27251 }
27252
27253 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
27254 self.write_keyword("ALTER COLUMN");
27256 self.write_space();
27257 self.generate_expression(&e.this)?;
27258
27259 if let Some(dtype) = &e.dtype {
27260 self.write_space();
27261 self.write_keyword("SET DATA TYPE");
27262 self.write_space();
27263 self.generate_expression(dtype)?;
27264 if let Some(collate) = &e.collate {
27265 self.write_space();
27266 self.write_keyword("COLLATE");
27267 self.write_space();
27268 self.generate_expression(collate)?;
27269 }
27270 if let Some(using) = &e.using {
27271 self.write_space();
27272 self.write_keyword("USING");
27273 self.write_space();
27274 self.generate_expression(using)?;
27275 }
27276 } else if let Some(default) = &e.default {
27277 self.write_space();
27278 self.write_keyword("SET DEFAULT");
27279 self.write_space();
27280 self.generate_expression(default)?;
27281 } else if let Some(comment) = &e.comment {
27282 self.write_space();
27283 self.write_keyword("COMMENT");
27284 self.write_space();
27285 self.generate_expression(comment)?;
27286 } else if let Some(drop) = &e.drop {
27287 self.write_space();
27288 self.write_keyword("DROP");
27289 self.write_space();
27290 self.generate_expression(drop)?;
27291 } else if let Some(visible) = &e.visible {
27292 self.write_space();
27293 self.generate_expression(visible)?;
27294 } else if let Some(rename_to) = &e.rename_to {
27295 self.write_space();
27296 self.write_keyword("RENAME TO");
27297 self.write_space();
27298 self.generate_expression(rename_to)?;
27299 } else if let Some(allow_null) = &e.allow_null {
27300 self.write_space();
27301 self.generate_expression(allow_null)?;
27302 }
27303 Ok(())
27304 }
27305
27306 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
27307 self.write_keyword("ALTER SESSION");
27309 self.write_space();
27310 if e.unset.is_some() {
27311 self.write_keyword("UNSET");
27312 } else {
27313 self.write_keyword("SET");
27314 }
27315 self.write_space();
27316 for (i, expr) in e.expressions.iter().enumerate() {
27317 if i > 0 {
27318 self.write(", ");
27319 }
27320 self.generate_expression(expr)?;
27321 }
27322 Ok(())
27323 }
27324
27325 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
27326 self.write_keyword("SET");
27328
27329 if let Some(opt) = &e.option {
27331 self.write_space();
27332 self.generate_expression(opt)?;
27333 }
27334
27335 if !e.expressions.is_empty() {
27338 let is_properties = e
27340 .expressions
27341 .iter()
27342 .any(|expr| matches!(expr, Expression::Eq(_)));
27343 if is_properties && e.option.is_none() {
27344 self.write_space();
27345 self.write_keyword("PROPERTIES");
27346 }
27347 self.write_space();
27348 for (i, expr) in e.expressions.iter().enumerate() {
27349 if i > 0 {
27350 self.write(", ");
27351 }
27352 self.generate_expression(expr)?;
27353 }
27354 }
27355
27356 if let Some(file_format) = &e.file_format {
27358 self.write(" ");
27359 self.write_keyword("STAGE_FILE_FORMAT");
27360 self.write(" = (");
27361 self.generate_space_separated_properties(file_format)?;
27362 self.write(")");
27363 }
27364
27365 if let Some(copy_options) = &e.copy_options {
27367 self.write(" ");
27368 self.write_keyword("STAGE_COPY_OPTIONS");
27369 self.write(" = (");
27370 self.generate_space_separated_properties(copy_options)?;
27371 self.write(")");
27372 }
27373
27374 if let Some(tag) = &e.tag {
27376 self.write(" ");
27377 self.write_keyword("TAG");
27378 self.write(" ");
27379 self.generate_expression(tag)?;
27380 }
27381
27382 Ok(())
27383 }
27384
27385 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
27387 match expr {
27388 Expression::Tuple(t) => {
27389 for (i, prop) in t.expressions.iter().enumerate() {
27390 if i > 0 {
27391 self.write(" ");
27392 }
27393 self.generate_expression(prop)?;
27394 }
27395 }
27396 _ => {
27397 self.generate_expression(expr)?;
27398 }
27399 }
27400 Ok(())
27401 }
27402
27403 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
27404 self.write_keyword("ALTER");
27406 if e.compound.is_some() {
27407 self.write_space();
27408 self.write_keyword("COMPOUND");
27409 }
27410 self.write_space();
27411 self.write_keyword("SORTKEY");
27412 self.write_space();
27413 if let Some(this) = &e.this {
27414 self.generate_expression(this)?;
27415 } else if !e.expressions.is_empty() {
27416 self.write("(");
27417 for (i, expr) in e.expressions.iter().enumerate() {
27418 if i > 0 {
27419 self.write(", ");
27420 }
27421 self.generate_expression(expr)?;
27422 }
27423 self.write(")");
27424 }
27425 Ok(())
27426 }
27427
27428 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
27429 self.write_keyword("ANALYZE");
27431 if !e.options.is_empty() {
27432 self.write_space();
27433 for (i, opt) in e.options.iter().enumerate() {
27434 if i > 0 {
27435 self.write_space();
27436 }
27437 if let Expression::Identifier(id) = opt {
27439 self.write_keyword(&id.name);
27440 } else {
27441 self.generate_expression(opt)?;
27442 }
27443 }
27444 }
27445 if let Some(kind) = &e.kind {
27446 self.write_space();
27447 self.write_keyword(kind);
27448 }
27449 if let Some(this) = &e.this {
27450 self.write_space();
27451 self.generate_expression(this)?;
27452 }
27453 if !e.columns.is_empty() {
27455 self.write("(");
27456 for (i, col) in e.columns.iter().enumerate() {
27457 if i > 0 {
27458 self.write(", ");
27459 }
27460 self.write(col);
27461 }
27462 self.write(")");
27463 }
27464 if let Some(partition) = &e.partition {
27465 self.write_space();
27466 self.generate_expression(partition)?;
27467 }
27468 if let Some(mode) = &e.mode {
27469 self.write_space();
27470 self.generate_expression(mode)?;
27471 }
27472 if let Some(expression) = &e.expression {
27473 self.write_space();
27474 self.generate_expression(expression)?;
27475 }
27476 if !e.properties.is_empty() {
27477 self.write_space();
27478 self.write_keyword(self.config.with_properties_prefix);
27479 self.write(" (");
27480 for (i, prop) in e.properties.iter().enumerate() {
27481 if i > 0 {
27482 self.write(", ");
27483 }
27484 self.generate_expression(prop)?;
27485 }
27486 self.write(")");
27487 }
27488 Ok(())
27489 }
27490
27491 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
27492 self.write_keyword("DELETE");
27494 if let Some(kind) = &e.kind {
27495 self.write_space();
27496 self.write_keyword(kind);
27497 }
27498 self.write_space();
27499 self.write_keyword("STATISTICS");
27500 Ok(())
27501 }
27502
27503 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
27504 if let Expression::Identifier(id) = e.this.as_ref() {
27507 self.write_keyword(&id.name);
27508 } else {
27509 self.generate_expression(&e.this)?;
27510 }
27511 self.write_space();
27512 self.write_keyword("HISTOGRAM ON");
27513 self.write_space();
27514 for (i, expr) in e.expressions.iter().enumerate() {
27515 if i > 0 {
27516 self.write(", ");
27517 }
27518 self.generate_expression(expr)?;
27519 }
27520 if let Some(expression) = &e.expression {
27521 self.write_space();
27522 self.generate_expression(expression)?;
27523 }
27524 if let Some(update_options) = &e.update_options {
27525 self.write_space();
27526 self.generate_expression(update_options)?;
27527 self.write_space();
27528 self.write_keyword("UPDATE");
27529 }
27530 Ok(())
27531 }
27532
27533 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
27534 self.write_keyword("LIST CHAINED ROWS");
27536 if let Some(expression) = &e.expression {
27537 self.write_space();
27538 self.write_keyword("INTO");
27539 self.write_space();
27540 self.generate_expression(expression)?;
27541 }
27542 Ok(())
27543 }
27544
27545 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
27546 self.write_keyword("SAMPLE");
27548 self.write_space();
27549 if let Some(sample) = &e.sample {
27550 self.generate_expression(sample)?;
27551 self.write_space();
27552 }
27553 self.write_keyword(&e.kind);
27554 Ok(())
27555 }
27556
27557 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
27558 self.write_keyword(&e.kind);
27560 if let Some(option) = &e.option {
27561 self.write_space();
27562 self.generate_expression(option)?;
27563 }
27564 self.write_space();
27565 self.write_keyword("STATISTICS");
27566 if let Some(this) = &e.this {
27567 self.write_space();
27568 self.generate_expression(this)?;
27569 }
27570 if !e.expressions.is_empty() {
27571 self.write_space();
27572 for (i, expr) in e.expressions.iter().enumerate() {
27573 if i > 0 {
27574 self.write(", ");
27575 }
27576 self.generate_expression(expr)?;
27577 }
27578 }
27579 Ok(())
27580 }
27581
27582 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
27583 self.write_keyword("VALIDATE");
27585 self.write_space();
27586 self.write_keyword(&e.kind);
27587 if let Some(this) = &e.this {
27588 self.write_space();
27589 if let Expression::Identifier(id) = this.as_ref() {
27591 self.write_keyword(&id.name);
27592 } else {
27593 self.generate_expression(this)?;
27594 }
27595 }
27596 if let Some(expression) = &e.expression {
27597 self.write_space();
27598 self.write_keyword("INTO");
27599 self.write_space();
27600 self.generate_expression(expression)?;
27601 }
27602 Ok(())
27603 }
27604
27605 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
27606 self.write_keyword("WITH");
27608 self.write_space();
27609 for (i, expr) in e.expressions.iter().enumerate() {
27610 if i > 0 {
27611 self.write(", ");
27612 }
27613 self.generate_expression(expr)?;
27614 }
27615 Ok(())
27616 }
27617
27618 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
27619 self.generate_expression(&e.this)?;
27622 self.write("(");
27623 for (i, arg) in e.expressions.iter().enumerate() {
27624 if i > 0 {
27625 self.write(", ");
27626 }
27627 self.generate_expression(arg)?;
27628 }
27629 self.write(")");
27630 Ok(())
27631 }
27632
27633 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
27634 self.generate_expression(&e.this)?;
27636 self.write("(");
27637 for (i, arg) in e.expressions.iter().enumerate() {
27638 if i > 0 {
27639 self.write(", ");
27640 }
27641 self.generate_expression(arg)?;
27642 }
27643 self.write(")");
27644 Ok(())
27645 }
27646
27647 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
27648 self.generate_expression(&e.this)?;
27650 self.write_space();
27651 self.write_keyword("APPLY");
27652 self.write("(");
27653 self.generate_expression(&e.expression)?;
27654 self.write(")");
27655 Ok(())
27656 }
27657
27658 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
27659 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
27661 self.write("(");
27662 self.generate_expression(&e.this)?;
27663 if let Some(percentile) = &e.percentile {
27664 self.write(", ");
27665 self.generate_expression(percentile)?;
27666 }
27667 self.write(")");
27668 Ok(())
27669 }
27670
27671 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
27672 self.write_keyword("APPROX_QUANTILE");
27674 self.write("(");
27675 self.generate_expression(&e.this)?;
27676 if let Some(quantile) = &e.quantile {
27677 self.write(", ");
27678 self.generate_expression(quantile)?;
27679 }
27680 if let Some(accuracy) = &e.accuracy {
27681 self.write(", ");
27682 self.generate_expression(accuracy)?;
27683 }
27684 if let Some(weight) = &e.weight {
27685 self.write(", ");
27686 self.generate_expression(weight)?;
27687 }
27688 self.write(")");
27689 Ok(())
27690 }
27691
27692 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
27693 self.write_keyword("APPROX_QUANTILES");
27695 self.write("(");
27696 self.generate_expression(&e.this)?;
27697 if let Some(expression) = &e.expression {
27698 self.write(", ");
27699 self.generate_expression(expression)?;
27700 }
27701 self.write(")");
27702 Ok(())
27703 }
27704
27705 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
27706 self.write_keyword("APPROX_TOP_K");
27708 self.write("(");
27709 self.generate_expression(&e.this)?;
27710 if let Some(expression) = &e.expression {
27711 self.write(", ");
27712 self.generate_expression(expression)?;
27713 }
27714 if let Some(counters) = &e.counters {
27715 self.write(", ");
27716 self.generate_expression(counters)?;
27717 }
27718 self.write(")");
27719 Ok(())
27720 }
27721
27722 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
27723 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
27725 self.write("(");
27726 self.generate_expression(&e.this)?;
27727 if let Some(expression) = &e.expression {
27728 self.write(", ");
27729 self.generate_expression(expression)?;
27730 }
27731 self.write(")");
27732 Ok(())
27733 }
27734
27735 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
27736 self.write_keyword("APPROX_TOP_K_COMBINE");
27738 self.write("(");
27739 self.generate_expression(&e.this)?;
27740 if let Some(expression) = &e.expression {
27741 self.write(", ");
27742 self.generate_expression(expression)?;
27743 }
27744 self.write(")");
27745 Ok(())
27746 }
27747
27748 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
27749 self.write_keyword("APPROX_TOP_K_ESTIMATE");
27751 self.write("(");
27752 self.generate_expression(&e.this)?;
27753 if let Some(expression) = &e.expression {
27754 self.write(", ");
27755 self.generate_expression(expression)?;
27756 }
27757 self.write(")");
27758 Ok(())
27759 }
27760
27761 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
27762 self.write_keyword("APPROX_TOP_SUM");
27764 self.write("(");
27765 self.generate_expression(&e.this)?;
27766 self.write(", ");
27767 self.generate_expression(&e.expression)?;
27768 if let Some(count) = &e.count {
27769 self.write(", ");
27770 self.generate_expression(count)?;
27771 }
27772 self.write(")");
27773 Ok(())
27774 }
27775
27776 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
27777 self.write_keyword("ARG_MAX");
27779 self.write("(");
27780 self.generate_expression(&e.this)?;
27781 self.write(", ");
27782 self.generate_expression(&e.expression)?;
27783 if let Some(count) = &e.count {
27784 self.write(", ");
27785 self.generate_expression(count)?;
27786 }
27787 self.write(")");
27788 Ok(())
27789 }
27790
27791 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
27792 self.write_keyword("ARG_MIN");
27794 self.write("(");
27795 self.generate_expression(&e.this)?;
27796 self.write(", ");
27797 self.generate_expression(&e.expression)?;
27798 if let Some(count) = &e.count {
27799 self.write(", ");
27800 self.generate_expression(count)?;
27801 }
27802 self.write(")");
27803 Ok(())
27804 }
27805
27806 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
27807 self.write_keyword("ARRAY_ALL");
27809 self.write("(");
27810 self.generate_expression(&e.this)?;
27811 self.write(", ");
27812 self.generate_expression(&e.expression)?;
27813 self.write(")");
27814 Ok(())
27815 }
27816
27817 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
27818 self.write_keyword("ARRAY_ANY");
27820 self.write("(");
27821 self.generate_expression(&e.this)?;
27822 self.write(", ");
27823 self.generate_expression(&e.expression)?;
27824 self.write(")");
27825 Ok(())
27826 }
27827
27828 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
27829 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
27831 self.write("(");
27832 for (i, expr) in e.expressions.iter().enumerate() {
27833 if i > 0 {
27834 self.write(", ");
27835 }
27836 self.generate_expression(expr)?;
27837 }
27838 self.write(")");
27839 Ok(())
27840 }
27841
27842 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
27843 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
27845 self.write("arraySum");
27846 } else {
27847 self.write_keyword("ARRAY_SUM");
27848 }
27849 self.write("(");
27850 self.generate_expression(&e.this)?;
27851 if let Some(expression) = &e.expression {
27852 self.write(", ");
27853 self.generate_expression(expression)?;
27854 }
27855 self.write(")");
27856 Ok(())
27857 }
27858
27859 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
27860 self.generate_expression(&e.this)?;
27862 self.write_space();
27863 self.write_keyword("AT");
27864 self.write_space();
27865 self.generate_expression(&e.expression)?;
27866 Ok(())
27867 }
27868
27869 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
27870 self.write_keyword("ATTACH");
27872 if e.exists {
27873 self.write_space();
27874 self.write_keyword("IF NOT EXISTS");
27875 }
27876 self.write_space();
27877 self.generate_expression(&e.this)?;
27878 if !e.expressions.is_empty() {
27879 self.write(" (");
27880 for (i, expr) in e.expressions.iter().enumerate() {
27881 if i > 0 {
27882 self.write(", ");
27883 }
27884 self.generate_expression(expr)?;
27885 }
27886 self.write(")");
27887 }
27888 Ok(())
27889 }
27890
27891 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
27892 self.generate_expression(&e.this)?;
27895 if let Some(expression) = &e.expression {
27896 self.write_space();
27897 self.generate_expression(expression)?;
27898 }
27899 Ok(())
27900 }
27901
27902 fn generate_auto_increment_keyword(
27906 &mut self,
27907 col: &crate::expressions::ColumnDef,
27908 ) -> Result<()> {
27909 use crate::dialects::DialectType;
27910 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
27911 self.write_keyword("IDENTITY");
27912 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27913 self.write("(");
27914 if let Some(ref start) = col.auto_increment_start {
27915 self.generate_expression(start)?;
27916 } else {
27917 self.write("0");
27918 }
27919 self.write(", ");
27920 if let Some(ref inc) = col.auto_increment_increment {
27921 self.generate_expression(inc)?;
27922 } else {
27923 self.write("1");
27924 }
27925 self.write(")");
27926 }
27927 } else if matches!(
27928 self.config.dialect,
27929 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
27930 ) {
27931 self.write_keyword("AUTOINCREMENT");
27932 if let Some(ref start) = col.auto_increment_start {
27933 self.write_space();
27934 self.write_keyword("START");
27935 self.write_space();
27936 self.generate_expression(start)?;
27937 }
27938 if let Some(ref inc) = col.auto_increment_increment {
27939 self.write_space();
27940 self.write_keyword("INCREMENT");
27941 self.write_space();
27942 self.generate_expression(inc)?;
27943 }
27944 if let Some(order) = col.auto_increment_order {
27945 self.write_space();
27946 if order {
27947 self.write_keyword("ORDER");
27948 } else {
27949 self.write_keyword("NOORDER");
27950 }
27951 }
27952 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
27953 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
27954 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27955 self.write(" (");
27956 let mut first = true;
27957 if let Some(ref start) = col.auto_increment_start {
27958 self.write_keyword("START WITH");
27959 self.write_space();
27960 self.generate_expression(start)?;
27961 first = false;
27962 }
27963 if let Some(ref inc) = col.auto_increment_increment {
27964 if !first {
27965 self.write_space();
27966 }
27967 self.write_keyword("INCREMENT BY");
27968 self.write_space();
27969 self.generate_expression(inc)?;
27970 }
27971 self.write(")");
27972 }
27973 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
27974 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27977 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
27978 } else {
27979 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
27980 }
27981 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
27982 self.write(" (");
27983 let mut first = true;
27984 if let Some(ref start) = col.auto_increment_start {
27985 self.write_keyword("START WITH");
27986 self.write_space();
27987 self.generate_expression(start)?;
27988 first = false;
27989 }
27990 if let Some(ref inc) = col.auto_increment_increment {
27991 if !first {
27992 self.write_space();
27993 }
27994 self.write_keyword("INCREMENT BY");
27995 self.write_space();
27996 self.generate_expression(inc)?;
27997 }
27998 self.write(")");
27999 }
28000 } else if matches!(
28001 self.config.dialect,
28002 Some(DialectType::TSQL) | Some(DialectType::Fabric)
28003 ) {
28004 self.write_keyword("IDENTITY");
28005 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
28006 self.write("(");
28007 if let Some(ref start) = col.auto_increment_start {
28008 self.generate_expression(start)?;
28009 } else {
28010 self.write("0");
28011 }
28012 self.write(", ");
28013 if let Some(ref inc) = col.auto_increment_increment {
28014 self.generate_expression(inc)?;
28015 } else {
28016 self.write("1");
28017 }
28018 self.write(")");
28019 }
28020 } else {
28021 self.write_keyword("AUTO_INCREMENT");
28022 if let Some(ref start) = col.auto_increment_start {
28023 self.write_space();
28024 self.write_keyword("START");
28025 self.write_space();
28026 self.generate_expression(start)?;
28027 }
28028 if let Some(ref inc) = col.auto_increment_increment {
28029 self.write_space();
28030 self.write_keyword("INCREMENT");
28031 self.write_space();
28032 self.generate_expression(inc)?;
28033 }
28034 if let Some(order) = col.auto_increment_order {
28035 self.write_space();
28036 if order {
28037 self.write_keyword("ORDER");
28038 } else {
28039 self.write_keyword("NOORDER");
28040 }
28041 }
28042 }
28043 Ok(())
28044 }
28045
28046 fn generate_tidb_auto_random(&mut self, auto_random: &TiDBAutoRandom) -> Result<()> {
28047 let is_tidb = matches!(self.config.dialect, Some(DialectType::TiDB));
28048 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
28049
28050 if !is_tidb && !is_mysql {
28051 return self
28052 .write_unsupported_comment("AUTO_RANDOM is only supported by the TiDB dialect");
28053 }
28054 if is_mysql {
28055 self.unsupported("MySQL ignores TiDB AUTO_RANDOM executable comments")?;
28056 }
28057
28058 let use_comment = auto_random.executable_comment || is_mysql;
28059 if use_comment {
28060 self.write("/*T![auto_rand] ");
28061 }
28062 self.write_keyword("AUTO_RANDOM");
28063 if let Some(shard_bits) = auto_random.shard_bits {
28064 self.write("(");
28065 self.write(&shard_bits.to_string());
28066 if let Some(range_bits) = auto_random.range_bits {
28067 self.write(", ");
28068 self.write(&range_bits.to_string());
28069 }
28070 self.write(")");
28071 }
28072 if use_comment {
28073 self.write(" */");
28074 }
28075 Ok(())
28076 }
28077
28078 fn generate_tidb_table_option(&mut self, option: &TiDBTableOption, force: bool) -> Result<()> {
28079 let is_tidb = matches!(self.config.dialect, Some(DialectType::TiDB));
28080 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
28081 if !is_tidb && !is_mysql {
28082 return self.write_unsupported_comment(
28083 "TiDB table options are not supported by the target dialect",
28084 );
28085 }
28086 if is_mysql {
28087 self.unsupported("MySQL ignores TiDB table-option executable comments")?;
28088 }
28089
28090 let use_comment = option.executable_comment || is_mysql;
28091 if use_comment {
28092 match option.kind {
28093 TiDBTableOptionKind::Ttl { .. }
28094 | TiDBTableOptionKind::TtlEnable { .. }
28095 | TiDBTableOptionKind::TtlJobInterval { .. } => self.write("/*T![ttl] "),
28096 TiDBTableOptionKind::PlacementPolicy { .. } => self.write("/*T![placement] "),
28097 _ => self.write("/*T! "),
28098 }
28099 }
28100 if force {
28101 self.write_keyword("FORCE");
28102 self.write_space();
28103 }
28104 match &option.kind {
28105 TiDBTableOptionKind::ShardRowIdBits { bits } => {
28106 self.write_keyword("SHARD_ROW_ID_BITS");
28107 self.write("=");
28108 self.write(&bits.to_string());
28109 }
28110 TiDBTableOptionKind::PreSplitRegions { regions } => {
28111 self.write_keyword("PRE_SPLIT_REGIONS");
28112 self.write("=");
28113 self.write(®ions.to_string());
28114 }
28115 TiDBTableOptionKind::AutoRandomBase { value } => {
28116 self.write_keyword("AUTO_RANDOM_BASE");
28117 self.write("=");
28118 self.write(&value.to_string());
28119 }
28120 TiDBTableOptionKind::PlacementPolicy { policy } => {
28121 self.write_keyword("PLACEMENT POLICY");
28122 self.write("=");
28123 if let Some(policy) = policy {
28124 self.generate_identifier(policy)?;
28125 } else {
28126 self.write_keyword("DEFAULT");
28127 }
28128 }
28129 TiDBTableOptionKind::Ttl {
28130 column,
28131 interval,
28132 enabled,
28133 } => {
28134 self.write_keyword("TTL");
28135 self.write("=");
28136 self.generate_identifier(column)?;
28137 self.write(" + ");
28138 self.generate_tidb_ttl_interval(interval)?;
28139 if let Some(enabled) = enabled {
28140 self.write_space();
28141 self.write_keyword("TTL_ENABLE");
28142 self.write("='");
28143 self.write(if *enabled { "ON" } else { "OFF" });
28144 self.write("'");
28145 }
28146 }
28147 TiDBTableOptionKind::TtlEnable { enabled } => {
28148 self.write_keyword("TTL_ENABLE");
28149 self.write("='");
28150 self.write(if *enabled { "ON" } else { "OFF" });
28151 self.write("'");
28152 }
28153 TiDBTableOptionKind::TtlJobInterval { interval } => {
28154 self.write_keyword("TTL_JOB_INTERVAL");
28155 self.write("=");
28156 self.generate_string_literal(interval)?;
28157 }
28158 }
28159 if use_comment {
28160 self.write(" */");
28161 }
28162 Ok(())
28163 }
28164
28165 fn generate_tidb_ttl_interval(&mut self, interval: &Interval) -> Result<()> {
28166 self.write_keyword("INTERVAL");
28167 if let Some(value) = &interval.this {
28168 self.write_space();
28169 if let Expression::Literal(literal) = value {
28170 if let Literal::String(value) = literal.as_ref() {
28171 if value.parse::<f64>().is_ok() {
28172 self.write(value);
28173 } else {
28174 self.generate_string_literal(value)?;
28175 }
28176 } else {
28177 self.generate_expression(value)?;
28178 }
28179 } else {
28180 self.generate_expression(value)?;
28181 }
28182 }
28183 if let Some(unit) = &interval.unit {
28184 self.write_space();
28185 self.write_interval_unit_spec(unit)?;
28186 }
28187 Ok(())
28188 }
28189
28190 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
28191 self.write_keyword("AUTO_INCREMENT");
28193 self.write("=");
28194 self.generate_expression(&e.this)?;
28195 Ok(())
28196 }
28197
28198 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
28199 self.write_keyword("AUTO_REFRESH");
28201 self.write("=");
28202 self.generate_expression(&e.this)?;
28203 Ok(())
28204 }
28205
28206 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
28207 self.write_keyword("BACKUP");
28209 self.write_space();
28210 self.generate_expression(&e.this)?;
28211 Ok(())
28212 }
28213
28214 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
28215 self.write_keyword("BASE64_DECODE_BINARY");
28217 self.write("(");
28218 self.generate_expression(&e.this)?;
28219 if let Some(alphabet) = &e.alphabet {
28220 self.write(", ");
28221 self.generate_expression(alphabet)?;
28222 }
28223 self.write(")");
28224 Ok(())
28225 }
28226
28227 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
28228 self.write_keyword("BASE64_DECODE_STRING");
28230 self.write("(");
28231 self.generate_expression(&e.this)?;
28232 if let Some(alphabet) = &e.alphabet {
28233 self.write(", ");
28234 self.generate_expression(alphabet)?;
28235 }
28236 self.write(")");
28237 Ok(())
28238 }
28239
28240 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
28241 self.write_keyword("BASE64_ENCODE");
28243 self.write("(");
28244 self.generate_expression(&e.this)?;
28245 if let Some(max_line_length) = &e.max_line_length {
28246 self.write(", ");
28247 self.generate_expression(max_line_length)?;
28248 }
28249 if let Some(alphabet) = &e.alphabet {
28250 self.write(", ");
28251 self.generate_expression(alphabet)?;
28252 }
28253 self.write(")");
28254 Ok(())
28255 }
28256
28257 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
28258 self.write_keyword("BLOCKCOMPRESSION");
28260 self.write("=");
28261 if let Some(autotemp) = &e.autotemp {
28262 self.write_keyword("AUTOTEMP");
28263 self.write("(");
28264 self.generate_expression(autotemp)?;
28265 self.write(")");
28266 }
28267 if let Some(always) = &e.always {
28268 self.generate_expression(always)?;
28269 }
28270 if let Some(default) = &e.default {
28271 self.generate_expression(default)?;
28272 }
28273 if let Some(manual) = &e.manual {
28274 self.generate_expression(manual)?;
28275 }
28276 if let Some(never) = &e.never {
28277 self.generate_expression(never)?;
28278 }
28279 Ok(())
28280 }
28281
28282 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
28283 self.write("((");
28285 self.generate_expression(&e.this)?;
28286 self.write(") ");
28287 self.write_keyword("AND");
28288 self.write(" (");
28289 self.generate_expression(&e.expression)?;
28290 self.write("))");
28291 Ok(())
28292 }
28293
28294 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
28295 self.write("((");
28297 self.generate_expression(&e.this)?;
28298 self.write(") ");
28299 self.write_keyword("OR");
28300 self.write(" (");
28301 self.generate_expression(&e.expression)?;
28302 self.write("))");
28303 Ok(())
28304 }
28305
28306 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
28307 self.write_keyword("BUILD");
28309 self.write_space();
28310 self.generate_expression(&e.this)?;
28311 Ok(())
28312 }
28313
28314 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
28315 self.generate_expression(&e.this)?;
28317 Ok(())
28318 }
28319
28320 fn generate_case_specific_column_constraint(
28321 &mut self,
28322 e: &CaseSpecificColumnConstraint,
28323 ) -> Result<()> {
28324 if e.not_.is_some() {
28326 self.write_keyword("NOT");
28327 self.write_space();
28328 }
28329 self.write_keyword("CASESPECIFIC");
28330 Ok(())
28331 }
28332
28333 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
28334 self.write_keyword("CAST");
28336 self.write("(");
28337 self.generate_expression(&e.this)?;
28338 if self.config.dialect == Some(DialectType::ClickHouse) {
28339 self.write(", ");
28341 } else {
28342 self.write_space();
28343 self.write_keyword("AS");
28344 self.write_space();
28345 }
28346 if let Some(to) = &e.to {
28347 self.generate_expression(to)?;
28348 }
28349 self.write(")");
28350 Ok(())
28351 }
28352
28353 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
28354 self.write_keyword("CHANGES");
28357 self.write(" (");
28358 if let Some(information) = &e.information {
28359 self.write_keyword("INFORMATION");
28360 self.write(" => ");
28361 self.generate_expression(information)?;
28362 }
28363 self.write(")");
28364 if let Some(at_before) = &e.at_before {
28366 self.write(" ");
28367 self.generate_expression(at_before)?;
28368 }
28369 if let Some(end) = &e.end {
28370 self.write(" ");
28371 self.generate_expression(end)?;
28372 }
28373 Ok(())
28374 }
28375
28376 fn generate_character_set_column_constraint(
28377 &mut self,
28378 e: &CharacterSetColumnConstraint,
28379 ) -> Result<()> {
28380 self.write_keyword("CHARACTER SET");
28382 self.write_space();
28383 self.generate_expression(&e.this)?;
28384 Ok(())
28385 }
28386
28387 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
28388 if e.default.is_some() {
28390 self.write_keyword("DEFAULT");
28391 self.write_space();
28392 }
28393 self.write_keyword("CHARACTER SET");
28394 self.write("=");
28395 self.generate_expression(&e.this)?;
28396 Ok(())
28397 }
28398
28399 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
28400 self.write_keyword("CHECK");
28402 self.write(" (");
28403 self.generate_expression(&e.this)?;
28404 self.write(")");
28405 if e.enforced.is_some() {
28406 self.write_space();
28407 self.write_keyword("ENFORCED");
28408 }
28409 Ok(())
28410 }
28411
28412 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
28413 self.write_keyword("ASSUME");
28415 self.write(" (");
28416 self.generate_expression(&e.this)?;
28417 self.write(")");
28418 Ok(())
28419 }
28420
28421 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
28422 self.write_keyword("CHECK_JSON");
28424 self.write("(");
28425 self.generate_expression(&e.this)?;
28426 self.write(")");
28427 Ok(())
28428 }
28429
28430 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
28431 self.write_keyword("CHECK_XML");
28433 self.write("(");
28434 self.generate_expression(&e.this)?;
28435 self.write(")");
28436 Ok(())
28437 }
28438
28439 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
28440 self.write_keyword("CHECKSUM");
28442 self.write("=");
28443 if e.on.is_some() {
28444 self.write_keyword("ON");
28445 } else if e.default.is_some() {
28446 self.write_keyword("DEFAULT");
28447 } else {
28448 self.write_keyword("OFF");
28449 }
28450 Ok(())
28451 }
28452
28453 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
28454 if e.shallow.is_some() {
28456 self.write_keyword("SHALLOW");
28457 self.write_space();
28458 }
28459 if e.copy.is_some() {
28460 self.write_keyword("COPY");
28461 } else {
28462 self.write_keyword("CLONE");
28463 }
28464 self.write_space();
28465 self.generate_expression(&e.this)?;
28466 Ok(())
28467 }
28468
28469 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
28470 self.write_keyword("CLUSTER BY");
28472 self.write(" (");
28473 for (i, ord) in e.expressions.iter().enumerate() {
28474 if i > 0 {
28475 self.write(", ");
28476 }
28477 self.generate_ordered(ord)?;
28478 }
28479 self.write(")");
28480 Ok(())
28481 }
28482
28483 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
28484 self.write_keyword("CLUSTER BY");
28486 self.write_space();
28487 for (i, col) in e.columns.iter().enumerate() {
28488 if i > 0 {
28489 self.write(", ");
28490 }
28491 self.generate_identifier(col)?;
28492 }
28493 Ok(())
28494 }
28495
28496 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
28497 self.write_keyword("CLUSTERED BY");
28499 self.write(" (");
28500 for (i, expr) in e.expressions.iter().enumerate() {
28501 if i > 0 {
28502 self.write(", ");
28503 }
28504 self.generate_expression(expr)?;
28505 }
28506 self.write(")");
28507 if let Some(sorted_by) = &e.sorted_by {
28508 self.write_space();
28509 self.write_keyword("SORTED BY");
28510 self.write(" (");
28511 if let Expression::Tuple(t) = sorted_by.as_ref() {
28513 for (i, expr) in t.expressions.iter().enumerate() {
28514 if i > 0 {
28515 self.write(", ");
28516 }
28517 self.generate_expression(expr)?;
28518 }
28519 } else {
28520 self.generate_expression(sorted_by)?;
28521 }
28522 self.write(")");
28523 }
28524 if let Some(buckets) = &e.buckets {
28525 self.write_space();
28526 self.write_keyword("INTO");
28527 self.write_space();
28528 self.generate_expression(buckets)?;
28529 self.write_space();
28530 self.write_keyword("BUCKETS");
28531 }
28532 Ok(())
28533 }
28534
28535 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
28536 if e.default.is_some() {
28540 self.write_keyword("DEFAULT");
28541 self.write_space();
28542 }
28543 self.write_keyword("COLLATE");
28544 match self.config.dialect {
28546 Some(DialectType::BigQuery) => self.write_space(),
28547 _ => self.write("="),
28548 }
28549 self.generate_expression(&e.this)?;
28550 Ok(())
28551 }
28552
28553 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
28554 match e {
28556 ColumnConstraint::NotNull => {
28557 self.write_keyword("NOT NULL");
28558 }
28559 ColumnConstraint::Null => {
28560 self.write_keyword("NULL");
28561 }
28562 ColumnConstraint::Unique => {
28563 self.write_keyword("UNIQUE");
28564 }
28565 ColumnConstraint::PrimaryKey => {
28566 self.write_keyword("PRIMARY KEY");
28567 }
28568 ColumnConstraint::Default(expr) => {
28569 self.write_keyword("DEFAULT");
28570 self.write_space();
28571 self.generate_expression(expr)?;
28572 }
28573 ColumnConstraint::Check(expr) => {
28574 self.write_keyword("CHECK");
28575 self.write(" (");
28576 self.generate_expression(expr)?;
28577 self.write(")");
28578 }
28579 ColumnConstraint::References(fk_ref) => {
28580 if fk_ref.has_foreign_key_keywords {
28581 self.write_keyword("FOREIGN KEY");
28582 self.write_space();
28583 }
28584 self.write_keyword("REFERENCES");
28585 self.write_space();
28586 self.generate_table(&fk_ref.table)?;
28587 if !fk_ref.columns.is_empty() {
28588 self.write(" (");
28589 for (i, col) in fk_ref.columns.iter().enumerate() {
28590 if i > 0 {
28591 self.write(", ");
28592 }
28593 self.generate_identifier(col)?;
28594 }
28595 self.write(")");
28596 }
28597 }
28598 ColumnConstraint::GeneratedAsIdentity(gen) => {
28599 self.write_keyword("GENERATED");
28600 self.write_space();
28601 if gen.always {
28602 self.write_keyword("ALWAYS");
28603 } else {
28604 self.write_keyword("BY DEFAULT");
28605 if gen.on_null {
28606 self.write_space();
28607 self.write_keyword("ON NULL");
28608 }
28609 }
28610 self.write_space();
28611 self.write_keyword("AS IDENTITY");
28612 }
28613 ColumnConstraint::Collate(collation) => {
28614 self.write_keyword("COLLATE");
28615 self.write_space();
28616 self.generate_identifier(collation)?;
28617 }
28618 ColumnConstraint::Comment(comment) => {
28619 self.write_keyword("COMMENT");
28620 self.write(" '");
28621 self.write(comment);
28622 self.write("'");
28623 }
28624 ColumnConstraint::ComputedColumn(cc) => {
28625 self.generate_computed_column_inline(cc)?;
28626 }
28627 ColumnConstraint::GeneratedAsRow(gar) => {
28628 self.generate_generated_as_row_inline(gar)?;
28629 }
28630 ColumnConstraint::Tags(tags) => {
28631 self.write_keyword("TAG");
28632 self.write(" (");
28633 for (i, expr) in tags.expressions.iter().enumerate() {
28634 if i > 0 {
28635 self.write(", ");
28636 }
28637 self.generate_expression(expr)?;
28638 }
28639 self.write(")");
28640 }
28641 ColumnConstraint::Path(path_expr) => {
28642 self.write_keyword("PATH");
28643 self.write_space();
28644 self.generate_expression(path_expr)?;
28645 }
28646 }
28647 Ok(())
28648 }
28649
28650 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
28651 match e {
28653 ColumnPosition::First => {
28654 self.write_keyword("FIRST");
28655 }
28656 ColumnPosition::After(ident) => {
28657 self.write_keyword("AFTER");
28658 self.write_space();
28659 self.generate_identifier(ident)?;
28660 }
28661 }
28662 Ok(())
28663 }
28664
28665 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
28666 self.generate_expression(&e.this)?;
28668 self.write("(");
28669 self.generate_expression(&e.expression)?;
28670 self.write(")");
28671 Ok(())
28672 }
28673
28674 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
28675 if let Some(ref unpack) = e.unpack {
28678 if let Expression::Boolean(b) = unpack.as_ref() {
28679 if b.value {
28680 self.write("*");
28681 }
28682 }
28683 }
28684 self.write_keyword("COLUMNS");
28685 self.write("(");
28686 self.generate_expression(&e.this)?;
28687 self.write(")");
28688 Ok(())
28689 }
28690
28691 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
28692 self.generate_expression(&e.this)?;
28694 self.write("(");
28695 for (i, expr) in e.expressions.iter().enumerate() {
28696 if i > 0 {
28697 self.write(", ");
28698 }
28699 self.generate_expression(expr)?;
28700 }
28701 self.write(")");
28702 Ok(())
28703 }
28704
28705 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
28706 self.generate_expression(&e.this)?;
28708 self.write("(");
28709 for (i, param) in e.params.iter().enumerate() {
28710 if i > 0 {
28711 self.write(", ");
28712 }
28713 self.generate_expression(param)?;
28714 }
28715 self.write(")(");
28716 for (i, expr) in e.expressions.iter().enumerate() {
28717 if i > 0 {
28718 self.write(", ");
28719 }
28720 self.generate_expression(expr)?;
28721 }
28722 self.write(")");
28723 Ok(())
28724 }
28725
28726 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
28727 self.write_keyword("COMMIT");
28729
28730 if e.this.is_none()
28732 && matches!(
28733 self.config.dialect,
28734 Some(DialectType::TSQL) | Some(DialectType::Fabric)
28735 )
28736 {
28737 self.write_space();
28738 self.write_keyword("TRANSACTION");
28739 }
28740
28741 if let Some(this) = &e.this {
28743 let is_transaction_marker = matches!(
28745 this.as_ref(),
28746 Expression::Identifier(id) if id.name == "TRANSACTION"
28747 );
28748
28749 self.write_space();
28750 self.write_keyword("TRANSACTION");
28751
28752 if !is_transaction_marker {
28754 self.write_space();
28755 self.generate_expression(this)?;
28756 }
28757 }
28758
28759 if let Some(durability) = &e.durability {
28761 self.write_space();
28762 self.write_keyword("WITH");
28763 self.write(" (");
28764 self.write_keyword("DELAYED_DURABILITY");
28765 self.write(" = ");
28766 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
28767 self.write_keyword("ON");
28768 } else {
28769 self.write_keyword("OFF");
28770 }
28771 self.write(")");
28772 }
28773
28774 if let Some(chain) = &e.chain {
28776 self.write_space();
28777 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
28778 self.write_keyword("AND NO CHAIN");
28779 } else {
28780 self.write_keyword("AND CHAIN");
28781 }
28782 }
28783 Ok(())
28784 }
28785
28786 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
28787 self.write("[");
28789 self.generate_expression(&e.this)?;
28790 self.write_space();
28791 self.write_keyword("FOR");
28792 self.write_space();
28793 self.generate_expression(&e.expression)?;
28794 if let Some(pos) = &e.position {
28796 self.write(", ");
28797 self.generate_expression(pos)?;
28798 }
28799 if let Some(iterator) = &e.iterator {
28800 self.write_space();
28801 self.write_keyword("IN");
28802 self.write_space();
28803 self.generate_expression(iterator)?;
28804 }
28805 if let Some(condition) = &e.condition {
28806 self.write_space();
28807 self.write_keyword("IF");
28808 self.write_space();
28809 self.generate_expression(condition)?;
28810 }
28811 self.write("]");
28812 Ok(())
28813 }
28814
28815 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
28816 self.write_keyword("COMPRESS");
28818 self.write("(");
28819 self.generate_expression(&e.this)?;
28820 if let Some(method) = &e.method {
28821 self.write(", '");
28822 self.write(method);
28823 self.write("'");
28824 }
28825 self.write(")");
28826 Ok(())
28827 }
28828
28829 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
28830 self.write_keyword("COMPRESS");
28832 if let Some(this) = &e.this {
28833 self.write_space();
28834 self.generate_expression(this)?;
28835 }
28836 Ok(())
28837 }
28838
28839 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
28840 self.write_keyword("AS");
28842 self.write_space();
28843 self.generate_expression(&e.this)?;
28844 if e.not_null.is_some() {
28845 self.write_space();
28846 self.write_keyword("PERSISTED NOT NULL");
28847 } else if e.persisted.is_some() {
28848 self.write_space();
28849 self.write_keyword("PERSISTED");
28850 }
28851 Ok(())
28852 }
28853
28854 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
28858 let computed_expr = if matches!(
28859 self.config.dialect,
28860 Some(DialectType::TSQL) | Some(DialectType::Fabric)
28861 ) {
28862 match &*cc.expression {
28863 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
28864 {
28865 let wrapped = Expression::Cast(Box::new(Cast {
28866 this: y.this.clone(),
28867 to: DataType::Date,
28868 trailing_comments: Vec::new(),
28869 double_colon_syntax: false,
28870 format: None,
28871 default: None,
28872 inferred_type: None,
28873 }));
28874 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
28875 }
28876 Expression::Function(f)
28877 if f.name.eq_ignore_ascii_case("YEAR")
28878 && f.args.len() == 1
28879 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
28880 {
28881 let wrapped = Expression::Cast(Box::new(Cast {
28882 this: f.args[0].clone(),
28883 to: DataType::Date,
28884 trailing_comments: Vec::new(),
28885 double_colon_syntax: false,
28886 format: None,
28887 default: None,
28888 inferred_type: None,
28889 }));
28890 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
28891 }
28892 _ => *cc.expression.clone(),
28893 }
28894 } else {
28895 *cc.expression.clone()
28896 };
28897
28898 match cc.persistence_kind.as_deref() {
28899 Some("STORED") | Some("VIRTUAL") => {
28900 self.write_keyword("GENERATED ALWAYS AS");
28902 self.write(" (");
28903 self.generate_expression(&computed_expr)?;
28904 self.write(")");
28905 self.write_space();
28906 if cc.persisted {
28907 self.write_keyword("STORED");
28908 } else {
28909 self.write_keyword("VIRTUAL");
28910 }
28911 }
28912 Some("PERSISTED") => {
28913 self.write_keyword("AS");
28915 self.write(" (");
28916 self.generate_expression(&computed_expr)?;
28917 self.write(")");
28918 self.write_space();
28919 self.write_keyword("PERSISTED");
28920 if let Some(ref dt) = cc.data_type {
28922 self.write_space();
28923 self.generate_data_type(dt)?;
28924 }
28925 if cc.not_null {
28926 self.write_space();
28927 self.write_keyword("NOT NULL");
28928 }
28929 }
28930 _ => {
28931 if matches!(
28934 self.config.dialect,
28935 Some(DialectType::Spark)
28936 | Some(DialectType::Databricks)
28937 | Some(DialectType::Hive)
28938 ) {
28939 self.write_keyword("GENERATED ALWAYS AS");
28940 self.write(" (");
28941 self.generate_expression(&computed_expr)?;
28942 self.write(")");
28943 } else if matches!(
28944 self.config.dialect,
28945 Some(DialectType::TSQL) | Some(DialectType::Fabric)
28946 ) {
28947 self.write_keyword("AS");
28948 let omit_parens = matches!(computed_expr, Expression::Year(_))
28949 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
28950 if omit_parens {
28951 self.write_space();
28952 self.generate_expression(&computed_expr)?;
28953 } else {
28954 self.write(" (");
28955 self.generate_expression(&computed_expr)?;
28956 self.write(")");
28957 }
28958 } else {
28959 self.write_keyword("AS");
28960 self.write(" (");
28961 self.generate_expression(&computed_expr)?;
28962 self.write(")");
28963 }
28964 }
28965 }
28966 Ok(())
28967 }
28968
28969 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
28972 self.write_keyword("GENERATED ALWAYS AS ROW ");
28973 if gar.start {
28974 self.write_keyword("START");
28975 } else {
28976 self.write_keyword("END");
28977 }
28978 if gar.hidden {
28979 self.write_space();
28980 self.write_keyword("HIDDEN");
28981 }
28982 Ok(())
28983 }
28984
28985 fn generate_system_versioning_content(
28987 &mut self,
28988 e: &WithSystemVersioningProperty,
28989 ) -> Result<()> {
28990 let mut parts = Vec::new();
28991
28992 if let Some(this) = &e.this {
28993 let mut s = String::from("HISTORY_TABLE=");
28994 let mut gen = Generator::with_arc_config(self.config.clone());
28995 gen.generate_expression(this)?;
28996 s.push_str(&gen.output);
28997 parts.push(s);
28998 }
28999
29000 if let Some(data_consistency) = &e.data_consistency {
29001 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
29002 let mut gen = Generator::with_arc_config(self.config.clone());
29003 gen.generate_expression(data_consistency)?;
29004 s.push_str(&gen.output);
29005 parts.push(s);
29006 }
29007
29008 if let Some(retention_period) = &e.retention_period {
29009 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
29010 let mut gen = Generator::with_arc_config(self.config.clone());
29011 gen.generate_expression(retention_period)?;
29012 s.push_str(&gen.output);
29013 parts.push(s);
29014 }
29015
29016 self.write_keyword("SYSTEM_VERSIONING");
29017 self.write("=");
29018
29019 if !parts.is_empty() {
29020 self.write_keyword("ON");
29021 self.write("(");
29022 self.write(&parts.join(", "));
29023 self.write(")");
29024 } else if e.on.is_some() {
29025 self.write_keyword("ON");
29026 } else {
29027 self.write_keyword("OFF");
29028 }
29029
29030 Ok(())
29031 }
29032
29033 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
29034 if e.else_.is_some() {
29037 self.write_keyword("ELSE");
29038 self.write_space();
29039 } else if let Some(expression) = &e.expression {
29040 self.write_keyword("WHEN");
29041 self.write_space();
29042 self.generate_expression(expression)?;
29043 self.write_space();
29044 self.write_keyword("THEN");
29045 self.write_space();
29046 }
29047
29048 if let Expression::Insert(insert) = e.this.as_ref() {
29051 self.write_keyword("INTO");
29052 self.write_space();
29053 self.generate_table(&insert.table)?;
29054
29055 if !insert.columns.is_empty() {
29057 self.write(" (");
29058 for (i, col) in insert.columns.iter().enumerate() {
29059 if i > 0 {
29060 self.write(", ");
29061 }
29062 self.generate_identifier(col)?;
29063 }
29064 self.write(")");
29065 }
29066
29067 if !insert.values.is_empty() {
29069 self.write_space();
29070 self.write_keyword("VALUES");
29071 for (row_idx, row) in insert.values.iter().enumerate() {
29072 if row_idx > 0 {
29073 self.write(", ");
29074 }
29075 self.write(" (");
29076 for (i, val) in row.iter().enumerate() {
29077 if i > 0 {
29078 self.write(", ");
29079 }
29080 self.generate_expression(val)?;
29081 }
29082 self.write(")");
29083 }
29084 }
29085 } else {
29086 self.generate_expression(&e.this)?;
29088 }
29089 Ok(())
29090 }
29091
29092 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
29093 self.write_keyword("CONSTRAINT");
29095 self.write_space();
29096 self.generate_expression(&e.this)?;
29097 if !e.expressions.is_empty() {
29098 self.write_space();
29099 for (i, expr) in e.expressions.iter().enumerate() {
29100 if i > 0 {
29101 self.write_space();
29102 }
29103 self.generate_expression(expr)?;
29104 }
29105 }
29106 Ok(())
29107 }
29108
29109 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
29110 self.write_keyword("CONVERT_TIMEZONE");
29112 self.write("(");
29113 let mut first = true;
29114 if let Some(source_tz) = &e.source_tz {
29115 self.generate_expression(source_tz)?;
29116 first = false;
29117 }
29118 if let Some(target_tz) = &e.target_tz {
29119 if !first {
29120 self.write(", ");
29121 }
29122 self.generate_expression(target_tz)?;
29123 first = false;
29124 }
29125 if let Some(timestamp) = &e.timestamp {
29126 if !first {
29127 self.write(", ");
29128 }
29129 self.generate_expression(timestamp)?;
29130 }
29131 self.write(")");
29132 Ok(())
29133 }
29134
29135 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
29136 self.write_keyword("CONVERT");
29138 self.write("(");
29139 self.generate_expression(&e.this)?;
29140 if let Some(dest) = &e.dest {
29141 self.write_space();
29142 self.write_keyword("USING");
29143 self.write_space();
29144 self.generate_expression(dest)?;
29145 }
29146 self.write(")");
29147 Ok(())
29148 }
29149
29150 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
29151 self.write_keyword("COPY");
29152 if e.is_into {
29153 self.write_space();
29154 self.write_keyword("INTO");
29155 }
29156 self.write_space();
29157
29158 if let Expression::Literal(lit) = &e.this {
29160 if let Literal::String(s) = lit.as_ref() {
29161 if s.starts_with('@') {
29162 self.write(s);
29163 } else {
29164 self.generate_expression(&e.this)?;
29165 }
29166 }
29167 } else {
29168 self.generate_expression(&e.this)?;
29169 }
29170
29171 if e.kind {
29173 if self.config.pretty {
29175 self.write_newline();
29176 } else {
29177 self.write_space();
29178 }
29179 self.write_keyword("FROM");
29180 self.write_space();
29181 } else if !e.files.is_empty() {
29182 if self.config.pretty {
29184 self.write_newline();
29185 } else {
29186 self.write_space();
29187 }
29188 self.write_keyword("TO");
29189 self.write_space();
29190 }
29191
29192 for (i, file) in e.files.iter().enumerate() {
29194 if i > 0 {
29195 self.write_space();
29196 }
29197 if let Expression::Literal(lit) = file {
29199 if let Literal::String(s) = lit.as_ref() {
29200 if s.starts_with('@') {
29201 self.write(s);
29202 } else {
29203 self.generate_expression(file)?;
29204 }
29205 }
29206 } else if let Expression::Identifier(id) = file {
29207 if id.quoted {
29209 self.write("`");
29210 self.write(&id.name);
29211 self.write("`");
29212 } else {
29213 self.generate_expression(file)?;
29214 }
29215 } else {
29216 self.generate_expression(file)?;
29217 }
29218 }
29219
29220 if !e.with_wrapped {
29222 if let Some(ref creds) = e.credentials {
29223 if let Some(ref storage) = creds.storage {
29224 if self.config.pretty {
29225 self.write_newline();
29226 } else {
29227 self.write_space();
29228 }
29229 self.write_keyword("STORAGE_INTEGRATION");
29230 self.write(" = ");
29231 self.write(storage);
29232 }
29233 if creds.credentials.is_empty() {
29234 if self.config.pretty {
29236 self.write_newline();
29237 } else {
29238 self.write_space();
29239 }
29240 self.write_keyword("CREDENTIALS");
29241 self.write(" = ()");
29242 } else {
29243 if self.config.pretty {
29244 self.write_newline();
29245 } else {
29246 self.write_space();
29247 }
29248 self.write_keyword("CREDENTIALS");
29249 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
29252 self.write(" '");
29254 self.write(&creds.credentials[0].1);
29255 self.write("'");
29256 } else {
29257 self.write(" = (");
29259 for (i, (k, v)) in creds.credentials.iter().enumerate() {
29260 if i > 0 {
29261 self.write_space();
29262 }
29263 self.write(k);
29264 self.write("='");
29265 self.write(v);
29266 self.write("'");
29267 }
29268 self.write(")");
29269 }
29270 }
29271 if let Some(ref encryption) = creds.encryption {
29272 self.write_space();
29273 self.write_keyword("ENCRYPTION");
29274 self.write(" = ");
29275 self.write(encryption);
29276 }
29277 }
29278 }
29279
29280 if !e.params.is_empty() {
29282 if e.with_wrapped {
29283 self.write_space();
29285 self.write_keyword("WITH");
29286 self.write(" (");
29287 for (i, param) in e.params.iter().enumerate() {
29288 if i > 0 {
29289 self.write(", ");
29290 }
29291 self.generate_copy_param_with_format(param)?;
29292 }
29293 self.write(")");
29294 } else {
29295 for param in &e.params {
29299 if self.config.pretty {
29300 self.write_newline();
29301 } else {
29302 self.write_space();
29303 }
29304 self.write(¶m.name);
29306 if let Some(ref value) = param.value {
29307 if param.eq {
29309 self.write(" = ");
29310 } else {
29311 self.write(" ");
29312 }
29313 if !param.values.is_empty() {
29314 self.write("(");
29315 for (i, v) in param.values.iter().enumerate() {
29316 if i > 0 {
29317 self.write_space();
29318 }
29319 self.generate_copy_nested_param(v)?;
29320 }
29321 self.write(")");
29322 } else {
29323 self.generate_copy_param_value(value)?;
29325 }
29326 } else if !param.values.is_empty() {
29327 if param.eq {
29329 self.write(" = (");
29330 } else {
29331 self.write(" (");
29332 }
29333 let is_key_value_pairs = param
29338 .values
29339 .first()
29340 .map_or(false, |v| matches!(v, Expression::Eq(_)));
29341 let sep = if is_key_value_pairs && param.eq {
29342 " "
29343 } else {
29344 ", "
29345 };
29346 for (i, v) in param.values.iter().enumerate() {
29347 if i > 0 {
29348 self.write(sep);
29349 }
29350 self.generate_copy_nested_param(v)?;
29351 }
29352 self.write(")");
29353 }
29354 }
29355 }
29356 }
29357
29358 Ok(())
29359 }
29360
29361 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
29364 self.write_keyword(¶m.name);
29365 if !param.values.is_empty() {
29366 self.write(" = (");
29368 for (i, v) in param.values.iter().enumerate() {
29369 if i > 0 {
29370 self.write(", ");
29371 }
29372 self.generate_copy_nested_param(v)?;
29373 }
29374 self.write(")");
29375 } else if let Some(ref value) = param.value {
29376 if param.eq {
29377 self.write(" = ");
29378 } else {
29379 self.write(" ");
29380 }
29381 self.generate_expression(value)?;
29382 }
29383 Ok(())
29384 }
29385
29386 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
29388 match expr {
29389 Expression::Eq(eq) => {
29390 match &eq.left {
29392 Expression::Column(c) => self.write(&c.name.name),
29393 _ => self.generate_expression(&eq.left)?,
29394 }
29395 self.write("=");
29396 match &eq.right {
29398 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
29399 let Literal::String(s) = lit.as_ref() else {
29400 unreachable!()
29401 };
29402 self.write("'");
29403 self.write(s);
29404 self.write("'");
29405 }
29406 Expression::Tuple(t) => {
29407 self.write("(");
29409 if self.config.pretty {
29410 self.write_newline();
29411 self.indent_level += 1;
29412 for (i, item) in t.expressions.iter().enumerate() {
29413 if i > 0 {
29414 self.write(", ");
29415 }
29416 self.write_indent();
29417 self.generate_expression(item)?;
29418 }
29419 self.write_newline();
29420 self.indent_level -= 1;
29421 } else {
29422 for (i, item) in t.expressions.iter().enumerate() {
29423 if i > 0 {
29424 self.write(", ");
29425 }
29426 self.generate_expression(item)?;
29427 }
29428 }
29429 self.write(")");
29430 }
29431 _ => self.generate_expression(&eq.right)?,
29432 }
29433 Ok(())
29434 }
29435 Expression::Column(c) => {
29436 self.write(&c.name.name);
29438 Ok(())
29439 }
29440 _ => self.generate_expression(expr),
29441 }
29442 }
29443
29444 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
29447 match expr {
29448 Expression::Column(c) => {
29449 if c.name.quoted {
29451 self.write("\"");
29452 self.write(&c.name.name);
29453 self.write("\"");
29454 } else {
29455 self.write(&c.name.name);
29456 }
29457 Ok(())
29458 }
29459 Expression::Identifier(id) => {
29460 if id.quoted {
29462 self.write("\"");
29463 self.write(&id.name);
29464 self.write("\"");
29465 } else {
29466 self.write(&id.name);
29467 }
29468 Ok(())
29469 }
29470 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
29471 let Literal::String(s) = lit.as_ref() else {
29472 unreachable!()
29473 };
29474 self.write("'");
29476 self.write(s);
29477 self.write("'");
29478 Ok(())
29479 }
29480 _ => self.generate_expression(expr),
29481 }
29482 }
29483
29484 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
29485 self.write_keyword(&e.name);
29486 if let Some(ref value) = e.value {
29487 if e.eq {
29488 self.write(" = ");
29489 } else {
29490 self.write(" ");
29491 }
29492 self.generate_expression(value)?;
29493 }
29494 if !e.values.is_empty() {
29495 if e.eq {
29496 self.write(" = ");
29497 } else {
29498 self.write(" ");
29499 }
29500 self.write("(");
29501 for (i, v) in e.values.iter().enumerate() {
29502 if i > 0 {
29503 self.write(", ");
29504 }
29505 self.generate_expression(v)?;
29506 }
29507 self.write(")");
29508 }
29509 Ok(())
29510 }
29511
29512 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
29513 self.write_keyword("CORR");
29515 self.write("(");
29516 self.generate_expression(&e.this)?;
29517 self.write(", ");
29518 self.generate_expression(&e.expression)?;
29519 self.write(")");
29520 Ok(())
29521 }
29522
29523 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
29524 self.write_keyword("COSINE_DISTANCE");
29526 self.write("(");
29527 self.generate_expression(&e.this)?;
29528 self.write(", ");
29529 self.generate_expression(&e.expression)?;
29530 self.write(")");
29531 Ok(())
29532 }
29533
29534 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
29535 self.write_keyword("COVAR_POP");
29537 self.write("(");
29538 self.generate_expression(&e.this)?;
29539 self.write(", ");
29540 self.generate_expression(&e.expression)?;
29541 self.write(")");
29542 Ok(())
29543 }
29544
29545 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
29546 self.write_keyword("COVAR_SAMP");
29548 self.write("(");
29549 self.generate_expression(&e.this)?;
29550 self.write(", ");
29551 self.generate_expression(&e.expression)?;
29552 self.write(")");
29553 Ok(())
29554 }
29555
29556 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
29557 self.write_keyword("CREDENTIALS");
29559 self.write(" (");
29560 for (i, (key, value)) in e.credentials.iter().enumerate() {
29561 if i > 0 {
29562 self.write(", ");
29563 }
29564 self.write(key);
29565 self.write("='");
29566 self.write(value);
29567 self.write("'");
29568 }
29569 self.write(")");
29570 Ok(())
29571 }
29572
29573 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
29574 self.write_keyword("CREDENTIALS");
29576 self.write("=(");
29577 for (i, expr) in e.expressions.iter().enumerate() {
29578 if i > 0 {
29579 self.write(", ");
29580 }
29581 self.generate_expression(expr)?;
29582 }
29583 self.write(")");
29584 Ok(())
29585 }
29586
29587 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
29588 use crate::dialects::DialectType;
29589
29590 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
29593 self.generate_expression(&e.this)?;
29594 self.write_space();
29595 self.write_keyword("AS");
29596 self.write_space();
29597 self.generate_identifier(&e.alias)?;
29598 return Ok(());
29599 }
29600 self.write(&e.alias.name);
29601
29602 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
29604
29605 if !e.columns.is_empty() && !skip_cte_columns {
29606 self.write("(");
29607 for (i, col) in e.columns.iter().enumerate() {
29608 if i > 0 {
29609 self.write(", ");
29610 }
29611 self.write(&col.name);
29612 }
29613 self.write(")");
29614 }
29615 if !e.key_expressions.is_empty() {
29617 self.write_space();
29618 self.write_keyword("USING KEY");
29619 self.write(" (");
29620 for (i, key) in e.key_expressions.iter().enumerate() {
29621 if i > 0 {
29622 self.write(", ");
29623 }
29624 self.write(&key.name);
29625 }
29626 self.write(")");
29627 }
29628 self.write_space();
29629 self.write_keyword("AS");
29630 self.write_space();
29631 if let Some(materialized) = e.materialized {
29632 if materialized {
29633 self.write_keyword("MATERIALIZED");
29634 } else {
29635 self.write_keyword("NOT MATERIALIZED");
29636 }
29637 self.write_space();
29638 }
29639 self.write("(");
29640 self.generate_expression(&e.this)?;
29641 self.write(")");
29642 Ok(())
29643 }
29644
29645 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
29646 if e.expressions.is_empty() {
29648 self.write_keyword("WITH CUBE");
29649 } else {
29650 self.write_keyword("CUBE");
29651 self.write("(");
29652 for (i, expr) in e.expressions.iter().enumerate() {
29653 if i > 0 {
29654 self.write(", ");
29655 }
29656 self.generate_expression(expr)?;
29657 }
29658 self.write(")");
29659 }
29660 Ok(())
29661 }
29662
29663 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
29664 self.write_keyword("CURRENT_DATETIME");
29666 if let Some(this) = &e.this {
29667 self.write("(");
29668 self.generate_expression(this)?;
29669 self.write(")");
29670 }
29671 Ok(())
29672 }
29673
29674 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
29675 self.write_keyword("CURRENT_SCHEMA");
29677 Ok(())
29678 }
29679
29680 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
29681 self.write_keyword("CURRENT_SCHEMAS");
29683 self.write("(");
29684 if !matches!(
29686 self.config.dialect,
29687 Some(crate::dialects::DialectType::Snowflake)
29688 ) {
29689 if let Some(this) = &e.this {
29690 self.generate_expression(this)?;
29691 }
29692 }
29693 self.write(")");
29694 Ok(())
29695 }
29696
29697 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
29698 self.write_keyword("CURRENT_USER");
29700 let needs_parens = e.this.is_some()
29702 || matches!(
29703 self.config.dialect,
29704 Some(DialectType::Snowflake)
29705 | Some(DialectType::Spark)
29706 | Some(DialectType::Hive)
29707 | Some(DialectType::DuckDB)
29708 | Some(DialectType::BigQuery)
29709 | Some(DialectType::MySQL)
29710 | Some(DialectType::Databricks)
29711 );
29712 if needs_parens {
29713 self.write("()");
29714 }
29715 Ok(())
29716 }
29717
29718 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
29719 if self.config.dialect == Some(DialectType::Solr) {
29721 self.generate_expression(&e.this)?;
29722 self.write(" ");
29723 self.write_keyword("OR");
29724 self.write(" ");
29725 self.generate_expression(&e.expression)?;
29726 } else if self.config.dialect == Some(DialectType::MySQL) {
29727 self.generate_mysql_concat_from_dpipe(e)?;
29728 } else {
29729 self.generate_expression(&e.this)?;
29731 self.write(" || ");
29732 self.generate_expression(&e.expression)?;
29733 }
29734 Ok(())
29735 }
29736
29737 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
29738 self.write_keyword("DATABLOCKSIZE");
29740 self.write("=");
29741 if let Some(size) = e.size {
29742 self.write(&size.to_string());
29743 if let Some(units) = &e.units {
29744 self.write_space();
29745 self.generate_expression(units)?;
29746 }
29747 } else if e.minimum.is_some() {
29748 self.write_keyword("MINIMUM");
29749 } else if e.maximum.is_some() {
29750 self.write_keyword("MAXIMUM");
29751 } else if e.default.is_some() {
29752 self.write_keyword("DEFAULT");
29753 }
29754 Ok(())
29755 }
29756
29757 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
29758 self.write_keyword("DATA_DELETION");
29760 self.write("=");
29761
29762 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
29763 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
29764
29765 if is_on {
29766 self.write_keyword("ON");
29767 if has_options {
29768 self.write("(");
29769 let mut first = true;
29770 if let Some(filter_column) = &e.filter_column {
29771 self.write_keyword("FILTER_COLUMN");
29772 self.write("=");
29773 self.generate_expression(filter_column)?;
29774 first = false;
29775 }
29776 if let Some(retention_period) = &e.retention_period {
29777 if !first {
29778 self.write(", ");
29779 }
29780 self.write_keyword("RETENTION_PERIOD");
29781 self.write("=");
29782 self.generate_expression(retention_period)?;
29783 }
29784 self.write(")");
29785 }
29786 } else {
29787 self.write_keyword("OFF");
29788 }
29789 Ok(())
29790 }
29791
29792 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
29796 use crate::dialects::DialectType;
29797 use crate::expressions::Literal;
29798
29799 match self.config.dialect {
29800 Some(DialectType::Exasol) => {
29802 self.write_keyword("TO_DATE");
29803 self.write("(");
29804 match &e.this {
29806 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
29807 let Literal::String(s) = lit.as_ref() else {
29808 unreachable!()
29809 };
29810 self.write("'");
29811 self.write(s);
29812 self.write("'");
29813 }
29814 _ => {
29815 self.generate_expression(&e.this)?;
29816 }
29817 }
29818 self.write(")");
29819 }
29820 _ => {
29822 self.write_keyword("DATE");
29823 self.write("(");
29824 self.generate_expression(&e.this)?;
29825 self.write(")");
29826 }
29827 }
29828 Ok(())
29829 }
29830
29831 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
29832 self.write_keyword("DATE_BIN");
29834 self.write("(");
29835 self.generate_expression(&e.this)?;
29836 self.write(", ");
29837 self.generate_expression(&e.expression)?;
29838 if let Some(origin) = &e.origin {
29839 self.write(", ");
29840 self.generate_expression(origin)?;
29841 }
29842 self.write(")");
29843 Ok(())
29844 }
29845
29846 fn generate_date_format_column_constraint(
29847 &mut self,
29848 e: &DateFormatColumnConstraint,
29849 ) -> Result<()> {
29850 self.write_keyword("FORMAT");
29852 self.write_space();
29853 self.generate_expression(&e.this)?;
29854 Ok(())
29855 }
29856
29857 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
29858 self.write_keyword("DATE_FROM_PARTS");
29860 self.write("(");
29861 let mut first = true;
29862 if let Some(year) = &e.year {
29863 self.generate_expression(year)?;
29864 first = false;
29865 }
29866 if let Some(month) = &e.month {
29867 if !first {
29868 self.write(", ");
29869 }
29870 self.generate_expression(month)?;
29871 first = false;
29872 }
29873 if let Some(day) = &e.day {
29874 if !first {
29875 self.write(", ");
29876 }
29877 self.generate_expression(day)?;
29878 }
29879 self.write(")");
29880 Ok(())
29881 }
29882
29883 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
29884 self.write_keyword("DATETIME");
29886 self.write("(");
29887 self.generate_expression(&e.this)?;
29888 if let Some(expr) = &e.expression {
29889 self.write(", ");
29890 self.generate_expression(expr)?;
29891 }
29892 self.write(")");
29893 Ok(())
29894 }
29895
29896 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
29897 self.write_keyword("DATETIME_ADD");
29899 self.write("(");
29900 self.generate_expression(&e.this)?;
29901 self.write(", ");
29902 self.generate_expression(&e.expression)?;
29903 if let Some(unit) = &e.unit {
29904 self.write(", ");
29905 self.write_keyword(unit);
29906 }
29907 self.write(")");
29908 Ok(())
29909 }
29910
29911 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
29912 self.write_keyword("DATETIME_DIFF");
29914 self.write("(");
29915 self.generate_expression(&e.this)?;
29916 self.write(", ");
29917 self.generate_expression(&e.expression)?;
29918 if let Some(unit) = &e.unit {
29919 self.write(", ");
29920 self.write_keyword(unit);
29921 }
29922 self.write(")");
29923 Ok(())
29924 }
29925
29926 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
29927 self.write_keyword("DATETIME_SUB");
29929 self.write("(");
29930 self.generate_expression(&e.this)?;
29931 self.write(", ");
29932 self.generate_expression(&e.expression)?;
29933 if let Some(unit) = &e.unit {
29934 self.write(", ");
29935 self.write_keyword(unit);
29936 }
29937 self.write(")");
29938 Ok(())
29939 }
29940
29941 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
29942 self.write_keyword("DATETIME_TRUNC");
29944 self.write("(");
29945 self.generate_expression(&e.this)?;
29946 self.write(", ");
29947 self.write_keyword(&e.unit);
29948 if let Some(zone) = &e.zone {
29949 self.write(", ");
29950 self.generate_expression(zone)?;
29951 }
29952 self.write(")");
29953 Ok(())
29954 }
29955
29956 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
29957 self.write_keyword("DAYNAME");
29959 self.write("(");
29960 self.generate_expression(&e.this)?;
29961 self.write(")");
29962 Ok(())
29963 }
29964
29965 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
29966 self.write_keyword("DECLARE");
29968 self.write_space();
29969 if e.replace {
29970 self.write_keyword("OR");
29971 self.write_space();
29972 self.write_keyword("REPLACE");
29973 self.write_space();
29974 }
29975 for (i, expr) in e.expressions.iter().enumerate() {
29976 if i > 0 {
29977 self.write(", ");
29978 }
29979 self.generate_expression(expr)?;
29980 }
29981 Ok(())
29982 }
29983
29984 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
29985 use crate::dialects::DialectType;
29986
29987 self.generate_expression(&e.this)?;
29989 for name in &e.additional_names {
29991 self.write(", ");
29992 self.generate_expression(name)?;
29993 }
29994 if let Some(kind) = &e.kind {
29995 self.write_space();
29996 match self.config.dialect {
30000 Some(DialectType::BigQuery) => {
30001 self.write(kind);
30002 }
30003 Some(DialectType::TSQL) => {
30004 let is_complex_table = kind.starts_with("TABLE")
30008 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
30009 if is_complex_table {
30010 self.write(kind);
30011 } else if kind == "INT" {
30012 self.write("INTEGER");
30013 } else if kind.starts_with("TABLE") {
30014 let normalized = kind
30016 .replace(" INT ", " INTEGER ")
30017 .replace(" INT,", " INTEGER,")
30018 .replace(" INT)", " INTEGER)")
30019 .replace("(INT ", "(INTEGER ");
30020 self.write(&normalized);
30021 } else {
30022 self.write(kind);
30023 }
30024 }
30025 _ => {
30026 if e.has_as {
30027 self.write_keyword("AS");
30028 self.write_space();
30029 }
30030 self.write(kind);
30031 }
30032 }
30033 }
30034 if let Some(default) = &e.default {
30035 match self.config.dialect {
30037 Some(DialectType::BigQuery) => {
30038 self.write_space();
30039 self.write_keyword("DEFAULT");
30040 self.write_space();
30041 }
30042 _ => {
30043 self.write(" = ");
30044 }
30045 }
30046 self.generate_expression(default)?;
30047 }
30048 Ok(())
30049 }
30050
30051 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
30052 self.write_keyword("DECODE");
30054 self.write("(");
30055 for (i, expr) in e.expressions.iter().enumerate() {
30056 if i > 0 {
30057 self.write(", ");
30058 }
30059 self.generate_expression(expr)?;
30060 }
30061 self.write(")");
30062 Ok(())
30063 }
30064
30065 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
30066 self.write_keyword("DECOMPRESS");
30068 self.write("(");
30069 self.generate_expression(&e.this)?;
30070 self.write(", '");
30071 self.write(&e.method);
30072 self.write("')");
30073 Ok(())
30074 }
30075
30076 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
30077 self.write_keyword("DECOMPRESS");
30079 self.write("(");
30080 self.generate_expression(&e.this)?;
30081 self.write(", '");
30082 self.write(&e.method);
30083 self.write("')");
30084 Ok(())
30085 }
30086
30087 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
30088 self.write_keyword("DECRYPT");
30090 self.write("(");
30091 self.generate_expression(&e.this)?;
30092 if let Some(passphrase) = &e.passphrase {
30093 self.write(", ");
30094 self.generate_expression(passphrase)?;
30095 }
30096 if let Some(aad) = &e.aad {
30097 self.write(", ");
30098 self.generate_expression(aad)?;
30099 }
30100 if let Some(method) = &e.encryption_method {
30101 self.write(", ");
30102 self.generate_expression(method)?;
30103 }
30104 self.write(")");
30105 Ok(())
30106 }
30107
30108 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
30109 self.write_keyword("DECRYPT_RAW");
30111 self.write("(");
30112 self.generate_expression(&e.this)?;
30113 if let Some(key) = &e.key {
30114 self.write(", ");
30115 self.generate_expression(key)?;
30116 }
30117 if let Some(iv) = &e.iv {
30118 self.write(", ");
30119 self.generate_expression(iv)?;
30120 }
30121 if let Some(aad) = &e.aad {
30122 self.write(", ");
30123 self.generate_expression(aad)?;
30124 }
30125 if let Some(method) = &e.encryption_method {
30126 self.write(", ");
30127 self.generate_expression(method)?;
30128 }
30129 self.write(")");
30130 Ok(())
30131 }
30132
30133 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
30134 self.write_keyword("DEFINER");
30136 self.write(" = ");
30137 self.generate_expression(&e.this)?;
30138 Ok(())
30139 }
30140
30141 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
30142 self.write_keyword("DETACH");
30144 if e.exists {
30145 self.write_keyword(" DATABASE IF EXISTS");
30146 }
30147 self.write_space();
30148 self.generate_expression(&e.this)?;
30149 Ok(())
30150 }
30151
30152 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
30153 let property_name = match e.this.as_ref() {
30154 Expression::Identifier(id) => id.name.as_str(),
30155 Expression::Var(v) => v.this.as_str(),
30156 _ => "DICTIONARY",
30157 };
30158 self.write_keyword(property_name);
30159 self.write("(");
30160 self.write(&e.kind);
30161 if let Some(settings) = &e.settings {
30162 self.write("(");
30163 if let Expression::Tuple(t) = settings.as_ref() {
30164 if self.config.pretty && !t.expressions.is_empty() {
30165 self.write_newline();
30166 self.indent_level += 1;
30167 for (i, pair) in t.expressions.iter().enumerate() {
30168 if i > 0 {
30169 self.write(",");
30170 self.write_newline();
30171 }
30172 self.write_indent();
30173 if let Expression::Tuple(pair_tuple) = pair {
30174 if let Some(k) = pair_tuple.expressions.first() {
30175 self.generate_expression(k)?;
30176 }
30177 if let Some(v) = pair_tuple.expressions.get(1) {
30178 self.write(" ");
30179 self.generate_expression(v)?;
30180 }
30181 } else {
30182 self.generate_expression(pair)?;
30183 }
30184 }
30185 self.indent_level -= 1;
30186 self.write_newline();
30187 self.write_indent();
30188 } else {
30189 for (i, pair) in t.expressions.iter().enumerate() {
30190 if i > 0 {
30191 self.write(" ");
30193 }
30194 if let Expression::Tuple(pair_tuple) = pair {
30195 if let Some(k) = pair_tuple.expressions.first() {
30196 self.generate_expression(k)?;
30197 }
30198 if let Some(v) = pair_tuple.expressions.get(1) {
30199 self.write(" ");
30200 self.generate_expression(v)?;
30201 }
30202 } else {
30203 self.generate_expression(pair)?;
30204 }
30205 }
30206 }
30207 } else {
30208 self.generate_expression(settings)?;
30209 }
30210 self.write(")");
30211 } else {
30212 self.write("()");
30214 }
30215 self.write(")");
30216 Ok(())
30217 }
30218
30219 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
30220 let property_name = match e.this.as_ref() {
30221 Expression::Identifier(id) => id.name.as_str(),
30222 Expression::Var(v) => v.this.as_str(),
30223 _ => "RANGE",
30224 };
30225 self.write_keyword(property_name);
30226 self.write("(");
30227 if let Some(min) = &e.min {
30228 self.write_keyword("MIN");
30229 self.write_space();
30230 self.generate_expression(min)?;
30231 }
30232 if let Some(max) = &e.max {
30233 self.write_space();
30234 self.write_keyword("MAX");
30235 self.write_space();
30236 self.generate_expression(max)?;
30237 }
30238 self.write(")");
30239 Ok(())
30240 }
30241
30242 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
30243 if e.local.is_some() {
30245 self.write_keyword("LOCAL ");
30246 }
30247 self.write_keyword("DIRECTORY");
30248 self.write_space();
30249 self.generate_expression(&e.this)?;
30250 if let Some(row_format) = &e.row_format {
30251 self.write_space();
30252 self.generate_expression(row_format)?;
30253 }
30254 Ok(())
30255 }
30256
30257 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
30258 self.write_keyword("DISTKEY");
30260 self.write("(");
30261 self.generate_expression(&e.this)?;
30262 self.write(")");
30263 Ok(())
30264 }
30265
30266 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
30267 self.write_keyword("DISTSTYLE");
30269 self.write_space();
30270 self.generate_expression(&e.this)?;
30271 Ok(())
30272 }
30273
30274 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
30275 self.write_keyword("DISTRIBUTE BY");
30277 self.write_space();
30278 for (i, expr) in e.expressions.iter().enumerate() {
30279 if i > 0 {
30280 self.write(", ");
30281 }
30282 self.generate_expression(expr)?;
30283 }
30284 Ok(())
30285 }
30286
30287 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
30288 self.write_keyword("DISTRIBUTED BY");
30290 self.write_space();
30291 self.write(&e.kind);
30292 if !e.expressions.is_empty() {
30293 self.write(" (");
30294 for (i, expr) in e.expressions.iter().enumerate() {
30295 if i > 0 {
30296 self.write(", ");
30297 }
30298 self.generate_expression(expr)?;
30299 }
30300 self.write(")");
30301 }
30302 if let Some(buckets) = &e.buckets {
30303 self.write_space();
30304 self.write_keyword("BUCKETS");
30305 self.write_space();
30306 self.generate_expression(buckets)?;
30307 }
30308 if let Some(order) = &e.order {
30309 self.write_space();
30310 self.generate_expression(order)?;
30311 }
30312 Ok(())
30313 }
30314
30315 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
30316 self.write_keyword("DOT_PRODUCT");
30318 self.write("(");
30319 self.generate_expression(&e.this)?;
30320 self.write(", ");
30321 self.generate_expression(&e.expression)?;
30322 self.write(")");
30323 Ok(())
30324 }
30325
30326 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
30327 self.write_keyword("DROP");
30329 if e.exists {
30330 self.write_keyword(" IF EXISTS ");
30331 } else {
30332 self.write_space();
30333 }
30334 for (i, expr) in e.expressions.iter().enumerate() {
30335 if i > 0 {
30336 self.write(", ");
30337 }
30338 self.generate_expression(expr)?;
30339 }
30340 Ok(())
30341 }
30342
30343 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
30344 self.write_keyword("DUPLICATE KEY");
30346 self.write(" (");
30347 for (i, expr) in e.expressions.iter().enumerate() {
30348 if i > 0 {
30349 self.write(", ");
30350 }
30351 self.generate_expression(expr)?;
30352 }
30353 self.write(")");
30354 Ok(())
30355 }
30356
30357 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
30358 self.write_keyword("ELT");
30360 self.write("(");
30361 self.generate_expression(&e.this)?;
30362 for expr in &e.expressions {
30363 self.write(", ");
30364 self.generate_expression(expr)?;
30365 }
30366 self.write(")");
30367 Ok(())
30368 }
30369
30370 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
30371 self.write_keyword("ENCODE");
30373 self.write("(");
30374 self.generate_expression(&e.this)?;
30375 if let Some(charset) = &e.charset {
30376 self.write(", ");
30377 self.generate_expression(charset)?;
30378 }
30379 self.write(")");
30380 Ok(())
30381 }
30382
30383 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
30384 if e.key.is_some() {
30386 self.write_keyword("KEY ");
30387 }
30388 self.write_keyword("ENCODE");
30389 self.write_space();
30390 self.generate_expression(&e.this)?;
30391 if !e.properties.is_empty() {
30392 self.write(" (");
30393 for (i, prop) in e.properties.iter().enumerate() {
30394 if i > 0 {
30395 self.write(", ");
30396 }
30397 self.generate_expression(prop)?;
30398 }
30399 self.write(")");
30400 }
30401 Ok(())
30402 }
30403
30404 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
30405 self.write_keyword("ENCRYPT");
30407 self.write("(");
30408 self.generate_expression(&e.this)?;
30409 if let Some(passphrase) = &e.passphrase {
30410 self.write(", ");
30411 self.generate_expression(passphrase)?;
30412 }
30413 if let Some(aad) = &e.aad {
30414 self.write(", ");
30415 self.generate_expression(aad)?;
30416 }
30417 if let Some(method) = &e.encryption_method {
30418 self.write(", ");
30419 self.generate_expression(method)?;
30420 }
30421 self.write(")");
30422 Ok(())
30423 }
30424
30425 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
30426 self.write_keyword("ENCRYPT_RAW");
30428 self.write("(");
30429 self.generate_expression(&e.this)?;
30430 if let Some(key) = &e.key {
30431 self.write(", ");
30432 self.generate_expression(key)?;
30433 }
30434 if let Some(iv) = &e.iv {
30435 self.write(", ");
30436 self.generate_expression(iv)?;
30437 }
30438 if let Some(aad) = &e.aad {
30439 self.write(", ");
30440 self.generate_expression(aad)?;
30441 }
30442 if let Some(method) = &e.encryption_method {
30443 self.write(", ");
30444 self.generate_expression(method)?;
30445 }
30446 self.write(")");
30447 Ok(())
30448 }
30449
30450 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
30451 self.write_keyword("ENGINE");
30453 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
30454 self.write("=");
30455 } else {
30456 self.write(" = ");
30457 }
30458 self.generate_expression(&e.this)?;
30459 Ok(())
30460 }
30461
30462 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
30463 self.write_keyword("ENVIRONMENT");
30465 self.write(" (");
30466 for (i, expr) in e.expressions.iter().enumerate() {
30467 if i > 0 {
30468 self.write(", ");
30469 }
30470 self.generate_expression(expr)?;
30471 }
30472 self.write(")");
30473 Ok(())
30474 }
30475
30476 fn generate_ephemeral_column_constraint(
30477 &mut self,
30478 e: &EphemeralColumnConstraint,
30479 ) -> Result<()> {
30480 self.write_keyword("EPHEMERAL");
30482 if let Some(this) = &e.this {
30483 self.write_space();
30484 self.generate_expression(this)?;
30485 }
30486 Ok(())
30487 }
30488
30489 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
30490 self.write_keyword("EQUAL_NULL");
30492 self.write("(");
30493 self.generate_expression(&e.this)?;
30494 self.write(", ");
30495 self.generate_expression(&e.expression)?;
30496 self.write(")");
30497 Ok(())
30498 }
30499
30500 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
30501 use crate::dialects::DialectType;
30502
30503 match self.config.dialect {
30505 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
30506 self.generate_expression(&e.this)?;
30507 self.write(" <-> ");
30508 self.generate_expression(&e.expression)?;
30509 }
30510 _ => {
30511 self.write_keyword("EUCLIDEAN_DISTANCE");
30513 self.write("(");
30514 self.generate_expression(&e.this)?;
30515 self.write(", ");
30516 self.generate_expression(&e.expression)?;
30517 self.write(")");
30518 }
30519 }
30520 Ok(())
30521 }
30522
30523 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
30524 self.write_keyword("EXECUTE AS");
30526 self.write_space();
30527 self.generate_expression(&e.this)?;
30528 Ok(())
30529 }
30530
30531 fn generate_export(&mut self, e: &Export) -> Result<()> {
30532 self.write_keyword("EXPORT DATA");
30534 if let Some(connection) = &e.connection {
30535 self.write_space();
30536 self.write_keyword("WITH CONNECTION");
30537 self.write_space();
30538 self.generate_expression(connection)?;
30539 }
30540 if !e.options.is_empty() {
30541 self.write_space();
30542 self.generate_options_clause(&e.options)?;
30543 }
30544 self.write_space();
30545 self.write_keyword("AS");
30546 self.write_space();
30547 self.generate_expression(&e.this)?;
30548 Ok(())
30549 }
30550
30551 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
30552 self.write_keyword("EXTERNAL");
30554 if let Some(this) = &e.this {
30555 self.write_space();
30556 self.generate_expression(this)?;
30557 }
30558 Ok(())
30559 }
30560
30561 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
30562 if e.no.is_some() {
30564 self.write_keyword("NO ");
30565 }
30566 self.write_keyword("FALLBACK");
30567 if e.protection.is_some() {
30568 self.write_keyword(" PROTECTION");
30569 }
30570 Ok(())
30571 }
30572
30573 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
30574 self.write_keyword("FARM_FINGERPRINT");
30576 self.write("(");
30577 for (i, expr) in e.expressions.iter().enumerate() {
30578 if i > 0 {
30579 self.write(", ");
30580 }
30581 self.generate_expression(expr)?;
30582 }
30583 self.write(")");
30584 Ok(())
30585 }
30586
30587 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
30588 self.write_keyword("FEATURES_AT_TIME");
30590 self.write("(");
30591 self.generate_expression(&e.this)?;
30592 if let Some(time) = &e.time {
30593 self.write(", ");
30594 self.generate_expression(time)?;
30595 }
30596 if let Some(num_rows) = &e.num_rows {
30597 self.write(", ");
30598 self.generate_expression(num_rows)?;
30599 }
30600 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
30601 self.write(", ");
30602 self.generate_expression(ignore_nulls)?;
30603 }
30604 self.write(")");
30605 Ok(())
30606 }
30607
30608 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
30609 let use_limit = !e.percent
30611 && !e.with_ties
30612 && e.count.is_some()
30613 && matches!(
30614 self.config.dialect,
30615 Some(DialectType::Spark)
30616 | Some(DialectType::Hive)
30617 | Some(DialectType::DuckDB)
30618 | Some(DialectType::SQLite)
30619 | Some(DialectType::MySQL)
30620 | Some(DialectType::BigQuery)
30621 | Some(DialectType::Databricks)
30622 | Some(DialectType::StarRocks)
30623 | Some(DialectType::Doris)
30624 | Some(DialectType::Athena)
30625 | Some(DialectType::ClickHouse)
30626 );
30627
30628 if use_limit {
30629 self.write_keyword("LIMIT");
30630 self.write_space();
30631 self.generate_expression(e.count.as_ref().unwrap())?;
30632 return Ok(());
30633 }
30634
30635 self.write_keyword("FETCH");
30637 if !e.direction.is_empty() {
30638 self.write_space();
30639 self.write_keyword(&e.direction);
30640 }
30641 if let Some(count) = &e.count {
30642 self.write_space();
30643 self.generate_expression(count)?;
30644 }
30645 if e.percent {
30647 self.write_keyword(" PERCENT");
30648 }
30649 if e.rows {
30650 self.write_keyword(" ROWS");
30651 }
30652 if e.with_ties {
30653 self.write_keyword(" WITH TIES");
30654 } else if e.rows {
30655 self.write_keyword(" ONLY");
30656 } else {
30657 self.write_keyword(" ROWS ONLY");
30658 }
30659 Ok(())
30660 }
30661
30662 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
30663 if e.hive_format.is_some() {
30667 self.write_keyword("STORED AS");
30669 self.write_space();
30670 if let Some(this) = &e.this {
30671 if let Expression::Identifier(id) = this.as_ref() {
30673 self.write_keyword(&id.name.to_ascii_uppercase());
30674 } else {
30675 self.generate_expression(this)?;
30676 }
30677 }
30678 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
30679 self.write_keyword("STORED AS");
30681 self.write_space();
30682 if let Some(this) = &e.this {
30683 if let Expression::Identifier(id) = this.as_ref() {
30684 self.write_keyword(&id.name.to_ascii_uppercase());
30685 } else {
30686 self.generate_expression(this)?;
30687 }
30688 }
30689 } else if matches!(
30690 self.config.dialect,
30691 Some(DialectType::Spark) | Some(DialectType::Databricks)
30692 ) {
30693 self.write_keyword("USING");
30695 self.write_space();
30696 if let Some(this) = &e.this {
30697 self.generate_expression(this)?;
30698 }
30699 } else {
30700 self.write_keyword("FILE_FORMAT");
30702 self.write(" = ");
30703 if let Some(this) = &e.this {
30704 self.generate_expression(this)?;
30705 } else if !e.expressions.is_empty() {
30706 self.write("(");
30707 for (i, expr) in e.expressions.iter().enumerate() {
30708 if i > 0 {
30709 self.write(", ");
30710 }
30711 self.generate_expression(expr)?;
30712 }
30713 self.write(")");
30714 }
30715 }
30716 Ok(())
30717 }
30718
30719 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
30720 self.generate_expression(&e.this)?;
30722 self.write_space();
30723 self.write_keyword("FILTER");
30724 self.write("(");
30725 self.write_keyword("WHERE");
30726 self.write_space();
30727 self.generate_expression(&e.expression)?;
30728 self.write(")");
30729 Ok(())
30730 }
30731
30732 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
30733 self.write_keyword("FLOAT64");
30735 self.write("(");
30736 self.generate_expression(&e.this)?;
30737 if let Some(expr) = &e.expression {
30738 self.write(", ");
30739 self.generate_expression(expr)?;
30740 }
30741 self.write(")");
30742 Ok(())
30743 }
30744
30745 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
30746 self.write_keyword("FOR");
30748 self.write_space();
30749 self.generate_expression(&e.this)?;
30750 self.write_space();
30751 self.write_keyword("DO");
30752 self.write_space();
30753 self.generate_expression(&e.expression)?;
30754 Ok(())
30755 }
30756
30757 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
30758 self.write_keyword("FOREIGN KEY");
30760 if !e.expressions.is_empty() {
30761 self.write(" (");
30762 for (i, expr) in e.expressions.iter().enumerate() {
30763 if i > 0 {
30764 self.write(", ");
30765 }
30766 self.generate_expression(expr)?;
30767 }
30768 self.write(")");
30769 }
30770 if let Some(reference) = &e.reference {
30771 self.write_space();
30772 self.generate_expression(reference)?;
30773 }
30774 if let Some(delete) = &e.delete {
30775 self.write_space();
30776 self.write_keyword("ON DELETE");
30777 self.write_space();
30778 self.generate_expression(delete)?;
30779 }
30780 if let Some(update) = &e.update {
30781 self.write_space();
30782 self.write_keyword("ON UPDATE");
30783 self.write_space();
30784 self.generate_expression(update)?;
30785 }
30786 if !e.options.is_empty() {
30787 self.write_space();
30788 for (i, opt) in e.options.iter().enumerate() {
30789 if i > 0 {
30790 self.write_space();
30791 }
30792 self.generate_expression(opt)?;
30793 }
30794 }
30795 Ok(())
30796 }
30797
30798 fn generate_format(&mut self, e: &Format) -> Result<()> {
30799 self.write_keyword("FORMAT");
30801 self.write("(");
30802 self.generate_expression(&e.this)?;
30803 for expr in &e.expressions {
30804 self.write(", ");
30805 self.generate_expression(expr)?;
30806 }
30807 self.write(")");
30808 Ok(())
30809 }
30810
30811 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
30812 self.generate_expression(&e.this)?;
30814 self.write(" (");
30815 self.write_keyword("FORMAT");
30816 self.write(" '");
30817 self.write(&e.format);
30818 self.write("')");
30819 Ok(())
30820 }
30821
30822 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
30823 self.write_keyword("FREESPACE");
30825 self.write("=");
30826 self.generate_expression(&e.this)?;
30827 if e.percent.is_some() {
30828 self.write_keyword(" PERCENT");
30829 }
30830 Ok(())
30831 }
30832
30833 fn generate_from(&mut self, e: &From) -> Result<()> {
30834 self.write_keyword("FROM");
30836 self.write_space();
30837
30838 use crate::dialects::DialectType;
30842 let has_tablesample = e
30843 .expressions
30844 .iter()
30845 .any(|expr| matches!(expr, Expression::TableSample(_)));
30846 let is_cross_join_dialect = matches!(
30847 self.config.dialect,
30848 Some(DialectType::BigQuery)
30849 | Some(DialectType::Hive)
30850 | Some(DialectType::Spark)
30851 | Some(DialectType::Databricks)
30852 | Some(DialectType::SQLite)
30853 | Some(DialectType::ClickHouse)
30854 );
30855 let source_is_same_as_target2 = self.config.source_dialect.is_some()
30856 && self.config.source_dialect == self.config.dialect;
30857 let source_is_cross_join_dialect2 = matches!(
30858 self.config.source_dialect,
30859 Some(DialectType::BigQuery)
30860 | Some(DialectType::Hive)
30861 | Some(DialectType::Spark)
30862 | Some(DialectType::Databricks)
30863 | Some(DialectType::SQLite)
30864 | Some(DialectType::ClickHouse)
30865 );
30866 let use_cross_join = !has_tablesample
30867 && is_cross_join_dialect
30868 && (source_is_same_as_target2
30869 || source_is_cross_join_dialect2
30870 || self.config.source_dialect.is_none());
30871
30872 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
30874
30875 for (i, expr) in e.expressions.iter().enumerate() {
30876 if i > 0 {
30877 if use_cross_join {
30878 self.write(" CROSS JOIN ");
30879 } else {
30880 self.write(", ");
30881 }
30882 }
30883 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
30884 self.write("(");
30885 self.generate_expression(expr)?;
30886 self.write(")");
30887 } else {
30888 self.generate_expression(expr)?;
30889 }
30890 let leading = Self::extract_table_leading_comments(expr);
30893 for comment in &leading {
30894 self.write_space();
30895 self.write_formatted_comment(comment);
30896 }
30897 }
30898 Ok(())
30899 }
30900
30901 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
30903 match expr {
30904 Expression::Table(t) => t.leading_comments.clone(),
30905 Expression::Pivot(p) => {
30906 if let Expression::Table(t) = &p.this {
30907 t.leading_comments.clone()
30908 } else {
30909 Vec::new()
30910 }
30911 }
30912 _ => Vec::new(),
30913 }
30914 }
30915
30916 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
30917 self.write_keyword("FROM_BASE");
30919 self.write("(");
30920 self.generate_expression(&e.this)?;
30921 self.write(", ");
30922 self.generate_expression(&e.expression)?;
30923 self.write(")");
30924 Ok(())
30925 }
30926
30927 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
30928 self.generate_expression(&e.this)?;
30930 if let Some(zone) = &e.zone {
30931 self.write_space();
30932 self.write_keyword("AT TIME ZONE");
30933 self.write_space();
30934 self.generate_expression(zone)?;
30935 self.write_space();
30936 self.write_keyword("AT TIME ZONE");
30937 self.write(" 'UTC'");
30938 }
30939 Ok(())
30940 }
30941
30942 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
30943 self.write_keyword("GAP_FILL");
30945 self.write("(");
30946 self.generate_expression(&e.this)?;
30947 if let Some(ts_column) = &e.ts_column {
30948 self.write(", ");
30949 self.generate_expression(ts_column)?;
30950 }
30951 if let Some(bucket_width) = &e.bucket_width {
30952 self.write(", ");
30953 self.generate_expression(bucket_width)?;
30954 }
30955 if let Some(partitioning_columns) = &e.partitioning_columns {
30956 self.write(", ");
30957 self.generate_expression(partitioning_columns)?;
30958 }
30959 if let Some(value_columns) = &e.value_columns {
30960 self.write(", ");
30961 self.generate_expression(value_columns)?;
30962 }
30963 self.write(")");
30964 Ok(())
30965 }
30966
30967 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
30968 self.write_keyword("GENERATE_DATE_ARRAY");
30970 self.write("(");
30971 let mut first = true;
30972 if let Some(start) = &e.start {
30973 self.generate_expression(start)?;
30974 first = false;
30975 }
30976 if let Some(end) = &e.end {
30977 if !first {
30978 self.write(", ");
30979 }
30980 self.generate_expression(end)?;
30981 first = false;
30982 }
30983 if let Some(step) = &e.step {
30984 if !first {
30985 self.write(", ");
30986 }
30987 self.generate_expression(step)?;
30988 }
30989 self.write(")");
30990 Ok(())
30991 }
30992
30993 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
30994 self.write_keyword("ML.GENERATE_EMBEDDING");
30996 self.write("(");
30997 self.generate_expression(&e.this)?;
30998 self.write(", ");
30999 self.generate_expression(&e.expression)?;
31000 if let Some(params) = &e.params_struct {
31001 self.write(", ");
31002 self.generate_expression(params)?;
31003 }
31004 self.write(")");
31005 Ok(())
31006 }
31007
31008 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
31009 let fn_name = match self.config.dialect {
31011 Some(DialectType::Presto)
31012 | Some(DialectType::Trino)
31013 | Some(DialectType::Athena)
31014 | Some(DialectType::Spark)
31015 | Some(DialectType::Databricks)
31016 | Some(DialectType::Hive) => "SEQUENCE",
31017 _ => "GENERATE_SERIES",
31018 };
31019 self.write_keyword(fn_name);
31020 self.write("(");
31021 let mut first = true;
31022 if let Some(start) = &e.start {
31023 self.generate_expression(start)?;
31024 first = false;
31025 }
31026 if let Some(end) = &e.end {
31027 if !first {
31028 self.write(", ");
31029 }
31030 self.generate_expression(end)?;
31031 first = false;
31032 }
31033 if let Some(step) = &e.step {
31034 if !first {
31035 self.write(", ");
31036 }
31037 if matches!(
31040 self.config.dialect,
31041 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
31042 ) {
31043 if let Some(converted) = self.convert_week_interval_to_day(step) {
31044 self.generate_expression(&converted)?;
31045 } else {
31046 self.generate_expression(step)?;
31047 }
31048 } else {
31049 self.generate_expression(step)?;
31050 }
31051 }
31052 self.write(")");
31053 Ok(())
31054 }
31055
31056 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
31059 use crate::expressions::*;
31060 if let Expression::Interval(ref iv) = expr {
31061 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
31063 unit: IntervalUnit::Week,
31064 ..
31065 }) = &iv.unit
31066 {
31067 let count = match &iv.this {
31069 Some(Expression::Literal(lit)) => match lit.as_ref() {
31070 Literal::String(s) | Literal::Number(s) => s.clone(),
31071 _ => return None,
31072 },
31073 _ => return None,
31074 };
31075 (true, count)
31076 } else if iv.unit.is_none() {
31077 if let Some(Expression::Literal(lit)) = &iv.this {
31079 if let Literal::String(s) = lit.as_ref() {
31080 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
31081 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
31082 (true, parts[0].to_string())
31083 } else {
31084 (false, String::new())
31085 }
31086 } else {
31087 (false, String::new())
31088 }
31089 } else {
31090 (false, String::new())
31091 }
31092 } else {
31093 (false, String::new())
31094 };
31095
31096 if is_week {
31097 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
31099 let day_interval = Expression::Interval(Box::new(Interval {
31100 this: Some(Expression::Literal(Box::new(Literal::String(
31101 "7".to_string(),
31102 )))),
31103 unit: Some(IntervalUnitSpec::Simple {
31104 unit: IntervalUnit::Day,
31105 use_plural: false,
31106 }),
31107 }));
31108 let mul = Expression::Mul(Box::new(BinaryOp {
31109 left: count_expr,
31110 right: day_interval,
31111 left_comments: vec![],
31112 operator_comments: vec![],
31113 trailing_comments: vec![],
31114 inferred_type: None,
31115 }));
31116 return Some(Expression::Paren(Box::new(Paren {
31117 this: mul,
31118 trailing_comments: vec![],
31119 })));
31120 }
31121 }
31122 None
31123 }
31124
31125 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
31126 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
31128 self.write("(");
31129 let mut first = true;
31130 if let Some(start) = &e.start {
31131 self.generate_expression(start)?;
31132 first = false;
31133 }
31134 if let Some(end) = &e.end {
31135 if !first {
31136 self.write(", ");
31137 }
31138 self.generate_expression(end)?;
31139 first = false;
31140 }
31141 if let Some(step) = &e.step {
31142 if !first {
31143 self.write(", ");
31144 }
31145 self.generate_expression(step)?;
31146 }
31147 self.write(")");
31148 Ok(())
31149 }
31150
31151 fn generate_generated_as_identity_column_constraint(
31152 &mut self,
31153 e: &GeneratedAsIdentityColumnConstraint,
31154 ) -> Result<()> {
31155 use crate::dialects::DialectType;
31156
31157 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
31159 self.write_keyword("AUTOINCREMENT");
31160 if let Some(start) = &e.start {
31161 self.write_keyword(" START ");
31162 self.generate_expression(start)?;
31163 }
31164 if let Some(increment) = &e.increment {
31165 self.write_keyword(" INCREMENT ");
31166 self.generate_expression(increment)?;
31167 }
31168 return Ok(());
31169 }
31170
31171 self.write_keyword("GENERATED");
31173 if let Some(this) = &e.this {
31174 if let Expression::Boolean(b) = this.as_ref() {
31176 if b.value {
31177 self.write_keyword(" ALWAYS");
31178 } else {
31179 self.write_keyword(" BY DEFAULT");
31180 if e.on_null.is_some() {
31181 self.write_keyword(" ON NULL");
31182 }
31183 }
31184 } else {
31185 self.write_keyword(" ALWAYS");
31186 }
31187 }
31188 self.write_keyword(" AS IDENTITY");
31189 let has_options = e.start.is_some()
31191 || e.increment.is_some()
31192 || e.minvalue.is_some()
31193 || e.maxvalue.is_some();
31194 if has_options {
31195 self.write(" (");
31196 let mut first = true;
31197 if let Some(start) = &e.start {
31198 self.write_keyword("START WITH ");
31199 self.generate_expression(start)?;
31200 first = false;
31201 }
31202 if let Some(increment) = &e.increment {
31203 if !first {
31204 self.write(" ");
31205 }
31206 self.write_keyword("INCREMENT BY ");
31207 self.generate_expression(increment)?;
31208 first = false;
31209 }
31210 if let Some(minvalue) = &e.minvalue {
31211 if !first {
31212 self.write(" ");
31213 }
31214 self.write_keyword("MINVALUE ");
31215 self.generate_expression(minvalue)?;
31216 first = false;
31217 }
31218 if let Some(maxvalue) = &e.maxvalue {
31219 if !first {
31220 self.write(" ");
31221 }
31222 self.write_keyword("MAXVALUE ");
31223 self.generate_expression(maxvalue)?;
31224 }
31225 self.write(")");
31226 }
31227 Ok(())
31228 }
31229
31230 fn generate_generated_as_row_column_constraint(
31231 &mut self,
31232 e: &GeneratedAsRowColumnConstraint,
31233 ) -> Result<()> {
31234 self.write_keyword("GENERATED ALWAYS AS ROW ");
31236 if e.start.is_some() {
31237 self.write_keyword("START");
31238 } else {
31239 self.write_keyword("END");
31240 }
31241 if e.hidden.is_some() {
31242 self.write_keyword(" HIDDEN");
31243 }
31244 Ok(())
31245 }
31246
31247 fn generate_get(&mut self, e: &Get) -> Result<()> {
31248 self.write_keyword("GET");
31250 self.write_space();
31251 self.generate_expression(&e.this)?;
31252 if let Some(target) = &e.target {
31253 self.write_space();
31254 self.generate_expression(target)?;
31255 }
31256 for prop in &e.properties {
31257 self.write_space();
31258 self.generate_expression(prop)?;
31259 }
31260 Ok(())
31261 }
31262
31263 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
31264 self.generate_expression(&e.this)?;
31266 self.write("[");
31267 self.generate_expression(&e.expression)?;
31268 self.write("]");
31269 Ok(())
31270 }
31271
31272 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
31273 self.write_keyword("GETBIT");
31275 self.write("(");
31276 self.generate_expression(&e.this)?;
31277 self.write(", ");
31278 self.generate_expression(&e.expression)?;
31279 self.write(")");
31280 Ok(())
31281 }
31282
31283 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
31284 if e.is_role {
31286 self.write_keyword("ROLE");
31287 self.write_space();
31288 } else if e.is_group {
31289 self.write_keyword("GROUP");
31290 self.write_space();
31291 } else if e.is_share {
31292 self.write_keyword("SHARE");
31293 self.write_space();
31294 }
31295 self.write(&e.name.name);
31296 Ok(())
31297 }
31298
31299 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
31300 self.generate_expression(&e.this)?;
31302 if !e.expressions.is_empty() {
31303 self.write("(");
31304 for (i, expr) in e.expressions.iter().enumerate() {
31305 if i > 0 {
31306 self.write(", ");
31307 }
31308 self.generate_expression(expr)?;
31309 }
31310 self.write(")");
31311 }
31312 Ok(())
31313 }
31314
31315 fn generate_group(&mut self, e: &Group) -> Result<()> {
31316 self.write_keyword("GROUP BY");
31318 match e.all {
31320 Some(true) => {
31321 self.write_space();
31322 self.write_keyword("ALL");
31323 }
31324 Some(false) => {
31325 self.write_space();
31326 self.write_keyword("DISTINCT");
31327 }
31328 None => {}
31329 }
31330 if !e.expressions.is_empty() {
31331 self.write_space();
31332 for (i, expr) in e.expressions.iter().enumerate() {
31333 if i > 0 {
31334 self.write(", ");
31335 }
31336 self.generate_expression(expr)?;
31337 }
31338 }
31339 if let Some(cube) = &e.cube {
31341 if !e.expressions.is_empty() {
31342 self.write(", ");
31343 } else {
31344 self.write_space();
31345 }
31346 self.generate_expression(cube)?;
31347 }
31348 if let Some(rollup) = &e.rollup {
31349 if !e.expressions.is_empty() || e.cube.is_some() {
31350 self.write(", ");
31351 } else {
31352 self.write_space();
31353 }
31354 self.generate_expression(rollup)?;
31355 }
31356 if let Some(grouping_sets) = &e.grouping_sets {
31357 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
31358 self.write(", ");
31359 } else {
31360 self.write_space();
31361 }
31362 self.generate_expression(grouping_sets)?;
31363 }
31364 if let Some(totals) = &e.totals {
31365 self.write_space();
31366 self.write_keyword("WITH TOTALS");
31367 self.generate_expression(totals)?;
31368 }
31369 Ok(())
31370 }
31371
31372 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
31373 self.write_keyword("GROUP BY");
31375 match e.all {
31377 Some(true) => {
31378 self.write_space();
31379 self.write_keyword("ALL");
31380 }
31381 Some(false) => {
31382 self.write_space();
31383 self.write_keyword("DISTINCT");
31384 }
31385 None => {}
31386 }
31387
31388 let mut trailing_cube = false;
31391 let mut trailing_rollup = false;
31392 let mut regular_expressions: Vec<&Expression> = Vec::new();
31393
31394 for expr in &e.expressions {
31395 match expr {
31396 Expression::Cube(c) if c.expressions.is_empty() => {
31397 trailing_cube = true;
31398 }
31399 Expression::Rollup(r) if r.expressions.is_empty() => {
31400 trailing_rollup = true;
31401 }
31402 _ => {
31403 regular_expressions.push(expr);
31404 }
31405 }
31406 }
31407
31408 if self.config.pretty {
31410 self.write_newline();
31411 self.indent_level += 1;
31412 for (i, expr) in regular_expressions.iter().enumerate() {
31413 if i > 0 {
31414 self.write(",");
31415 self.write_newline();
31416 }
31417 self.write_indent();
31418 self.generate_expression(expr)?;
31419 }
31420 self.indent_level -= 1;
31421 } else {
31422 self.write_space();
31423 for (i, expr) in regular_expressions.iter().enumerate() {
31424 if i > 0 {
31425 self.write(", ");
31426 }
31427 self.generate_expression(expr)?;
31428 }
31429 }
31430
31431 if trailing_cube {
31433 self.write_space();
31434 self.write_keyword("WITH CUBE");
31435 } else if trailing_rollup {
31436 self.write_space();
31437 self.write_keyword("WITH ROLLUP");
31438 }
31439
31440 if e.totals {
31442 self.write_space();
31443 self.write_keyword("WITH TOTALS");
31444 }
31445
31446 Ok(())
31447 }
31448
31449 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
31450 let function_name = if e.expressions.len() > 1
31451 && matches!(
31452 self.config.dialect,
31453 Some(DialectType::TSQL | DialectType::Fabric)
31454 ) {
31455 "GROUPING_ID"
31456 } else {
31457 "GROUPING"
31458 };
31459 self.write_keyword(function_name);
31460 self.write("(");
31461 for (i, expr) in e.expressions.iter().enumerate() {
31462 if i > 0 {
31463 self.write(", ");
31464 }
31465 self.generate_expression(expr)?;
31466 }
31467 self.write(")");
31468 Ok(())
31469 }
31470
31471 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
31472 self.write_keyword("GROUPING_ID");
31474 self.write("(");
31475 for (i, expr) in e.expressions.iter().enumerate() {
31476 if i > 0 {
31477 self.write(", ");
31478 }
31479 self.generate_expression(expr)?;
31480 }
31481 self.write(")");
31482 Ok(())
31483 }
31484
31485 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
31486 self.write_keyword("GROUPING SETS");
31488 self.write(" (");
31489 for (i, expr) in e.expressions.iter().enumerate() {
31490 if i > 0 {
31491 self.write(", ");
31492 }
31493 self.generate_expression(expr)?;
31494 }
31495 self.write(")");
31496 Ok(())
31497 }
31498
31499 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
31500 self.write_keyword("HASH_AGG");
31502 self.write("(");
31503 self.generate_expression(&e.this)?;
31504 for expr in &e.expressions {
31505 self.write(", ");
31506 self.generate_expression(expr)?;
31507 }
31508 self.write(")");
31509 Ok(())
31510 }
31511
31512 fn generate_having(&mut self, e: &Having) -> Result<()> {
31513 self.write_keyword("HAVING");
31515 self.write_space();
31516 self.generate_expression(&e.this)?;
31517 Ok(())
31518 }
31519
31520 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
31521 self.generate_expression(&e.this)?;
31523 self.write_space();
31524 self.write_keyword("HAVING");
31525 self.write_space();
31526 if e.max.is_some() {
31527 self.write_keyword("MAX");
31528 } else {
31529 self.write_keyword("MIN");
31530 }
31531 self.write_space();
31532 self.generate_expression(&e.expression)?;
31533 Ok(())
31534 }
31535
31536 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
31537 use crate::dialects::DialectType;
31538 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
31540 if let Expression::Literal(ref lit) = *e.this {
31542 if let Literal::String(ref s) = lit.as_ref() {
31543 return self.generate_string_literal(s);
31544 }
31545 }
31546 }
31547 if matches!(
31549 self.config.dialect,
31550 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31551 ) {
31552 self.write("$");
31553 if let Some(tag) = &e.tag {
31554 self.generate_expression(tag)?;
31555 }
31556 self.write("$");
31557 self.generate_expression(&e.this)?;
31558 self.write("$");
31559 if let Some(tag) = &e.tag {
31560 self.generate_expression(tag)?;
31561 }
31562 self.write("$");
31563 return Ok(());
31564 }
31565 self.write("$");
31567 if let Some(tag) = &e.tag {
31568 self.generate_expression(tag)?;
31569 }
31570 self.write("$");
31571 self.generate_expression(&e.this)?;
31572 self.write("$");
31573 if let Some(tag) = &e.tag {
31574 self.generate_expression(tag)?;
31575 }
31576 self.write("$");
31577 Ok(())
31578 }
31579
31580 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
31581 self.write_keyword("HEX_ENCODE");
31583 self.write("(");
31584 self.generate_expression(&e.this)?;
31585 self.write(")");
31586 Ok(())
31587 }
31588
31589 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
31590 match e.this.as_ref() {
31593 Expression::Identifier(id) => self.write(&id.name),
31594 other => self.generate_expression(other)?,
31595 }
31596 self.write(" (");
31597 self.write(&e.kind);
31598 self.write(" => ");
31599 self.generate_expression(&e.expression)?;
31600 self.write(")");
31601 Ok(())
31602 }
31603
31604 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
31605 self.write_keyword("HLL");
31607 self.write("(");
31608 self.generate_expression(&e.this)?;
31609 for expr in &e.expressions {
31610 self.write(", ");
31611 self.generate_expression(expr)?;
31612 }
31613 self.write(")");
31614 Ok(())
31615 }
31616
31617 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
31618 if e.input_.is_some() && e.output.is_some() {
31620 self.write_keyword("IN OUT");
31621 } else if e.input_.is_some() {
31622 self.write_keyword("IN");
31623 } else if e.output.is_some() {
31624 self.write_keyword("OUT");
31625 }
31626 Ok(())
31627 }
31628
31629 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
31630 self.write_keyword("INCLUDE");
31632 self.write_space();
31633 self.generate_expression(&e.this)?;
31634 if let Some(column_def) = &e.column_def {
31635 self.write_space();
31636 self.generate_expression(column_def)?;
31637 }
31638 if let Some(alias) = &e.alias {
31639 self.write_space();
31640 self.write_keyword("AS");
31641 self.write_space();
31642 self.write(alias);
31643 }
31644 Ok(())
31645 }
31646
31647 fn generate_index(&mut self, e: &Index) -> Result<()> {
31648 if e.unique {
31650 self.write_keyword("UNIQUE");
31651 self.write_space();
31652 }
31653 if e.primary.is_some() {
31654 self.write_keyword("PRIMARY");
31655 self.write_space();
31656 }
31657 if e.amp.is_some() {
31658 self.write_keyword("AMP");
31659 self.write_space();
31660 }
31661 if e.table.is_none() {
31662 self.write_keyword("INDEX");
31663 self.write_space();
31664 }
31665 if let Some(name) = &e.this {
31666 self.generate_expression(name)?;
31667 self.write_space();
31668 }
31669 if let Some(table) = &e.table {
31670 self.write_keyword("ON");
31671 self.write_space();
31672 self.generate_expression(table)?;
31673 }
31674 if !e.params.is_empty() {
31675 self.write("(");
31676 for (i, param) in e.params.iter().enumerate() {
31677 if i > 0 {
31678 self.write(", ");
31679 }
31680 self.generate_expression(param)?;
31681 }
31682 self.write(")");
31683 }
31684 Ok(())
31685 }
31686
31687 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
31688 if let Some(kind) = &e.kind {
31690 self.write(kind);
31691 self.write_space();
31692 }
31693 self.write_keyword("INDEX");
31694 if let Some(this) = &e.this {
31695 self.write_space();
31696 self.generate_expression(this)?;
31697 }
31698 if let Some(index_type) = &e.index_type {
31699 self.write_space();
31700 self.write_keyword("USING");
31701 self.write_space();
31702 self.generate_expression(index_type)?;
31703 }
31704 if !e.expressions.is_empty() {
31705 self.write(" (");
31706 for (i, expr) in e.expressions.iter().enumerate() {
31707 if i > 0 {
31708 self.write(", ");
31709 }
31710 self.generate_expression(expr)?;
31711 }
31712 self.write(")");
31713 }
31714 for opt in &e.options {
31715 self.write_space();
31716 self.generate_expression(opt)?;
31717 }
31718 Ok(())
31719 }
31720
31721 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
31722 if let Some(key_block_size) = &e.key_block_size {
31724 self.write_keyword("KEY_BLOCK_SIZE");
31725 self.write(" = ");
31726 self.generate_expression(key_block_size)?;
31727 } else if let Some(using) = &e.using {
31728 self.write_keyword("USING");
31729 self.write_space();
31730 self.generate_expression(using)?;
31731 } else if let Some(parser) = &e.parser {
31732 self.write_keyword("WITH PARSER");
31733 self.write_space();
31734 self.generate_expression(parser)?;
31735 } else if let Some(comment) = &e.comment {
31736 self.write_keyword("COMMENT");
31737 self.write_space();
31738 self.generate_expression(comment)?;
31739 } else if let Some(visible) = &e.visible {
31740 self.generate_expression(visible)?;
31741 } else if let Some(engine_attr) = &e.engine_attr {
31742 self.write_keyword("ENGINE_ATTRIBUTE");
31743 self.write(" = ");
31744 self.generate_expression(engine_attr)?;
31745 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
31746 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
31747 self.write(" = ");
31748 self.generate_expression(secondary_engine_attr)?;
31749 }
31750 Ok(())
31751 }
31752
31753 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
31754 if let Some(using) = &e.using {
31756 self.write_keyword("USING");
31757 self.write_space();
31758 self.generate_expression(using)?;
31759 }
31760 if !e.columns.is_empty() {
31761 self.write("(");
31762 for (i, col) in e.columns.iter().enumerate() {
31763 if i > 0 {
31764 self.write(", ");
31765 }
31766 self.generate_expression(col)?;
31767 }
31768 self.write(")");
31769 }
31770 if let Some(partition_by) = &e.partition_by {
31771 self.write_space();
31772 self.write_keyword("PARTITION BY");
31773 self.write_space();
31774 self.generate_expression(partition_by)?;
31775 }
31776 if let Some(where_) = &e.where_ {
31777 self.write_space();
31778 self.generate_expression(where_)?;
31779 }
31780 if let Some(include) = &e.include {
31781 self.write_space();
31782 self.write_keyword("INCLUDE");
31783 self.write(" (");
31784 self.generate_expression(include)?;
31785 self.write(")");
31786 }
31787 if let Some(with_storage) = &e.with_storage {
31788 self.write_space();
31789 self.write_keyword("WITH");
31790 self.write(" (");
31791 self.generate_expression(with_storage)?;
31792 self.write(")");
31793 }
31794 if let Some(tablespace) = &e.tablespace {
31795 self.write_space();
31796 self.write_keyword("USING INDEX TABLESPACE");
31797 self.write_space();
31798 self.generate_expression(tablespace)?;
31799 }
31800 Ok(())
31801 }
31802
31803 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
31804 if let Expression::Identifier(id) = &*e.this {
31808 self.write_keyword(&id.name);
31809 } else {
31810 self.generate_expression(&e.this)?;
31811 }
31812 self.write_space();
31813 self.write_keyword("INDEX");
31814 if let Some(target) = &e.target {
31815 self.write_space();
31816 self.write_keyword("FOR");
31817 self.write_space();
31818 if let Expression::Identifier(id) = &**target {
31819 self.write_keyword(&id.name);
31820 } else {
31821 self.generate_expression(target)?;
31822 }
31823 }
31824 self.write(" (");
31826 for (i, expr) in e.expressions.iter().enumerate() {
31827 if i > 0 {
31828 self.write(", ");
31829 }
31830 self.generate_expression(expr)?;
31831 }
31832 self.write(")");
31833 Ok(())
31834 }
31835
31836 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
31837 self.write_keyword("INHERITS");
31839 self.write(" (");
31840 for (i, expr) in e.expressions.iter().enumerate() {
31841 if i > 0 {
31842 self.write(", ");
31843 }
31844 self.generate_expression(expr)?;
31845 }
31846 self.write(")");
31847 Ok(())
31848 }
31849
31850 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
31851 self.write_keyword("INPUT");
31853 self.write("(");
31854 self.generate_expression(&e.this)?;
31855 self.write(")");
31856 Ok(())
31857 }
31858
31859 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
31860 if let Some(input_format) = &e.input_format {
31862 self.write_keyword("INPUTFORMAT");
31863 self.write_space();
31864 self.generate_expression(input_format)?;
31865 }
31866 if let Some(output_format) = &e.output_format {
31867 if e.input_format.is_some() {
31868 self.write(" ");
31869 }
31870 self.write_keyword("OUTPUTFORMAT");
31871 self.write_space();
31872 self.generate_expression(output_format)?;
31873 }
31874 Ok(())
31875 }
31876
31877 fn generate_install(&mut self, e: &Install) -> Result<()> {
31878 if e.force.is_some() {
31880 self.write_keyword("FORCE");
31881 self.write_space();
31882 }
31883 self.write_keyword("INSTALL");
31884 self.write_space();
31885 self.generate_expression(&e.this)?;
31886 if let Some(from) = &e.from_ {
31887 self.write_space();
31888 self.write_keyword("FROM");
31889 self.write_space();
31890 self.generate_expression(from)?;
31891 }
31892 Ok(())
31893 }
31894
31895 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
31896 self.write_keyword("INTERVAL");
31898 self.write_space();
31899 self.generate_expression(&e.expression)?;
31901 if let Some(unit) = &e.unit {
31902 self.write_space();
31903 self.write(unit);
31904 }
31905 Ok(())
31906 }
31907
31908 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
31909 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
31911 self.write_space();
31912 self.write_keyword("TO");
31913 self.write_space();
31914 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
31915 Ok(())
31916 }
31917
31918 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
31919 self.write_keyword("INTO");
31921 if e.temporary {
31922 self.write_keyword(" TEMPORARY");
31923 }
31924 if e.unlogged.is_some() {
31925 self.write_keyword(" UNLOGGED");
31926 }
31927 if let Some(this) = &e.this {
31928 self.write_space();
31929 self.generate_expression(this)?;
31930 }
31931 if !e.expressions.is_empty() {
31932 self.write(" (");
31933 for (i, expr) in e.expressions.iter().enumerate() {
31934 if i > 0 {
31935 self.write(", ");
31936 }
31937 self.generate_expression(expr)?;
31938 }
31939 self.write(")");
31940 }
31941 Ok(())
31942 }
31943
31944 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
31945 self.generate_expression(&e.this)?;
31947 self.write_space();
31948 self.generate_expression(&e.expression)?;
31949 Ok(())
31950 }
31951
31952 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
31953 self.write_keyword("WITH");
31955 if e.no.is_some() {
31956 self.write_keyword(" NO");
31957 }
31958 if e.concurrent.is_some() {
31959 self.write_keyword(" CONCURRENT");
31960 }
31961 self.write_keyword(" ISOLATED LOADING");
31962 if let Some(target) = &e.target {
31963 self.write_space();
31964 self.generate_expression(target)?;
31965 }
31966 Ok(())
31967 }
31968
31969 fn generate_json(&mut self, e: &JSON) -> Result<()> {
31970 self.write_keyword("JSON");
31972 if let Some(this) = &e.this {
31973 self.write_space();
31974 self.generate_expression(this)?;
31975 }
31976 if let Some(with_) = &e.with_ {
31977 if let Expression::Boolean(b) = with_.as_ref() {
31979 if b.value {
31980 self.write_keyword(" WITH");
31981 } else {
31982 self.write_keyword(" WITHOUT");
31983 }
31984 }
31985 }
31986 if e.unique {
31987 self.write_keyword(" UNIQUE KEYS");
31988 }
31989 Ok(())
31990 }
31991
31992 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
31993 self.write_keyword("JSON_ARRAY");
31995 self.write("(");
31996 for (i, expr) in e.expressions.iter().enumerate() {
31997 if i > 0 {
31998 self.write(", ");
31999 }
32000 self.generate_expression(expr)?;
32001 }
32002 if let Some(null_handling) = &e.null_handling {
32003 self.write_space();
32004 self.generate_expression(null_handling)?;
32005 }
32006 if let Some(return_type) = &e.return_type {
32007 self.write_space();
32008 self.write_keyword("RETURNING");
32009 self.write_space();
32010 self.generate_expression(return_type)?;
32011 }
32012 if e.strict.is_some() {
32013 self.write_space();
32014 self.write_keyword("STRICT");
32015 }
32016 self.write(")");
32017 Ok(())
32018 }
32019
32020 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
32021 self.write_keyword("JSON_ARRAYAGG");
32023 self.write("(");
32024 self.generate_expression(&e.this)?;
32025 if let Some(order) = &e.order {
32026 self.write_space();
32027 if let Expression::OrderBy(ob) = order.as_ref() {
32029 self.write_keyword("ORDER BY");
32030 self.write_space();
32031 for (i, ord) in ob.expressions.iter().enumerate() {
32032 if i > 0 {
32033 self.write(", ");
32034 }
32035 self.generate_ordered(ord)?;
32036 }
32037 } else {
32038 self.generate_expression(order)?;
32040 }
32041 }
32042 if let Some(null_handling) = &e.null_handling {
32043 self.write_space();
32044 self.generate_expression(null_handling)?;
32045 }
32046 if let Some(return_type) = &e.return_type {
32047 self.write_space();
32048 self.write_keyword("RETURNING");
32049 self.write_space();
32050 self.generate_expression(return_type)?;
32051 }
32052 if e.strict.is_some() {
32053 self.write_space();
32054 self.write_keyword("STRICT");
32055 }
32056 self.write(")");
32057 Ok(())
32058 }
32059
32060 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
32061 self.write_keyword("JSON_OBJECTAGG");
32063 self.write("(");
32064 for (i, expr) in e.expressions.iter().enumerate() {
32065 if i > 0 {
32066 self.write(", ");
32067 }
32068 self.generate_expression(expr)?;
32069 }
32070 if let Some(null_handling) = &e.null_handling {
32071 self.write_space();
32072 self.generate_expression(null_handling)?;
32073 }
32074 if let Some(unique_keys) = &e.unique_keys {
32075 self.write_space();
32076 if let Expression::Boolean(b) = unique_keys.as_ref() {
32077 if b.value {
32078 self.write_keyword("WITH UNIQUE KEYS");
32079 } else {
32080 self.write_keyword("WITHOUT UNIQUE KEYS");
32081 }
32082 }
32083 }
32084 if let Some(return_type) = &e.return_type {
32085 self.write_space();
32086 self.write_keyword("RETURNING");
32087 self.write_space();
32088 self.generate_expression(return_type)?;
32089 }
32090 self.write(")");
32091 Ok(())
32092 }
32093
32094 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
32095 self.write_keyword("JSON_ARRAY_APPEND");
32097 self.write("(");
32098 self.generate_expression(&e.this)?;
32099 for expr in &e.expressions {
32100 self.write(", ");
32101 self.generate_expression(expr)?;
32102 }
32103 self.write(")");
32104 Ok(())
32105 }
32106
32107 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
32108 self.write_keyword("JSON_ARRAY_CONTAINS");
32110 self.write("(");
32111 self.generate_expression(&e.this)?;
32112 self.write(", ");
32113 self.generate_expression(&e.expression)?;
32114 self.write(")");
32115 Ok(())
32116 }
32117
32118 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
32119 self.write_keyword("JSON_ARRAY_INSERT");
32121 self.write("(");
32122 self.generate_expression(&e.this)?;
32123 for expr in &e.expressions {
32124 self.write(", ");
32125 self.generate_expression(expr)?;
32126 }
32127 self.write(")");
32128 Ok(())
32129 }
32130
32131 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
32132 self.write_keyword("JSONB_EXISTS");
32134 self.write("(");
32135 self.generate_expression(&e.this)?;
32136 if let Some(path) = &e.path {
32137 self.write(", ");
32138 self.generate_expression(path)?;
32139 }
32140 self.write(")");
32141 Ok(())
32142 }
32143
32144 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
32145 self.write_keyword("JSONB_EXTRACT_SCALAR");
32147 self.write("(");
32148 self.generate_expression(&e.this)?;
32149 self.write(", ");
32150 self.generate_expression(&e.expression)?;
32151 self.write(")");
32152 Ok(())
32153 }
32154
32155 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
32156 self.write_keyword("JSONB_OBJECT_AGG");
32158 self.write("(");
32159 self.generate_expression(&e.this)?;
32160 self.write(", ");
32161 self.generate_expression(&e.expression)?;
32162 self.write(")");
32163 Ok(())
32164 }
32165
32166 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
32167 if let Some(nested_schema) = &e.nested_schema {
32169 self.write_keyword("NESTED");
32170 if let Some(path) = &e.path {
32171 self.write_space();
32172 self.write_keyword("PATH");
32173 self.write_space();
32174 self.generate_expression(path)?;
32175 }
32176 self.write_space();
32177 self.generate_expression(nested_schema)?;
32178 } else {
32179 if let Some(this) = &e.this {
32180 self.generate_expression(this)?;
32181 }
32182 if let Some(kind) = &e.kind {
32183 self.write_space();
32184 self.write(kind);
32185 }
32186 if e.format_json {
32187 self.write_space();
32188 self.write_keyword("FORMAT JSON");
32189 }
32190 if let Some(path) = &e.path {
32191 self.write_space();
32192 self.write_keyword("PATH");
32193 self.write_space();
32194 self.generate_expression(path)?;
32195 }
32196 if e.ordinality.is_some() {
32197 self.write_keyword(" FOR ORDINALITY");
32198 }
32199 }
32200 Ok(())
32201 }
32202
32203 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
32204 self.write_keyword("JSON_EXISTS");
32206 self.write("(");
32207 self.generate_expression(&e.this)?;
32208 if let Some(path) = &e.path {
32209 self.write(", ");
32210 self.generate_expression(path)?;
32211 }
32212 if let Some(passing) = &e.passing {
32213 self.write_space();
32214 self.write_keyword("PASSING");
32215 self.write_space();
32216 self.generate_expression(passing)?;
32217 }
32218 if let Some(on_condition) = &e.on_condition {
32219 self.write_space();
32220 self.generate_expression(on_condition)?;
32221 }
32222 self.write(")");
32223 Ok(())
32224 }
32225
32226 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
32227 self.generate_expression(&e.this)?;
32228 self.write(".:");
32229 if Self::data_type_has_nested_expressions(&e.to) {
32233 let saved = std::mem::take(&mut self.output);
32235 self.generate_data_type(&e.to)?;
32236 let type_sql = std::mem::replace(&mut self.output, saved);
32237 self.write("\"");
32238 self.write(&type_sql);
32239 self.write("\"");
32240 } else {
32241 self.generate_data_type(&e.to)?;
32242 }
32243 Ok(())
32244 }
32245
32246 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
32249 matches!(
32250 dt,
32251 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
32252 )
32253 }
32254
32255 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
32256 self.write_keyword("JSON_EXTRACT_ARRAY");
32258 self.write("(");
32259 self.generate_expression(&e.this)?;
32260 if let Some(expr) = &e.expression {
32261 self.write(", ");
32262 self.generate_expression(expr)?;
32263 }
32264 self.write(")");
32265 Ok(())
32266 }
32267
32268 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
32269 if let Some(option) = &e.option {
32271 self.generate_expression(option)?;
32272 self.write_space();
32273 }
32274 self.write_keyword("QUOTES");
32275 if e.scalar.is_some() {
32276 self.write_keyword(" SCALAR_ONLY");
32277 }
32278 Ok(())
32279 }
32280
32281 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
32282 self.write_keyword("JSON_EXTRACT_SCALAR");
32284 self.write("(");
32285 self.generate_expression(&e.this)?;
32286 self.write(", ");
32287 self.generate_expression(&e.expression)?;
32288 self.write(")");
32289 Ok(())
32290 }
32291
32292 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
32293 if e.variant_extract.is_some() {
32297 use crate::dialects::DialectType;
32298 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
32299 self.generate_expression(&e.this)?;
32303 self.write(":");
32304 match e.expression.as_ref() {
32305 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
32306 let Literal::String(s) = lit.as_ref() else {
32307 unreachable!()
32308 };
32309 self.write_databricks_json_path(s);
32310 }
32311 _ => {
32312 self.generate_expression(&e.expression)?;
32314 }
32315 }
32316 } else {
32317 self.write_keyword("GET_PATH");
32319 self.write("(");
32320 self.generate_expression(&e.this)?;
32321 self.write(", ");
32322 self.generate_expression(&e.expression)?;
32323 self.write(")");
32324 }
32325 } else {
32326 self.write_keyword("JSON_EXTRACT");
32327 self.write("(");
32328 self.generate_expression(&e.this)?;
32329 self.write(", ");
32330 self.generate_expression(&e.expression)?;
32331 for expr in &e.expressions {
32332 self.write(", ");
32333 self.generate_expression(expr)?;
32334 }
32335 self.write(")");
32336 }
32337 Ok(())
32338 }
32339
32340 fn write_databricks_json_path(&mut self, path: &str) {
32344 if path.starts_with("[\"") || path.starts_with("['") {
32347 self.write(path);
32348 return;
32349 }
32350 let mut first = true;
32354 for segment in path.split('.') {
32355 if !first {
32356 self.write(".");
32357 }
32358 first = false;
32359 if let Some(bracket_pos) = segment.find('[') {
32361 let key = &segment[..bracket_pos];
32362 let subscript = &segment[bracket_pos..];
32363 if key.is_empty() {
32364 self.write(segment);
32366 } else if Self::is_safe_json_path_key(key) {
32367 self.write(key);
32368 self.write(subscript);
32369 } else {
32370 self.write("[\"");
32371 self.write(key);
32372 self.write("\"]");
32373 self.write(subscript);
32374 }
32375 } else if Self::is_safe_json_path_key(segment) {
32376 self.write(segment);
32377 } else {
32378 self.write("[\"");
32379 self.write(segment);
32380 self.write("\"]");
32381 }
32382 }
32383 }
32384
32385 fn is_safe_json_path_key(key: &str) -> bool {
32388 if key.is_empty() {
32389 return false;
32390 }
32391 let mut chars = key.chars();
32392 let first = chars.next().unwrap();
32393 if first != '_' && !first.is_ascii_alphabetic() {
32394 return false;
32395 }
32396 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
32397 }
32398
32399 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
32400 if let Some(this) = &e.this {
32403 self.generate_expression(this)?;
32404 self.write_space();
32405 }
32406 self.write_keyword("FORMAT JSON");
32407 Ok(())
32408 }
32409
32410 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
32411 self.generate_expression(&e.this)?;
32413 self.write(": ");
32414 self.generate_expression(&e.expression)?;
32415 Ok(())
32416 }
32417
32418 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
32419 self.write_keyword("JSON_KEYS");
32421 self.write("(");
32422 self.generate_expression(&e.this)?;
32423 if let Some(expr) = &e.expression {
32424 self.write(", ");
32425 self.generate_expression(expr)?;
32426 }
32427 for expr in &e.expressions {
32428 self.write(", ");
32429 self.generate_expression(expr)?;
32430 }
32431 self.write(")");
32432 Ok(())
32433 }
32434
32435 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
32436 self.write_keyword("JSON_KEYS");
32438 self.write("(");
32439 self.generate_expression(&e.this)?;
32440 if let Some(expr) = &e.expression {
32441 self.write(", ");
32442 self.generate_expression(expr)?;
32443 }
32444 self.write(")");
32445 Ok(())
32446 }
32447
32448 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
32449 let mut path_str = String::new();
32452 for expr in &e.expressions {
32453 match expr {
32454 Expression::JSONPathRoot(_) => {
32455 path_str.push('$');
32456 }
32457 Expression::JSONPathKey(k) => {
32458 if let Expression::Literal(lit) = k.this.as_ref() {
32460 if let crate::expressions::Literal::String(s) = lit.as_ref() {
32461 path_str.push('.');
32462 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
32464 if needs_quoting {
32465 path_str.push('"');
32466 path_str.push_str(s);
32467 path_str.push('"');
32468 } else {
32469 path_str.push_str(s);
32470 }
32471 }
32472 }
32473 }
32474 Expression::JSONPathSubscript(s) => {
32475 if let Expression::Literal(lit) = s.this.as_ref() {
32477 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
32478 path_str.push('[');
32479 path_str.push_str(n);
32480 path_str.push(']');
32481 }
32482 }
32483 }
32484 _ => {
32485 let mut temp_gen = Self::with_arc_config(self.config.clone());
32487 temp_gen.generate_expression(expr)?;
32488 path_str.push_str(&temp_gen.output);
32489 }
32490 }
32491 }
32492 self.write("'");
32494 self.write(&path_str);
32495 self.write("'");
32496 Ok(())
32497 }
32498
32499 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
32500 self.write("?(");
32502 self.generate_expression(&e.this)?;
32503 self.write(")");
32504 Ok(())
32505 }
32506
32507 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
32508 self.write(".");
32510 self.generate_expression(&e.this)?;
32511 Ok(())
32512 }
32513
32514 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
32515 self.write("..");
32517 if let Some(this) = &e.this {
32518 self.generate_expression(this)?;
32519 }
32520 Ok(())
32521 }
32522
32523 fn generate_json_path_root(&mut self) -> Result<()> {
32524 self.write("$");
32526 Ok(())
32527 }
32528
32529 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
32530 self.write("(");
32532 self.generate_expression(&e.this)?;
32533 self.write(")");
32534 Ok(())
32535 }
32536
32537 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
32538 self.generate_expression(&e.this)?;
32540 Ok(())
32541 }
32542
32543 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
32544 self.write("[");
32546 if let Some(start) = &e.start {
32547 self.generate_expression(start)?;
32548 }
32549 self.write(":");
32550 if let Some(end) = &e.end {
32551 self.generate_expression(end)?;
32552 }
32553 if let Some(step) = &e.step {
32554 self.write(":");
32555 self.generate_expression(step)?;
32556 }
32557 self.write("]");
32558 Ok(())
32559 }
32560
32561 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
32562 self.write("[");
32564 self.generate_expression(&e.this)?;
32565 self.write("]");
32566 Ok(())
32567 }
32568
32569 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
32570 self.write("[");
32572 for (i, expr) in e.expressions.iter().enumerate() {
32573 if i > 0 {
32574 self.write(", ");
32575 }
32576 self.generate_expression(expr)?;
32577 }
32578 self.write("]");
32579 Ok(())
32580 }
32581
32582 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
32583 self.write_keyword("JSON_REMOVE");
32585 self.write("(");
32586 self.generate_expression(&e.this)?;
32587 for expr in &e.expressions {
32588 self.write(", ");
32589 self.generate_expression(expr)?;
32590 }
32591 self.write(")");
32592 Ok(())
32593 }
32594
32595 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
32596 self.write_keyword("COLUMNS");
32599 self.write("(");
32600
32601 if self.config.pretty && !e.expressions.is_empty() {
32602 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
32604 for expr in &e.expressions {
32605 let mut temp_gen = Generator::with_arc_config(self.config.clone());
32606 temp_gen.generate_expression(expr)?;
32607 expr_strings.push(temp_gen.output);
32608 }
32609
32610 if self.too_wide(&expr_strings) {
32612 self.write_newline();
32614 self.indent_level += 1;
32615 for (i, expr_str) in expr_strings.iter().enumerate() {
32616 if i > 0 {
32617 self.write(",");
32618 self.write_newline();
32619 }
32620 self.write_indent();
32621 self.write(expr_str);
32622 }
32623 self.write_newline();
32624 self.indent_level -= 1;
32625 self.write_indent();
32626 } else {
32627 for (i, expr_str) in expr_strings.iter().enumerate() {
32629 if i > 0 {
32630 self.write(", ");
32631 }
32632 self.write(expr_str);
32633 }
32634 }
32635 } else {
32636 for (i, expr) in e.expressions.iter().enumerate() {
32638 if i > 0 {
32639 self.write(", ");
32640 }
32641 self.generate_expression(expr)?;
32642 }
32643 }
32644 self.write(")");
32645 Ok(())
32646 }
32647
32648 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
32649 self.write_keyword("JSON_SET");
32651 self.write("(");
32652 self.generate_expression(&e.this)?;
32653 for expr in &e.expressions {
32654 self.write(", ");
32655 self.generate_expression(expr)?;
32656 }
32657 self.write(")");
32658 Ok(())
32659 }
32660
32661 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
32662 self.write_keyword("JSON_STRIP_NULLS");
32664 self.write("(");
32665 self.generate_expression(&e.this)?;
32666 if let Some(expr) = &e.expression {
32667 self.write(", ");
32668 self.generate_expression(expr)?;
32669 }
32670 self.write(")");
32671 Ok(())
32672 }
32673
32674 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
32675 self.write_keyword("JSON_TABLE");
32677 self.write("(");
32678 self.generate_expression(&e.this)?;
32679 if let Some(path) = &e.path {
32680 self.write(", ");
32681 self.generate_expression(path)?;
32682 }
32683 if let Some(error_handling) = &e.error_handling {
32684 self.write_space();
32685 self.generate_expression(error_handling)?;
32686 }
32687 if let Some(empty_handling) = &e.empty_handling {
32688 self.write_space();
32689 self.generate_expression(empty_handling)?;
32690 }
32691 if let Some(schema) = &e.schema {
32692 self.write_space();
32693 self.generate_expression(schema)?;
32694 }
32695 self.write(")");
32696 Ok(())
32697 }
32698
32699 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
32700 self.write_keyword("JSON_TYPE");
32702 self.write("(");
32703 self.generate_expression(&e.this)?;
32704 self.write(")");
32705 Ok(())
32706 }
32707
32708 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
32709 self.write_keyword("JSON_VALUE");
32711 self.write("(");
32712 self.generate_expression(&e.this)?;
32713 if let Some(path) = &e.path {
32714 self.write(", ");
32715 self.generate_expression(path)?;
32716 }
32717 if let Some(returning) = &e.returning {
32718 self.write_space();
32719 self.write_keyword("RETURNING");
32720 self.write_space();
32721 self.generate_expression(returning)?;
32722 }
32723 if let Some(on_condition) = &e.on_condition {
32724 self.write_space();
32725 self.generate_expression(on_condition)?;
32726 }
32727 self.write(")");
32728 Ok(())
32729 }
32730
32731 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
32732 self.write_keyword("JSON_VALUE_ARRAY");
32734 self.write("(");
32735 self.generate_expression(&e.this)?;
32736 self.write(")");
32737 Ok(())
32738 }
32739
32740 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
32741 self.write_keyword("JAROWINKLER_SIMILARITY");
32743 self.write("(");
32744 self.generate_expression(&e.this)?;
32745 self.write(", ");
32746 self.generate_expression(&e.expression)?;
32747 self.write(")");
32748 Ok(())
32749 }
32750
32751 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
32752 self.generate_expression(&e.this)?;
32754 self.write("(");
32755 for (i, expr) in e.expressions.iter().enumerate() {
32756 if i > 0 {
32757 self.write(", ");
32758 }
32759 self.generate_expression(expr)?;
32760 }
32761 self.write(")");
32762 Ok(())
32763 }
32764
32765 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
32766 if e.no.is_some() {
32768 self.write_keyword("NO ");
32769 }
32770 if let Some(local) = &e.local {
32771 self.generate_expression(local)?;
32772 self.write_space();
32773 }
32774 if e.dual.is_some() {
32775 self.write_keyword("DUAL ");
32776 }
32777 if e.before.is_some() {
32778 self.write_keyword("BEFORE ");
32779 }
32780 if e.after.is_some() {
32781 self.write_keyword("AFTER ");
32782 }
32783 self.write_keyword("JOURNAL");
32784 Ok(())
32785 }
32786
32787 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
32788 self.write_keyword("LANGUAGE");
32790 self.write_space();
32791 self.generate_expression(&e.this)?;
32792 Ok(())
32793 }
32794
32795 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
32796 if e.view.is_some() {
32798 self.write_keyword("LATERAL VIEW");
32800 if e.outer.is_some() {
32801 self.write_space();
32802 self.write_keyword("OUTER");
32803 }
32804 self.write_space();
32805 self.generate_expression(&e.this)?;
32806 if let Some(alias) = &e.alias {
32807 self.write_space();
32808 self.write(alias);
32809 }
32810 } else {
32811 self.write_keyword("LATERAL");
32813 self.write_space();
32814 self.generate_expression(&e.this)?;
32815 if e.ordinality.is_some() {
32816 self.write_space();
32817 self.write_keyword("WITH ORDINALITY");
32818 }
32819 if let Some(alias) = &e.alias {
32820 self.write_space();
32821 self.write_keyword("AS");
32822 self.write_space();
32823 self.write(alias);
32824 if !e.column_aliases.is_empty() {
32825 self.write("(");
32826 for (i, col) in e.column_aliases.iter().enumerate() {
32827 if i > 0 {
32828 self.write(", ");
32829 }
32830 self.write(col);
32831 }
32832 self.write(")");
32833 }
32834 }
32835 }
32836 Ok(())
32837 }
32838
32839 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
32840 self.write_keyword("LIKE");
32842 self.write_space();
32843 self.generate_expression(&e.this)?;
32844 for expr in &e.expressions {
32845 self.write_space();
32846 self.generate_expression(expr)?;
32847 }
32848 Ok(())
32849 }
32850
32851 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
32852 self.write_keyword("LIMIT");
32853 self.write_space();
32854 self.write_limit_expr(&e.this)?;
32855 if e.percent {
32856 self.write_space();
32857 self.write_keyword("PERCENT");
32858 }
32859 for comment in &e.comments {
32861 self.write(" ");
32862 self.write_formatted_comment(comment);
32863 }
32864 Ok(())
32865 }
32866
32867 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
32868 if e.percent.is_some() {
32870 self.write_keyword(" PERCENT");
32871 }
32872 if e.rows.is_some() {
32873 self.write_keyword(" ROWS");
32874 }
32875 if e.with_ties.is_some() {
32876 self.write_keyword(" WITH TIES");
32877 } else if e.rows.is_some() {
32878 self.write_keyword(" ONLY");
32879 }
32880 Ok(())
32881 }
32882
32883 fn generate_list(&mut self, e: &List) -> Result<()> {
32884 use crate::dialects::DialectType;
32885 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
32886
32887 if e.expressions.len() == 1 {
32889 if let Expression::Select(_) = &e.expressions[0] {
32890 self.write_keyword("LIST");
32891 self.write("(");
32892 self.generate_expression(&e.expressions[0])?;
32893 self.write(")");
32894 return Ok(());
32895 }
32896 }
32897
32898 if is_materialize {
32900 self.write_keyword("LIST");
32901 self.write("[");
32902 for (i, expr) in e.expressions.iter().enumerate() {
32903 if i > 0 {
32904 self.write(", ");
32905 }
32906 self.generate_expression(expr)?;
32907 }
32908 self.write("]");
32909 } else {
32910 self.write_keyword("LIST");
32912 self.write("(");
32913 for (i, expr) in e.expressions.iter().enumerate() {
32914 if i > 0 {
32915 self.write(", ");
32916 }
32917 self.generate_expression(expr)?;
32918 }
32919 self.write(")");
32920 }
32921 Ok(())
32922 }
32923
32924 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
32925 if let Expression::Select(_) = &*e.this {
32927 self.write_keyword("MAP");
32928 self.write("(");
32929 self.generate_expression(&e.this)?;
32930 self.write(")");
32931 return Ok(());
32932 }
32933
32934 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
32935
32936 self.write_keyword("MAP");
32938 if is_duckdb {
32939 self.write(" {");
32940 } else {
32941 self.write("[");
32942 }
32943 if let Expression::Struct(s) = &*e.this {
32944 for (i, (_, expr)) in s.fields.iter().enumerate() {
32945 if i > 0 {
32946 self.write(", ");
32947 }
32948 if let Expression::PropertyEQ(op) = expr {
32949 self.generate_expression(&op.left)?;
32950 if is_duckdb {
32951 self.write(": ");
32952 } else {
32953 self.write(" => ");
32954 }
32955 self.generate_expression(&op.right)?;
32956 } else {
32957 self.generate_expression(expr)?;
32958 }
32959 }
32960 }
32961 if is_duckdb {
32962 self.write("}");
32963 } else {
32964 self.write("]");
32965 }
32966 Ok(())
32967 }
32968
32969 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
32970 self.write_keyword("LOCALTIME");
32972 if let Some(precision) = &e.this {
32973 self.write("(");
32974 self.generate_expression(precision)?;
32975 self.write(")");
32976 }
32977 Ok(())
32978 }
32979
32980 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
32981 self.write_keyword("LOCALTIMESTAMP");
32983 if let Some(precision) = &e.this {
32984 self.write("(");
32985 self.generate_expression(precision)?;
32986 self.write(")");
32987 }
32988 Ok(())
32989 }
32990
32991 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
32992 self.write_keyword("LOCATION");
32994 self.write_space();
32995 self.generate_expression(&e.this)?;
32996 Ok(())
32997 }
32998
32999 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
33000 if e.update.is_some() {
33002 if e.key.is_some() {
33003 self.write_keyword("FOR NO KEY UPDATE");
33004 } else {
33005 self.write_keyword("FOR UPDATE");
33006 }
33007 } else {
33008 if e.key.is_some() {
33009 self.write_keyword("FOR KEY SHARE");
33010 } else {
33011 self.write_keyword("FOR SHARE");
33012 }
33013 }
33014 if !e.expressions.is_empty() {
33015 self.write_keyword(" OF ");
33016 for (i, expr) in e.expressions.iter().enumerate() {
33017 if i > 0 {
33018 self.write(", ");
33019 }
33020 self.generate_expression(expr)?;
33021 }
33022 }
33023 if let Some(wait) = &e.wait {
33028 match wait.as_ref() {
33029 Expression::Boolean(b) => {
33030 if b.value {
33031 self.write_keyword(" NOWAIT");
33032 } else {
33033 self.write_keyword(" SKIP LOCKED");
33034 }
33035 }
33036 _ => {
33037 self.write_keyword(" WAIT ");
33039 self.generate_expression(wait)?;
33040 }
33041 }
33042 }
33043 Ok(())
33044 }
33045
33046 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
33047 self.write_keyword("LOCK");
33049 self.write_space();
33050 self.generate_expression(&e.this)?;
33051 Ok(())
33052 }
33053
33054 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
33055 self.write_keyword("LOCKING");
33057 self.write_space();
33058 self.write(&e.kind);
33059 if let Some(this) = &e.this {
33060 self.write_space();
33061 self.generate_expression(this)?;
33062 }
33063 if let Some(for_or_in) = &e.for_or_in {
33064 self.write_space();
33065 self.generate_expression(for_or_in)?;
33066 }
33067 if let Some(lock_type) = &e.lock_type {
33068 self.write_space();
33069 self.generate_expression(lock_type)?;
33070 }
33071 if e.override_.is_some() {
33072 self.write_keyword(" OVERRIDE");
33073 }
33074 Ok(())
33075 }
33076
33077 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
33078 self.generate_expression(&e.this)?;
33080 self.write_space();
33081 self.generate_expression(&e.expression)?;
33082 Ok(())
33083 }
33084
33085 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
33086 if e.no.is_some() {
33088 self.write_keyword("NO ");
33089 }
33090 self.write_keyword("LOG");
33091 Ok(())
33092 }
33093
33094 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
33095 self.write_keyword("MD5");
33097 self.write("(");
33098 self.generate_expression(&e.this)?;
33099 for expr in &e.expressions {
33100 self.write(", ");
33101 self.generate_expression(expr)?;
33102 }
33103 self.write(")");
33104 Ok(())
33105 }
33106
33107 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
33108 self.write_keyword("ML.FORECAST");
33110 self.write("(");
33111 self.generate_expression(&e.this)?;
33112 if let Some(expression) = &e.expression {
33113 self.write(", ");
33114 self.generate_expression(expression)?;
33115 }
33116 if let Some(params) = &e.params_struct {
33117 self.write(", ");
33118 self.generate_expression(params)?;
33119 }
33120 self.write(")");
33121 Ok(())
33122 }
33123
33124 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
33125 self.write_keyword("ML.TRANSLATE");
33127 self.write("(");
33128 self.generate_expression(&e.this)?;
33129 self.write(", ");
33130 self.generate_expression(&e.expression)?;
33131 if let Some(params) = &e.params_struct {
33132 self.write(", ");
33133 self.generate_expression(params)?;
33134 }
33135 self.write(")");
33136 Ok(())
33137 }
33138
33139 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
33140 self.write_keyword("MAKE_INTERVAL");
33142 self.write("(");
33143 let mut first = true;
33144 if let Some(year) = &e.year {
33145 self.write("years => ");
33146 self.generate_expression(year)?;
33147 first = false;
33148 }
33149 if let Some(month) = &e.month {
33150 if !first {
33151 self.write(", ");
33152 }
33153 self.write("months => ");
33154 self.generate_expression(month)?;
33155 first = false;
33156 }
33157 if let Some(week) = &e.week {
33158 if !first {
33159 self.write(", ");
33160 }
33161 self.write("weeks => ");
33162 self.generate_expression(week)?;
33163 first = false;
33164 }
33165 if let Some(day) = &e.day {
33166 if !first {
33167 self.write(", ");
33168 }
33169 self.write("days => ");
33170 self.generate_expression(day)?;
33171 first = false;
33172 }
33173 if let Some(hour) = &e.hour {
33174 if !first {
33175 self.write(", ");
33176 }
33177 self.write("hours => ");
33178 self.generate_expression(hour)?;
33179 first = false;
33180 }
33181 if let Some(minute) = &e.minute {
33182 if !first {
33183 self.write(", ");
33184 }
33185 self.write("mins => ");
33186 self.generate_expression(minute)?;
33187 first = false;
33188 }
33189 if let Some(second) = &e.second {
33190 if !first {
33191 self.write(", ");
33192 }
33193 self.write("secs => ");
33194 self.generate_expression(second)?;
33195 }
33196 self.write(")");
33197 Ok(())
33198 }
33199
33200 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
33201 self.write_keyword("MANHATTAN_DISTANCE");
33203 self.write("(");
33204 self.generate_expression(&e.this)?;
33205 self.write(", ");
33206 self.generate_expression(&e.expression)?;
33207 self.write(")");
33208 Ok(())
33209 }
33210
33211 fn generate_map(&mut self, e: &Map) -> Result<()> {
33212 self.write_keyword("MAP");
33214 self.write("(");
33215 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
33216 if i > 0 {
33217 self.write(", ");
33218 }
33219 self.generate_expression(key)?;
33220 self.write(", ");
33221 self.generate_expression(value)?;
33222 }
33223 self.write(")");
33224 Ok(())
33225 }
33226
33227 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
33228 self.write_keyword("MAP_CAT");
33230 self.write("(");
33231 self.generate_expression(&e.this)?;
33232 self.write(", ");
33233 self.generate_expression(&e.expression)?;
33234 self.write(")");
33235 Ok(())
33236 }
33237
33238 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
33239 self.write_keyword("MAP_DELETE");
33241 self.write("(");
33242 self.generate_expression(&e.this)?;
33243 for expr in &e.expressions {
33244 self.write(", ");
33245 self.generate_expression(expr)?;
33246 }
33247 self.write(")");
33248 Ok(())
33249 }
33250
33251 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
33252 self.write_keyword("MAP_INSERT");
33254 self.write("(");
33255 self.generate_expression(&e.this)?;
33256 if let Some(key) = &e.key {
33257 self.write(", ");
33258 self.generate_expression(key)?;
33259 }
33260 if let Some(value) = &e.value {
33261 self.write(", ");
33262 self.generate_expression(value)?;
33263 }
33264 if let Some(update_flag) = &e.update_flag {
33265 self.write(", ");
33266 self.generate_expression(update_flag)?;
33267 }
33268 self.write(")");
33269 Ok(())
33270 }
33271
33272 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
33273 self.write_keyword("MAP_PICK");
33275 self.write("(");
33276 self.generate_expression(&e.this)?;
33277 for expr in &e.expressions {
33278 self.write(", ");
33279 self.generate_expression(expr)?;
33280 }
33281 self.write(")");
33282 Ok(())
33283 }
33284
33285 fn generate_masking_policy_column_constraint(
33286 &mut self,
33287 e: &MaskingPolicyColumnConstraint,
33288 ) -> Result<()> {
33289 self.write_keyword("MASKING POLICY");
33291 self.write_space();
33292 self.generate_expression(&e.this)?;
33293 if !e.expressions.is_empty() {
33294 self.write_keyword(" USING");
33295 self.write(" (");
33296 for (i, expr) in e.expressions.iter().enumerate() {
33297 if i > 0 {
33298 self.write(", ");
33299 }
33300 self.generate_expression(expr)?;
33301 }
33302 self.write(")");
33303 }
33304 Ok(())
33305 }
33306
33307 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
33308 if matches!(
33309 self.config.dialect,
33310 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
33311 ) {
33312 if e.expressions.len() > 1 {
33313 self.write("(");
33314 }
33315 for (i, expr) in e.expressions.iter().enumerate() {
33316 if i > 0 {
33317 self.write_keyword(" OR ");
33318 }
33319 self.generate_expression(expr)?;
33320 self.write_space();
33321 self.write("@@");
33322 self.write_space();
33323 self.generate_expression(&e.this)?;
33324 }
33325 if e.expressions.len() > 1 {
33326 self.write(")");
33327 }
33328 return Ok(());
33329 }
33330
33331 self.write_keyword("MATCH");
33333 self.write("(");
33334 for (i, expr) in e.expressions.iter().enumerate() {
33335 if i > 0 {
33336 self.write(", ");
33337 }
33338 self.generate_expression(expr)?;
33339 }
33340 self.write(")");
33341 self.write_keyword(" AGAINST");
33342 self.write("(");
33343 self.generate_expression(&e.this)?;
33344 if let Some(modifier) = &e.modifier {
33345 self.write_space();
33346 self.generate_expression(modifier)?;
33347 }
33348 self.write(")");
33349 Ok(())
33350 }
33351
33352 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
33353 if let Some(window_frame) = &e.window_frame {
33355 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
33356 self.write_space();
33357 }
33358 self.generate_expression(&e.this)?;
33359 Ok(())
33360 }
33361
33362 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
33363 self.write_keyword("MATERIALIZED");
33365 if let Some(this) = &e.this {
33366 self.write_space();
33367 self.generate_expression(this)?;
33368 }
33369 Ok(())
33370 }
33371
33372 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
33373 if let Some(with_) = &e.with_ {
33376 if let Expression::With(with_clause) = with_.as_ref() {
33377 self.generate_with(with_clause)?;
33378 self.write_space();
33379 } else {
33380 self.generate_expression(with_)?;
33381 self.write_space();
33382 }
33383 }
33384 self.write_keyword("MERGE INTO");
33385 self.write_space();
33386 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
33387 if let Expression::Alias(alias) = e.this.as_ref() {
33388 self.generate_expression(&alias.this)?;
33389 self.write_space();
33390 self.generate_identifier(&alias.alias)?;
33391 } else {
33392 self.generate_expression(&e.this)?;
33393 }
33394 } else {
33395 self.generate_expression(&e.this)?;
33396 }
33397
33398 if self.config.pretty {
33400 self.write_newline();
33401 self.write_indent();
33402 } else {
33403 self.write_space();
33404 }
33405 self.write_keyword("USING");
33406 self.write_space();
33407 self.generate_expression(&e.using)?;
33408
33409 if let Some(on) = &e.on {
33411 if self.config.pretty {
33412 self.write_newline();
33413 self.write_indent();
33414 } else {
33415 self.write_space();
33416 }
33417 self.write_keyword("ON");
33418 self.write_space();
33419 self.generate_expression(on)?;
33420 }
33421 if let Some(using_cond) = &e.using_cond {
33423 self.write_space();
33424 self.write_keyword("USING");
33425 self.write_space();
33426 self.write("(");
33427 if let Expression::Tuple(tuple) = using_cond.as_ref() {
33429 for (i, col) in tuple.expressions.iter().enumerate() {
33430 if i > 0 {
33431 self.write(", ");
33432 }
33433 self.generate_expression(col)?;
33434 }
33435 } else {
33436 self.generate_expression(using_cond)?;
33437 }
33438 self.write(")");
33439 }
33440 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
33442 if matches!(
33443 self.config.dialect,
33444 Some(crate::DialectType::PostgreSQL)
33445 | Some(crate::DialectType::Redshift)
33446 | Some(crate::DialectType::Trino)
33447 | Some(crate::DialectType::Presto)
33448 | Some(crate::DialectType::Athena)
33449 ) {
33450 let mut names = Vec::new();
33451 match e.this.as_ref() {
33452 Expression::Alias(a) => {
33453 if let Expression::Table(t) = &a.this {
33455 names.push(t.name.name.clone());
33456 } else if let Expression::Identifier(id) = &a.this {
33457 names.push(id.name.clone());
33458 }
33459 names.push(a.alias.name.clone());
33460 }
33461 Expression::Table(t) => {
33462 names.push(t.name.name.clone());
33463 }
33464 Expression::Identifier(id) => {
33465 names.push(id.name.clone());
33466 }
33467 _ => {}
33468 }
33469 self.merge_strip_qualifiers = names;
33470 }
33471
33472 if let Some(whens) = &e.whens {
33474 if self.config.pretty {
33475 self.write_newline();
33476 self.write_indent();
33477 } else {
33478 self.write_space();
33479 }
33480 self.generate_expression(whens)?;
33481 }
33482
33483 self.merge_strip_qualifiers = saved_merge_strip;
33485
33486 if let Some(returning) = &e.returning {
33488 if self.config.pretty {
33489 self.write_newline();
33490 self.write_indent();
33491 } else {
33492 self.write_space();
33493 }
33494 self.generate_expression(returning)?;
33495 }
33496 Ok(())
33497 }
33498
33499 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
33500 if e.no.is_some() {
33502 self.write_keyword("NO MERGEBLOCKRATIO");
33503 } else if e.default.is_some() {
33504 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
33505 } else {
33506 self.write_keyword("MERGEBLOCKRATIO");
33507 self.write("=");
33508 if let Some(this) = &e.this {
33509 self.generate_expression(this)?;
33510 }
33511 if e.percent.is_some() {
33512 self.write_keyword(" PERCENT");
33513 }
33514 }
33515 Ok(())
33516 }
33517
33518 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
33519 self.write_keyword("TTL");
33521 let pretty_clickhouse = self.config.pretty
33522 && matches!(
33523 self.config.dialect,
33524 Some(crate::dialects::DialectType::ClickHouse)
33525 );
33526
33527 if pretty_clickhouse {
33528 self.write_newline();
33529 self.indent_level += 1;
33530 for (i, expr) in e.expressions.iter().enumerate() {
33531 if i > 0 {
33532 self.write(",");
33533 self.write_newline();
33534 }
33535 self.write_indent();
33536 self.generate_expression(expr)?;
33537 }
33538 self.indent_level -= 1;
33539 } else {
33540 self.write_space();
33541 for (i, expr) in e.expressions.iter().enumerate() {
33542 if i > 0 {
33543 self.write(", ");
33544 }
33545 self.generate_expression(expr)?;
33546 }
33547 }
33548
33549 if let Some(where_) = &e.where_ {
33550 if pretty_clickhouse {
33551 self.write_newline();
33552 if let Expression::Where(w) = where_.as_ref() {
33553 self.write_indent();
33554 self.write_keyword("WHERE");
33555 self.write_newline();
33556 self.indent_level += 1;
33557 self.write_indent();
33558 self.generate_expression(&w.this)?;
33559 self.indent_level -= 1;
33560 } else {
33561 self.write_indent();
33562 self.generate_expression(where_)?;
33563 }
33564 } else {
33565 self.write_space();
33566 self.generate_expression(where_)?;
33567 }
33568 }
33569 if let Some(group) = &e.group {
33570 if pretty_clickhouse {
33571 self.write_newline();
33572 if let Expression::Group(g) = group.as_ref() {
33573 self.write_indent();
33574 self.write_keyword("GROUP BY");
33575 self.write_newline();
33576 self.indent_level += 1;
33577 for (i, expr) in g.expressions.iter().enumerate() {
33578 if i > 0 {
33579 self.write(",");
33580 self.write_newline();
33581 }
33582 self.write_indent();
33583 self.generate_expression(expr)?;
33584 }
33585 self.indent_level -= 1;
33586 } else {
33587 self.write_indent();
33588 self.generate_expression(group)?;
33589 }
33590 } else {
33591 self.write_space();
33592 self.generate_expression(group)?;
33593 }
33594 }
33595 if let Some(aggregates) = &e.aggregates {
33596 if pretty_clickhouse {
33597 self.write_newline();
33598 self.write_indent();
33599 self.write_keyword("SET");
33600 self.write_newline();
33601 self.indent_level += 1;
33602 if let Expression::Tuple(t) = aggregates.as_ref() {
33603 for (i, agg) in t.expressions.iter().enumerate() {
33604 if i > 0 {
33605 self.write(",");
33606 self.write_newline();
33607 }
33608 self.write_indent();
33609 self.generate_expression(agg)?;
33610 }
33611 } else {
33612 self.write_indent();
33613 self.generate_expression(aggregates)?;
33614 }
33615 self.indent_level -= 1;
33616 } else {
33617 self.write_space();
33618 self.write_keyword("SET");
33619 self.write_space();
33620 if let Expression::Tuple(t) = aggregates.as_ref() {
33621 for (i, agg) in t.expressions.iter().enumerate() {
33622 if i > 0 {
33623 self.write(", ");
33624 }
33625 self.generate_expression(agg)?;
33626 }
33627 } else {
33628 self.generate_expression(aggregates)?;
33629 }
33630 }
33631 }
33632 Ok(())
33633 }
33634
33635 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
33636 self.generate_expression(&e.this)?;
33638 if e.delete.is_some() {
33639 self.write_keyword(" DELETE");
33640 }
33641 if let Some(recompress) = &e.recompress {
33642 self.write_keyword(" RECOMPRESS ");
33643 self.generate_expression(recompress)?;
33644 }
33645 if let Some(to_disk) = &e.to_disk {
33646 self.write_keyword(" TO DISK ");
33647 self.generate_expression(to_disk)?;
33648 }
33649 if let Some(to_volume) = &e.to_volume {
33650 self.write_keyword(" TO VOLUME ");
33651 self.generate_expression(to_volume)?;
33652 }
33653 Ok(())
33654 }
33655
33656 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
33657 self.write_keyword("MINHASH");
33659 self.write("(");
33660 self.generate_expression(&e.this)?;
33661 for expr in &e.expressions {
33662 self.write(", ");
33663 self.generate_expression(expr)?;
33664 }
33665 self.write(")");
33666 Ok(())
33667 }
33668
33669 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
33670 self.generate_expression(&e.this)?;
33672 self.write("!");
33673 self.generate_expression(&e.expression)?;
33674 Ok(())
33675 }
33676
33677 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
33678 self.write_keyword("MONTHNAME");
33680 self.write("(");
33681 self.generate_expression(&e.this)?;
33682 self.write(")");
33683 Ok(())
33684 }
33685
33686 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
33687 for comment in &e.leading_comments {
33689 self.write_formatted_comment(comment);
33690 if self.config.pretty {
33691 self.write_newline();
33692 self.write_indent();
33693 } else {
33694 self.write_space();
33695 }
33696 }
33697 self.write_keyword("INSERT");
33699 if e.overwrite {
33700 self.write_space();
33701 self.write_keyword("OVERWRITE");
33702 }
33703 self.write_space();
33704 self.write(&e.kind);
33705 if self.config.pretty {
33706 self.indent_level += 1;
33707 for expr in &e.expressions {
33708 self.write_newline();
33709 self.write_indent();
33710 self.generate_expression(expr)?;
33711 }
33712 self.indent_level -= 1;
33713 } else {
33714 for expr in &e.expressions {
33715 self.write_space();
33716 self.generate_expression(expr)?;
33717 }
33718 }
33719 if let Some(source) = &e.source {
33720 if self.config.pretty {
33721 self.write_newline();
33722 self.write_indent();
33723 } else {
33724 self.write_space();
33725 }
33726 self.generate_expression(source)?;
33727 }
33728 Ok(())
33729 }
33730
33731 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
33732 self.write_keyword("NEXT VALUE FOR");
33734 self.write_space();
33735 self.generate_expression(&e.this)?;
33736 if let Some(order) = &e.order {
33737 self.write_space();
33738 self.write_keyword("OVER");
33739 self.write(" (");
33740 self.generate_expression(order)?;
33741 self.write(")");
33742 }
33743 Ok(())
33744 }
33745
33746 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
33747 self.write_keyword("NORMAL");
33749 self.write("(");
33750 self.generate_expression(&e.this)?;
33751 if let Some(stddev) = &e.stddev {
33752 self.write(", ");
33753 self.generate_expression(stddev)?;
33754 }
33755 if let Some(gen) = &e.gen {
33756 self.write(", ");
33757 self.generate_expression(gen)?;
33758 }
33759 self.write(")");
33760 Ok(())
33761 }
33762
33763 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
33764 if e.is_casefold.is_some() {
33766 self.write_keyword("NORMALIZE_AND_CASEFOLD");
33767 } else {
33768 self.write_keyword("NORMALIZE");
33769 }
33770 self.write("(");
33771 self.generate_expression(&e.this)?;
33772 if let Some(form) = &e.form {
33773 self.write(", ");
33774 self.generate_expression(form)?;
33775 }
33776 self.write(")");
33777 Ok(())
33778 }
33779
33780 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
33781 if e.allow_null.is_none() {
33783 self.write_keyword("NOT ");
33784 }
33785 self.write_keyword("NULL");
33786 Ok(())
33787 }
33788
33789 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
33790 self.write_keyword("NULLIF");
33792 self.write("(");
33793 self.generate_expression(&e.this)?;
33794 self.write(", ");
33795 self.generate_expression(&e.expression)?;
33796 self.write(")");
33797 Ok(())
33798 }
33799
33800 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
33801 self.write_keyword("FORMAT");
33803 self.write("(");
33804 self.generate_expression(&e.this)?;
33805 self.write(", '");
33806 self.write(&e.format);
33807 self.write("'");
33808 if let Some(culture) = &e.culture {
33809 self.write(", ");
33810 self.generate_expression(culture)?;
33811 }
33812 self.write(")");
33813 Ok(())
33814 }
33815
33816 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
33817 self.write_keyword("OBJECT_AGG");
33819 self.write("(");
33820 self.generate_expression(&e.this)?;
33821 self.write(", ");
33822 self.generate_expression(&e.expression)?;
33823 self.write(")");
33824 Ok(())
33825 }
33826
33827 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
33828 self.generate_expression(&e.this)?;
33830 Ok(())
33831 }
33832
33833 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
33834 self.write_keyword("OBJECT_INSERT");
33836 self.write("(");
33837 self.generate_expression(&e.this)?;
33838 if let Some(key) = &e.key {
33839 self.write(", ");
33840 self.generate_expression(key)?;
33841 }
33842 if let Some(value) = &e.value {
33843 self.write(", ");
33844 self.generate_expression(value)?;
33845 }
33846 if let Some(update_flag) = &e.update_flag {
33847 self.write(", ");
33848 self.generate_expression(update_flag)?;
33849 }
33850 self.write(")");
33851 Ok(())
33852 }
33853
33854 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
33855 self.write_keyword("OFFSET");
33857 self.write_space();
33858 self.generate_expression(&e.this)?;
33859 if e.rows == Some(true)
33861 && matches!(
33862 self.config.dialect,
33863 Some(crate::dialects::DialectType::TSQL)
33864 | Some(crate::dialects::DialectType::Oracle)
33865 )
33866 {
33867 self.write_space();
33868 self.write_keyword("ROWS");
33869 }
33870 Ok(())
33871 }
33872
33873 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
33874 self.write_keyword("QUALIFY");
33876 self.write_space();
33877 self.generate_expression(&e.this)?;
33878 Ok(())
33879 }
33880
33881 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
33882 self.write_keyword("ON CLUSTER");
33884 self.write_space();
33885 self.generate_expression(&e.this)?;
33886 Ok(())
33887 }
33888
33889 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
33890 self.write_keyword("ON COMMIT");
33892 if e.delete.is_some() {
33893 self.write_keyword(" DELETE ROWS");
33894 } else {
33895 self.write_keyword(" PRESERVE ROWS");
33896 }
33897 Ok(())
33898 }
33899
33900 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
33901 if let Some(empty) = &e.empty {
33903 self.generate_expression(empty)?;
33904 self.write_keyword(" ON EMPTY");
33905 }
33906 if let Some(error) = &e.error {
33907 if e.empty.is_some() {
33908 self.write_space();
33909 }
33910 self.generate_expression(error)?;
33911 self.write_keyword(" ON ERROR");
33912 }
33913 if let Some(null) = &e.null {
33914 if e.empty.is_some() || e.error.is_some() {
33915 self.write_space();
33916 }
33917 self.generate_expression(null)?;
33918 self.write_keyword(" ON NULL");
33919 }
33920 Ok(())
33921 }
33922
33923 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
33924 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
33926 return Ok(());
33927 }
33928 if e.duplicate.is_some() {
33930 self.write_keyword("ON DUPLICATE KEY UPDATE");
33932 for (i, expr) in e.expressions.iter().enumerate() {
33933 if i > 0 {
33934 self.write(",");
33935 }
33936 self.write_space();
33937 self.generate_expression(expr)?;
33938 }
33939 return Ok(());
33940 } else {
33941 self.write_keyword("ON CONFLICT");
33942 }
33943 if let Some(constraint) = &e.constraint {
33944 self.write_keyword(" ON CONSTRAINT ");
33945 self.generate_expression(constraint)?;
33946 }
33947 if let Some(conflict_keys) = &e.conflict_keys {
33948 if let Expression::Tuple(t) = conflict_keys.as_ref() {
33950 self.write("(");
33951 for (i, expr) in t.expressions.iter().enumerate() {
33952 if i > 0 {
33953 self.write(", ");
33954 }
33955 self.generate_expression(expr)?;
33956 }
33957 self.write(")");
33958 } else {
33959 self.write("(");
33960 self.generate_expression(conflict_keys)?;
33961 self.write(")");
33962 }
33963 }
33964 if let Some(index_predicate) = &e.index_predicate {
33965 self.write_keyword(" WHERE ");
33966 self.generate_expression(index_predicate)?;
33967 }
33968 if let Some(action) = &e.action {
33969 if let Expression::Identifier(id) = action.as_ref() {
33971 if id.name.eq_ignore_ascii_case("NOTHING") {
33972 self.write_keyword(" DO NOTHING");
33973 } else {
33974 self.write_keyword(" DO ");
33975 self.generate_expression(action)?;
33976 }
33977 } else if let Expression::Tuple(t) = action.as_ref() {
33978 self.write_keyword(" DO UPDATE SET ");
33980 for (i, expr) in t.expressions.iter().enumerate() {
33981 if i > 0 {
33982 self.write(", ");
33983 }
33984 self.generate_expression(expr)?;
33985 }
33986 } else {
33987 self.write_keyword(" DO ");
33988 self.generate_expression(action)?;
33989 }
33990 }
33991 if let Some(where_) = &e.where_ {
33993 self.write_keyword(" WHERE ");
33994 self.generate_expression(where_)?;
33995 }
33996 Ok(())
33997 }
33998
33999 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
34000 self.write_keyword("ON");
34002 self.write_space();
34003 self.generate_expression(&e.this)?;
34004 Ok(())
34005 }
34006
34007 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
34008 self.generate_expression(&e.this)?;
34010 self.write_space();
34011 self.generate_expression(&e.expression)?;
34012 Ok(())
34013 }
34014
34015 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
34016 self.write_keyword("OPENJSON");
34018 self.write("(");
34019 self.generate_expression(&e.this)?;
34020 if let Some(path) = &e.path {
34021 self.write(", ");
34022 self.generate_expression(path)?;
34023 }
34024 self.write(")");
34025 if !e.expressions.is_empty() {
34026 self.write_keyword(" WITH");
34027 if self.config.pretty {
34028 self.write(" (\n");
34029 self.indent_level += 2;
34030 for (i, expr) in e.expressions.iter().enumerate() {
34031 if i > 0 {
34032 self.write(",\n");
34033 }
34034 self.write_indent();
34035 self.generate_expression(expr)?;
34036 }
34037 self.write("\n");
34038 self.indent_level -= 2;
34039 self.write(")");
34040 } else {
34041 self.write(" (");
34042 for (i, expr) in e.expressions.iter().enumerate() {
34043 if i > 0 {
34044 self.write(", ");
34045 }
34046 self.generate_expression(expr)?;
34047 }
34048 self.write(")");
34049 }
34050 }
34051 Ok(())
34052 }
34053
34054 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
34055 self.generate_expression(&e.this)?;
34057 self.write_space();
34058 if let Some(ref dt) = e.data_type {
34060 self.generate_data_type(dt)?;
34061 } else if !e.kind.is_empty() {
34062 self.write(&e.kind);
34063 }
34064 if let Some(path) = &e.path {
34065 self.write_space();
34066 self.generate_expression(path)?;
34067 }
34068 if e.as_json.is_some() {
34069 self.write_keyword(" AS JSON");
34070 }
34071 Ok(())
34072 }
34073
34074 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
34075 self.generate_expression(&e.this)?;
34077 self.write_space();
34078 if let Some(op) = &e.operator {
34079 self.write_keyword("OPERATOR");
34080 self.write("(");
34081 self.generate_expression(op)?;
34082 self.write(")");
34083 }
34084 for comment in &e.comments {
34086 self.write_space();
34087 self.write_formatted_comment(comment);
34088 }
34089 self.write_space();
34090 self.generate_expression(&e.expression)?;
34091 Ok(())
34092 }
34093
34094 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
34095 self.write_keyword("ORDER BY");
34097 let pretty_clickhouse_single_paren = self.config.pretty
34098 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
34099 && e.expressions.len() == 1
34100 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
34101 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
34102 && e.expressions.len() == 1
34103 && matches!(e.expressions[0].this, Expression::Tuple(_))
34104 && !e.expressions[0].desc
34105 && e.expressions[0].nulls_first.is_none();
34106
34107 if pretty_clickhouse_single_paren {
34108 self.write_space();
34109 if let Expression::Paren(p) = &e.expressions[0].this {
34110 self.write("(");
34111 self.write_newline();
34112 self.indent_level += 1;
34113 self.write_indent();
34114 self.generate_expression(&p.this)?;
34115 self.indent_level -= 1;
34116 self.write_newline();
34117 self.write(")");
34118 }
34119 return Ok(());
34120 }
34121
34122 if clickhouse_single_tuple {
34123 self.write_space();
34124 if let Expression::Tuple(t) = &e.expressions[0].this {
34125 self.write("(");
34126 for (i, expr) in t.expressions.iter().enumerate() {
34127 if i > 0 {
34128 self.write(", ");
34129 }
34130 self.generate_expression(expr)?;
34131 }
34132 self.write(")");
34133 }
34134 return Ok(());
34135 }
34136
34137 self.write_space();
34138 for (i, ordered) in e.expressions.iter().enumerate() {
34139 if i > 0 {
34140 self.write(", ");
34141 }
34142 self.generate_expression(&ordered.this)?;
34143 if ordered.desc {
34144 self.write_space();
34145 self.write_keyword("DESC");
34146 } else if ordered.explicit_asc {
34147 self.write_space();
34148 self.write_keyword("ASC");
34149 }
34150 if let Some(nulls_first) = ordered.nulls_first {
34151 let skip_nulls_last =
34153 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
34154 if !skip_nulls_last {
34155 self.write_space();
34156 self.write_keyword("NULLS");
34157 self.write_space();
34158 if nulls_first {
34159 self.write_keyword("FIRST");
34160 } else {
34161 self.write_keyword("LAST");
34162 }
34163 }
34164 }
34165 }
34166 Ok(())
34167 }
34168
34169 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
34170 self.write_keyword("OUTPUT");
34172 self.write("(");
34173 if self.config.pretty {
34174 self.indent_level += 1;
34175 self.write_newline();
34176 self.write_indent();
34177 self.generate_expression(&e.this)?;
34178 self.indent_level -= 1;
34179 self.write_newline();
34180 } else {
34181 self.generate_expression(&e.this)?;
34182 }
34183 self.write(")");
34184 Ok(())
34185 }
34186
34187 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
34188 self.write_keyword("TRUNCATE");
34190 if let Some(this) = &e.this {
34191 self.write_space();
34192 self.generate_expression(this)?;
34193 }
34194 if e.with_count.is_some() {
34195 self.write_keyword(" WITH COUNT");
34196 } else {
34197 self.write_keyword(" WITHOUT COUNT");
34198 }
34199 Ok(())
34200 }
34201
34202 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
34203 self.generate_expression(&e.this)?;
34205 self.write("(");
34206 for (i, expr) in e.expressions.iter().enumerate() {
34207 if i > 0 {
34208 self.write(", ");
34209 }
34210 self.generate_expression(expr)?;
34211 }
34212 self.write(")(");
34213 for (i, param) in e.params.iter().enumerate() {
34214 if i > 0 {
34215 self.write(", ");
34216 }
34217 self.generate_expression(param)?;
34218 }
34219 self.write(")");
34220 Ok(())
34221 }
34222
34223 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
34224 self.write_keyword("PARSE_DATETIME");
34226 self.write("(");
34227 if let Some(format) = &e.format {
34228 self.write("'");
34229 self.write(format);
34230 self.write("', ");
34231 }
34232 self.generate_expression(&e.this)?;
34233 if let Some(zone) = &e.zone {
34234 self.write(", ");
34235 self.generate_expression(zone)?;
34236 }
34237 self.write(")");
34238 Ok(())
34239 }
34240
34241 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
34242 self.write_keyword("PARSE_IP");
34244 self.write("(");
34245 self.generate_expression(&e.this)?;
34246 if let Some(type_) = &e.type_ {
34247 self.write(", ");
34248 self.generate_expression(type_)?;
34249 }
34250 if let Some(permissive) = &e.permissive {
34251 self.write(", ");
34252 self.generate_expression(permissive)?;
34253 }
34254 self.write(")");
34255 Ok(())
34256 }
34257
34258 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
34259 self.write_keyword("PARSE_JSON");
34261 self.write("(");
34262 self.generate_expression(&e.this)?;
34263 if let Some(expression) = &e.expression {
34264 self.write(", ");
34265 self.generate_expression(expression)?;
34266 }
34267 self.write(")");
34268 Ok(())
34269 }
34270
34271 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
34272 self.write_keyword("PARSE_TIME");
34274 self.write("(");
34275 self.write(&format!("'{}'", e.format));
34276 self.write(", ");
34277 self.generate_expression(&e.this)?;
34278 self.write(")");
34279 Ok(())
34280 }
34281
34282 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
34283 self.write_keyword("PARSE_URL");
34285 self.write("(");
34286 self.generate_expression(&e.this)?;
34287 if let Some(part) = &e.part_to_extract {
34288 self.write(", ");
34289 self.generate_expression(part)?;
34290 }
34291 if let Some(key) = &e.key {
34292 self.write(", ");
34293 self.generate_expression(key)?;
34294 }
34295 if let Some(permissive) = &e.permissive {
34296 self.write(", ");
34297 self.generate_expression(permissive)?;
34298 }
34299 self.write(")");
34300 Ok(())
34301 }
34302
34303 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
34304 if e.subpartition {
34306 self.write_keyword("SUBPARTITION");
34307 } else {
34308 self.write_keyword("PARTITION");
34309 }
34310 self.write("(");
34311 for (i, expr) in e.expressions.iter().enumerate() {
34312 if i > 0 {
34313 self.write(", ");
34314 }
34315 self.generate_expression(expr)?;
34316 }
34317 self.write(")");
34318 Ok(())
34319 }
34320
34321 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
34322 if let Some(this) = &e.this {
34324 if let Some(expression) = &e.expression {
34325 self.write_keyword("WITH");
34327 self.write(" (");
34328 self.write_keyword("MODULUS");
34329 self.write_space();
34330 self.generate_expression(this)?;
34331 self.write(", ");
34332 self.write_keyword("REMAINDER");
34333 self.write_space();
34334 self.generate_expression(expression)?;
34335 self.write(")");
34336 } else {
34337 self.write_keyword("IN");
34339 self.write(" (");
34340 self.generate_partition_bound_values(this)?;
34341 self.write(")");
34342 }
34343 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
34344 self.write_keyword("FROM");
34346 self.write(" (");
34347 self.generate_partition_bound_values(from)?;
34348 self.write(") ");
34349 self.write_keyword("TO");
34350 self.write(" (");
34351 self.generate_partition_bound_values(to)?;
34352 self.write(")");
34353 }
34354 Ok(())
34355 }
34356
34357 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
34360 if let Expression::Tuple(t) = expr {
34361 for (i, e) in t.expressions.iter().enumerate() {
34362 if i > 0 {
34363 self.write(", ");
34364 }
34365 self.generate_expression(e)?;
34366 }
34367 Ok(())
34368 } else {
34369 self.generate_expression(expr)
34370 }
34371 }
34372
34373 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
34374 self.write_keyword("PARTITION BY LIST");
34376 if let Some(partition_exprs) = &e.partition_expressions {
34377 self.write(" (");
34378 self.generate_doris_partition_expressions(partition_exprs)?;
34380 self.write(")");
34381 }
34382 if let Some(create_exprs) = &e.create_expressions {
34383 self.write(" (");
34384 self.generate_doris_partition_definitions(create_exprs)?;
34386 self.write(")");
34387 }
34388 Ok(())
34389 }
34390
34391 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
34392 self.write_keyword("PARTITION BY RANGE");
34394 if let Some(partition_exprs) = &e.partition_expressions {
34395 self.write(" (");
34396 self.generate_doris_partition_expressions(partition_exprs)?;
34398 self.write(")");
34399 }
34400 if let Some(create_exprs) = &e.create_expressions {
34401 self.write(" (");
34402 self.generate_doris_partition_definitions(create_exprs)?;
34404 self.write(")");
34405 }
34406 Ok(())
34407 }
34408
34409 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
34411 if let Expression::Tuple(t) = expr {
34412 for (i, e) in t.expressions.iter().enumerate() {
34413 if i > 0 {
34414 self.write(", ");
34415 }
34416 self.generate_expression(e)?;
34417 }
34418 } else {
34419 self.generate_expression(expr)?;
34420 }
34421 Ok(())
34422 }
34423
34424 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
34426 match expr {
34427 Expression::Tuple(t) => {
34428 for (i, part) in t.expressions.iter().enumerate() {
34430 if i > 0 {
34431 self.write(", ");
34432 }
34433 if let Expression::Partition(p) = part {
34435 for (j, inner) in p.expressions.iter().enumerate() {
34436 if j > 0 {
34437 self.write(", ");
34438 }
34439 self.generate_expression(inner)?;
34440 }
34441 } else {
34442 self.generate_expression(part)?;
34443 }
34444 }
34445 }
34446 Expression::PartitionByRangePropertyDynamic(_) => {
34447 self.generate_expression(expr)?;
34449 }
34450 _ => {
34451 self.generate_expression(expr)?;
34452 }
34453 }
34454 Ok(())
34455 }
34456
34457 fn generate_partition_by_range_property_dynamic(
34458 &mut self,
34459 e: &PartitionByRangePropertyDynamic,
34460 ) -> Result<()> {
34461 if e.use_start_end {
34462 if let Some(start) = &e.start {
34464 self.write_keyword("START");
34465 self.write(" (");
34466 self.generate_expression(start)?;
34467 self.write(")");
34468 }
34469 if let Some(end) = &e.end {
34470 self.write_space();
34471 self.write_keyword("END");
34472 self.write(" (");
34473 self.generate_expression(end)?;
34474 self.write(")");
34475 }
34476 if let Some(every) = &e.every {
34477 self.write_space();
34478 self.write_keyword("EVERY");
34479 self.write(" (");
34480 self.generate_doris_interval(every)?;
34482 self.write(")");
34483 }
34484 } else {
34485 if let Some(start) = &e.start {
34487 self.write_keyword("FROM");
34488 self.write(" (");
34489 self.generate_expression(start)?;
34490 self.write(")");
34491 }
34492 if let Some(end) = &e.end {
34493 self.write_space();
34494 self.write_keyword("TO");
34495 self.write(" (");
34496 self.generate_expression(end)?;
34497 self.write(")");
34498 }
34499 if let Some(every) = &e.every {
34500 self.write_space();
34501 self.generate_doris_interval(every)?;
34503 }
34504 }
34505 Ok(())
34506 }
34507
34508 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
34510 if let Expression::Interval(interval) = expr {
34511 self.write_keyword("INTERVAL");
34512 if let Some(ref value) = interval.this {
34513 self.write_space();
34514 match value {
34518 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()) => {
34519 if let Literal::String(s) = lit.as_ref() {
34520 self.write(s);
34521 }
34522 }
34523 _ => {
34524 self.generate_expression(value)?;
34525 }
34526 }
34527 }
34528 if let Some(ref unit_spec) = interval.unit {
34529 self.write_space();
34530 self.write_interval_unit_spec(unit_spec)?;
34531 }
34532 Ok(())
34533 } else {
34534 self.generate_expression(expr)
34535 }
34536 }
34537
34538 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
34539 self.write_keyword("TRUNCATE");
34541 self.write("(");
34542 self.generate_expression(&e.expression)?;
34543 self.write(", ");
34544 self.generate_expression(&e.this)?;
34545 self.write(")");
34546 Ok(())
34547 }
34548
34549 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
34550 self.write_keyword("PARTITION");
34552 self.write_space();
34553 self.generate_expression(&e.this)?;
34554 self.write_space();
34555 self.write_keyword("VALUES IN");
34556 self.write(" (");
34557 for (i, expr) in e.expressions.iter().enumerate() {
34558 if i > 0 {
34559 self.write(", ");
34560 }
34561 self.generate_expression(expr)?;
34562 }
34563 self.write(")");
34564 Ok(())
34565 }
34566
34567 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
34568 if e.expressions.is_empty() && e.expression.is_some() {
34571 self.generate_expression(&e.this)?;
34573 self.write_space();
34574 self.write_keyword("TO");
34575 self.write_space();
34576 self.generate_expression(e.expression.as_ref().unwrap())?;
34577 return Ok(());
34578 }
34579
34580 self.write_keyword("PARTITION");
34582 self.write_space();
34583 self.generate_expression(&e.this)?;
34584 self.write_space();
34585
34586 if e.expressions.len() == 1 {
34588 self.write_keyword("VALUES LESS THAN");
34590 self.write(" (");
34591 self.generate_expression(&e.expressions[0])?;
34592 self.write(")");
34593 } else if !e.expressions.is_empty() {
34594 self.write_keyword("VALUES");
34596 self.write(" [");
34597 for (i, expr) in e.expressions.iter().enumerate() {
34598 if i > 0 {
34599 self.write(", ");
34600 }
34601 if let Expression::Tuple(t) = expr {
34603 self.write("(");
34604 for (j, inner) in t.expressions.iter().enumerate() {
34605 if j > 0 {
34606 self.write(", ");
34607 }
34608 self.generate_expression(inner)?;
34609 }
34610 self.write(")");
34611 } else {
34612 self.write("(");
34613 self.generate_expression(expr)?;
34614 self.write(")");
34615 }
34616 }
34617 self.write(")");
34618 }
34619 Ok(())
34620 }
34621
34622 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
34623 self.write_keyword("BUCKET");
34625 self.write("(");
34626 self.generate_expression(&e.this)?;
34627 self.write(", ");
34628 self.generate_expression(&e.expression)?;
34629 self.write(")");
34630 Ok(())
34631 }
34632
34633 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
34634 self.write_keyword("PARTITION BY");
34636 self.write_space();
34637 for (i, expr) in e.expressions.iter().enumerate() {
34638 if i > 0 {
34639 self.write(", ");
34640 }
34641 self.generate_expression(expr)?;
34642 }
34643 Ok(())
34644 }
34645
34646 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
34647 if matches!(
34649 self.config.dialect,
34650 Some(crate::dialects::DialectType::Teradata)
34651 | Some(crate::dialects::DialectType::ClickHouse)
34652 ) {
34653 self.write_keyword("PARTITION BY");
34654 } else {
34655 self.write_keyword("PARTITIONED BY");
34656 }
34657 self.write_space();
34658 if self.config.pretty {
34660 if let Expression::Tuple(ref tuple) = *e.this {
34661 self.write("(");
34662 self.write_newline();
34663 self.indent_level += 1;
34664 for (i, expr) in tuple.expressions.iter().enumerate() {
34665 if i > 0 {
34666 self.write(",");
34667 self.write_newline();
34668 }
34669 self.write_indent();
34670 self.generate_expression(expr)?;
34671 }
34672 self.indent_level -= 1;
34673 self.write_newline();
34674 self.write(")");
34675 } else {
34676 self.generate_expression(&e.this)?;
34677 }
34678 } else {
34679 self.generate_expression(&e.this)?;
34680 }
34681 Ok(())
34682 }
34683
34684 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
34685 self.write_keyword("PARTITION OF");
34687 self.write_space();
34688 self.generate_expression(&e.this)?;
34689 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
34691 self.write_space();
34692 self.write_keyword("FOR VALUES");
34693 self.write_space();
34694 self.generate_expression(&e.expression)?;
34695 } else {
34696 self.write_space();
34697 self.write_keyword("DEFAULT");
34698 }
34699 Ok(())
34700 }
34701
34702 fn generate_period_for_system_time_constraint(
34703 &mut self,
34704 e: &PeriodForSystemTimeConstraint,
34705 ) -> Result<()> {
34706 self.write_keyword("PERIOD FOR SYSTEM_TIME");
34708 self.write(" (");
34709 self.generate_expression(&e.this)?;
34710 self.write(", ");
34711 self.generate_expression(&e.expression)?;
34712 self.write(")");
34713 Ok(())
34714 }
34715
34716 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
34717 self.generate_expression(&e.this)?;
34720 self.write_space();
34721 self.write_keyword("AS");
34722 self.write_space();
34723 if self.config.unpivot_aliases_are_identifiers {
34725 match &e.alias {
34726 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
34727 let Literal::String(s) = lit.as_ref() else {
34728 unreachable!()
34729 };
34730 self.generate_identifier(&Identifier::new(s.clone()))?;
34732 }
34733 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
34734 let Literal::Number(n) = lit.as_ref() else {
34735 unreachable!()
34736 };
34737 let mut id = Identifier::new(n.clone());
34739 id.quoted = true;
34740 self.generate_identifier(&id)?;
34741 }
34742 other => {
34743 self.generate_expression(other)?;
34744 }
34745 }
34746 } else {
34747 self.generate_expression(&e.alias)?;
34748 }
34749 Ok(())
34750 }
34751
34752 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
34753 self.write_keyword("ANY");
34755 if let Some(this) = &e.this {
34756 self.write_space();
34757 self.generate_expression(this)?;
34758 }
34759 Ok(())
34760 }
34761
34762 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
34763 self.write_keyword("ML.PREDICT");
34765 self.write("(");
34766 self.write_keyword("MODEL");
34767 self.write_space();
34768 self.generate_expression(&e.this)?;
34769 self.write(", ");
34770 self.generate_expression(&e.expression)?;
34771 if let Some(params) = &e.params_struct {
34772 self.write(", ");
34773 self.generate_expression(params)?;
34774 }
34775 self.write(")");
34776 Ok(())
34777 }
34778
34779 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
34780 self.write_keyword("PREVIOUS_DAY");
34782 self.write("(");
34783 self.generate_expression(&e.this)?;
34784 self.write(", ");
34785 self.generate_expression(&e.expression)?;
34786 self.write(")");
34787 Ok(())
34788 }
34789
34790 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
34791 self.write_keyword("PRIMARY KEY");
34793 if let Some(name) = &e.this {
34794 self.write_space();
34795 self.generate_expression(name)?;
34796 }
34797 if !e.expressions.is_empty() {
34798 self.write(" (");
34799 for (i, expr) in e.expressions.iter().enumerate() {
34800 if i > 0 {
34801 self.write(", ");
34802 }
34803 self.generate_expression(expr)?;
34804 }
34805 self.write(")");
34806 }
34807 if let Some(include) = &e.include {
34808 self.write_space();
34809 self.generate_expression(include)?;
34810 }
34811 if !e.options.is_empty() {
34812 self.write_space();
34813 for (i, opt) in e.options.iter().enumerate() {
34814 if i > 0 {
34815 self.write_space();
34816 }
34817 self.generate_expression(opt)?;
34818 }
34819 }
34820 Ok(())
34821 }
34822
34823 fn generate_primary_key_column_constraint(
34824 &mut self,
34825 _e: &PrimaryKeyColumnConstraint,
34826 ) -> Result<()> {
34827 self.write_keyword("PRIMARY KEY");
34829 Ok(())
34830 }
34831
34832 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
34833 self.write_keyword("PATH");
34835 self.write_space();
34836 self.generate_expression(&e.this)?;
34837 Ok(())
34838 }
34839
34840 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
34841 self.write_keyword("PROJECTION");
34843 self.write_space();
34844 self.generate_expression(&e.this)?;
34845 self.write(" (");
34846 self.generate_expression(&e.expression)?;
34847 self.write(")");
34848 Ok(())
34849 }
34850
34851 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
34852 for (i, prop) in e.expressions.iter().enumerate() {
34854 if i > 0 {
34855 self.write(", ");
34856 }
34857 self.generate_expression(prop)?;
34858 }
34859 Ok(())
34860 }
34861
34862 fn generate_property(&mut self, e: &Property) -> Result<()> {
34863 self.generate_expression(&e.this)?;
34865 if let Some(value) = &e.value {
34866 self.write("=");
34867 self.generate_expression(value)?;
34868 }
34869 Ok(())
34870 }
34871
34872 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
34873 self.write_keyword("OPTIONS");
34874 if e.entries.is_empty() {
34875 self.write(" ()");
34876 return Ok(());
34877 }
34878
34879 if self.config.pretty {
34880 self.write(" (");
34881 self.write_newline();
34882 self.indent_level += 1;
34883 for (i, entry) in e.entries.iter().enumerate() {
34884 if i > 0 {
34885 self.write(",");
34886 self.write_newline();
34887 }
34888 self.write_indent();
34889 self.generate_identifier(&entry.key)?;
34890 self.write("=");
34891 self.generate_expression(&entry.value)?;
34892 }
34893 self.indent_level -= 1;
34894 self.write_newline();
34895 self.write(")");
34896 } else {
34897 self.write(" (");
34898 for (i, entry) in e.entries.iter().enumerate() {
34899 if i > 0 {
34900 self.write(", ");
34901 }
34902 self.generate_identifier(&entry.key)?;
34903 self.write("=");
34904 self.generate_expression(&entry.value)?;
34905 }
34906 self.write(")");
34907 }
34908 Ok(())
34909 }
34910
34911 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
34913 self.write_keyword("OPTIONS");
34914 self.write(" (");
34915 for (i, opt) in options.iter().enumerate() {
34916 if i > 0 {
34917 self.write(", ");
34918 }
34919 self.generate_option_expression(opt)?;
34920 }
34921 self.write(")");
34922 Ok(())
34923 }
34924
34925 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
34927 self.write_keyword("PROPERTIES");
34928 self.write(" (");
34929 for (i, prop) in properties.iter().enumerate() {
34930 if i > 0 {
34931 self.write(", ");
34932 }
34933 self.generate_option_expression(prop)?;
34934 }
34935 self.write(")");
34936 Ok(())
34937 }
34938
34939 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
34941 self.write_keyword("ENVIRONMENT");
34942 self.write(" (");
34943 for (i, env_item) in environment.iter().enumerate() {
34944 if i > 0 {
34945 self.write(", ");
34946 }
34947 self.generate_environment_expression(env_item)?;
34948 }
34949 self.write(")");
34950 Ok(())
34951 }
34952
34953 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
34955 match expr {
34956 Expression::Eq(eq) => {
34957 self.generate_expression(&eq.left)?;
34959 self.write(" = ");
34960 self.generate_expression(&eq.right)?;
34961 Ok(())
34962 }
34963 _ => self.generate_expression(expr),
34964 }
34965 }
34966
34967 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
34969 self.write_keyword("TBLPROPERTIES");
34970 if self.config.pretty {
34971 self.write(" (");
34972 self.write_newline();
34973 self.indent_level += 1;
34974 for (i, opt) in options.iter().enumerate() {
34975 if i > 0 {
34976 self.write(",");
34977 self.write_newline();
34978 }
34979 self.write_indent();
34980 self.generate_option_expression(opt)?;
34981 }
34982 self.indent_level -= 1;
34983 self.write_newline();
34984 self.write(")");
34985 } else {
34986 self.write(" (");
34987 for (i, opt) in options.iter().enumerate() {
34988 if i > 0 {
34989 self.write(", ");
34990 }
34991 self.generate_option_expression(opt)?;
34992 }
34993 self.write(")");
34994 }
34995 Ok(())
34996 }
34997
34998 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
35000 match expr {
35001 Expression::Eq(eq) => {
35002 self.generate_expression(&eq.left)?;
35004 self.write("=");
35005 self.generate_expression(&eq.right)?;
35006 Ok(())
35007 }
35008 _ => self.generate_expression(expr),
35009 }
35010 }
35011
35012 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
35013 self.generate_expression(&e.this)?;
35015 Ok(())
35016 }
35017
35018 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
35019 self.write_keyword("PUT");
35021 self.write_space();
35022
35023 if e.source_quoted {
35025 self.write("'");
35026 self.write(&e.source);
35027 self.write("'");
35028 } else {
35029 self.write(&e.source);
35030 }
35031
35032 self.write_space();
35033
35034 if let Expression::Literal(lit) = &e.target {
35036 if let Literal::String(s) = lit.as_ref() {
35037 self.write(s);
35038 }
35039 } else {
35040 self.generate_expression(&e.target)?;
35041 }
35042
35043 for param in &e.params {
35045 self.write_space();
35046 self.write(¶m.name);
35047 if let Some(ref value) = param.value {
35048 self.write("=");
35049 self.generate_expression(value)?;
35050 }
35051 }
35052
35053 Ok(())
35054 }
35055
35056 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
35057 self.write_keyword("QUANTILE");
35059 self.write("(");
35060 self.generate_expression(&e.this)?;
35061 if let Some(quantile) = &e.quantile {
35062 self.write(", ");
35063 self.generate_expression(quantile)?;
35064 }
35065 self.write(")");
35066 Ok(())
35067 }
35068
35069 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
35070 if matches!(
35072 self.config.dialect,
35073 Some(crate::dialects::DialectType::Teradata)
35074 ) {
35075 self.write_keyword("SET");
35076 self.write_space();
35077 }
35078 self.write_keyword("QUERY_BAND");
35079 self.write(" = ");
35080 self.generate_expression(&e.this)?;
35081 if e.update.is_some() {
35082 self.write_space();
35083 self.write_keyword("UPDATE");
35084 }
35085 if let Some(scope) = &e.scope {
35086 self.write_space();
35087 self.write_keyword("FOR");
35088 self.write_space();
35089 self.generate_expression(scope)?;
35090 }
35091 Ok(())
35092 }
35093
35094 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
35095 self.generate_expression(&e.this)?;
35097 if let Some(expression) = &e.expression {
35098 self.write(" = ");
35099 self.generate_expression(expression)?;
35100 }
35101 Ok(())
35102 }
35103
35104 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
35105 self.write_keyword("TRANSFORM");
35107 self.write("(");
35108 for (i, expr) in e.expressions.iter().enumerate() {
35109 if i > 0 {
35110 self.write(", ");
35111 }
35112 self.generate_expression(expr)?;
35113 }
35114 self.write(")");
35115 if let Some(row_format_before) = &e.row_format_before {
35116 self.write_space();
35117 self.generate_expression(row_format_before)?;
35118 }
35119 if let Some(record_writer) = &e.record_writer {
35120 self.write_space();
35121 self.write_keyword("RECORDWRITER");
35122 self.write_space();
35123 self.generate_expression(record_writer)?;
35124 }
35125 if let Some(command_script) = &e.command_script {
35126 self.write_space();
35127 self.write_keyword("USING");
35128 self.write_space();
35129 self.generate_expression(command_script)?;
35130 }
35131 if let Some(schema) = &e.schema {
35132 self.write_space();
35133 self.write_keyword("AS");
35134 self.write_space();
35135 self.generate_expression(schema)?;
35136 }
35137 if let Some(row_format_after) = &e.row_format_after {
35138 self.write_space();
35139 self.generate_expression(row_format_after)?;
35140 }
35141 if let Some(record_reader) = &e.record_reader {
35142 self.write_space();
35143 self.write_keyword("RECORDREADER");
35144 self.write_space();
35145 self.generate_expression(record_reader)?;
35146 }
35147 Ok(())
35148 }
35149
35150 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
35151 self.write_keyword("RANDN");
35153 self.write("(");
35154 if let Some(this) = &e.this {
35155 self.generate_expression(this)?;
35156 }
35157 self.write(")");
35158 Ok(())
35159 }
35160
35161 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
35162 self.write_keyword("RANDSTR");
35164 self.write("(");
35165 self.generate_expression(&e.this)?;
35166 if let Some(generator) = &e.generator {
35167 self.write(", ");
35168 self.generate_expression(generator)?;
35169 }
35170 self.write(")");
35171 Ok(())
35172 }
35173
35174 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
35175 self.write_keyword("RANGE_BUCKET");
35177 self.write("(");
35178 self.generate_expression(&e.this)?;
35179 self.write(", ");
35180 self.generate_expression(&e.expression)?;
35181 self.write(")");
35182 Ok(())
35183 }
35184
35185 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
35186 self.write_keyword("RANGE_N");
35188 self.write("(");
35189 self.generate_expression(&e.this)?;
35190 self.write_space();
35191 self.write_keyword("BETWEEN");
35192 self.write_space();
35193 for (i, expr) in e.expressions.iter().enumerate() {
35194 if i > 0 {
35195 self.write(", ");
35196 }
35197 self.generate_expression(expr)?;
35198 }
35199 if let Some(each) = &e.each {
35200 self.write_space();
35201 self.write_keyword("EACH");
35202 self.write_space();
35203 self.generate_expression(each)?;
35204 }
35205 self.write(")");
35206 Ok(())
35207 }
35208
35209 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
35210 self.write_keyword("READ_CSV");
35212 self.write("(");
35213 self.generate_expression(&e.this)?;
35214 for expr in &e.expressions {
35215 self.write(", ");
35216 self.generate_expression(expr)?;
35217 }
35218 self.write(")");
35219 Ok(())
35220 }
35221
35222 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
35223 self.write_keyword("READ_PARQUET");
35225 self.write("(");
35226 for (i, expr) in e.expressions.iter().enumerate() {
35227 if i > 0 {
35228 self.write(", ");
35229 }
35230 self.generate_expression(expr)?;
35231 }
35232 self.write(")");
35233 Ok(())
35234 }
35235
35236 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
35237 if e.kind == "CYCLE" {
35240 self.write_keyword("CYCLE");
35241 } else {
35242 self.write_keyword("SEARCH");
35243 self.write_space();
35244 self.write(&e.kind);
35245 self.write_space();
35246 self.write_keyword("FIRST BY");
35247 }
35248 self.write_space();
35249 self.generate_expression(&e.this)?;
35250 self.write_space();
35251 self.write_keyword("SET");
35252 self.write_space();
35253 self.generate_expression(&e.expression)?;
35254 if let Some(using) = &e.using {
35255 self.write_space();
35256 self.write_keyword("USING");
35257 self.write_space();
35258 self.generate_expression(using)?;
35259 }
35260 Ok(())
35261 }
35262
35263 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
35264 self.write_keyword("REDUCE");
35266 self.write("(");
35267 self.generate_expression(&e.this)?;
35268 if let Some(initial) = &e.initial {
35269 self.write(", ");
35270 self.generate_expression(initial)?;
35271 }
35272 if let Some(merge) = &e.merge {
35273 self.write(", ");
35274 self.generate_expression(merge)?;
35275 }
35276 if let Some(finish) = &e.finish {
35277 self.write(", ");
35278 self.generate_expression(finish)?;
35279 }
35280 self.write(")");
35281 Ok(())
35282 }
35283
35284 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
35285 self.write_keyword("REFERENCES");
35287 self.write_space();
35288 self.generate_expression(&e.this)?;
35289 if !e.expressions.is_empty() {
35290 self.write(" (");
35291 for (i, expr) in e.expressions.iter().enumerate() {
35292 if i > 0 {
35293 self.write(", ");
35294 }
35295 self.generate_expression(expr)?;
35296 }
35297 self.write(")");
35298 }
35299 for opt in &e.options {
35300 self.write_space();
35301 self.generate_expression(opt)?;
35302 }
35303 Ok(())
35304 }
35305
35306 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
35307 self.write_keyword("REFRESH");
35309 if !e.kind.is_empty() {
35310 self.write_space();
35311 self.write_keyword(&e.kind);
35312 }
35313 self.write_space();
35314 self.generate_expression(&e.this)?;
35315 Ok(())
35316 }
35317
35318 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
35319 self.write_keyword("REFRESH");
35321 self.write_space();
35322 self.write_keyword(&e.method);
35323
35324 if let Some(ref kind) = e.kind {
35325 self.write_space();
35326 self.write_keyword("ON");
35327 self.write_space();
35328 self.write_keyword(kind);
35329
35330 if let Some(ref every) = e.every {
35332 self.write_space();
35333 self.write_keyword("EVERY");
35334 self.write_space();
35335 self.generate_expression(every)?;
35336 if let Some(ref unit) = e.unit {
35337 self.write_space();
35338 self.write_keyword(unit);
35339 }
35340 }
35341
35342 if let Some(ref starts) = e.starts {
35344 self.write_space();
35345 self.write_keyword("STARTS");
35346 self.write_space();
35347 self.generate_expression(starts)?;
35348 }
35349 }
35350 Ok(())
35351 }
35352
35353 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
35354 self.write_keyword("REGEXP_COUNT");
35356 self.write("(");
35357 self.generate_expression(&e.this)?;
35358 self.write(", ");
35359 self.generate_expression(&e.expression)?;
35360 if let Some(position) = &e.position {
35361 self.write(", ");
35362 self.generate_expression(position)?;
35363 }
35364 if let Some(parameters) = &e.parameters {
35365 self.write(", ");
35366 self.generate_expression(parameters)?;
35367 }
35368 self.write(")");
35369 Ok(())
35370 }
35371
35372 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
35373 self.write_keyword("REGEXP_EXTRACT_ALL");
35375 self.write("(");
35376 self.generate_expression(&e.this)?;
35377 self.write(", ");
35378 self.generate_expression(&e.expression)?;
35379 if let Some(group) = &e.group {
35380 self.write(", ");
35381 self.generate_expression(group)?;
35382 }
35383 self.write(")");
35384 Ok(())
35385 }
35386
35387 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
35388 self.write_keyword("REGEXP_FULL_MATCH");
35390 self.write("(");
35391 self.generate_expression(&e.this)?;
35392 self.write(", ");
35393 self.generate_expression(&e.expression)?;
35394 self.write(")");
35395 Ok(())
35396 }
35397
35398 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
35399 use crate::dialects::DialectType;
35400 if matches!(
35402 self.config.dialect,
35403 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
35404 ) && e.flag.is_none()
35405 {
35406 self.generate_expression(&e.this)?;
35407 self.write(" ~* ");
35408 self.generate_expression(&e.expression)?;
35409 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && e.flag.is_none() {
35410 self.write("match(");
35414 self.generate_expression(&e.this)?;
35415 self.write(", ");
35416 if let Expression::Literal(lit) = e.expression.as_ref() {
35417 if let Literal::String(s) = lit.as_ref() {
35418 let insensitive =
35419 Expression::Literal(Box::new(Literal::String(format!("(?i){s}"))));
35420 self.generate_expression(&insensitive)?;
35421 self.write(")");
35422 return Ok(());
35423 }
35424 }
35425 self.write("concat('(?i)', ");
35426 self.generate_expression(&e.expression)?;
35427 self.write("))");
35428 return Ok(());
35429 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35430 self.write_keyword("REGEXP_LIKE");
35432 self.write("(");
35433 self.generate_expression(&e.this)?;
35434 self.write(", ");
35435 self.generate_expression(&e.expression)?;
35436 self.write(", ");
35437 if let Some(flag) = &e.flag {
35438 self.generate_expression(flag)?;
35439 } else {
35440 self.write("'i'");
35441 }
35442 self.write(")");
35443 } else {
35444 self.generate_expression(&e.this)?;
35446 self.write_space();
35447 self.write_keyword("REGEXP_ILIKE");
35448 self.write_space();
35449 self.generate_expression(&e.expression)?;
35450 if let Some(flag) = &e.flag {
35451 self.write(", ");
35452 self.generate_expression(flag)?;
35453 }
35454 }
35455 Ok(())
35456 }
35457
35458 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
35459 self.write_keyword("REGEXP_INSTR");
35461 self.write("(");
35462 self.generate_expression(&e.this)?;
35463 self.write(", ");
35464 self.generate_expression(&e.expression)?;
35465 if let Some(position) = &e.position {
35466 self.write(", ");
35467 self.generate_expression(position)?;
35468 }
35469 if let Some(occurrence) = &e.occurrence {
35470 self.write(", ");
35471 self.generate_expression(occurrence)?;
35472 }
35473 if let Some(option) = &e.option {
35474 self.write(", ");
35475 self.generate_expression(option)?;
35476 }
35477 if let Some(parameters) = &e.parameters {
35478 self.write(", ");
35479 self.generate_expression(parameters)?;
35480 }
35481 if let Some(group) = &e.group {
35482 self.write(", ");
35483 self.generate_expression(group)?;
35484 }
35485 self.write(")");
35486 Ok(())
35487 }
35488
35489 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
35490 self.write_keyword("REGEXP_SPLIT");
35492 self.write("(");
35493 self.generate_expression(&e.this)?;
35494 self.write(", ");
35495 self.generate_expression(&e.expression)?;
35496 if let Some(limit) = &e.limit {
35497 self.write(", ");
35498 self.generate_expression(limit)?;
35499 }
35500 self.write(")");
35501 Ok(())
35502 }
35503
35504 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
35505 self.write_keyword("REGR_AVGX");
35507 self.write("(");
35508 self.generate_expression(&e.this)?;
35509 self.write(", ");
35510 self.generate_expression(&e.expression)?;
35511 self.write(")");
35512 Ok(())
35513 }
35514
35515 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
35516 self.write_keyword("REGR_AVGY");
35518 self.write("(");
35519 self.generate_expression(&e.this)?;
35520 self.write(", ");
35521 self.generate_expression(&e.expression)?;
35522 self.write(")");
35523 Ok(())
35524 }
35525
35526 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
35527 self.write_keyword("REGR_COUNT");
35529 self.write("(");
35530 self.generate_expression(&e.this)?;
35531 self.write(", ");
35532 self.generate_expression(&e.expression)?;
35533 self.write(")");
35534 Ok(())
35535 }
35536
35537 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
35538 self.write_keyword("REGR_INTERCEPT");
35540 self.write("(");
35541 self.generate_expression(&e.this)?;
35542 self.write(", ");
35543 self.generate_expression(&e.expression)?;
35544 self.write(")");
35545 Ok(())
35546 }
35547
35548 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
35549 self.write_keyword("REGR_R2");
35551 self.write("(");
35552 self.generate_expression(&e.this)?;
35553 self.write(", ");
35554 self.generate_expression(&e.expression)?;
35555 self.write(")");
35556 Ok(())
35557 }
35558
35559 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
35560 self.write_keyword("REGR_SLOPE");
35562 self.write("(");
35563 self.generate_expression(&e.this)?;
35564 self.write(", ");
35565 self.generate_expression(&e.expression)?;
35566 self.write(")");
35567 Ok(())
35568 }
35569
35570 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
35571 self.write_keyword("REGR_SXX");
35573 self.write("(");
35574 self.generate_expression(&e.this)?;
35575 self.write(", ");
35576 self.generate_expression(&e.expression)?;
35577 self.write(")");
35578 Ok(())
35579 }
35580
35581 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
35582 self.write_keyword("REGR_SXY");
35584 self.write("(");
35585 self.generate_expression(&e.this)?;
35586 self.write(", ");
35587 self.generate_expression(&e.expression)?;
35588 self.write(")");
35589 Ok(())
35590 }
35591
35592 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
35593 self.write_keyword("REGR_SYY");
35595 self.write("(");
35596 self.generate_expression(&e.this)?;
35597 self.write(", ");
35598 self.generate_expression(&e.expression)?;
35599 self.write(")");
35600 Ok(())
35601 }
35602
35603 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
35604 self.write_keyword("REGR_VALX");
35606 self.write("(");
35607 self.generate_expression(&e.this)?;
35608 self.write(", ");
35609 self.generate_expression(&e.expression)?;
35610 self.write(")");
35611 Ok(())
35612 }
35613
35614 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
35615 self.write_keyword("REGR_VALY");
35617 self.write("(");
35618 self.generate_expression(&e.this)?;
35619 self.write(", ");
35620 self.generate_expression(&e.expression)?;
35621 self.write(")");
35622 Ok(())
35623 }
35624
35625 fn generate_remote_with_connection_model_property(
35626 &mut self,
35627 e: &RemoteWithConnectionModelProperty,
35628 ) -> Result<()> {
35629 self.write_keyword("REMOTE WITH CONNECTION");
35631 self.write_space();
35632 self.generate_expression(&e.this)?;
35633 Ok(())
35634 }
35635
35636 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
35637 self.write_keyword("RENAME COLUMN");
35639 if e.exists {
35640 self.write_space();
35641 self.write_keyword("IF EXISTS");
35642 }
35643 self.write_space();
35644 self.generate_expression(&e.this)?;
35645 if let Some(to) = &e.to {
35646 self.write_space();
35647 self.write_keyword("TO");
35648 self.write_space();
35649 self.generate_expression(to)?;
35650 }
35651 Ok(())
35652 }
35653
35654 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
35655 self.write_keyword("REPLACE PARTITION");
35657 self.write_space();
35658 self.generate_expression(&e.expression)?;
35659 if let Some(source) = &e.source {
35660 self.write_space();
35661 self.write_keyword("FROM");
35662 self.write_space();
35663 self.generate_expression(source)?;
35664 }
35665 Ok(())
35666 }
35667
35668 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
35669 let keyword = match self.config.dialect {
35672 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
35673 _ => "RETURNING",
35674 };
35675 self.write_keyword(keyword);
35676 self.write_space();
35677 for (i, expr) in e.expressions.iter().enumerate() {
35678 if i > 0 {
35679 self.write(", ");
35680 }
35681 self.generate_expression(expr)?;
35682 }
35683 if let Some(into) = &e.into {
35684 self.write_space();
35685 self.write_keyword("INTO");
35686 self.write_space();
35687 self.generate_expression(into)?;
35688 }
35689 Ok(())
35690 }
35691
35692 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
35693 self.write_space();
35695 self.write_keyword("OUTPUT");
35696 self.write_space();
35697 for (i, expr) in output.columns.iter().enumerate() {
35698 if i > 0 {
35699 self.write(", ");
35700 }
35701 self.generate_expression(expr)?;
35702 }
35703 if let Some(into_table) = &output.into_table {
35704 self.write_space();
35705 self.write_keyword("INTO");
35706 self.write_space();
35707 self.generate_expression(into_table)?;
35708 }
35709 Ok(())
35710 }
35711
35712 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
35713 self.write_keyword("RETURNS");
35715 if e.is_table.is_some() {
35716 self.write_space();
35717 self.write_keyword("TABLE");
35718 }
35719 if let Some(table) = &e.table {
35720 self.write_space();
35721 self.generate_expression(table)?;
35722 } else if let Some(this) = &e.this {
35723 self.write_space();
35724 self.generate_expression(this)?;
35725 }
35726 if e.null.is_some() {
35727 self.write_space();
35728 self.write_keyword("NULL ON NULL INPUT");
35729 }
35730 Ok(())
35731 }
35732
35733 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
35734 self.write_keyword("ROLLBACK");
35736
35737 if e.this.is_none()
35739 && matches!(
35740 self.config.dialect,
35741 Some(DialectType::TSQL) | Some(DialectType::Fabric)
35742 )
35743 {
35744 self.write_space();
35745 self.write_keyword("TRANSACTION");
35746 }
35747
35748 if let Some(this) = &e.this {
35750 let is_transaction_marker = matches!(
35752 this.as_ref(),
35753 Expression::Identifier(id) if id.name == "TRANSACTION"
35754 );
35755
35756 self.write_space();
35757 self.write_keyword("TRANSACTION");
35758
35759 if !is_transaction_marker {
35761 self.write_space();
35762 self.generate_expression(this)?;
35763 }
35764 }
35765
35766 if let Some(savepoint) = &e.savepoint {
35768 self.write_space();
35769 self.write_keyword("TO");
35770 self.write_space();
35771 self.generate_expression(savepoint)?;
35772 }
35773 Ok(())
35774 }
35775
35776 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
35777 if e.expressions.is_empty() {
35779 self.write_keyword("WITH ROLLUP");
35780 } else {
35781 self.write_keyword("ROLLUP");
35782 self.write("(");
35783 for (i, expr) in e.expressions.iter().enumerate() {
35784 if i > 0 {
35785 self.write(", ");
35786 }
35787 self.generate_expression(expr)?;
35788 }
35789 self.write(")");
35790 }
35791 Ok(())
35792 }
35793
35794 fn generate_row_format_delimited_property(
35795 &mut self,
35796 e: &RowFormatDelimitedProperty,
35797 ) -> Result<()> {
35798 self.write_keyword("ROW FORMAT DELIMITED");
35800 if let Some(fields) = &e.fields {
35801 self.write_space();
35802 self.write_keyword("FIELDS TERMINATED BY");
35803 self.write_space();
35804 self.generate_expression(fields)?;
35805 }
35806 if let Some(escaped) = &e.escaped {
35807 self.write_space();
35808 self.write_keyword("ESCAPED BY");
35809 self.write_space();
35810 self.generate_expression(escaped)?;
35811 }
35812 if let Some(items) = &e.collection_items {
35813 self.write_space();
35814 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
35815 self.write_space();
35816 self.generate_expression(items)?;
35817 }
35818 if let Some(keys) = &e.map_keys {
35819 self.write_space();
35820 self.write_keyword("MAP KEYS TERMINATED BY");
35821 self.write_space();
35822 self.generate_expression(keys)?;
35823 }
35824 if let Some(lines) = &e.lines {
35825 self.write_space();
35826 self.write_keyword("LINES TERMINATED BY");
35827 self.write_space();
35828 self.generate_expression(lines)?;
35829 }
35830 if let Some(null) = &e.null {
35831 self.write_space();
35832 self.write_keyword("NULL DEFINED AS");
35833 self.write_space();
35834 self.generate_expression(null)?;
35835 }
35836 if let Some(serde) = &e.serde {
35837 self.write_space();
35838 self.generate_expression(serde)?;
35839 }
35840 Ok(())
35841 }
35842
35843 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
35844 self.write_keyword("ROW FORMAT");
35846 self.write_space();
35847 self.generate_expression(&e.this)?;
35848 Ok(())
35849 }
35850
35851 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
35852 self.write_keyword("ROW FORMAT SERDE");
35854 self.write_space();
35855 self.generate_expression(&e.this)?;
35856 if let Some(props) = &e.serde_properties {
35857 self.write_space();
35858 self.generate_expression(props)?;
35860 }
35861 Ok(())
35862 }
35863
35864 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
35865 self.write_keyword("SHA2");
35867 self.write("(");
35868 self.generate_expression(&e.this)?;
35869 if let Some(length) = e.length {
35870 self.write(", ");
35871 self.write(&length.to_string());
35872 }
35873 self.write(")");
35874 Ok(())
35875 }
35876
35877 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
35878 self.write_keyword("SHA2_DIGEST");
35880 self.write("(");
35881 self.generate_expression(&e.this)?;
35882 if let Some(length) = e.length {
35883 self.write(", ");
35884 self.write(&length.to_string());
35885 }
35886 self.write(")");
35887 Ok(())
35888 }
35889
35890 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
35891 let name = if matches!(
35892 self.config.dialect,
35893 Some(crate::dialects::DialectType::Spark)
35894 | Some(crate::dialects::DialectType::Databricks)
35895 ) {
35896 "TRY_ADD"
35897 } else {
35898 "SAFE_ADD"
35899 };
35900 self.write_keyword(name);
35901 self.write("(");
35902 self.generate_expression(&e.this)?;
35903 self.write(", ");
35904 self.generate_expression(&e.expression)?;
35905 self.write(")");
35906 Ok(())
35907 }
35908
35909 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
35910 self.write_keyword("SAFE_DIVIDE");
35912 self.write("(");
35913 self.generate_expression(&e.this)?;
35914 self.write(", ");
35915 self.generate_expression(&e.expression)?;
35916 self.write(")");
35917 Ok(())
35918 }
35919
35920 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
35921 let name = if matches!(
35922 self.config.dialect,
35923 Some(crate::dialects::DialectType::Spark)
35924 | Some(crate::dialects::DialectType::Databricks)
35925 ) {
35926 "TRY_MULTIPLY"
35927 } else {
35928 "SAFE_MULTIPLY"
35929 };
35930 self.write_keyword(name);
35931 self.write("(");
35932 self.generate_expression(&e.this)?;
35933 self.write(", ");
35934 self.generate_expression(&e.expression)?;
35935 self.write(")");
35936 Ok(())
35937 }
35938
35939 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
35940 let name = if matches!(
35941 self.config.dialect,
35942 Some(crate::dialects::DialectType::Spark)
35943 | Some(crate::dialects::DialectType::Databricks)
35944 ) {
35945 "TRY_SUBTRACT"
35946 } else {
35947 "SAFE_SUBTRACT"
35948 };
35949 self.write_keyword(name);
35950 self.write("(");
35951 self.generate_expression(&e.this)?;
35952 self.write(", ");
35953 self.generate_expression(&e.expression)?;
35954 self.write(")");
35955 Ok(())
35956 }
35957
35958 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
35961 if matches!(sample.method, SampleMethod::Bucket) {
35963 self.write(" (");
35964 self.write_keyword("BUCKET");
35965 self.write_space();
35966 if let Some(ref num) = sample.bucket_numerator {
35967 self.generate_expression(num)?;
35968 }
35969 self.write_space();
35970 self.write_keyword("OUT OF");
35971 self.write_space();
35972 if let Some(ref denom) = sample.bucket_denominator {
35973 self.generate_expression(denom)?;
35974 }
35975 if let Some(ref field) = sample.bucket_field {
35976 self.write_space();
35977 self.write_keyword("ON");
35978 self.write_space();
35979 self.generate_expression(field)?;
35980 }
35981 self.write(")");
35982 return Ok(());
35983 }
35984
35985 let is_snowflake = matches!(
35987 self.config.dialect,
35988 Some(crate::dialects::DialectType::Snowflake)
35989 );
35990 let is_postgres = matches!(
35991 self.config.dialect,
35992 Some(crate::dialects::DialectType::PostgreSQL)
35993 | Some(crate::dialects::DialectType::Redshift)
35994 );
35995 let is_databricks = matches!(
35997 self.config.dialect,
35998 Some(crate::dialects::DialectType::Databricks)
35999 );
36000 let is_spark = matches!(
36001 self.config.dialect,
36002 Some(crate::dialects::DialectType::Spark)
36003 );
36004 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
36005 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
36007 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
36008 self.write_space();
36009 if !sample.explicit_method && (is_snowflake || force_method) {
36010 self.write_keyword("BERNOULLI");
36012 } else {
36013 match sample.method {
36014 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
36015 SampleMethod::System => self.write_keyword("SYSTEM"),
36016 SampleMethod::Block => self.write_keyword("BLOCK"),
36017 SampleMethod::Row => self.write_keyword("ROW"),
36018 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
36019 SampleMethod::Percent => self.write_keyword("SYSTEM"),
36020 SampleMethod::Bucket => {} }
36022 }
36023 }
36024
36025 let emit_size_no_parens = !self.config.tablesample_requires_parens;
36027 if emit_size_no_parens {
36028 self.write_space();
36029 match &sample.size {
36030 Expression::Tuple(tuple) => {
36031 for (i, expr) in tuple.expressions.iter().enumerate() {
36032 if i > 0 {
36033 self.write(", ");
36034 }
36035 self.generate_expression(expr)?;
36036 }
36037 }
36038 expr => self.generate_expression(expr)?,
36039 }
36040 } else {
36041 self.write(" (");
36042 self.generate_expression(&sample.size)?;
36043 }
36044
36045 let is_rows_method = matches!(
36047 sample.method,
36048 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
36049 );
36050 let is_percent = matches!(
36051 sample.method,
36052 SampleMethod::Percent
36053 | SampleMethod::System
36054 | SampleMethod::Bernoulli
36055 | SampleMethod::Block
36056 );
36057
36058 let is_presto = matches!(
36062 self.config.dialect,
36063 Some(crate::dialects::DialectType::Presto)
36064 | Some(crate::dialects::DialectType::Trino)
36065 | Some(crate::dialects::DialectType::Athena)
36066 );
36067 let should_output_unit = if is_databricks || is_spark {
36068 is_percent || is_rows_method || sample.unit_after_size
36070 } else if is_snowflake || is_postgres || is_presto {
36071 sample.unit_after_size
36072 } else {
36073 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
36074 };
36075
36076 if should_output_unit {
36077 self.write_space();
36078 if sample.is_percent {
36079 self.write_keyword("PERCENT");
36080 } else if is_rows_method && !sample.unit_after_size {
36081 self.write_keyword("ROWS");
36082 } else if sample.unit_after_size {
36083 match sample.method {
36084 SampleMethod::Percent
36085 | SampleMethod::System
36086 | SampleMethod::Bernoulli
36087 | SampleMethod::Block => {
36088 self.write_keyword("PERCENT");
36089 }
36090 SampleMethod::Row | SampleMethod::Reservoir => {
36091 self.write_keyword("ROWS");
36092 }
36093 _ => self.write_keyword("ROWS"),
36094 }
36095 } else {
36096 self.write_keyword("PERCENT");
36097 }
36098 }
36099
36100 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
36101 if let Some(ref offset) = sample.offset {
36102 self.write_space();
36103 self.write_keyword("OFFSET");
36104 self.write_space();
36105 self.generate_expression(offset)?;
36106 }
36107 }
36108 if !emit_size_no_parens {
36109 self.write(")");
36110 }
36111
36112 Ok(())
36113 }
36114
36115 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
36116 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
36118 self.write_keyword("SAMPLE BY");
36119 } else {
36120 self.write_keyword("SAMPLE");
36121 }
36122 self.write_space();
36123 self.generate_expression(&e.this)?;
36124 Ok(())
36125 }
36126
36127 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
36128 if let Some(this) = &e.this {
36130 self.generate_expression(this)?;
36131 }
36132 if !e.expressions.is_empty() {
36133 if e.this.is_some() {
36135 self.write_space();
36136 }
36137 self.write("(");
36138 for (i, expr) in e.expressions.iter().enumerate() {
36139 if i > 0 {
36140 self.write(", ");
36141 }
36142 self.generate_expression(expr)?;
36143 }
36144 self.write(")");
36145 }
36146 Ok(())
36147 }
36148
36149 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
36150 self.write_keyword("COMMENT");
36152 self.write_space();
36153 self.generate_expression(&e.this)?;
36154 Ok(())
36155 }
36156
36157 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
36158 if let Some(this) = &e.this {
36160 self.generate_expression(this)?;
36161 self.write("::");
36162 }
36163 self.generate_expression(&e.expression)?;
36164 Ok(())
36165 }
36166
36167 fn generate_search(&mut self, e: &Search) -> Result<()> {
36168 self.write_keyword("SEARCH");
36170 self.write("(");
36171 self.generate_expression(&e.this)?;
36172 self.write(", ");
36173 self.generate_expression(&e.expression)?;
36174 if let Some(json_scope) = &e.json_scope {
36175 self.write(", ");
36176 self.generate_expression(json_scope)?;
36177 }
36178 if let Some(analyzer) = &e.analyzer {
36179 self.write(", ");
36180 self.generate_expression(analyzer)?;
36181 }
36182 if let Some(analyzer_options) = &e.analyzer_options {
36183 self.write(", ");
36184 self.generate_expression(analyzer_options)?;
36185 }
36186 if let Some(search_mode) = &e.search_mode {
36187 self.write(", ");
36188 self.generate_expression(search_mode)?;
36189 }
36190 self.write(")");
36191 Ok(())
36192 }
36193
36194 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
36195 self.write_keyword("SEARCH_IP");
36197 self.write("(");
36198 self.generate_expression(&e.this)?;
36199 self.write(", ");
36200 self.generate_expression(&e.expression)?;
36201 self.write(")");
36202 Ok(())
36203 }
36204
36205 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
36206 self.write_keyword("SECURITY");
36208 self.write_space();
36209 self.generate_expression(&e.this)?;
36210 Ok(())
36211 }
36212
36213 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
36214 self.write("SEMANTIC_VIEW(");
36216
36217 if self.config.pretty {
36218 self.write_newline();
36220 self.indent_level += 1;
36221 self.write_indent();
36222 self.generate_expression(&e.this)?;
36223
36224 if let Some(metrics) = &e.metrics {
36225 self.write_newline();
36226 self.write_indent();
36227 self.write_keyword("METRICS");
36228 self.write_space();
36229 self.generate_semantic_view_tuple(metrics)?;
36230 }
36231 if let Some(dimensions) = &e.dimensions {
36232 self.write_newline();
36233 self.write_indent();
36234 self.write_keyword("DIMENSIONS");
36235 self.write_space();
36236 self.generate_semantic_view_tuple(dimensions)?;
36237 }
36238 if let Some(facts) = &e.facts {
36239 self.write_newline();
36240 self.write_indent();
36241 self.write_keyword("FACTS");
36242 self.write_space();
36243 self.generate_semantic_view_tuple(facts)?;
36244 }
36245 if let Some(where_) = &e.where_ {
36246 self.write_newline();
36247 self.write_indent();
36248 self.write_keyword("WHERE");
36249 self.write_space();
36250 self.generate_expression(where_)?;
36251 }
36252 self.write_newline();
36253 self.indent_level -= 1;
36254 self.write_indent();
36255 } else {
36256 self.generate_expression(&e.this)?;
36258 if let Some(metrics) = &e.metrics {
36259 self.write_space();
36260 self.write_keyword("METRICS");
36261 self.write_space();
36262 self.generate_semantic_view_tuple(metrics)?;
36263 }
36264 if let Some(dimensions) = &e.dimensions {
36265 self.write_space();
36266 self.write_keyword("DIMENSIONS");
36267 self.write_space();
36268 self.generate_semantic_view_tuple(dimensions)?;
36269 }
36270 if let Some(facts) = &e.facts {
36271 self.write_space();
36272 self.write_keyword("FACTS");
36273 self.write_space();
36274 self.generate_semantic_view_tuple(facts)?;
36275 }
36276 if let Some(where_) = &e.where_ {
36277 self.write_space();
36278 self.write_keyword("WHERE");
36279 self.write_space();
36280 self.generate_expression(where_)?;
36281 }
36282 }
36283 self.write(")");
36284 Ok(())
36285 }
36286
36287 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
36289 if let Expression::Tuple(t) = expr {
36290 for (i, e) in t.expressions.iter().enumerate() {
36291 if i > 0 {
36292 self.write(", ");
36293 }
36294 self.generate_expression(e)?;
36295 }
36296 } else {
36297 self.generate_expression(expr)?;
36298 }
36299 Ok(())
36300 }
36301
36302 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
36303 if let Some(start) = &e.start {
36305 self.write_keyword("START WITH");
36306 self.write_space();
36307 self.generate_expression(start)?;
36308 }
36309 if let Some(increment) = &e.increment {
36310 self.write_space();
36311 self.write_keyword("INCREMENT BY");
36312 self.write_space();
36313 self.generate_expression(increment)?;
36314 }
36315 if let Some(minvalue) = &e.minvalue {
36316 self.write_space();
36317 self.write_keyword("MINVALUE");
36318 self.write_space();
36319 self.generate_expression(minvalue)?;
36320 }
36321 if let Some(maxvalue) = &e.maxvalue {
36322 self.write_space();
36323 self.write_keyword("MAXVALUE");
36324 self.write_space();
36325 self.generate_expression(maxvalue)?;
36326 }
36327 if let Some(cache) = &e.cache {
36328 self.write_space();
36329 self.write_keyword("CACHE");
36330 self.write_space();
36331 self.generate_expression(cache)?;
36332 }
36333 if let Some(owned) = &e.owned {
36334 self.write_space();
36335 self.write_keyword("OWNED BY");
36336 self.write_space();
36337 self.generate_expression(owned)?;
36338 }
36339 for opt in &e.options {
36340 self.write_space();
36341 self.generate_expression(opt)?;
36342 }
36343 Ok(())
36344 }
36345
36346 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
36347 if e.with_.is_some() {
36349 self.write_keyword("WITH");
36350 self.write_space();
36351 }
36352 self.write_keyword("SERDEPROPERTIES");
36353 self.write(" (");
36354 for (i, expr) in e.expressions.iter().enumerate() {
36355 if i > 0 {
36356 self.write(", ");
36357 }
36358 match expr {
36360 Expression::Eq(eq) => {
36361 self.generate_expression(&eq.left)?;
36362 self.write("=");
36363 self.generate_expression(&eq.right)?;
36364 }
36365 _ => self.generate_expression(expr)?,
36366 }
36367 }
36368 self.write(")");
36369 Ok(())
36370 }
36371
36372 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
36373 self.write("@@");
36375 if let Some(kind) = &e.kind {
36376 self.write(kind);
36377 self.write(".");
36378 }
36379 self.generate_expression(&e.this)?;
36380 Ok(())
36381 }
36382
36383 fn generate_set(&mut self, e: &Set) -> Result<()> {
36384 if e.unset.is_some() {
36386 self.write_keyword("UNSET");
36387 } else {
36388 self.write_keyword("SET");
36389 }
36390 if e.tag.is_some() {
36391 self.write_space();
36392 self.write_keyword("TAG");
36393 }
36394 if !e.expressions.is_empty() {
36395 self.write_space();
36396 for (i, expr) in e.expressions.iter().enumerate() {
36397 if i > 0 {
36398 self.write(", ");
36399 }
36400 self.generate_expression(expr)?;
36401 }
36402 }
36403 Ok(())
36404 }
36405
36406 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
36407 self.write_keyword("SET");
36409 self.write_space();
36410 self.generate_expression(&e.this)?;
36411 Ok(())
36412 }
36413
36414 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
36415 if let Some(kind) = &e.kind {
36417 self.write_keyword(kind);
36418 self.write_space();
36419 }
36420 self.generate_expression(&e.name)?;
36421 self.write(" = ");
36422 self.generate_expression(&e.value)?;
36423 Ok(())
36424 }
36425
36426 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
36427 if let Some(with_) = &e.with_ {
36429 self.generate_expression(with_)?;
36430 self.write_space();
36431 }
36432 self.generate_expression(&e.this)?;
36433 self.write_space();
36434 if let Some(kind) = &e.kind {
36436 self.write_keyword(kind);
36437 }
36438 if e.distinct {
36439 self.write_space();
36440 self.write_keyword("DISTINCT");
36441 } else {
36442 self.write_space();
36443 self.write_keyword("ALL");
36444 }
36445 if e.by_name.is_some() {
36446 self.write_space();
36447 self.write_keyword("BY NAME");
36448 }
36449 self.write_space();
36450 self.generate_expression(&e.expression)?;
36451 Ok(())
36452 }
36453
36454 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
36455 if e.multi.is_some() {
36457 self.write_keyword("MULTISET");
36458 } else {
36459 self.write_keyword("SET");
36460 }
36461 Ok(())
36462 }
36463
36464 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
36465 self.write_keyword("SETTINGS");
36467 if self.config.pretty && e.expressions.len() > 1 {
36468 self.indent_level += 1;
36470 for (i, expr) in e.expressions.iter().enumerate() {
36471 if i > 0 {
36472 self.write(",");
36473 }
36474 self.write_newline();
36475 self.write_indent();
36476 self.generate_expression(expr)?;
36477 }
36478 self.indent_level -= 1;
36479 } else {
36480 self.write_space();
36481 for (i, expr) in e.expressions.iter().enumerate() {
36482 if i > 0 {
36483 self.write(", ");
36484 }
36485 self.generate_expression(expr)?;
36486 }
36487 }
36488 Ok(())
36489 }
36490
36491 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
36492 self.write_keyword("SHARING");
36494 if let Some(this) = &e.this {
36495 self.write(" = ");
36496 self.generate_expression(this)?;
36497 }
36498 Ok(())
36499 }
36500
36501 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
36502 if let Some(begin) = &e.this {
36504 self.generate_expression(begin)?;
36505 }
36506 self.write(":");
36507 if let Some(end) = &e.expression {
36508 self.generate_expression(end)?;
36509 }
36510 if let Some(step) = &e.step {
36511 self.write(":");
36512 self.generate_expression(step)?;
36513 }
36514 Ok(())
36515 }
36516
36517 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
36518 self.write_keyword("SORT_ARRAY");
36520 self.write("(");
36521 self.generate_expression(&e.this)?;
36522 if let Some(asc) = &e.asc {
36523 self.write(", ");
36524 self.generate_expression(asc)?;
36525 }
36526 self.write(")");
36527 Ok(())
36528 }
36529
36530 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
36531 self.write_keyword("SORT BY");
36533 self.write_space();
36534 for (i, expr) in e.expressions.iter().enumerate() {
36535 if i > 0 {
36536 self.write(", ");
36537 }
36538 self.generate_ordered(expr)?;
36539 }
36540 Ok(())
36541 }
36542
36543 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
36544 if e.compound.is_some() {
36546 self.write_keyword("COMPOUND");
36547 self.write_space();
36548 }
36549 self.write_keyword("SORTKEY");
36550 self.write("(");
36551 if let Expression::Tuple(t) = e.this.as_ref() {
36553 for (i, expr) in t.expressions.iter().enumerate() {
36554 if i > 0 {
36555 self.write(", ");
36556 }
36557 self.generate_expression(expr)?;
36558 }
36559 } else {
36560 self.generate_expression(&e.this)?;
36561 }
36562 self.write(")");
36563 Ok(())
36564 }
36565
36566 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
36567 self.write_keyword("SPLIT_PART");
36569 self.write("(");
36570 self.generate_expression(&e.this)?;
36571 if let Some(delimiter) = &e.delimiter {
36572 self.write(", ");
36573 self.generate_expression(delimiter)?;
36574 }
36575 if let Some(part_index) = &e.part_index {
36576 self.write(", ");
36577 self.generate_expression(part_index)?;
36578 }
36579 self.write(")");
36580 Ok(())
36581 }
36582
36583 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
36584 self.generate_expression(&e.this)?;
36586 Ok(())
36587 }
36588
36589 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
36590 self.write_keyword("SQL SECURITY");
36592 self.write_space();
36593 self.generate_expression(&e.this)?;
36594 Ok(())
36595 }
36596
36597 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
36598 self.write_keyword("ST_DISTANCE");
36600 self.write("(");
36601 self.generate_expression(&e.this)?;
36602 self.write(", ");
36603 self.generate_expression(&e.expression)?;
36604 if let Some(use_spheroid) = &e.use_spheroid {
36605 self.write(", ");
36606 self.generate_expression(use_spheroid)?;
36607 }
36608 self.write(")");
36609 Ok(())
36610 }
36611
36612 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
36613 self.write_keyword("ST_POINT");
36615 self.write("(");
36616 self.generate_expression(&e.this)?;
36617 self.write(", ");
36618 self.generate_expression(&e.expression)?;
36619 self.write(")");
36620 Ok(())
36621 }
36622
36623 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
36624 self.generate_expression(&e.this)?;
36626 Ok(())
36627 }
36628
36629 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
36630 self.write_keyword("STANDARD_HASH");
36632 self.write("(");
36633 self.generate_expression(&e.this)?;
36634 if let Some(expression) = &e.expression {
36635 self.write(", ");
36636 self.generate_expression(expression)?;
36637 }
36638 self.write(")");
36639 Ok(())
36640 }
36641
36642 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
36643 self.write_keyword("STORED BY");
36645 self.write_space();
36646 self.generate_expression(&e.this)?;
36647 Ok(())
36648 }
36649
36650 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
36651 use crate::dialects::DialectType;
36654 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36655 self.write_keyword("CHARINDEX");
36657 self.write("(");
36658 if let Some(substr) = &e.substr {
36659 self.generate_expression(substr)?;
36660 self.write(", ");
36661 }
36662 self.generate_expression(&e.this)?;
36663 if let Some(position) = &e.position {
36664 self.write(", ");
36665 self.generate_expression(position)?;
36666 }
36667 self.write(")");
36668 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
36669 self.write_keyword("POSITION");
36670 self.write("(");
36671 self.generate_expression(&e.this)?;
36672 if let Some(substr) = &e.substr {
36673 self.write(", ");
36674 self.generate_expression(substr)?;
36675 }
36676 if let Some(position) = &e.position {
36677 self.write(", ");
36678 self.generate_expression(position)?;
36679 }
36680 if let Some(occurrence) = &e.occurrence {
36681 self.write(", ");
36682 self.generate_expression(occurrence)?;
36683 }
36684 self.write(")");
36685 } else if matches!(
36686 self.config.dialect,
36687 Some(DialectType::SQLite)
36688 | Some(DialectType::Oracle)
36689 | Some(DialectType::BigQuery)
36690 | Some(DialectType::Teradata)
36691 ) {
36692 self.write_keyword("INSTR");
36693 self.write("(");
36694 self.generate_expression(&e.this)?;
36695 if let Some(substr) = &e.substr {
36696 self.write(", ");
36697 self.generate_expression(substr)?;
36698 }
36699 if let Some(position) = &e.position {
36700 self.write(", ");
36701 self.generate_expression(position)?;
36702 } else if e.occurrence.is_some() {
36703 self.write(", 1");
36706 }
36707 if let Some(occurrence) = &e.occurrence {
36708 self.write(", ");
36709 self.generate_expression(occurrence)?;
36710 }
36711 self.write(")");
36712 } else if matches!(
36713 self.config.dialect,
36714 Some(DialectType::MySQL)
36715 | Some(DialectType::SingleStore)
36716 | Some(DialectType::Doris)
36717 | Some(DialectType::StarRocks)
36718 | Some(DialectType::Hive)
36719 | Some(DialectType::Spark)
36720 | Some(DialectType::Databricks)
36721 ) {
36722 self.write_keyword("LOCATE");
36724 self.write("(");
36725 if let Some(substr) = &e.substr {
36726 self.generate_expression(substr)?;
36727 self.write(", ");
36728 }
36729 self.generate_expression(&e.this)?;
36730 if let Some(position) = &e.position {
36731 self.write(", ");
36732 self.generate_expression(position)?;
36733 }
36734 self.write(")");
36735 } else if matches!(
36736 self.config.dialect,
36737 Some(DialectType::TSQL) | Some(DialectType::Fabric)
36738 ) {
36739 self.write_keyword("CHARINDEX");
36741 self.write("(");
36742 if let Some(substr) = &e.substr {
36743 self.generate_expression(substr)?;
36744 self.write(", ");
36745 }
36746 self.generate_expression(&e.this)?;
36747 if let Some(position) = &e.position {
36748 self.write(", ");
36749 self.generate_expression(position)?;
36750 }
36751 self.write(")");
36752 } else if matches!(
36753 self.config.dialect,
36754 Some(DialectType::PostgreSQL)
36755 | Some(DialectType::Materialize)
36756 | Some(DialectType::RisingWave)
36757 | Some(DialectType::Redshift)
36758 ) {
36759 self.write_keyword("POSITION");
36761 self.write("(");
36762 if let Some(substr) = &e.substr {
36763 self.generate_expression(substr)?;
36764 self.write(" IN ");
36765 }
36766 self.generate_expression(&e.this)?;
36767 self.write(")");
36768 } else {
36769 self.write_keyword("STRPOS");
36770 self.write("(");
36771 self.generate_expression(&e.this)?;
36772 if let Some(substr) = &e.substr {
36773 self.write(", ");
36774 self.generate_expression(substr)?;
36775 }
36776 if let Some(position) = &e.position {
36777 self.write(", ");
36778 self.generate_expression(position)?;
36779 }
36780 if let Some(occurrence) = &e.occurrence {
36781 self.write(", ");
36782 self.generate_expression(occurrence)?;
36783 }
36784 self.write(")");
36785 }
36786 Ok(())
36787 }
36788
36789 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
36790 match self.config.dialect {
36791 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
36792 self.generate_tsql_str_to_temporal(&e.this, e.format.as_deref(), "DATE")?;
36793 }
36794 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
36795 self.write_keyword("TO_DATE");
36797 self.write("(");
36798 self.generate_expression(&e.this)?;
36799 if let Some(format) = &e.format {
36800 self.write(", '");
36801 self.write(&Self::strftime_to_java_format(format));
36802 self.write("'");
36803 }
36804 self.write(")");
36805 }
36806 Some(DialectType::DuckDB) => {
36807 self.write_keyword("CAST");
36809 self.write("(");
36810 self.write_keyword("STRPTIME");
36811 self.write("(");
36812 self.generate_expression(&e.this)?;
36813 if let Some(format) = &e.format {
36814 self.write(", '");
36815 self.write(format);
36816 self.write("'");
36817 }
36818 self.write(")");
36819 self.write_keyword(" AS ");
36820 self.write_keyword("DATE");
36821 self.write(")");
36822 }
36823 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
36824 self.write_keyword("TO_DATE");
36826 self.write("(");
36827 self.generate_expression(&e.this)?;
36828 if let Some(format) = &e.format {
36829 self.write(", '");
36830 self.write(&Self::strftime_to_postgres_format(format));
36831 self.write("'");
36832 }
36833 self.write(")");
36834 }
36835 Some(DialectType::BigQuery) => {
36836 self.write_keyword("PARSE_DATE");
36838 self.write("(");
36839 if let Some(format) = &e.format {
36840 self.write("'");
36841 self.write(format);
36842 self.write("'");
36843 self.write(", ");
36844 }
36845 self.generate_expression(&e.this)?;
36846 self.write(")");
36847 }
36848 Some(DialectType::Teradata) => {
36849 self.write_keyword("CAST");
36851 self.write("(");
36852 self.generate_expression(&e.this)?;
36853 self.write_keyword(" AS ");
36854 self.write_keyword("DATE");
36855 if let Some(format) = &e.format {
36856 self.write_keyword(" FORMAT ");
36857 self.write("'");
36858 self.write(&Self::strftime_to_teradata_format(format));
36859 self.write("'");
36860 }
36861 self.write(")");
36862 }
36863 _ => {
36864 self.write_keyword("STR_TO_DATE");
36866 self.write("(");
36867 self.generate_expression(&e.this)?;
36868 if let Some(format) = &e.format {
36869 self.write(", '");
36870 self.write(format);
36871 self.write("'");
36872 }
36873 self.write(")");
36874 }
36875 }
36876 Ok(())
36877 }
36878
36879 fn strftime_to_teradata_format(fmt: &str) -> String {
36881 let mut result = String::with_capacity(fmt.len() * 2);
36882 let bytes = fmt.as_bytes();
36883 let len = bytes.len();
36884 let mut i = 0;
36885 while i < len {
36886 if bytes[i] == b'%' && i + 1 < len {
36887 let replacement = match bytes[i + 1] {
36888 b'Y' => "YYYY",
36889 b'y' => "YY",
36890 b'm' => "MM",
36891 b'B' => "MMMM",
36892 b'b' => "MMM",
36893 b'd' => "DD",
36894 b'j' => "DDD",
36895 b'H' => "HH",
36896 b'M' => "MI",
36897 b'S' => "SS",
36898 b'f' => "SSSSSS",
36899 b'A' => "EEEE",
36900 b'a' => "EEE",
36901 _ => {
36902 result.push('%');
36903 i += 1;
36904 continue;
36905 }
36906 };
36907 result.push_str(replacement);
36908 i += 2;
36909 } else {
36910 result.push(bytes[i] as char);
36911 i += 1;
36912 }
36913 }
36914 result
36915 }
36916
36917 pub fn strftime_to_java_format_static(fmt: &str) -> String {
36920 Self::strftime_to_java_format(fmt)
36921 }
36922
36923 fn strftime_to_java_format(fmt: &str) -> String {
36925 let mut result = String::with_capacity(fmt.len() * 2);
36926 let bytes = fmt.as_bytes();
36927 let len = bytes.len();
36928 let mut i = 0;
36929 while i < len {
36930 if bytes[i] == b'%' && i + 1 < len {
36931 if bytes[i + 1] == b'-' && i + 2 < len {
36933 let replacement = match bytes[i + 2] {
36934 b'd' => "d",
36935 b'm' => "M",
36936 b'H' => "H",
36937 b'M' => "m",
36938 b'S' => "s",
36939 _ => {
36940 result.push('%');
36941 i += 1;
36942 continue;
36943 }
36944 };
36945 result.push_str(replacement);
36946 i += 3;
36947 } else {
36948 let replacement = match bytes[i + 1] {
36949 b'Y' => "yyyy",
36950 b'y' => "yy",
36951 b'm' => "MM",
36952 b'B' => "MMMM",
36953 b'b' => "MMM",
36954 b'd' => "dd",
36955 b'j' => "DDD",
36956 b'H' => "HH",
36957 b'M' => "mm",
36958 b'S' => "ss",
36959 b'f' => "SSSSSS",
36960 b'A' => "EEEE",
36961 b'a' => "EEE",
36962 _ => {
36963 result.push('%');
36964 i += 1;
36965 continue;
36966 }
36967 };
36968 result.push_str(replacement);
36969 i += 2;
36970 }
36971 } else {
36972 result.push(bytes[i] as char);
36973 i += 1;
36974 }
36975 }
36976 result
36977 }
36978
36979 fn strftime_to_tsql_format(fmt: &str) -> String {
36982 let mut result = String::with_capacity(fmt.len() * 2);
36983 let bytes = fmt.as_bytes();
36984 let len = bytes.len();
36985 let mut i = 0;
36986 while i < len {
36987 if bytes[i] == b'%' && i + 1 < len {
36988 if bytes[i + 1] == b'-' && i + 2 < len {
36990 let replacement = match bytes[i + 2] {
36991 b'd' => "d",
36992 b'm' => "M",
36993 b'H' => "H",
36994 b'M' => "m",
36995 b'S' => "s",
36996 _ => {
36997 result.push('%');
36998 i += 1;
36999 continue;
37000 }
37001 };
37002 result.push_str(replacement);
37003 i += 3;
37004 } else {
37005 let replacement = match bytes[i + 1] {
37006 b'Y' => "yyyy",
37007 b'y' => "yy",
37008 b'm' => "MM",
37009 b'B' => "MMMM",
37010 b'b' => "MMM",
37011 b'd' => "dd",
37012 b'j' => "DDD",
37013 b'H' => "HH",
37014 b'M' => "mm",
37015 b'S' => "ss",
37016 b'f' => "ffffff",
37017 b'A' => "dddd",
37018 b'a' => "ddd",
37019 _ => {
37020 result.push('%');
37021 i += 1;
37022 continue;
37023 }
37024 };
37025 result.push_str(replacement);
37026 i += 2;
37027 }
37028 } else {
37029 result.push(bytes[i] as char);
37030 i += 1;
37031 }
37032 }
37033 result
37034 }
37035
37036 fn tsql_convert_style_for_strftime(fmt: &str) -> Option<u16> {
37037 match fmt.trim() {
37038 "%b %d %Y %-I:%M%p" => Some(100),
37039 "%m/%d/%y" => Some(1),
37040 "%y.%m.%d" => Some(2),
37041 "%d/%m/%y" => Some(3),
37042 "%d.%m.%y" => Some(4),
37043 "%d-%m-%y" => Some(5),
37044 "%d %b %y" => Some(6),
37045 "%b %d, %y" => Some(7),
37046 "%H:%M:%S" => Some(108),
37047 "%b %d %Y %-I:%M:%S:%f%p" => Some(109),
37048 "%m-%d-%y" => Some(10),
37049 "%y/%m/%d" => Some(11),
37050 "%y%m%d" => Some(12),
37051 "%d %b %Y %H:%M:%S:%f" => Some(113),
37052 "%H:%M:%S:%f" => Some(114),
37053 "%m/%d/%Y" => Some(101),
37054 "%Y.%m.%d" => Some(102),
37055 "%d/%m/%Y" => Some(103),
37056 "%d.%m.%Y" => Some(104),
37057 "%d-%m-%Y" => Some(105),
37058 "%d %b %Y" => Some(106),
37059 "%b %d, %Y" => Some(107),
37060 "%m-%d-%Y" => Some(110),
37061 "%Y/%m/%d" => Some(111),
37062 "%Y%m%d" => Some(112),
37063 "%Y-%m-%d %H:%M:%S" => Some(120),
37064 "%Y-%m-%d %H:%M:%S.%f" => Some(121),
37065 "%Y-%m-%dT%H:%M:%S" | "%Y-%m-%dT%H:%M:%S.%f" => Some(126),
37066 "%Y-%m-%d" => Some(23),
37067 _ => None,
37068 }
37069 }
37070
37071 fn generate_tsql_str_to_temporal(
37072 &mut self,
37073 this: &Expression,
37074 format: Option<&str>,
37075 target_type: &str,
37076 ) -> Result<()> {
37077 if let Some(format) = format {
37078 if let Some(style) = Self::tsql_convert_style_for_strftime(format) {
37079 self.write_keyword("CONVERT");
37080 self.write("(");
37081 self.write_keyword(target_type);
37082 self.write(", ");
37083 self.generate_expression(this)?;
37084 self.write(", ");
37085 self.write(&style.to_string());
37086 self.write(")");
37087 return Ok(());
37088 }
37089
37090 self.unsupported(format!(
37091 "T-SQL/Fabric {target_type} parsing format '{format}' has no CONVERT style mapping"
37092 ))?;
37093 }
37094
37095 self.write_keyword("CAST");
37096 self.write("(");
37097 self.generate_expression(this)?;
37098 self.write(" AS ");
37099 self.write_keyword(target_type);
37100 self.write(")");
37101 Ok(())
37102 }
37103
37104 fn decompose_json_path(path: &str) -> Vec<String> {
37107 let mut parts = Vec::new();
37108 let path = if path.starts_with("$.") {
37110 &path[2..]
37111 } else if path.starts_with('$') {
37112 &path[1..]
37113 } else {
37114 path
37115 };
37116 if path.is_empty() {
37117 return parts;
37118 }
37119 let mut current = String::new();
37120 let chars: Vec<char> = path.chars().collect();
37121 let mut i = 0;
37122 while i < chars.len() {
37123 match chars[i] {
37124 '.' => {
37125 if !current.is_empty() {
37126 parts.push(current.clone());
37127 current.clear();
37128 }
37129 i += 1;
37130 }
37131 '[' => {
37132 if !current.is_empty() {
37133 parts.push(current.clone());
37134 current.clear();
37135 }
37136 i += 1;
37137 let mut bracket_content = String::new();
37139 while i < chars.len() && chars[i] != ']' {
37140 if chars[i] == '"' || chars[i] == '\'' {
37142 let quote = chars[i];
37143 i += 1;
37144 while i < chars.len() && chars[i] != quote {
37145 bracket_content.push(chars[i]);
37146 i += 1;
37147 }
37148 if i < chars.len() {
37149 i += 1;
37150 } } else {
37152 bracket_content.push(chars[i]);
37153 i += 1;
37154 }
37155 }
37156 if i < chars.len() {
37157 i += 1;
37158 } if bracket_content != "*" {
37161 parts.push(bracket_content);
37162 }
37163 }
37164 _ => {
37165 current.push(chars[i]);
37166 i += 1;
37167 }
37168 }
37169 }
37170 if !current.is_empty() {
37171 parts.push(current);
37172 }
37173 parts
37174 }
37175
37176 fn strftime_to_postgres_format(fmt: &str) -> String {
37178 let mut result = String::with_capacity(fmt.len() * 2);
37179 let bytes = fmt.as_bytes();
37180 let len = bytes.len();
37181 let mut i = 0;
37182 while i < len {
37183 if bytes[i] == b'%' && i + 1 < len {
37184 if bytes[i + 1] == b'-' && i + 2 < len {
37186 let replacement = match bytes[i + 2] {
37187 b'd' => "FMDD",
37188 b'm' => "FMMM",
37189 b'H' => "FMHH24",
37190 b'M' => "FMMI",
37191 b'S' => "FMSS",
37192 _ => {
37193 result.push('%');
37194 i += 1;
37195 continue;
37196 }
37197 };
37198 result.push_str(replacement);
37199 i += 3;
37200 } else {
37201 let replacement = match bytes[i + 1] {
37202 b'Y' => "YYYY",
37203 b'y' => "YY",
37204 b'm' => "MM",
37205 b'B' => "Month",
37206 b'b' => "Mon",
37207 b'd' => "DD",
37208 b'j' => "DDD",
37209 b'H' => "HH24",
37210 b'M' => "MI",
37211 b'S' => "SS",
37212 b'f' => "US",
37213 b'A' => "Day",
37214 b'a' => "Dy",
37215 _ => {
37216 result.push('%');
37217 i += 1;
37218 continue;
37219 }
37220 };
37221 result.push_str(replacement);
37222 i += 2;
37223 }
37224 } else {
37225 result.push(bytes[i] as char);
37226 i += 1;
37227 }
37228 }
37229 result
37230 }
37231
37232 fn strftime_to_snowflake_format(fmt: &str) -> String {
37234 let mut result = String::with_capacity(fmt.len() * 2);
37235 let bytes = fmt.as_bytes();
37236 let len = bytes.len();
37237 let mut i = 0;
37238 while i < len {
37239 if bytes[i] == b'%' && i + 1 < len {
37240 if bytes[i + 1] == b'-' && i + 2 < len {
37242 let replacement = match bytes[i + 2] {
37243 b'd' => "dd",
37244 b'm' => "mm",
37245 _ => {
37246 result.push('%');
37247 i += 1;
37248 continue;
37249 }
37250 };
37251 result.push_str(replacement);
37252 i += 3;
37253 } else {
37254 let replacement = match bytes[i + 1] {
37255 b'Y' => "yyyy",
37256 b'y' => "yy",
37257 b'm' => "mm",
37258 b'd' => "DD",
37259 b'H' => "hh24",
37260 b'M' => "mi",
37261 b'S' => "ss",
37262 b'f' => "ff",
37263 _ => {
37264 result.push('%');
37265 i += 1;
37266 continue;
37267 }
37268 };
37269 result.push_str(replacement);
37270 i += 2;
37271 }
37272 } else {
37273 result.push(bytes[i] as char);
37274 i += 1;
37275 }
37276 }
37277 result
37278 }
37279
37280 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
37281 self.write_keyword("STR_TO_MAP");
37283 self.write("(");
37284 self.generate_expression(&e.this)?;
37285 let needs_defaults = matches!(
37287 self.config.dialect,
37288 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
37289 );
37290 if let Some(pair_delim) = &e.pair_delim {
37291 self.write(", ");
37292 self.generate_expression(pair_delim)?;
37293 } else if needs_defaults {
37294 self.write(", ','");
37295 }
37296 if let Some(key_value_delim) = &e.key_value_delim {
37297 self.write(", ");
37298 self.generate_expression(key_value_delim)?;
37299 } else if needs_defaults {
37300 self.write(", ':'");
37301 }
37302 self.write(")");
37303 Ok(())
37304 }
37305
37306 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
37307 let is_strftime = e.format.contains('%');
37309 let to_strftime = |f: &str| -> String {
37311 if is_strftime {
37312 f.to_string()
37313 } else {
37314 Self::snowflake_format_to_strftime(f)
37315 }
37316 };
37317 let to_java = |f: &str| -> String {
37319 if is_strftime {
37320 Self::strftime_to_java_format(f)
37321 } else {
37322 Self::snowflake_format_to_spark(f)
37323 }
37324 };
37325 let to_pg = |f: &str| -> String {
37327 if is_strftime {
37328 Self::strftime_to_postgres_format(f)
37329 } else {
37330 Self::convert_strptime_to_postgres_format(f)
37331 }
37332 };
37333
37334 match self.config.dialect {
37335 Some(DialectType::Exasol) => {
37336 self.write_keyword("TO_DATE");
37337 self.write("(");
37338 self.generate_expression(&e.this)?;
37339 self.write(", '");
37340 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
37341 self.write("'");
37342 self.write(")");
37343 }
37344 Some(DialectType::BigQuery) => {
37345 let fmt = to_strftime(&e.format);
37347 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
37349 self.write_keyword("PARSE_TIMESTAMP");
37350 self.write("('");
37351 self.write(&fmt);
37352 self.write("', ");
37353 self.generate_expression(&e.this)?;
37354 self.write(")");
37355 }
37356 Some(DialectType::Hive) => {
37357 let java_fmt = to_java(&e.format);
37360 if java_fmt == "yyyy-MM-dd HH:mm:ss"
37361 || java_fmt == "yyyy-MM-dd"
37362 || e.format == "yyyy-MM-dd HH:mm:ss"
37363 || e.format == "yyyy-MM-dd"
37364 {
37365 self.write_keyword("CAST");
37366 self.write("(");
37367 self.generate_expression(&e.this)?;
37368 self.write(" ");
37369 self.write_keyword("AS TIMESTAMP");
37370 self.write(")");
37371 } else {
37372 self.write_keyword("CAST");
37374 self.write("(");
37375 self.write_keyword("FROM_UNIXTIME");
37376 self.write("(");
37377 self.write_keyword("UNIX_TIMESTAMP");
37378 self.write("(");
37379 self.generate_expression(&e.this)?;
37380 self.write(", '");
37381 self.write(&java_fmt);
37382 self.write("')");
37383 self.write(") ");
37384 self.write_keyword("AS TIMESTAMP");
37385 self.write(")");
37386 }
37387 }
37388 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37389 let java_fmt = to_java(&e.format);
37391 self.write_keyword("TO_TIMESTAMP");
37392 self.write("(");
37393 self.generate_expression(&e.this)?;
37394 self.write(", '");
37395 self.write(&java_fmt);
37396 self.write("')");
37397 }
37398 Some(DialectType::MySQL) => {
37399 let mut fmt = to_strftime(&e.format);
37401 fmt = fmt.replace("%-d", "%e");
37403 fmt = fmt.replace("%-m", "%c");
37404 fmt = fmt.replace("%H:%M:%S", "%T");
37405 self.write_keyword("STR_TO_DATE");
37406 self.write("(");
37407 self.generate_expression(&e.this)?;
37408 self.write(", '");
37409 self.write(&fmt);
37410 self.write("')");
37411 }
37412 Some(DialectType::Drill) => {
37413 let java_fmt = to_java(&e.format);
37415 let java_fmt = java_fmt.replace('T', "''T''");
37417 self.write_keyword("TO_TIMESTAMP");
37418 self.write("(");
37419 self.generate_expression(&e.this)?;
37420 self.write(", '");
37421 self.write(&java_fmt);
37422 self.write("')");
37423 }
37424 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
37425 let mut fmt = to_strftime(&e.format);
37427 fmt = fmt.replace("%-d", "%e");
37429 fmt = fmt.replace("%-m", "%c");
37430 fmt = fmt.replace("%H:%M:%S", "%T");
37431 self.write_keyword("DATE_PARSE");
37432 self.write("(");
37433 self.generate_expression(&e.this)?;
37434 self.write(", '");
37435 self.write(&fmt);
37436 self.write("')");
37437 }
37438 Some(DialectType::DuckDB) => {
37439 let fmt = to_strftime(&e.format);
37441 self.write_keyword("STRPTIME");
37442 self.write("(");
37443 self.generate_expression(&e.this)?;
37444 self.write(", '");
37445 self.write(&fmt);
37446 self.write("')");
37447 }
37448 Some(DialectType::PostgreSQL)
37449 | Some(DialectType::Redshift)
37450 | Some(DialectType::Materialize) => {
37451 let pg_fmt = to_pg(&e.format);
37453 self.write_keyword("TO_TIMESTAMP");
37454 self.write("(");
37455 self.generate_expression(&e.this)?;
37456 self.write(", '");
37457 self.write(&pg_fmt);
37458 self.write("')");
37459 }
37460 Some(DialectType::Oracle) => {
37461 let pg_fmt = to_pg(&e.format);
37463 self.write_keyword("TO_TIMESTAMP");
37464 self.write("(");
37465 self.generate_expression(&e.this)?;
37466 self.write(", '");
37467 self.write(&pg_fmt);
37468 self.write("')");
37469 }
37470 Some(DialectType::Snowflake) => {
37471 self.write_keyword("TO_TIMESTAMP");
37473 self.write("(");
37474 self.generate_expression(&e.this)?;
37475 self.write(", '");
37476 self.write(&e.format);
37477 self.write("')");
37478 }
37479 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
37480 self.generate_tsql_str_to_temporal(&e.this, Some(&e.format), "DATETIME2")?;
37481 }
37482 _ => {
37483 self.write_keyword("STR_TO_TIME");
37485 self.write("(");
37486 self.generate_expression(&e.this)?;
37487 self.write(", '");
37488 self.write(&e.format);
37489 self.write("'");
37490 self.write(")");
37491 }
37492 }
37493 Ok(())
37494 }
37495
37496 fn snowflake_format_to_strftime(format: &str) -> String {
37498 let mut result = String::new();
37499 let chars: Vec<char> = format.chars().collect();
37500 let mut i = 0;
37501 while i < chars.len() {
37502 let remaining = &format[i..];
37503 if remaining.starts_with("yyyy") {
37504 result.push_str("%Y");
37505 i += 4;
37506 } else if remaining.starts_with("yy") {
37507 result.push_str("%y");
37508 i += 2;
37509 } else if remaining.starts_with("mmmm") {
37510 result.push_str("%B"); i += 4;
37512 } else if remaining.starts_with("mon") {
37513 result.push_str("%b"); i += 3;
37515 } else if remaining.starts_with("mm") {
37516 result.push_str("%m");
37517 i += 2;
37518 } else if remaining.starts_with("DD") {
37519 result.push_str("%d");
37520 i += 2;
37521 } else if remaining.starts_with("dy") {
37522 result.push_str("%a"); i += 2;
37524 } else if remaining.starts_with("hh24") {
37525 result.push_str("%H");
37526 i += 4;
37527 } else if remaining.starts_with("hh12") {
37528 result.push_str("%I");
37529 i += 4;
37530 } else if remaining.starts_with("hh") {
37531 result.push_str("%H");
37532 i += 2;
37533 } else if remaining.starts_with("mi") {
37534 result.push_str("%M");
37535 i += 2;
37536 } else if remaining.starts_with("ss") {
37537 result.push_str("%S");
37538 i += 2;
37539 } else if remaining.starts_with("ff") {
37540 result.push_str("%f");
37542 i += 2;
37543 while i < chars.len() && chars[i].is_ascii_digit() {
37545 i += 1;
37546 }
37547 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
37548 result.push_str("%p");
37549 i += 2;
37550 } else if remaining.starts_with("tz") {
37551 result.push_str("%Z");
37552 i += 2;
37553 } else {
37554 result.push(chars[i]);
37555 i += 1;
37556 }
37557 }
37558 result
37559 }
37560
37561 fn snowflake_format_to_spark(format: &str) -> String {
37563 let mut result = String::new();
37564 let chars: Vec<char> = format.chars().collect();
37565 let mut i = 0;
37566 while i < chars.len() {
37567 let remaining = &format[i..];
37568 if remaining.starts_with("yyyy") {
37569 result.push_str("yyyy");
37570 i += 4;
37571 } else if remaining.starts_with("yy") {
37572 result.push_str("yy");
37573 i += 2;
37574 } else if remaining.starts_with("mmmm") {
37575 result.push_str("MMMM"); i += 4;
37577 } else if remaining.starts_with("mon") {
37578 result.push_str("MMM"); i += 3;
37580 } else if remaining.starts_with("mm") {
37581 result.push_str("MM");
37582 i += 2;
37583 } else if remaining.starts_with("DD") {
37584 result.push_str("dd");
37585 i += 2;
37586 } else if remaining.starts_with("dy") {
37587 result.push_str("EEE"); i += 2;
37589 } else if remaining.starts_with("hh24") {
37590 result.push_str("HH");
37591 i += 4;
37592 } else if remaining.starts_with("hh12") {
37593 result.push_str("hh");
37594 i += 4;
37595 } else if remaining.starts_with("hh") {
37596 result.push_str("HH");
37597 i += 2;
37598 } else if remaining.starts_with("mi") {
37599 result.push_str("mm");
37600 i += 2;
37601 } else if remaining.starts_with("ss") {
37602 result.push_str("ss");
37603 i += 2;
37604 } else if remaining.starts_with("ff") {
37605 result.push_str("SSS"); i += 2;
37607 while i < chars.len() && chars[i].is_ascii_digit() {
37609 i += 1;
37610 }
37611 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
37612 result.push_str("a");
37613 i += 2;
37614 } else if remaining.starts_with("tz") {
37615 result.push_str("z");
37616 i += 2;
37617 } else {
37618 result.push(chars[i]);
37619 i += 1;
37620 }
37621 }
37622 result
37623 }
37624
37625 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
37626 match self.config.dialect {
37627 Some(DialectType::DuckDB) => {
37628 self.write_keyword("EPOCH");
37630 self.write("(");
37631 self.write_keyword("STRPTIME");
37632 self.write("(");
37633 if let Some(this) = &e.this {
37634 self.generate_expression(this)?;
37635 }
37636 if let Some(format) = &e.format {
37637 self.write(", '");
37638 self.write(format);
37639 self.write("'");
37640 }
37641 self.write("))");
37642 }
37643 Some(DialectType::Hive) => {
37644 self.write_keyword("UNIX_TIMESTAMP");
37646 self.write("(");
37647 if let Some(this) = &e.this {
37648 self.generate_expression(this)?;
37649 }
37650 if let Some(format) = &e.format {
37651 let java_fmt = Self::strftime_to_java_format(format);
37652 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
37653 self.write(", '");
37654 self.write(&java_fmt);
37655 self.write("'");
37656 }
37657 }
37658 self.write(")");
37659 }
37660 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
37661 self.write_keyword("UNIX_TIMESTAMP");
37663 self.write("(");
37664 if let Some(this) = &e.this {
37665 self.generate_expression(this)?;
37666 }
37667 if let Some(format) = &e.format {
37668 self.write(", '");
37669 self.write(format);
37670 self.write("'");
37671 }
37672 self.write(")");
37673 }
37674 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37675 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
37678 let java_fmt = Self::strftime_to_java_format(c_fmt);
37679 self.write_keyword("TO_UNIXTIME");
37680 self.write("(");
37681 self.write_keyword("COALESCE");
37682 self.write("(");
37683 self.write_keyword("TRY");
37684 self.write("(");
37685 self.write_keyword("DATE_PARSE");
37686 self.write("(");
37687 self.write_keyword("CAST");
37688 self.write("(");
37689 if let Some(this) = &e.this {
37690 self.generate_expression(this)?;
37691 }
37692 self.write(" ");
37693 self.write_keyword("AS VARCHAR");
37694 self.write("), '");
37695 self.write(c_fmt);
37696 self.write("')), ");
37697 self.write_keyword("PARSE_DATETIME");
37698 self.write("(");
37699 self.write_keyword("DATE_FORMAT");
37700 self.write("(");
37701 self.write_keyword("CAST");
37702 self.write("(");
37703 if let Some(this) = &e.this {
37704 self.generate_expression(this)?;
37705 }
37706 self.write(" ");
37707 self.write_keyword("AS TIMESTAMP");
37708 self.write("), '");
37709 self.write(c_fmt);
37710 self.write("'), '");
37711 self.write(&java_fmt);
37712 self.write("')))");
37713 }
37714 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37715 self.write_keyword("UNIX_TIMESTAMP");
37717 self.write("(");
37718 if let Some(this) = &e.this {
37719 self.generate_expression(this)?;
37720 }
37721 if let Some(format) = &e.format {
37722 let java_fmt = Self::strftime_to_java_format(format);
37723 self.write(", '");
37724 self.write(&java_fmt);
37725 self.write("'");
37726 }
37727 self.write(")");
37728 }
37729 _ => {
37730 self.write_keyword("STR_TO_UNIX");
37732 self.write("(");
37733 if let Some(this) = &e.this {
37734 self.generate_expression(this)?;
37735 }
37736 if let Some(format) = &e.format {
37737 self.write(", '");
37738 self.write(format);
37739 self.write("'");
37740 }
37741 self.write(")");
37742 }
37743 }
37744 Ok(())
37745 }
37746
37747 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
37748 self.write_keyword("STRING_TO_ARRAY");
37750 self.write("(");
37751 self.generate_expression(&e.this)?;
37752 if let Some(expression) = &e.expression {
37753 self.write(", ");
37754 self.generate_expression(expression)?;
37755 }
37756 if let Some(null_val) = &e.null {
37757 self.write(", ");
37758 self.generate_expression(null_val)?;
37759 }
37760 self.write(")");
37761 Ok(())
37762 }
37763
37764 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
37765 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
37766 self.write_keyword("OBJECT_CONSTRUCT");
37768 self.write("(");
37769 for (i, (name, expr)) in e.fields.iter().enumerate() {
37770 if i > 0 {
37771 self.write(", ");
37772 }
37773 if let Some(name) = name {
37774 self.write("'");
37775 self.write(name);
37776 self.write("'");
37777 self.write(", ");
37778 } else {
37779 self.write("'_");
37780 self.write(&i.to_string());
37781 self.write("'");
37782 self.write(", ");
37783 }
37784 self.generate_expression(expr)?;
37785 }
37786 self.write(")");
37787 } else if self.config.struct_curly_brace_notation {
37788 self.write("{");
37790 for (i, (name, expr)) in e.fields.iter().enumerate() {
37791 if i > 0 {
37792 self.write(", ");
37793 }
37794 if let Some(name) = name {
37795 self.write("'");
37797 self.write(name);
37798 self.write("'");
37799 self.write(": ");
37800 } else {
37801 self.write("'_");
37803 self.write(&i.to_string());
37804 self.write("'");
37805 self.write(": ");
37806 }
37807 self.generate_expression(expr)?;
37808 }
37809 self.write("}");
37810 } else {
37811 let value_as_name = matches!(
37815 self.config.dialect,
37816 Some(DialectType::BigQuery)
37817 | Some(DialectType::Spark)
37818 | Some(DialectType::Databricks)
37819 | Some(DialectType::Hive)
37820 );
37821 self.write_keyword("STRUCT");
37822 self.write("(");
37823 for (i, (name, expr)) in e.fields.iter().enumerate() {
37824 if i > 0 {
37825 self.write(", ");
37826 }
37827 if let Some(name) = name {
37828 if value_as_name {
37829 self.generate_expression(expr)?;
37831 self.write_space();
37832 self.write_keyword("AS");
37833 self.write_space();
37834 let needs_quoting = name.contains(' ') || name.contains('-');
37836 if needs_quoting {
37837 if matches!(
37838 self.config.dialect,
37839 Some(DialectType::Spark)
37840 | Some(DialectType::Databricks)
37841 | Some(DialectType::Hive)
37842 ) {
37843 self.write("`");
37844 self.write(name);
37845 self.write("`");
37846 } else {
37847 self.write(name);
37848 }
37849 } else {
37850 self.write(name);
37851 }
37852 } else {
37853 self.write(name);
37855 self.write_space();
37856 self.write_keyword("AS");
37857 self.write_space();
37858 self.generate_expression(expr)?;
37859 }
37860 } else {
37861 self.generate_expression(expr)?;
37862 }
37863 }
37864 self.write(")");
37865 }
37866 Ok(())
37867 }
37868
37869 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
37870 self.write_keyword("STUFF");
37872 self.write("(");
37873 self.generate_expression(&e.this)?;
37874 if let Some(start) = &e.start {
37875 self.write(", ");
37876 self.generate_expression(start)?;
37877 }
37878 if let Some(length) = e.length {
37879 self.write(", ");
37880 self.write(&length.to_string());
37881 }
37882 self.write(", ");
37883 self.generate_expression(&e.expression)?;
37884 self.write(")");
37885 Ok(())
37886 }
37887
37888 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
37889 self.write_keyword("SUBSTRING_INDEX");
37891 self.write("(");
37892 self.generate_expression(&e.this)?;
37893 if let Some(delimiter) = &e.delimiter {
37894 self.write(", ");
37895 self.generate_expression(delimiter)?;
37896 }
37897 if let Some(count) = &e.count {
37898 self.write(", ");
37899 self.generate_expression(count)?;
37900 }
37901 self.write(")");
37902 Ok(())
37903 }
37904
37905 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
37906 self.write_keyword("SUMMARIZE");
37908 if e.table.is_some() {
37909 self.write_space();
37910 self.write_keyword("TABLE");
37911 }
37912 self.write_space();
37913 self.generate_expression(&e.this)?;
37914 Ok(())
37915 }
37916
37917 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
37918 self.write_keyword("SYSTIMESTAMP");
37920 Ok(())
37921 }
37922
37923 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
37924 if let Some(this) = &e.this {
37926 self.generate_expression(this)?;
37927 }
37928 if !e.columns.is_empty() {
37929 self.write("(");
37930 for (i, col) in e.columns.iter().enumerate() {
37931 if i > 0 {
37932 self.write(", ");
37933 }
37934 self.generate_expression(col)?;
37935 }
37936 self.write(")");
37937 }
37938 Ok(())
37939 }
37940
37941 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
37942 self.write_keyword("TABLE");
37944 self.write("(");
37945 self.generate_expression(&e.this)?;
37946 self.write(")");
37947 if let Some(alias) = &e.alias {
37948 self.write_space();
37949 self.write_keyword("AS");
37950 self.write_space();
37951 self.write(alias);
37952 }
37953 Ok(())
37954 }
37955
37956 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
37957 self.write_keyword("ROWS FROM");
37959 self.write(" (");
37960 for (i, expr) in e.expressions.iter().enumerate() {
37961 if i > 0 {
37962 self.write(", ");
37963 }
37964 match expr {
37968 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
37969 self.generate_expression(&tuple.expressions[0])?;
37971 self.write_space();
37972 self.write_keyword("AS");
37973 self.write_space();
37974 self.generate_expression(&tuple.expressions[1])?;
37975 }
37976 _ => {
37977 self.generate_expression(expr)?;
37978 }
37979 }
37980 }
37981 self.write(")");
37982 if e.ordinality {
37983 self.write_space();
37984 self.write_keyword("WITH ORDINALITY");
37985 }
37986 if let Some(alias) = &e.alias {
37987 self.write_space();
37988 self.write_keyword("AS");
37989 self.write_space();
37990 self.generate_expression(alias)?;
37991 }
37992 Ok(())
37993 }
37994
37995 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
37996 use crate::dialects::DialectType;
37997
37998 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
38000 if self.config.alias_post_tablesample {
38002 if let Expression::Subquery(ref s) = **this {
38004 if let Some(ref alias) = s.alias {
38005 let mut subquery_no_alias = (**s).clone();
38007 subquery_no_alias.alias = None;
38008 subquery_no_alias.column_aliases = Vec::new();
38009 self.generate_expression(&Expression::Subquery(Box::new(
38010 subquery_no_alias,
38011 )))?;
38012 self.write_space();
38013 self.write_keyword(self.config.tablesample_keywords);
38014 self.generate_sample_body(sample)?;
38015 if let Some(ref seed) = sample.seed {
38016 self.write_space();
38017 let use_seed = sample.use_seed_keyword
38018 && !matches!(
38019 self.config.dialect,
38020 Some(crate::dialects::DialectType::Databricks)
38021 | Some(crate::dialects::DialectType::Spark)
38022 );
38023 if use_seed {
38024 self.write_keyword("SEED");
38025 } else {
38026 self.write_keyword("REPEATABLE");
38027 }
38028 self.write(" (");
38029 self.generate_expression(seed)?;
38030 self.write(")");
38031 }
38032 self.write_space();
38033 self.write_keyword("AS");
38034 self.write_space();
38035 self.generate_identifier(alias)?;
38036 return Ok(());
38037 }
38038 } else if let Expression::Alias(ref a) = **this {
38039 self.generate_expression(&a.this)?;
38041 self.write_space();
38042 self.write_keyword(self.config.tablesample_keywords);
38043 self.generate_sample_body(sample)?;
38044 if let Some(ref seed) = sample.seed {
38045 self.write_space();
38046 let use_seed = sample.use_seed_keyword
38047 && !matches!(
38048 self.config.dialect,
38049 Some(crate::dialects::DialectType::Databricks)
38050 | Some(crate::dialects::DialectType::Spark)
38051 );
38052 if use_seed {
38053 self.write_keyword("SEED");
38054 } else {
38055 self.write_keyword("REPEATABLE");
38056 }
38057 self.write(" (");
38058 self.generate_expression(seed)?;
38059 self.write(")");
38060 }
38061 self.write_space();
38063 self.write_keyword("AS");
38064 self.write_space();
38065 self.generate_identifier(&a.alias)?;
38066 return Ok(());
38067 }
38068 }
38069 self.generate_expression(this)?;
38071 self.write_space();
38072 self.write_keyword(self.config.tablesample_keywords);
38073 self.generate_sample_body(sample)?;
38074 if let Some(ref seed) = sample.seed {
38076 self.write_space();
38077 let use_seed = sample.use_seed_keyword
38079 && !matches!(
38080 self.config.dialect,
38081 Some(crate::dialects::DialectType::Databricks)
38082 | Some(crate::dialects::DialectType::Spark)
38083 );
38084 if use_seed {
38085 self.write_keyword("SEED");
38086 } else {
38087 self.write_keyword("REPEATABLE");
38088 }
38089 self.write(" (");
38090 self.generate_expression(seed)?;
38091 self.write(")");
38092 }
38093 return Ok(());
38094 }
38095
38096 self.write_keyword(self.config.tablesample_keywords);
38098 if let Some(method) = &e.method {
38099 self.write_space();
38100 self.write_keyword(method);
38101 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
38102 self.write_space();
38104 self.write_keyword("BERNOULLI");
38105 }
38106 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
38107 self.write_space();
38108 self.write_keyword("BUCKET");
38109 self.write_space();
38110 self.generate_expression(numerator)?;
38111 self.write_space();
38112 self.write_keyword("OUT OF");
38113 self.write_space();
38114 self.generate_expression(denominator)?;
38115 if let Some(field) = &e.bucket_field {
38116 self.write_space();
38117 self.write_keyword("ON");
38118 self.write_space();
38119 self.generate_expression(field)?;
38120 }
38121 } else if !e.expressions.is_empty() {
38122 self.write(" (");
38123 for (i, expr) in e.expressions.iter().enumerate() {
38124 if i > 0 {
38125 self.write(", ");
38126 }
38127 self.generate_expression(expr)?;
38128 }
38129 self.write(")");
38130 } else if let Some(percent) = &e.percent {
38131 self.write(" (");
38132 self.generate_expression(percent)?;
38133 self.write_space();
38134 self.write_keyword("PERCENT");
38135 self.write(")");
38136 }
38137 Ok(())
38138 }
38139
38140 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
38141 if let Some(prefix) = &e.prefix {
38143 self.generate_expression(prefix)?;
38144 }
38145 if let Some(this) = &e.this {
38146 self.generate_expression(this)?;
38147 }
38148 if let Some(postfix) = &e.postfix {
38149 self.generate_expression(postfix)?;
38150 }
38151 Ok(())
38152 }
38153
38154 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
38155 self.write_keyword("TAG");
38157 self.write(" (");
38158 for (i, expr) in e.expressions.iter().enumerate() {
38159 if i > 0 {
38160 self.write(", ");
38161 }
38162 self.generate_expression(expr)?;
38163 }
38164 self.write(")");
38165 Ok(())
38166 }
38167
38168 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
38169 if let Some(this) = &e.this {
38171 self.generate_expression(this)?;
38172 self.write_space();
38173 }
38174 self.write_keyword("TEMPORARY");
38175 Ok(())
38176 }
38177
38178 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
38181 self.write_keyword("TIME");
38183 self.write("(");
38184 self.generate_expression(&e.this)?;
38185 self.write(")");
38186 Ok(())
38187 }
38188
38189 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
38190 self.write_keyword("TIME_ADD");
38192 self.write("(");
38193 self.generate_expression(&e.this)?;
38194 self.write(", ");
38195 self.generate_expression(&e.expression)?;
38196 if let Some(unit) = &e.unit {
38197 self.write(", ");
38198 self.write_keyword(unit);
38199 }
38200 self.write(")");
38201 Ok(())
38202 }
38203
38204 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
38205 self.write_keyword("TIME_DIFF");
38207 self.write("(");
38208 self.generate_expression(&e.this)?;
38209 self.write(", ");
38210 self.generate_expression(&e.expression)?;
38211 if let Some(unit) = &e.unit {
38212 self.write(", ");
38213 self.write_keyword(unit);
38214 }
38215 self.write(")");
38216 Ok(())
38217 }
38218
38219 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
38220 self.write_keyword("TIME_FROM_PARTS");
38222 self.write("(");
38223 let mut first = true;
38224 if let Some(hour) = &e.hour {
38225 self.generate_expression(hour)?;
38226 first = false;
38227 }
38228 if let Some(minute) = &e.min {
38229 if !first {
38230 self.write(", ");
38231 }
38232 self.generate_expression(minute)?;
38233 first = false;
38234 }
38235 if let Some(second) = &e.sec {
38236 if !first {
38237 self.write(", ");
38238 }
38239 self.generate_expression(second)?;
38240 first = false;
38241 }
38242 if let Some(ns) = &e.nano {
38243 if !first {
38244 self.write(", ");
38245 }
38246 self.generate_expression(ns)?;
38247 }
38248 self.write(")");
38249 Ok(())
38250 }
38251
38252 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
38253 self.write_keyword("TIME_SLICE");
38255 self.write("(");
38256 self.generate_expression(&e.this)?;
38257 self.write(", ");
38258 self.generate_expression(&e.expression)?;
38259 self.write(", ");
38260 self.write_keyword(&e.unit);
38261 self.write(")");
38262 Ok(())
38263 }
38264
38265 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
38266 self.write_keyword("TIME_STR_TO_TIME");
38268 self.write("(");
38269 self.generate_expression(&e.this)?;
38270 self.write(")");
38271 Ok(())
38272 }
38273
38274 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
38275 self.write_keyword("TIME_SUB");
38277 self.write("(");
38278 self.generate_expression(&e.this)?;
38279 self.write(", ");
38280 self.generate_expression(&e.expression)?;
38281 if let Some(unit) = &e.unit {
38282 self.write(", ");
38283 self.write_keyword(unit);
38284 }
38285 self.write(")");
38286 Ok(())
38287 }
38288
38289 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
38290 match self.config.dialect {
38291 Some(DialectType::Exasol) => {
38292 self.write_keyword("TO_CHAR");
38294 self.write("(");
38295 self.generate_expression(&e.this)?;
38296 self.write(", '");
38297 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
38298 self.write("'");
38299 self.write(")");
38300 }
38301 Some(DialectType::PostgreSQL)
38302 | Some(DialectType::Redshift)
38303 | Some(DialectType::Materialize) => {
38304 self.write_keyword("TO_CHAR");
38306 self.write("(");
38307 self.generate_expression(&e.this)?;
38308 self.write(", '");
38309 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
38310 self.write("'");
38311 self.write(")");
38312 }
38313 Some(DialectType::Oracle) => {
38314 self.write_keyword("TO_CHAR");
38316 self.write("(");
38317 self.generate_expression(&e.this)?;
38318 self.write(", '");
38319 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
38320 self.write("'");
38321 self.write(")");
38322 }
38323 Some(DialectType::Drill) => {
38324 self.write_keyword("TO_CHAR");
38326 self.write("(");
38327 self.generate_expression(&e.this)?;
38328 self.write(", '");
38329 self.write(&Self::strftime_to_java_format(&e.format));
38330 self.write("'");
38331 self.write(")");
38332 }
38333 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
38334 self.write_keyword("FORMAT");
38336 self.write("(");
38337 self.generate_expression(&e.this)?;
38338 self.write(", '");
38339 self.write(&Self::strftime_to_tsql_format(&e.format));
38340 self.write("'");
38341 self.write(")");
38342 }
38343 Some(DialectType::DuckDB) => {
38344 self.write_keyword("STRFTIME");
38346 self.write("(");
38347 self.generate_expression(&e.this)?;
38348 self.write(", '");
38349 self.write(&e.format);
38350 self.write("'");
38351 self.write(")");
38352 }
38353 Some(DialectType::BigQuery) => {
38354 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
38357 self.write_keyword("FORMAT_DATE");
38358 self.write("('");
38359 self.write(&fmt);
38360 self.write("', ");
38361 self.generate_expression(&e.this)?;
38362 self.write(")");
38363 }
38364 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
38365 self.write_keyword("DATE_FORMAT");
38367 self.write("(");
38368 self.generate_expression(&e.this)?;
38369 self.write(", '");
38370 self.write(&Self::strftime_to_java_format(&e.format));
38371 self.write("'");
38372 self.write(")");
38373 }
38374 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
38375 self.write_keyword("DATE_FORMAT");
38377 self.write("(");
38378 self.generate_expression(&e.this)?;
38379 self.write(", '");
38380 self.write(&e.format);
38381 self.write("'");
38382 self.write(")");
38383 }
38384 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
38385 self.write_keyword("DATE_FORMAT");
38387 self.write("(");
38388 self.generate_expression(&e.this)?;
38389 self.write(", '");
38390 self.write(&e.format);
38391 self.write("'");
38392 self.write(")");
38393 }
38394 _ => {
38395 self.write_keyword("TIME_TO_STR");
38397 self.write("(");
38398 self.generate_expression(&e.this)?;
38399 self.write(", '");
38400 self.write(&e.format);
38401 self.write("'");
38402 self.write(")");
38403 }
38404 }
38405 Ok(())
38406 }
38407
38408 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
38409 match self.config.dialect {
38410 Some(DialectType::DuckDB) => {
38411 self.write_keyword("EPOCH");
38413 self.write("(");
38414 self.generate_expression(&e.this)?;
38415 self.write(")");
38416 }
38417 Some(DialectType::Hive)
38418 | Some(DialectType::Spark)
38419 | Some(DialectType::Databricks)
38420 | Some(DialectType::Doris)
38421 | Some(DialectType::StarRocks)
38422 | Some(DialectType::Drill) => {
38423 self.write_keyword("UNIX_TIMESTAMP");
38425 self.write("(");
38426 self.generate_expression(&e.this)?;
38427 self.write(")");
38428 }
38429 Some(DialectType::Presto) | Some(DialectType::Trino) => {
38430 self.write_keyword("TO_UNIXTIME");
38432 self.write("(");
38433 self.generate_expression(&e.this)?;
38434 self.write(")");
38435 }
38436 _ => {
38437 self.write_keyword("TIME_TO_UNIX");
38439 self.write("(");
38440 self.generate_expression(&e.this)?;
38441 self.write(")");
38442 }
38443 }
38444 Ok(())
38445 }
38446
38447 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
38448 match self.config.dialect {
38449 Some(DialectType::Hive) => {
38450 self.write_keyword("TO_DATE");
38452 self.write("(");
38453 self.generate_expression(&e.this)?;
38454 self.write(")");
38455 }
38456 _ => {
38457 self.write_keyword("TIME_STR_TO_DATE");
38459 self.write("(");
38460 self.generate_expression(&e.this)?;
38461 self.write(")");
38462 }
38463 }
38464 Ok(())
38465 }
38466
38467 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
38468 self.write_keyword("TIME_TRUNC");
38470 self.write("(");
38471 self.generate_expression(&e.this)?;
38472 self.write(", ");
38473 self.write_keyword(&e.unit);
38474 self.write(")");
38475 Ok(())
38476 }
38477
38478 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
38479 if let Some(unit) = &e.unit {
38481 self.write_keyword(unit);
38482 }
38483 Ok(())
38484 }
38485
38486 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
38490 use crate::dialects::DialectType;
38491 use crate::expressions::Literal;
38492
38493 match self.config.dialect {
38494 Some(DialectType::Exasol) => {
38496 self.write_keyword("TO_TIMESTAMP");
38497 self.write("(");
38498 if let Some(this) = &e.this {
38500 match this.as_ref() {
38501 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
38502 let Literal::String(s) = lit.as_ref() else {
38503 unreachable!()
38504 };
38505 self.write("'");
38506 self.write(s);
38507 self.write("'");
38508 }
38509 _ => {
38510 self.generate_expression(this)?;
38511 }
38512 }
38513 }
38514 self.write(")");
38515 }
38516 _ => {
38518 self.write_keyword("TIMESTAMP");
38519 self.write("(");
38520 if let Some(this) = &e.this {
38521 self.generate_expression(this)?;
38522 }
38523 if let Some(zone) = &e.zone {
38524 self.write(", ");
38525 self.generate_expression(zone)?;
38526 }
38527 self.write(")");
38528 }
38529 }
38530 Ok(())
38531 }
38532
38533 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
38534 self.write_keyword("TIMESTAMP_ADD");
38536 self.write("(");
38537 self.generate_expression(&e.this)?;
38538 self.write(", ");
38539 self.generate_expression(&e.expression)?;
38540 if let Some(unit) = &e.unit {
38541 self.write(", ");
38542 self.write_keyword(unit);
38543 }
38544 self.write(")");
38545 Ok(())
38546 }
38547
38548 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
38549 self.write_keyword("TIMESTAMP_DIFF");
38551 self.write("(");
38552 self.generate_expression(&e.this)?;
38553 self.write(", ");
38554 self.generate_expression(&e.expression)?;
38555 if let Some(unit) = &e.unit {
38556 self.write(", ");
38557 self.write_keyword(unit);
38558 }
38559 self.write(")");
38560 Ok(())
38561 }
38562
38563 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
38564 self.write_keyword("TIMESTAMP_FROM_PARTS");
38566 self.write("(");
38567 if let Some(this) = &e.this {
38568 self.generate_expression(this)?;
38569 }
38570 if let Some(expression) = &e.expression {
38571 self.write(", ");
38572 self.generate_expression(expression)?;
38573 }
38574 if let Some(zone) = &e.zone {
38575 self.write(", ");
38576 self.generate_expression(zone)?;
38577 }
38578 if let Some(milli) = &e.milli {
38579 self.write(", ");
38580 self.generate_expression(milli)?;
38581 }
38582 self.write(")");
38583 Ok(())
38584 }
38585
38586 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
38587 self.write_keyword("TIMESTAMP_SUB");
38589 self.write("(");
38590 self.generate_expression(&e.this)?;
38591 self.write(", ");
38592 self.write_keyword("INTERVAL");
38593 self.write_space();
38594 self.generate_expression(&e.expression)?;
38595 if let Some(unit) = &e.unit {
38596 self.write_space();
38597 self.write_keyword(unit);
38598 }
38599 self.write(")");
38600 Ok(())
38601 }
38602
38603 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
38604 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
38606 self.write("(");
38607 if let Some(zone) = &e.zone {
38608 self.generate_expression(zone)?;
38609 }
38610 self.write(")");
38611 Ok(())
38612 }
38613
38614 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
38615 self.write_keyword("TO_BINARY");
38617 self.write("(");
38618 self.generate_expression(&e.this)?;
38619 if let Some(format) = &e.format {
38620 self.write(", '");
38621 self.write(format);
38622 self.write("'");
38623 }
38624 self.write(")");
38625 Ok(())
38626 }
38627
38628 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
38629 self.write_keyword("TO_BOOLEAN");
38631 self.write("(");
38632 self.generate_expression(&e.this)?;
38633 self.write(")");
38634 Ok(())
38635 }
38636
38637 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
38638 self.write_keyword("TO_CHAR");
38640 self.write("(");
38641 self.generate_expression(&e.this)?;
38642 if let Some(format) = &e.format {
38643 self.write(", '");
38644 self.write(format);
38645 self.write("'");
38646 }
38647 if let Some(nlsparam) = &e.nlsparam {
38648 self.write(", ");
38649 self.generate_expression(nlsparam)?;
38650 }
38651 self.write(")");
38652 Ok(())
38653 }
38654
38655 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
38656 self.write_keyword("TO_DECFLOAT");
38658 self.write("(");
38659 self.generate_expression(&e.this)?;
38660 if let Some(format) = &e.format {
38661 self.write(", '");
38662 self.write(format);
38663 self.write("'");
38664 }
38665 self.write(")");
38666 Ok(())
38667 }
38668
38669 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
38670 self.write_keyword("TO_DOUBLE");
38672 self.write("(");
38673 self.generate_expression(&e.this)?;
38674 if let Some(format) = &e.format {
38675 self.write(", '");
38676 self.write(format);
38677 self.write("'");
38678 }
38679 self.write(")");
38680 Ok(())
38681 }
38682
38683 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
38684 self.write_keyword("TO_FILE");
38686 self.write("(");
38687 self.generate_expression(&e.this)?;
38688 if let Some(path) = &e.path {
38689 self.write(", ");
38690 self.generate_expression(path)?;
38691 }
38692 self.write(")");
38693 Ok(())
38694 }
38695
38696 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
38697 let is_safe = e.safe.is_some();
38700 if is_safe {
38701 self.write_keyword("TRY_TO_NUMBER");
38702 } else {
38703 self.write_keyword("TO_NUMBER");
38704 }
38705 self.write("(");
38706 self.generate_expression(&e.this)?;
38707 let precision_is_snowflake_default = e.precision.is_none()
38708 || matches!(
38709 e.precision.as_deref(),
38710 Some(Expression::Literal(lit))
38711 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
38712 );
38713 let is_snowflake_default_precision =
38714 matches!(self.config.dialect, Some(DialectType::Snowflake))
38715 && e.nlsparam.is_none()
38716 && e.scale.is_none()
38717 && matches!(
38718 e.format.as_deref(),
38719 Some(Expression::Literal(lit))
38720 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
38721 )
38722 && precision_is_snowflake_default;
38723
38724 if !is_snowflake_default_precision {
38725 if let Some(format) = &e.format {
38726 self.write(", ");
38727 self.generate_expression(format)?;
38728 }
38729 if let Some(nlsparam) = &e.nlsparam {
38730 self.write(", ");
38731 self.generate_expression(nlsparam)?;
38732 }
38733 if let Some(precision) = &e.precision {
38734 self.write(", ");
38735 self.generate_expression(precision)?;
38736 }
38737 if let Some(scale) = &e.scale {
38738 self.write(", ");
38739 self.generate_expression(scale)?;
38740 }
38741 }
38742 self.write(")");
38743 Ok(())
38744 }
38745
38746 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
38747 self.write_keyword("TO_TABLE");
38749 self.write_space();
38750 self.generate_expression(&e.this)?;
38751 Ok(())
38752 }
38753
38754 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
38755 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
38757 Expression::Identifier(id) => id.name.clone(),
38758 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
38759 let Literal::String(s) = lit.as_ref() else {
38760 unreachable!()
38761 };
38762 s.clone()
38763 }
38764 _ => String::new(),
38765 });
38766
38767 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
38768 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
38769 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
38770 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
38771 });
38772
38773 let use_start_transaction = matches!(
38775 self.config.dialect,
38776 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
38777 );
38778 let strip_transaction = matches!(
38780 self.config.dialect,
38781 Some(DialectType::Snowflake)
38782 | Some(DialectType::PostgreSQL)
38783 | Some(DialectType::Redshift)
38784 | Some(DialectType::MySQL)
38785 | Some(DialectType::Hive)
38786 | Some(DialectType::Spark)
38787 | Some(DialectType::Databricks)
38788 | Some(DialectType::DuckDB)
38789 | Some(DialectType::Oracle)
38790 | Some(DialectType::Doris)
38791 | Some(DialectType::StarRocks)
38792 | Some(DialectType::Materialize)
38793 | Some(DialectType::ClickHouse)
38794 );
38795
38796 if is_start || use_start_transaction {
38797 self.write_keyword("START TRANSACTION");
38799 if let Some(modes) = &e.modes {
38800 self.write_space();
38801 self.generate_expression(modes)?;
38802 }
38803 } else {
38804 self.write_keyword("BEGIN");
38806
38807 let is_kind = e.this.as_ref().map_or(false, |t| {
38809 if let Expression::Identifier(id) = t.as_ref() {
38810 id.name.eq_ignore_ascii_case("DEFERRED")
38811 || id.name.eq_ignore_ascii_case("IMMEDIATE")
38812 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
38813 } else {
38814 false
38815 }
38816 });
38817
38818 if is_kind {
38820 if let Some(this) = &e.this {
38821 self.write_space();
38822 if let Expression::Identifier(id) = this.as_ref() {
38823 self.write_keyword(&id.name);
38824 }
38825 }
38826 }
38827
38828 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
38830 self.write_space();
38831 self.write_keyword("TRANSACTION");
38832 }
38833
38834 if !is_kind {
38836 if let Some(this) = &e.this {
38837 self.write_space();
38838 self.generate_expression(this)?;
38839 }
38840 }
38841
38842 if has_with_mark {
38844 self.write_space();
38845 self.write_keyword("WITH MARK");
38846 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
38847 if let Literal::String(desc) = lit.as_ref() {
38848 if !desc.is_empty() {
38849 self.write_space();
38850 self.write(&format!("'{}'", desc));
38851 }
38852 }
38853 }
38854 }
38855
38856 if let Some(modes) = &e.modes {
38858 self.write_space();
38859 self.generate_expression(modes)?;
38860 }
38861 }
38862 Ok(())
38863 }
38864
38865 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
38866 self.write_keyword("TRANSFORM");
38868 self.write("(");
38869 self.generate_expression(&e.this)?;
38870 self.write(", ");
38871 self.generate_expression(&e.expression)?;
38872 self.write(")");
38873 Ok(())
38874 }
38875
38876 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
38877 self.write_keyword("TRANSFORM");
38879 self.write("(");
38880 if self.config.pretty && !e.expressions.is_empty() {
38881 self.indent_level += 1;
38882 for (i, expr) in e.expressions.iter().enumerate() {
38883 if i > 0 {
38884 self.write(",");
38885 }
38886 self.write_newline();
38887 self.write_indent();
38888 self.generate_expression(expr)?;
38889 }
38890 self.indent_level -= 1;
38891 self.write_newline();
38892 self.write(")");
38893 } else {
38894 for (i, expr) in e.expressions.iter().enumerate() {
38895 if i > 0 {
38896 self.write(", ");
38897 }
38898 self.generate_expression(expr)?;
38899 }
38900 self.write(")");
38901 }
38902 Ok(())
38903 }
38904
38905 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
38906 use crate::dialects::DialectType;
38907 if let Some(this) = &e.this {
38909 self.generate_expression(this)?;
38910 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
38911 self.write_space();
38912 }
38913 }
38914 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
38915 self.write_keyword("TRANSIENT");
38916 }
38917 Ok(())
38918 }
38919
38920 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
38921 self.write_keyword("TRANSLATE");
38923 self.write("(");
38924 self.generate_expression(&e.this)?;
38925 if let Some(from) = &e.from_ {
38926 self.write(", ");
38927 self.generate_expression(from)?;
38928 }
38929 if let Some(to) = &e.to {
38930 self.write(", ");
38931 self.generate_expression(to)?;
38932 }
38933 self.write(")");
38934 Ok(())
38935 }
38936
38937 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
38938 self.write_keyword("TRANSLATE");
38940 self.write("(");
38941 self.generate_expression(&e.this)?;
38942 self.write_space();
38943 self.write_keyword("USING");
38944 self.write_space();
38945 self.generate_expression(&e.expression)?;
38946 if e.with_error.is_some() {
38947 self.write_space();
38948 self.write_keyword("WITH ERROR");
38949 }
38950 self.write(")");
38951 Ok(())
38952 }
38953
38954 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
38955 self.write_keyword("TRUNCATE TABLE");
38957 self.write_space();
38958 for (i, expr) in e.expressions.iter().enumerate() {
38959 if i > 0 {
38960 self.write(", ");
38961 }
38962 self.generate_expression(expr)?;
38963 }
38964 Ok(())
38965 }
38966
38967 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
38968 self.write_keyword("TRY_BASE64_DECODE_BINARY");
38970 self.write("(");
38971 self.generate_expression(&e.this)?;
38972 if let Some(alphabet) = &e.alphabet {
38973 self.write(", ");
38974 self.generate_expression(alphabet)?;
38975 }
38976 self.write(")");
38977 Ok(())
38978 }
38979
38980 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
38981 self.write_keyword("TRY_BASE64_DECODE_STRING");
38983 self.write("(");
38984 self.generate_expression(&e.this)?;
38985 if let Some(alphabet) = &e.alphabet {
38986 self.write(", ");
38987 self.generate_expression(alphabet)?;
38988 }
38989 self.write(")");
38990 Ok(())
38991 }
38992
38993 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
38994 self.write_keyword("TRY_TO_DECFLOAT");
38996 self.write("(");
38997 self.generate_expression(&e.this)?;
38998 if let Some(format) = &e.format {
38999 self.write(", '");
39000 self.write(format);
39001 self.write("'");
39002 }
39003 self.write(")");
39004 Ok(())
39005 }
39006
39007 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
39008 self.write_keyword("TS_OR_DS_ADD");
39010 self.write("(");
39011 self.generate_expression(&e.this)?;
39012 self.write(", ");
39013 self.generate_expression(&e.expression)?;
39014 if let Some(unit) = &e.unit {
39015 self.write(", ");
39016 self.write_keyword(unit);
39017 }
39018 if let Some(return_type) = &e.return_type {
39019 self.write(", ");
39020 self.generate_expression(return_type)?;
39021 }
39022 self.write(")");
39023 Ok(())
39024 }
39025
39026 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
39027 self.write_keyword("TS_OR_DS_DIFF");
39029 self.write("(");
39030 self.generate_expression(&e.this)?;
39031 self.write(", ");
39032 self.generate_expression(&e.expression)?;
39033 if let Some(unit) = &e.unit {
39034 self.write(", ");
39035 self.write_keyword(unit);
39036 }
39037 self.write(")");
39038 Ok(())
39039 }
39040
39041 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
39042 let default_time_format = "%Y-%m-%d %H:%M:%S";
39043 let default_date_format = "%Y-%m-%d";
39044 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
39045 f != default_time_format && f != default_date_format
39046 });
39047
39048 if has_non_default_format {
39049 let fmt = e.format.as_ref().unwrap();
39051 match self.config.dialect {
39052 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
39053 let str_to_time = crate::expressions::StrToTime {
39056 this: Box::new((*e.this).clone()),
39057 format: fmt.clone(),
39058 zone: None,
39059 safe: None,
39060 target_type: None,
39061 };
39062 self.generate_str_to_time(&str_to_time)?;
39063 }
39064 Some(DialectType::Hive)
39065 | Some(DialectType::Spark)
39066 | Some(DialectType::Databricks) => {
39067 self.write_keyword("TO_DATE");
39069 self.write("(");
39070 self.generate_expression(&e.this)?;
39071 self.write(", '");
39072 self.write(&Self::strftime_to_java_format(fmt));
39073 self.write("')");
39074 }
39075 Some(DialectType::Snowflake) => {
39076 self.write_keyword("TO_DATE");
39078 self.write("(");
39079 self.generate_expression(&e.this)?;
39080 self.write(", '");
39081 self.write(&Self::strftime_to_snowflake_format(fmt));
39082 self.write("')");
39083 }
39084 Some(DialectType::Doris) => {
39085 self.write_keyword("TO_DATE");
39087 self.write("(");
39088 self.generate_expression(&e.this)?;
39089 self.write(")");
39090 }
39091 _ => {
39092 self.write_keyword("CAST");
39094 self.write("(");
39095 let str_to_time = crate::expressions::StrToTime {
39096 this: Box::new((*e.this).clone()),
39097 format: fmt.clone(),
39098 zone: None,
39099 safe: None,
39100 target_type: None,
39101 };
39102 self.generate_str_to_time(&str_to_time)?;
39103 self.write_keyword(" AS ");
39104 self.write_keyword("DATE");
39105 self.write(")");
39106 }
39107 }
39108 } else {
39109 match self.config.dialect {
39111 Some(DialectType::MySQL)
39112 | Some(DialectType::SQLite)
39113 | Some(DialectType::StarRocks) => {
39114 self.write_keyword("DATE");
39116 self.write("(");
39117 self.generate_expression(&e.this)?;
39118 self.write(")");
39119 }
39120 Some(DialectType::Hive)
39121 | Some(DialectType::Spark)
39122 | Some(DialectType::Databricks)
39123 | Some(DialectType::Snowflake)
39124 | Some(DialectType::Doris) => {
39125 self.write_keyword("TO_DATE");
39127 self.write("(");
39128 self.generate_expression(&e.this)?;
39129 self.write(")");
39130 }
39131 Some(DialectType::Presto)
39132 | Some(DialectType::Trino)
39133 | Some(DialectType::Athena) => {
39134 self.write_keyword("CAST");
39136 self.write("(");
39137 self.write_keyword("CAST");
39138 self.write("(");
39139 self.generate_expression(&e.this)?;
39140 self.write_keyword(" AS ");
39141 self.write_keyword("TIMESTAMP");
39142 self.write(")");
39143 self.write_keyword(" AS ");
39144 self.write_keyword("DATE");
39145 self.write(")");
39146 }
39147 Some(DialectType::ClickHouse) => {
39148 self.write_keyword("CAST");
39150 self.write("(");
39151 self.generate_expression(&e.this)?;
39152 self.write_keyword(" AS ");
39153 self.write("Nullable(DATE)");
39154 self.write(")");
39155 }
39156 _ => {
39157 self.write_keyword("CAST");
39159 self.write("(");
39160 self.generate_expression(&e.this)?;
39161 self.write_keyword(" AS ");
39162 self.write_keyword("DATE");
39163 self.write(")");
39164 }
39165 }
39166 }
39167 Ok(())
39168 }
39169
39170 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
39171 self.write_keyword("TS_OR_DS_TO_TIME");
39173 self.write("(");
39174 self.generate_expression(&e.this)?;
39175 if let Some(format) = &e.format {
39176 self.write(", '");
39177 self.write(format);
39178 self.write("'");
39179 }
39180 self.write(")");
39181 Ok(())
39182 }
39183
39184 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
39185 self.write_keyword("UNHEX");
39187 self.write("(");
39188 self.generate_expression(&e.this)?;
39189 if let Some(expression) = &e.expression {
39190 self.write(", ");
39191 self.generate_expression(expression)?;
39192 }
39193 self.write(")");
39194 Ok(())
39195 }
39196
39197 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
39198 self.write("U&");
39200 self.generate_expression(&e.this)?;
39201 if let Some(escape) = &e.escape {
39202 self.write_space();
39203 self.write_keyword("UESCAPE");
39204 self.write_space();
39205 self.generate_expression(escape)?;
39206 }
39207 Ok(())
39208 }
39209
39210 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
39211 self.write_keyword("UNIFORM");
39213 self.write("(");
39214 self.generate_expression(&e.this)?;
39215 self.write(", ");
39216 self.generate_expression(&e.expression)?;
39217 if let Some(gen) = &e.gen {
39218 self.write(", ");
39219 self.generate_expression(gen)?;
39220 }
39221 if let Some(seed) = &e.seed {
39222 self.write(", ");
39223 self.generate_expression(seed)?;
39224 }
39225 self.write(")");
39226 Ok(())
39227 }
39228
39229 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
39230 self.write_keyword("UNIQUE");
39232 if e.nulls.is_some() {
39234 self.write(" NULLS NOT DISTINCT");
39235 }
39236 if let Some(this) = &e.this {
39237 self.write_space();
39238 self.generate_expression(this)?;
39239 }
39240 if let Some(index_type) = &e.index_type {
39241 self.write(" USING ");
39242 self.generate_expression(index_type)?;
39243 }
39244 if let Some(on_conflict) = &e.on_conflict {
39245 self.write_space();
39246 self.generate_expression(on_conflict)?;
39247 }
39248 for opt in &e.options {
39249 self.write_space();
39250 self.generate_expression(opt)?;
39251 }
39252 Ok(())
39253 }
39254
39255 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
39256 self.write_keyword("UNIQUE KEY");
39258 self.write(" (");
39259 for (i, expr) in e.expressions.iter().enumerate() {
39260 if i > 0 {
39261 self.write(", ");
39262 }
39263 self.generate_expression(expr)?;
39264 }
39265 self.write(")");
39266 Ok(())
39267 }
39268
39269 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
39270 self.write_keyword("ROLLUP");
39272 self.write(" (");
39273 for (i, index) in e.expressions.iter().enumerate() {
39274 if i > 0 {
39275 self.write(", ");
39276 }
39277 self.generate_identifier(&index.name)?;
39278 self.write("(");
39279 for (j, col) in index.expressions.iter().enumerate() {
39280 if j > 0 {
39281 self.write(", ");
39282 }
39283 self.generate_identifier(col)?;
39284 }
39285 self.write(")");
39286 }
39287 self.write(")");
39288 Ok(())
39289 }
39290
39291 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
39292 match self.config.dialect {
39293 Some(DialectType::DuckDB) => {
39294 self.write_keyword("STRFTIME");
39296 self.write("(");
39297 self.write_keyword("TO_TIMESTAMP");
39298 self.write("(");
39299 self.generate_expression(&e.this)?;
39300 self.write("), '");
39301 if let Some(format) = &e.format {
39302 self.write(format);
39303 }
39304 self.write("')");
39305 }
39306 Some(DialectType::Hive) => {
39307 self.write_keyword("FROM_UNIXTIME");
39309 self.write("(");
39310 self.generate_expression(&e.this)?;
39311 if let Some(format) = &e.format {
39312 if format != "yyyy-MM-dd HH:mm:ss" {
39313 self.write(", '");
39314 self.write(format);
39315 self.write("'");
39316 }
39317 }
39318 self.write(")");
39319 }
39320 Some(DialectType::Presto) | Some(DialectType::Trino) => {
39321 self.write_keyword("DATE_FORMAT");
39323 self.write("(");
39324 self.write_keyword("FROM_UNIXTIME");
39325 self.write("(");
39326 self.generate_expression(&e.this)?;
39327 self.write("), '");
39328 if let Some(format) = &e.format {
39329 self.write(format);
39330 }
39331 self.write("')");
39332 }
39333 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
39334 self.write_keyword("FROM_UNIXTIME");
39336 self.write("(");
39337 self.generate_expression(&e.this)?;
39338 if let Some(format) = &e.format {
39339 self.write(", '");
39340 self.write(format);
39341 self.write("'");
39342 }
39343 self.write(")");
39344 }
39345 _ => {
39346 self.write_keyword("UNIX_TO_STR");
39348 self.write("(");
39349 self.generate_expression(&e.this)?;
39350 if let Some(format) = &e.format {
39351 self.write(", '");
39352 self.write(format);
39353 self.write("'");
39354 }
39355 self.write(")");
39356 }
39357 }
39358 Ok(())
39359 }
39360
39361 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
39362 use crate::dialects::DialectType;
39363 let scale = e.scale.unwrap_or(0); match self.config.dialect {
39366 Some(DialectType::Snowflake) => {
39367 self.write_keyword("TO_TIMESTAMP");
39369 self.write("(");
39370 self.generate_expression(&e.this)?;
39371 if let Some(s) = e.scale {
39372 if s > 0 {
39373 self.write(", ");
39374 self.write(&s.to_string());
39375 }
39376 }
39377 self.write(")");
39378 }
39379 Some(DialectType::BigQuery) => {
39380 match scale {
39383 0 => {
39384 self.write_keyword("TIMESTAMP_SECONDS");
39385 self.write("(");
39386 self.generate_expression(&e.this)?;
39387 self.write(")");
39388 }
39389 3 => {
39390 self.write_keyword("TIMESTAMP_MILLIS");
39391 self.write("(");
39392 self.generate_expression(&e.this)?;
39393 self.write(")");
39394 }
39395 6 => {
39396 self.write_keyword("TIMESTAMP_MICROS");
39397 self.write("(");
39398 self.generate_expression(&e.this)?;
39399 self.write(")");
39400 }
39401 _ => {
39402 self.write_keyword("TIMESTAMP_SECONDS");
39404 self.write("(CAST(");
39405 self.generate_expression(&e.this)?;
39406 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
39407 }
39408 }
39409 }
39410 Some(DialectType::Spark) => {
39411 match scale {
39416 0 => {
39417 self.write_keyword("CAST");
39418 self.write("(");
39419 self.write_keyword("FROM_UNIXTIME");
39420 self.write("(");
39421 self.generate_expression(&e.this)?;
39422 self.write(") ");
39423 self.write_keyword("AS TIMESTAMP");
39424 self.write(")");
39425 }
39426 3 => {
39427 self.write_keyword("TIMESTAMP_MILLIS");
39428 self.write("(");
39429 self.generate_expression(&e.this)?;
39430 self.write(")");
39431 }
39432 6 => {
39433 self.write_keyword("TIMESTAMP_MICROS");
39434 self.write("(");
39435 self.generate_expression(&e.this)?;
39436 self.write(")");
39437 }
39438 _ => {
39439 self.write_keyword("TIMESTAMP_SECONDS");
39440 self.write("(");
39441 self.generate_expression(&e.this)?;
39442 self.write(&format!(" / POWER(10, {}))", scale));
39443 }
39444 }
39445 }
39446 Some(DialectType::Databricks) => {
39447 match scale {
39451 0 => {
39452 self.write_keyword("CAST");
39453 self.write("(");
39454 self.write_keyword("FROM_UNIXTIME");
39455 self.write("(");
39456 self.generate_expression(&e.this)?;
39457 self.write(") ");
39458 self.write_keyword("AS TIMESTAMP");
39459 self.write(")");
39460 }
39461 3 => {
39462 self.write_keyword("TIMESTAMP_MILLIS");
39463 self.write("(");
39464 self.generate_expression(&e.this)?;
39465 self.write(")");
39466 }
39467 6 => {
39468 self.write_keyword("TIMESTAMP_MICROS");
39469 self.write("(");
39470 self.generate_expression(&e.this)?;
39471 self.write(")");
39472 }
39473 _ => {
39474 self.write_keyword("TIMESTAMP_SECONDS");
39475 self.write("(");
39476 self.generate_expression(&e.this)?;
39477 self.write(&format!(" / POWER(10, {}))", scale));
39478 }
39479 }
39480 }
39481 Some(DialectType::Hive) => {
39482 if scale == 0 {
39484 self.write_keyword("FROM_UNIXTIME");
39485 self.write("(");
39486 self.generate_expression(&e.this)?;
39487 self.write(")");
39488 } else {
39489 self.write_keyword("FROM_UNIXTIME");
39490 self.write("(");
39491 self.generate_expression(&e.this)?;
39492 self.write(&format!(" / POWER(10, {})", scale));
39493 self.write(")");
39494 }
39495 }
39496 Some(DialectType::Presto) | Some(DialectType::Trino) => {
39497 if scale == 0 {
39500 self.write_keyword("FROM_UNIXTIME");
39501 self.write("(");
39502 self.generate_expression(&e.this)?;
39503 self.write(")");
39504 } else {
39505 self.write_keyword("FROM_UNIXTIME");
39506 self.write("(CAST(");
39507 self.generate_expression(&e.this)?;
39508 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
39509 }
39510 }
39511 Some(DialectType::DuckDB) => {
39512 match scale {
39516 0 => {
39517 self.write_keyword("TO_TIMESTAMP");
39518 self.write("(");
39519 self.generate_expression(&e.this)?;
39520 self.write(")");
39521 }
39522 3 => {
39523 self.write_keyword("EPOCH_MS");
39524 self.write("(");
39525 self.generate_expression(&e.this)?;
39526 self.write(")");
39527 }
39528 6 => {
39529 self.write_keyword("MAKE_TIMESTAMP");
39530 self.write("(");
39531 self.generate_expression(&e.this)?;
39532 self.write(")");
39533 }
39534 _ => {
39535 self.write_keyword("TO_TIMESTAMP");
39536 self.write("(");
39537 self.generate_expression(&e.this)?;
39538 self.write(&format!(" / POWER(10, {}))", scale));
39539 self.write_keyword(" AT TIME ZONE");
39540 self.write(" 'UTC'");
39541 }
39542 }
39543 }
39544 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
39545 self.write_keyword("FROM_UNIXTIME");
39547 self.write("(");
39548 self.generate_expression(&e.this)?;
39549 self.write(")");
39550 }
39551 Some(DialectType::Oracle) => {
39552 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
39554 self.generate_expression(&e.this)?;
39555 self.write(" / 86400)");
39556 }
39557 Some(DialectType::Redshift) => {
39558 self.write("(TIMESTAMP 'epoch' + ");
39561 if scale == 0 {
39562 self.generate_expression(&e.this)?;
39563 } else {
39564 self.write("(");
39565 self.generate_expression(&e.this)?;
39566 self.write(&format!(" / POWER(10, {}))", scale));
39567 }
39568 self.write(" * INTERVAL '1 SECOND')");
39569 }
39570 Some(DialectType::Exasol) => {
39571 self.write_keyword("FROM_POSIX_TIME");
39573 self.write("(");
39574 self.generate_expression(&e.this)?;
39575 self.write(")");
39576 }
39577 _ => {
39578 self.write_keyword("TO_TIMESTAMP");
39580 self.write("(");
39581 self.generate_expression(&e.this)?;
39582 if let Some(s) = e.scale {
39583 self.write(", ");
39584 self.write(&s.to_string());
39585 }
39586 self.write(")");
39587 }
39588 }
39589 Ok(())
39590 }
39591
39592 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
39593 if !matches!(&*e.this, Expression::Null(_)) {
39595 self.write_keyword("NAME");
39596 self.write_space();
39597 self.generate_expression(&e.this)?;
39598 }
39599 if !e.expressions.is_empty() {
39600 self.write_space();
39601 self.write_keyword("VALUE");
39602 self.write_space();
39603 for (i, expr) in e.expressions.iter().enumerate() {
39604 if i > 0 {
39605 self.write(", ");
39606 }
39607 self.generate_expression(expr)?;
39608 }
39609 }
39610 Ok(())
39611 }
39612
39613 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
39614 if e.wrapped.is_some() {
39616 self.write("(");
39617 }
39618 self.generate_expression(&e.this)?;
39619 if e.wrapped.is_some() {
39620 self.write(")");
39621 }
39622 self.write("(");
39623 for (i, expr) in e.expressions.iter().enumerate() {
39624 if i > 0 {
39625 self.write(", ");
39626 }
39627 self.generate_expression(expr)?;
39628 }
39629 self.write(")");
39630 Ok(())
39631 }
39632
39633 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
39634 self.write_keyword("USING TEMPLATE");
39636 self.write_space();
39637 self.generate_expression(&e.this)?;
39638 Ok(())
39639 }
39640
39641 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
39642 self.write_keyword("UTC_TIME");
39644 Ok(())
39645 }
39646
39647 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
39648 if matches!(
39649 self.config.dialect,
39650 Some(crate::dialects::DialectType::ClickHouse)
39651 ) {
39652 self.write_keyword("CURRENT_TIMESTAMP");
39653 self.write("('UTC')");
39654 } else {
39655 self.write_keyword("UTC_TIMESTAMP");
39656 }
39657 Ok(())
39658 }
39659
39660 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
39661 use crate::dialects::DialectType;
39662 let func_name = match self.config.dialect {
39664 Some(DialectType::Snowflake) => "UUID_STRING",
39665 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
39666 Some(DialectType::BigQuery) => "GENERATE_UUID",
39667 _ => {
39668 if let Some(name) = &e.name {
39669 name.as_str()
39670 } else {
39671 "UUID"
39672 }
39673 }
39674 };
39675 self.write_keyword(func_name);
39676 self.write("(");
39677 if let Some(this) = &e.this {
39678 self.generate_expression(this)?;
39679 }
39680 self.write(")");
39681 Ok(())
39682 }
39683
39684 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
39685 self.write_keyword("MAP");
39687 self.write("(");
39688 let mut first = true;
39689 for (k, v) in e.keys.iter().zip(e.values.iter()) {
39690 if !first {
39691 self.write(", ");
39692 }
39693 self.generate_expression(k)?;
39694 self.write(", ");
39695 self.generate_expression(v)?;
39696 first = false;
39697 }
39698 self.write(")");
39699 Ok(())
39700 }
39701
39702 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
39703 self.write_keyword("VECTOR_SEARCH");
39705 self.write("(");
39706 self.generate_expression(&e.this)?;
39707 if let Some(col) = &e.column_to_search {
39708 self.write(", ");
39709 self.generate_expression(col)?;
39710 }
39711 if let Some(query_table) = &e.query_table {
39712 self.write(", ");
39713 self.generate_expression(query_table)?;
39714 }
39715 if let Some(query_col) = &e.query_column_to_search {
39716 self.write(", ");
39717 self.generate_expression(query_col)?;
39718 }
39719 if let Some(top_k) = &e.top_k {
39720 self.write(", ");
39721 self.generate_expression(top_k)?;
39722 }
39723 if let Some(dist_type) = &e.distance_type {
39724 self.write(", ");
39725 self.generate_expression(dist_type)?;
39726 }
39727 self.write(")");
39728 Ok(())
39729 }
39730
39731 fn generate_version(&mut self, e: &Version) -> Result<()> {
39732 use crate::dialects::DialectType;
39738 let skip_for = matches!(
39739 self.config.dialect,
39740 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
39741 );
39742 if !skip_for {
39743 self.write_keyword("FOR");
39744 self.write_space();
39745 }
39746 match e.this.as_ref() {
39748 Expression::Identifier(ident) => {
39749 self.write_keyword(&ident.name);
39750 }
39751 _ => {
39752 self.generate_expression(&e.this)?;
39753 }
39754 }
39755 self.write_space();
39756 self.write_keyword(&e.kind);
39757 if let Some(expression) = &e.expression {
39758 self.write_space();
39759 self.generate_expression(expression)?;
39760 }
39761 Ok(())
39762 }
39763
39764 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
39765 self.generate_expression(&e.this)?;
39767 Ok(())
39768 }
39769
39770 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
39771 if e.this.is_some() {
39773 self.write_keyword("NOT VOLATILE");
39774 } else {
39775 self.write_keyword("VOLATILE");
39776 }
39777 Ok(())
39778 }
39779
39780 fn generate_watermark_column_constraint(
39781 &mut self,
39782 e: &WatermarkColumnConstraint,
39783 ) -> Result<()> {
39784 self.write_keyword("WATERMARK FOR");
39786 self.write_space();
39787 self.generate_expression(&e.this)?;
39788 self.write_space();
39789 self.write_keyword("AS");
39790 self.write_space();
39791 self.generate_expression(&e.expression)?;
39792 Ok(())
39793 }
39794
39795 fn generate_week(&mut self, e: &Week) -> Result<()> {
39796 self.write_keyword("WEEK");
39798 self.write("(");
39799 self.generate_expression(&e.this)?;
39800 if let Some(mode) = &e.mode {
39801 self.write(", ");
39802 self.generate_expression(mode)?;
39803 }
39804 self.write(")");
39805 Ok(())
39806 }
39807
39808 fn generate_when(&mut self, e: &When) -> Result<()> {
39809 self.write_keyword("WHEN");
39813 self.write_space();
39814
39815 if let Some(matched) = &e.matched {
39817 match matched.as_ref() {
39819 Expression::Boolean(b) if b.value => {
39820 self.write_keyword("MATCHED");
39821 }
39822 _ => {
39823 self.write_keyword("NOT MATCHED");
39824 }
39825 }
39826 } else {
39827 self.write_keyword("NOT MATCHED");
39828 }
39829
39830 if self.config.matched_by_source {
39835 if let Some(source) = &e.source {
39836 if let Expression::Boolean(b) = source.as_ref() {
39837 if b.value {
39838 self.write_space();
39840 self.write_keyword("BY SOURCE");
39841 }
39842 } else {
39844 self.write_space();
39846 self.write_keyword("BY SOURCE");
39847 }
39848 }
39849 }
39850
39851 if let Some(condition) = &e.condition {
39853 self.write_space();
39854 self.write_keyword("AND");
39855 self.write_space();
39856 self.generate_expression(condition)?;
39857 }
39858
39859 self.write_space();
39860 self.write_keyword("THEN");
39861 self.write_space();
39862
39863 self.generate_merge_action(&e.then)?;
39866
39867 Ok(())
39868 }
39869
39870 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
39871 match action {
39872 Expression::Tuple(tuple) => {
39873 let elements = &tuple.expressions;
39874 if elements.is_empty() {
39875 return self.generate_expression(action);
39876 }
39877 match &elements[0] {
39879 Expression::Var(v) if v.this == "INSERT" => {
39880 self.write_keyword("INSERT");
39881 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
39883 self.write(" *");
39884 if let Some(Expression::Where(w)) = elements.get(2) {
39885 self.write_space();
39886 self.generate_where(w)?;
39887 }
39888 } else {
39889 let mut values_idx = 1;
39890 if elements.len() > 1 {
39892 if let Expression::Tuple(cols) = &elements[1] {
39893 if elements.len() > 2 {
39895 self.write(" (");
39897 for (i, col) in cols.expressions.iter().enumerate() {
39898 if i > 0 {
39899 self.write(", ");
39900 }
39901 if !self.merge_strip_qualifiers.is_empty() {
39903 let stripped = self.strip_merge_qualifier(col);
39904 self.generate_expression(&stripped)?;
39905 } else {
39906 self.generate_expression(col)?;
39907 }
39908 }
39909 self.write(")");
39910 values_idx = 2;
39911 } else {
39912 values_idx = 1;
39914 }
39915 }
39916 }
39917 let mut next_idx = values_idx;
39918 if values_idx < elements.len()
39920 && !matches!(&elements[values_idx], Expression::Where(_))
39921 {
39922 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
39924 if !is_row {
39925 self.write_space();
39926 self.write_keyword("VALUES");
39927 }
39928 self.write(" ");
39929 if let Expression::Tuple(vals) = &elements[values_idx] {
39930 self.write("(");
39931 for (i, val) in vals.expressions.iter().enumerate() {
39932 if i > 0 {
39933 self.write(", ");
39934 }
39935 self.generate_expression(val)?;
39936 }
39937 self.write(")");
39938 } else {
39939 self.generate_expression(&elements[values_idx])?;
39940 }
39941 next_idx += 1;
39942 }
39943 if let Some(Expression::Where(w)) = elements.get(next_idx) {
39944 self.write_space();
39945 self.generate_where(w)?;
39946 }
39947 } }
39949 Expression::Var(v) if v.this == "UPDATE" => {
39950 self.write_keyword("UPDATE");
39951 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
39953 self.write(" *");
39954 if let Some(Expression::Where(w)) = elements.get(2) {
39955 self.write_space();
39956 self.generate_where(w)?;
39957 }
39958 } else if elements.len() > 1 {
39959 self.write_space();
39960 self.write_keyword("SET");
39961 if self.config.pretty {
39963 self.write_newline();
39964 self.indent_level += 1;
39965 self.write_indent();
39966 } else {
39967 self.write_space();
39968 }
39969 if let Expression::Tuple(assignments) = &elements[1] {
39970 for (i, assignment) in assignments.expressions.iter().enumerate() {
39971 if i > 0 {
39972 if self.config.pretty {
39973 self.write(",");
39974 self.write_newline();
39975 self.write_indent();
39976 } else {
39977 self.write(", ");
39978 }
39979 }
39980 if !self.merge_strip_qualifiers.is_empty() {
39982 self.generate_merge_set_assignment(assignment)?;
39983 } else {
39984 self.generate_expression(assignment)?;
39985 }
39986 }
39987 } else {
39988 self.generate_expression(&elements[1])?;
39989 }
39990 if self.config.pretty {
39991 self.indent_level -= 1;
39992 }
39993 if let Some(Expression::Where(w)) = elements.get(2) {
39994 self.write_space();
39995 self.generate_where(w)?;
39996 }
39997 }
39998 }
39999 Expression::Var(v) if v.this == "DELETE" => {
40000 self.write_keyword("DELETE");
40001 if let Some(Expression::Where(w)) = elements.get(1) {
40002 self.write_space();
40003 self.generate_where(w)?;
40004 }
40005 }
40006 _ => {
40007 self.generate_expression(action)?;
40009 }
40010 }
40011 }
40012 Expression::Var(v)
40013 if v.this == "INSERT"
40014 || v.this == "UPDATE"
40015 || v.this == "DELETE"
40016 || v.this == "DO NOTHING" =>
40017 {
40018 self.write_keyword(&v.this);
40019 }
40020 _ => {
40021 self.generate_expression(action)?;
40022 }
40023 }
40024 Ok(())
40025 }
40026
40027 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
40029 match assignment {
40030 Expression::Eq(eq) => {
40031 let stripped_left = self.strip_merge_qualifier(&eq.left);
40033 self.generate_expression(&stripped_left)?;
40034 self.write(" = ");
40035 self.generate_expression(&eq.right)?;
40036 Ok(())
40037 }
40038 other => self.generate_expression(other),
40039 }
40040 }
40041
40042 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
40044 match expr {
40045 Expression::Column(col) => {
40046 if let Some(ref table_ident) = col.table {
40047 if self
40048 .merge_strip_qualifiers
40049 .iter()
40050 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
40051 {
40052 let mut col = col.clone();
40054 col.table = None;
40055 return Expression::Column(col);
40056 }
40057 }
40058 expr.clone()
40059 }
40060 Expression::Dot(dot) => {
40061 if let Expression::Identifier(id) = &dot.this {
40063 if self
40064 .merge_strip_qualifiers
40065 .iter()
40066 .any(|n| n.eq_ignore_ascii_case(&id.name))
40067 {
40068 return Expression::Identifier(dot.field.clone());
40069 }
40070 }
40071 expr.clone()
40072 }
40073 _ => expr.clone(),
40074 }
40075 }
40076
40077 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
40078 for (i, expr) in e.expressions.iter().enumerate() {
40080 if i > 0 {
40081 if self.config.pretty {
40083 self.write_newline();
40084 self.write_indent();
40085 } else {
40086 self.write_space();
40087 }
40088 }
40089 self.generate_expression(expr)?;
40090 }
40091 Ok(())
40092 }
40093
40094 fn generate_where(&mut self, e: &Where) -> Result<()> {
40095 self.write_keyword("WHERE");
40097 self.write_space();
40098 self.generate_expression(&e.this)?;
40099 Ok(())
40100 }
40101
40102 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
40103 self.write_keyword("WIDTH_BUCKET");
40105 self.write("(");
40106 self.generate_expression(&e.this)?;
40107 if let Some(min_value) = &e.min_value {
40108 self.write(", ");
40109 self.generate_expression(min_value)?;
40110 }
40111 if let Some(max_value) = &e.max_value {
40112 self.write(", ");
40113 self.generate_expression(max_value)?;
40114 }
40115 if let Some(num_buckets) = &e.num_buckets {
40116 self.write(", ");
40117 self.generate_expression(num_buckets)?;
40118 }
40119 self.write(")");
40120 Ok(())
40121 }
40122
40123 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
40124 self.generate_window_spec(e)
40126 }
40127
40128 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
40129 let mut has_content = false;
40131
40132 if !e.partition_by.is_empty() {
40134 self.write_keyword("PARTITION BY");
40135 self.write_space();
40136 for (i, expr) in e.partition_by.iter().enumerate() {
40137 if i > 0 {
40138 self.write(", ");
40139 }
40140 self.generate_expression(expr)?;
40141 }
40142 has_content = true;
40143 }
40144
40145 if !e.order_by.is_empty() {
40147 if has_content {
40148 self.write_space();
40149 }
40150 self.write_keyword("ORDER BY");
40151 self.write_space();
40152 for (i, ordered) in e.order_by.iter().enumerate() {
40153 if i > 0 {
40154 self.write(", ");
40155 }
40156 self.generate_expression(&ordered.this)?;
40157 if ordered.desc {
40158 self.write_space();
40159 self.write_keyword("DESC");
40160 } else if ordered.explicit_asc {
40161 self.write_space();
40162 self.write_keyword("ASC");
40163 }
40164 if let Some(nulls_first) = ordered.nulls_first {
40165 self.write_space();
40166 self.write_keyword("NULLS");
40167 self.write_space();
40168 if nulls_first {
40169 self.write_keyword("FIRST");
40170 } else {
40171 self.write_keyword("LAST");
40172 }
40173 }
40174 }
40175 has_content = true;
40176 }
40177
40178 if let Some(frame) = &e.frame {
40180 if has_content {
40181 self.write_space();
40182 }
40183 self.generate_window_frame(frame)?;
40184 }
40185
40186 Ok(())
40187 }
40188
40189 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
40190 self.write_keyword("WITH");
40192 self.write_space();
40193 if e.no.is_some() {
40194 self.write_keyword("NO");
40195 self.write_space();
40196 }
40197 self.write_keyword("DATA");
40198
40199 if let Some(statistics) = &e.statistics {
40201 self.write_space();
40202 self.write_keyword("AND");
40203 self.write_space();
40204 match statistics.as_ref() {
40206 Expression::Boolean(b) if !b.value => {
40207 self.write_keyword("NO");
40208 self.write_space();
40209 }
40210 _ => {}
40211 }
40212 self.write_keyword("STATISTICS");
40213 }
40214 Ok(())
40215 }
40216
40217 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
40218 self.write_keyword("WITH FILL");
40220
40221 if let Some(from_) = &e.from_ {
40222 self.write_space();
40223 self.write_keyword("FROM");
40224 self.write_space();
40225 self.generate_expression(from_)?;
40226 }
40227
40228 if let Some(to) = &e.to {
40229 self.write_space();
40230 self.write_keyword("TO");
40231 self.write_space();
40232 self.generate_expression(to)?;
40233 }
40234
40235 if let Some(step) = &e.step {
40236 self.write_space();
40237 self.write_keyword("STEP");
40238 self.write_space();
40239 self.generate_expression(step)?;
40240 }
40241
40242 if let Some(staleness) = &e.staleness {
40243 self.write_space();
40244 self.write_keyword("STALENESS");
40245 self.write_space();
40246 self.generate_expression(staleness)?;
40247 }
40248
40249 if let Some(interpolate) = &e.interpolate {
40250 self.write_space();
40251 self.write_keyword("INTERPOLATE");
40252 self.write(" (");
40253 self.generate_interpolate_item(interpolate)?;
40255 self.write(")");
40256 }
40257
40258 Ok(())
40259 }
40260
40261 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
40263 match expr {
40264 Expression::Alias(alias) => {
40265 self.generate_identifier(&alias.alias)?;
40267 self.write_space();
40268 self.write_keyword("AS");
40269 self.write_space();
40270 self.generate_expression(&alias.this)?;
40271 }
40272 Expression::Tuple(tuple) => {
40273 for (i, item) in tuple.expressions.iter().enumerate() {
40274 if i > 0 {
40275 self.write(", ");
40276 }
40277 self.generate_interpolate_item(item)?;
40278 }
40279 }
40280 other => {
40281 self.generate_expression(other)?;
40282 }
40283 }
40284 Ok(())
40285 }
40286
40287 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
40288 self.write_keyword("WITH JOURNAL TABLE");
40290 self.write("=");
40291 self.generate_expression(&e.this)?;
40292 Ok(())
40293 }
40294
40295 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
40296 self.generate_expression(&e.this)?;
40298 self.write_space();
40299 self.write_keyword("WITH");
40300 self.write_space();
40301 self.write_keyword(&e.op);
40302 Ok(())
40303 }
40304
40305 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
40306 self.write_keyword("WITH");
40308 self.write_space();
40309 for (i, expr) in e.expressions.iter().enumerate() {
40310 if i > 0 {
40311 self.write(", ");
40312 }
40313 self.generate_expression(expr)?;
40314 }
40315 Ok(())
40316 }
40317
40318 fn generate_with_schema_binding_property(
40319 &mut self,
40320 e: &WithSchemaBindingProperty,
40321 ) -> Result<()> {
40322 self.write_keyword("WITH");
40324 self.write_space();
40325 self.generate_expression(&e.this)?;
40326 Ok(())
40327 }
40328
40329 fn generate_with_system_versioning_property(
40330 &mut self,
40331 e: &WithSystemVersioningProperty,
40332 ) -> Result<()> {
40333 let mut parts = Vec::new();
40339
40340 if let Some(this) = &e.this {
40341 let mut s = String::from("HISTORY_TABLE=");
40343 let mut gen = Generator::new();
40344 gen.generate_expression(this)?;
40345 s.push_str(&gen.output);
40346 parts.push(s);
40347 }
40348
40349 if let Some(data_consistency) = &e.data_consistency {
40350 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
40351 let mut gen = Generator::new();
40352 gen.generate_expression(data_consistency)?;
40353 s.push_str(&gen.output);
40354 parts.push(s);
40355 }
40356
40357 if let Some(retention_period) = &e.retention_period {
40358 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
40359 let mut gen = Generator::new();
40360 gen.generate_expression(retention_period)?;
40361 s.push_str(&gen.output);
40362 parts.push(s);
40363 }
40364
40365 self.write_keyword("SYSTEM_VERSIONING");
40366 self.write("=");
40367
40368 if !parts.is_empty() {
40369 self.write_keyword("ON");
40370 self.write("(");
40371 self.write(&parts.join(", "));
40372 self.write(")");
40373 } else if e.on.is_some() {
40374 self.write_keyword("ON");
40375 } else {
40376 self.write_keyword("OFF");
40377 }
40378
40379 if e.with_.is_some() {
40381 let inner = self.output.clone();
40382 self.output.clear();
40383 self.write("WITH(");
40384 self.write(&inner);
40385 self.write(")");
40386 }
40387
40388 Ok(())
40389 }
40390
40391 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
40392 self.write_keyword("WITH");
40394 self.write(" (");
40395 for (i, expr) in e.expressions.iter().enumerate() {
40396 if i > 0 {
40397 self.write(", ");
40398 }
40399 self.generate_expression(expr)?;
40400 }
40401 self.write(")");
40402 Ok(())
40403 }
40404
40405 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
40406 self.write_keyword("XMLELEMENT");
40409 self.write("(");
40410
40411 if e.evalname.is_some() {
40412 self.write_keyword("EVALNAME");
40413 } else {
40414 self.write_keyword("NAME");
40415 }
40416 self.write_space();
40417 self.generate_expression(&e.this)?;
40418
40419 for expr in &e.expressions {
40420 self.write(", ");
40421 self.generate_expression(expr)?;
40422 }
40423 self.write(")");
40424 Ok(())
40425 }
40426
40427 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
40428 self.write_keyword("XMLGET");
40430 self.write("(");
40431 self.generate_expression(&e.this)?;
40432 self.write(", ");
40433 self.generate_expression(&e.expression)?;
40434 if let Some(instance) = &e.instance {
40435 self.write(", ");
40436 self.generate_expression(instance)?;
40437 }
40438 self.write(")");
40439 Ok(())
40440 }
40441
40442 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
40443 self.generate_expression(&e.this)?;
40445 if let Some(expression) = &e.expression {
40446 self.write("(");
40447 self.generate_expression(expression)?;
40448 self.write(")");
40449 }
40450 Ok(())
40451 }
40452
40453 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
40454 self.write_keyword("XMLTABLE");
40456 self.write("(");
40457
40458 if self.config.pretty {
40459 self.indent_level += 1;
40460 self.write_newline();
40461 self.write_indent();
40462 self.generate_expression(&e.this)?;
40463
40464 if let Some(passing) = &e.passing {
40465 self.write_newline();
40466 self.write_indent();
40467 self.write_keyword("PASSING");
40468 if let Expression::Tuple(tuple) = passing.as_ref() {
40469 for expr in &tuple.expressions {
40470 self.write_newline();
40471 self.indent_level += 1;
40472 self.write_indent();
40473 self.generate_expression(expr)?;
40474 self.indent_level -= 1;
40475 }
40476 } else {
40477 self.write_newline();
40478 self.indent_level += 1;
40479 self.write_indent();
40480 self.generate_expression(passing)?;
40481 self.indent_level -= 1;
40482 }
40483 }
40484
40485 if e.by_ref.is_some() {
40486 self.write_newline();
40487 self.write_indent();
40488 self.write_keyword("RETURNING SEQUENCE BY REF");
40489 }
40490
40491 if !e.columns.is_empty() {
40492 self.write_newline();
40493 self.write_indent();
40494 self.write_keyword("COLUMNS");
40495 for (i, col) in e.columns.iter().enumerate() {
40496 self.write_newline();
40497 self.indent_level += 1;
40498 self.write_indent();
40499 self.generate_expression(col)?;
40500 self.indent_level -= 1;
40501 if i < e.columns.len() - 1 {
40502 self.write(",");
40503 }
40504 }
40505 }
40506
40507 self.indent_level -= 1;
40508 self.write_newline();
40509 self.write_indent();
40510 self.write(")");
40511 return Ok(());
40512 }
40513
40514 if let Some(namespaces) = &e.namespaces {
40516 self.write_keyword("XMLNAMESPACES");
40517 self.write("(");
40518 if let Expression::Tuple(tuple) = namespaces.as_ref() {
40520 for (i, expr) in tuple.expressions.iter().enumerate() {
40521 if i > 0 {
40522 self.write(", ");
40523 }
40524 if !matches!(expr, Expression::Alias(_)) {
40527 self.write_keyword("DEFAULT");
40528 self.write_space();
40529 }
40530 self.generate_expression(expr)?;
40531 }
40532 } else {
40533 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
40535 self.write_keyword("DEFAULT");
40536 self.write_space();
40537 }
40538 self.generate_expression(namespaces)?;
40539 }
40540 self.write("), ");
40541 }
40542
40543 self.generate_expression(&e.this)?;
40545
40546 if let Some(passing) = &e.passing {
40548 self.write_space();
40549 self.write_keyword("PASSING");
40550 self.write_space();
40551 if let Expression::Tuple(tuple) = passing.as_ref() {
40553 for (i, expr) in tuple.expressions.iter().enumerate() {
40554 if i > 0 {
40555 self.write(", ");
40556 }
40557 self.generate_expression(expr)?;
40558 }
40559 } else {
40560 self.generate_expression(passing)?;
40561 }
40562 }
40563
40564 if e.by_ref.is_some() {
40566 self.write_space();
40567 self.write_keyword("RETURNING SEQUENCE BY REF");
40568 }
40569
40570 if !e.columns.is_empty() {
40572 self.write_space();
40573 self.write_keyword("COLUMNS");
40574 self.write_space();
40575 for (i, col) in e.columns.iter().enumerate() {
40576 if i > 0 {
40577 self.write(", ");
40578 }
40579 self.generate_expression(col)?;
40580 }
40581 }
40582
40583 self.write(")");
40584 Ok(())
40585 }
40586
40587 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
40588 if let Some(this) = &e.this {
40591 self.generate_expression(this)?;
40592 if let Some(expression) = &e.expression {
40593 self.write_space();
40594 self.write_keyword("XOR");
40595 self.write_space();
40596 self.generate_expression(expression)?;
40597 }
40598 }
40599
40600 for (i, expr) in e.expressions.iter().enumerate() {
40602 if i > 0 || e.this.is_some() {
40603 self.write_space();
40604 self.write_keyword("XOR");
40605 self.write_space();
40606 }
40607 self.generate_expression(expr)?;
40608 }
40609 Ok(())
40610 }
40611
40612 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
40613 self.write_keyword("ZIPF");
40615 self.write("(");
40616 self.generate_expression(&e.this)?;
40617 if let Some(elementcount) = &e.elementcount {
40618 self.write(", ");
40619 self.generate_expression(elementcount)?;
40620 }
40621 if let Some(gen) = &e.gen {
40622 self.write(", ");
40623 self.generate_expression(gen)?;
40624 }
40625 self.write(")");
40626 Ok(())
40627 }
40628}
40629
40630impl Default for Generator {
40631 fn default() -> Self {
40632 Self::new()
40633 }
40634}
40635
40636#[cfg(test)]
40637mod tests {
40638 use super::*;
40639 use crate::parser::Parser;
40640
40641 fn roundtrip(sql: &str) -> String {
40642 let ast = Parser::parse_sql(sql).unwrap();
40643 Generator::sql(&ast[0]).unwrap()
40644 }
40645
40646 #[test]
40647 fn test_simple_select() {
40648 let result = roundtrip("SELECT 1");
40649 assert_eq!(result, "SELECT 1");
40650 }
40651
40652 #[test]
40653 fn test_select_from() {
40654 let result = roundtrip("SELECT a, b FROM t");
40655 assert_eq!(result, "SELECT a, b FROM t");
40656 }
40657
40658 #[test]
40659 fn test_select_where() {
40660 let result = roundtrip("SELECT * FROM t WHERE x = 1");
40661 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
40662 }
40663
40664 #[test]
40665 fn test_select_join() {
40666 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
40667 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
40668 }
40669
40670 #[test]
40671 fn test_insert() {
40672 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
40673 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
40674 }
40675
40676 #[test]
40677 fn test_pretty_print() {
40678 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
40679 let result = Generator::pretty_sql(&ast[0]).unwrap();
40680 assert!(result.contains('\n'));
40681 }
40682
40683 #[test]
40684 fn test_window_function() {
40685 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
40686 assert_eq!(
40687 result,
40688 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
40689 );
40690 }
40691
40692 #[test]
40693 fn test_window_function_with_frame() {
40694 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
40695 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
40696 }
40697
40698 #[test]
40699 fn test_aggregate_with_filter() {
40700 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
40701 assert_eq!(
40702 result,
40703 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
40704 );
40705 }
40706
40707 #[test]
40708 fn test_subscript() {
40709 let result = roundtrip("SELECT arr[0]");
40710 assert_eq!(result, "SELECT arr[0]");
40711 }
40712
40713 #[test]
40715 fn test_create_table() {
40716 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
40717 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
40718 }
40719
40720 #[test]
40721 fn test_create_table_with_constraints() {
40722 let result = roundtrip(
40723 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
40724 );
40725 assert_eq!(
40726 result,
40727 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
40728 );
40729 }
40730
40731 #[test]
40732 fn test_create_table_if_not_exists() {
40733 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
40734 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
40735 }
40736
40737 #[test]
40738 fn test_drop_table() {
40739 let result = roundtrip("DROP TABLE users");
40740 assert_eq!(result, "DROP TABLE users");
40741 }
40742
40743 #[test]
40744 fn test_drop_table_if_exists_cascade() {
40745 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
40746 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
40747 }
40748
40749 #[test]
40750 fn test_alter_table_add_column() {
40751 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
40752 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
40753 }
40754
40755 #[test]
40756 fn test_alter_table_drop_column() {
40757 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
40758 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
40759 }
40760
40761 #[test]
40762 fn test_create_index() {
40763 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
40764 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
40765 }
40766
40767 #[test]
40768 fn test_create_unique_index() {
40769 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
40770 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
40771 }
40772
40773 #[test]
40774 fn test_drop_index() {
40775 let result = roundtrip("DROP INDEX idx_name");
40776 assert_eq!(result, "DROP INDEX idx_name");
40777
40778 let result = roundtrip(r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#);
40779 assert_eq!(
40780 result,
40781 r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#
40782 );
40783
40784 let result = roundtrip(r#"DROP INDEX "public"."IdxMixed""#);
40785 assert_eq!(result, r#"DROP INDEX "public"."IdxMixed""#);
40786 }
40787
40788 #[test]
40789 fn test_create_view() {
40790 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
40791 assert_eq!(
40792 result,
40793 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
40794 );
40795 }
40796
40797 #[test]
40798 fn test_drop_view() {
40799 let result = roundtrip("DROP VIEW active_users");
40800 assert_eq!(result, "DROP VIEW active_users");
40801 }
40802
40803 #[test]
40804 fn test_truncate() {
40805 let result = roundtrip("TRUNCATE TABLE users");
40806 assert_eq!(result, "TRUNCATE TABLE users");
40807 }
40808
40809 #[test]
40810 fn test_string_literal_escaping_default() {
40811 let result = roundtrip("SELECT 'hello'");
40813 assert_eq!(result, "SELECT 'hello'");
40814
40815 let result = roundtrip("SELECT 'it''s a test'");
40817 assert_eq!(result, "SELECT 'it''s a test'");
40818 }
40819
40820 #[test]
40821 fn test_not_in_style_prefix_default_generic() {
40822 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
40823 assert_eq!(
40824 result,
40825 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
40826 );
40827 }
40828
40829 #[test]
40830 fn test_not_in_style_infix_generic_override() {
40831 let ast =
40832 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
40833 .unwrap();
40834 let config = GeneratorConfig {
40835 not_in_style: NotInStyle::Infix,
40836 ..Default::default()
40837 };
40838 let mut gen = Generator::with_config(config);
40839 let result = gen.generate(&ast[0]).unwrap();
40840 assert_eq!(
40841 result,
40842 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
40843 );
40844 }
40845
40846 #[test]
40847 fn test_string_literal_escaping_mysql() {
40848 use crate::dialects::DialectType;
40849
40850 let config = GeneratorConfig {
40851 dialect: Some(DialectType::MySQL),
40852 ..Default::default()
40853 };
40854
40855 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
40856 let mut gen = Generator::with_config(config.clone());
40857 let result = gen.generate(&ast[0]).unwrap();
40858 assert_eq!(result, "SELECT 'hello'");
40859
40860 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
40862 let mut gen = Generator::with_config(config.clone());
40863 let result = gen.generate(&ast[0]).unwrap();
40864 assert_eq!(result, "SELECT 'it''s'");
40865 }
40866
40867 #[test]
40868 fn test_string_literal_escaping_postgres() {
40869 use crate::dialects::DialectType;
40870
40871 let config = GeneratorConfig {
40872 dialect: Some(DialectType::PostgreSQL),
40873 ..Default::default()
40874 };
40875
40876 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
40877 let mut gen = Generator::with_config(config.clone());
40878 let result = gen.generate(&ast[0]).unwrap();
40879 assert_eq!(result, "SELECT 'hello'");
40880
40881 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
40883 let mut gen = Generator::with_config(config.clone());
40884 let result = gen.generate(&ast[0]).unwrap();
40885 assert_eq!(result, "SELECT 'it''s'");
40886 }
40887
40888 #[test]
40889 fn test_string_literal_escaping_bigquery() {
40890 use crate::dialects::DialectType;
40891
40892 let config = GeneratorConfig {
40893 dialect: Some(DialectType::BigQuery),
40894 ..Default::default()
40895 };
40896
40897 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
40898 let mut gen = Generator::with_config(config.clone());
40899 let result = gen.generate(&ast[0]).unwrap();
40900 assert_eq!(result, "SELECT 'hello'");
40901
40902 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
40904 let mut gen = Generator::with_config(config.clone());
40905 let result = gen.generate(&ast[0]).unwrap();
40906 assert_eq!(result, "SELECT 'it\\'s'");
40907 }
40908
40909 #[test]
40910 fn test_generate_deep_and_chain_without_stack_growth() {
40911 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
40912 Expression::column("c0"),
40913 Expression::number(0),
40914 )));
40915
40916 for i in 1..2500 {
40917 let predicate = Expression::Eq(Box::new(BinaryOp::new(
40918 Expression::column(format!("c{i}")),
40919 Expression::number(i as i64),
40920 )));
40921 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
40922 }
40923
40924 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
40925 assert!(sql.contains("c2499 = 2499"), "{}", sql);
40926 }
40927
40928 #[test]
40929 fn test_generate_deep_or_chain_without_stack_growth() {
40930 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
40931 Expression::column("c0"),
40932 Expression::number(0),
40933 )));
40934
40935 for i in 1..2500 {
40936 let predicate = Expression::Eq(Box::new(BinaryOp::new(
40937 Expression::column(format!("c{i}")),
40938 Expression::number(i as i64),
40939 )));
40940 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
40941 }
40942
40943 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
40944 assert!(sql.contains("c2499 = 2499"), "{}", sql);
40945 }
40946}