1use std::borrow::Cow;
14use std::sync::Arc;
15
16use crate::error::Result;
17use crate::expressions::*;
18use crate::DialectType;
19use serde::{Deserialize, Serialize};
20
21pub struct Generator {
46 config: Arc<GeneratorConfig>,
47 output: String,
48 unsupported_messages: Vec<String>,
49 indent_level: usize,
50 athena_hive_context: bool,
53 sqlite_inline_pk_columns: std::collections::HashSet<String>,
55 merge_strip_qualifiers: Vec<String>,
57 clickhouse_nullable_depth: i32,
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Default)]
70pub enum NormalizeFunctions {
71 #[default]
73 Upper,
74 Lower,
76 None,
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Default)]
82pub enum LimitFetchStyle {
83 #[default]
85 Limit,
86 Top,
88 FetchFirst,
90}
91
92#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
94pub enum NotInStyle {
95 #[default]
97 Prefix,
98 Infix,
100}
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
104#[serde(rename_all = "lowercase")]
105pub enum UnsupportedLevel {
106 Ignore,
108 #[default]
110 Warn,
111 Raise,
113 Immediate,
115}
116
117#[derive(Debug, Clone, Copy, PartialEq, Eq)]
118enum ConnectorOperator {
119 And,
120 Or,
121}
122
123impl ConnectorOperator {
124 fn keyword(self) -> &'static str {
125 match self {
126 Self::And => "AND",
127 Self::Or => "OR",
128 }
129 }
130}
131
132#[derive(Debug, Clone, Copy, PartialEq)]
134pub struct IdentifierQuoteStyle {
135 pub start: char,
137 pub end: char,
139}
140
141impl Default for IdentifierQuoteStyle {
142 fn default() -> Self {
143 Self {
144 start: '"',
145 end: '"',
146 }
147 }
148}
149
150impl IdentifierQuoteStyle {
151 pub const DOUBLE_QUOTE: Self = Self {
153 start: '"',
154 end: '"',
155 };
156 pub const BACKTICK: Self = Self {
158 start: '`',
159 end: '`',
160 };
161 pub const BRACKET: Self = Self {
163 start: '[',
164 end: ']',
165 };
166}
167
168#[derive(Debug, Clone)]
190pub struct GeneratorConfig {
191 pub pretty: bool,
194 pub indent: &'static str,
196 pub max_text_width: usize,
198 pub identifier_quote: char,
200 pub identifier_quote_style: IdentifierQuoteStyle,
202 pub uppercase_keywords: bool,
204 pub normalize_identifiers: bool,
206 pub dialect: Option<crate::dialects::DialectType>,
208 pub source_dialect: Option<crate::dialects::DialectType>,
210 pub unsupported_level: UnsupportedLevel,
212 pub max_unsupported: usize,
214 pub normalize_functions: NormalizeFunctions,
216 pub string_escape: char,
218 pub case_sensitive_identifiers: bool,
220 pub identifiers_can_start_with_digit: bool,
222 pub always_quote_identifiers: bool,
225 pub not_in_style: NotInStyle,
227
228 pub null_ordering_supported: bool,
232 pub ignore_nulls_in_func: bool,
235 pub nvl2_supported: bool,
237
238 pub limit_fetch_style: LimitFetchStyle,
241 pub limit_is_top: bool,
243 pub limit_only_literals: bool,
245
246 pub single_string_interval: bool,
249 pub interval_allows_plural_form: bool,
251
252 pub cte_recursive_keyword_required: bool,
255
256 pub values_as_table: bool,
259 pub wrap_derived_values: bool,
261
262 pub tablesample_seed_keyword: &'static str,
265 pub tablesample_requires_parens: bool,
267 pub tablesample_size_is_rows: bool,
269 pub tablesample_keywords: &'static str,
271 pub tablesample_with_method: bool,
273 pub alias_post_tablesample: bool,
275
276 pub aggregate_filter_supported: bool,
279 pub multi_arg_distinct: bool,
281 pub quantified_no_paren_space: bool,
283 pub supports_median: bool,
285
286 pub supports_select_into: bool,
289 pub locking_reads_supported: bool,
291
292 pub rename_table_with_db: bool,
295 pub semi_anti_join_with_side: bool,
297 pub supports_table_alias_columns: bool,
299 pub join_hints: bool,
301 pub table_hints: bool,
303 pub query_hints: bool,
305 pub query_hint_sep: &'static str,
307 pub supports_column_join_marks: bool,
309
310 pub index_using_no_space: bool,
314 pub supports_unlogged_tables: bool,
316 pub supports_create_table_like: bool,
318 pub like_property_inside_schema: bool,
320 pub alter_table_include_column_keyword: bool,
322 pub supports_table_copy: bool,
324 pub alter_set_type: &'static str,
326 pub alter_set_wrapped: bool,
328
329 pub tz_to_with_time_zone: bool,
332 pub supports_convert_timezone: bool,
334
335 pub json_type_required_for_extraction: bool,
338 pub json_path_bracketed_key_supported: bool,
340 pub json_path_single_quote_escape: bool,
342 pub quote_json_path: bool,
344 pub json_key_value_pair_sep: &'static str,
346
347 pub copy_params_are_wrapped: bool,
350 pub copy_params_eq_required: bool,
352 pub copy_has_into_keyword: bool,
354
355 pub supports_window_exclude: bool,
358 pub unnest_with_ordinality: bool,
360 pub lowercase_window_frame_keywords: bool,
363 pub normalize_window_frame_between: bool,
366
367 pub array_concat_is_var_len: bool,
370 pub array_size_dim_required: Option<bool>,
373 pub can_implement_array_any: bool,
375 pub array_size_name: &'static str,
377
378 pub supports_between_flags: bool,
381
382 pub is_bool_allowed: bool,
385 pub ensure_bools: bool,
387
388 pub extract_allows_quotes: bool,
391 pub normalize_extract_date_parts: bool,
393
394 pub try_supported: bool,
397 pub supports_uescape: bool,
399 pub supports_to_number: bool,
401 pub supports_single_arg_concat: bool,
403 pub last_day_supports_date_part: bool,
405 pub supports_exploding_projections: bool,
407 pub supports_unix_seconds: bool,
409 pub supports_like_quantifiers: bool,
411 pub supports_decode_case: bool,
413 pub set_op_modifiers: bool,
415 pub update_statement_supports_from: bool,
417
418 pub collate_is_func: bool,
421
422 pub duplicate_key_update_with_set: bool,
425 pub insert_overwrite: &'static str,
427
428 pub returning_end: bool,
431
432 pub matched_by_source: bool,
435
436 pub create_function_return_as: bool,
439 pub parameter_default_equals: bool,
441
442 pub computed_column_with_type: bool,
445
446 pub unpivot_aliases_are_identifiers: bool,
449
450 pub star_except: &'static str,
453
454 pub hex_func: &'static str,
457
458 pub with_properties_prefix: &'static str,
461
462 pub pad_fill_pattern_is_required: bool,
465
466 pub index_on: &'static str,
469
470 pub groupings_sep: &'static str,
473
474 pub struct_delimiter: (&'static str, &'static str),
477 pub struct_curly_brace_notation: bool,
479 pub array_bracket_only: bool,
481 pub struct_field_sep: &'static str,
483
484 pub except_intersect_support_all_clause: bool,
487
488 pub parameter_token: &'static str,
491 pub named_placeholder_token: &'static str,
493
494 pub data_type_specifiers_allowed: bool,
497
498 pub schema_comment_with_eq: bool,
502}
503
504impl Default for GeneratorConfig {
505 fn default() -> Self {
506 Self {
507 pretty: false,
509 indent: " ",
510 max_text_width: 80,
511 identifier_quote: '"',
512 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
513 uppercase_keywords: true,
514 normalize_identifiers: false,
515 dialect: None,
516 source_dialect: None,
517 unsupported_level: UnsupportedLevel::Warn,
518 max_unsupported: 3,
519 normalize_functions: NormalizeFunctions::Upper,
520 string_escape: '\'',
521 case_sensitive_identifiers: false,
522 identifiers_can_start_with_digit: false,
523 always_quote_identifiers: false,
524 not_in_style: NotInStyle::Prefix,
525
526 null_ordering_supported: true,
528 ignore_nulls_in_func: false,
529 nvl2_supported: true,
530
531 limit_fetch_style: LimitFetchStyle::Limit,
533 limit_is_top: false,
534 limit_only_literals: false,
535
536 single_string_interval: false,
538 interval_allows_plural_form: true,
539
540 cte_recursive_keyword_required: true,
542
543 values_as_table: true,
545 wrap_derived_values: true,
546
547 tablesample_seed_keyword: "SEED",
549 tablesample_requires_parens: true,
550 tablesample_size_is_rows: true,
551 tablesample_keywords: "TABLESAMPLE",
552 tablesample_with_method: true,
553 alias_post_tablesample: false,
554
555 aggregate_filter_supported: true,
557 multi_arg_distinct: true,
558 quantified_no_paren_space: false,
559 supports_median: true,
560
561 supports_select_into: false,
563 locking_reads_supported: true,
564
565 rename_table_with_db: true,
567 semi_anti_join_with_side: true,
568 supports_table_alias_columns: true,
569 join_hints: true,
570 table_hints: true,
571 query_hints: true,
572 query_hint_sep: ", ",
573 supports_column_join_marks: false,
574
575 index_using_no_space: false,
577 supports_unlogged_tables: false,
578 supports_create_table_like: true,
579 like_property_inside_schema: false,
580 alter_table_include_column_keyword: true,
581 supports_table_copy: true,
582 alter_set_type: "SET DATA TYPE",
583 alter_set_wrapped: false,
584
585 tz_to_with_time_zone: false,
587 supports_convert_timezone: false,
588
589 json_type_required_for_extraction: false,
591 json_path_bracketed_key_supported: true,
592 json_path_single_quote_escape: false,
593 quote_json_path: true,
594 json_key_value_pair_sep: ":",
595
596 copy_params_are_wrapped: true,
598 copy_params_eq_required: false,
599 copy_has_into_keyword: true,
600
601 supports_window_exclude: false,
603 unnest_with_ordinality: true,
604 lowercase_window_frame_keywords: false,
605 normalize_window_frame_between: false,
606
607 array_concat_is_var_len: true,
609 array_size_dim_required: None,
610 can_implement_array_any: false,
611 array_size_name: "ARRAY_LENGTH",
612
613 supports_between_flags: false,
615
616 is_bool_allowed: true,
618 ensure_bools: false,
619
620 extract_allows_quotes: true,
622 normalize_extract_date_parts: false,
623
624 try_supported: true,
626 supports_uescape: true,
627 supports_to_number: true,
628 supports_single_arg_concat: true,
629 last_day_supports_date_part: true,
630 supports_exploding_projections: true,
631 supports_unix_seconds: false,
632 supports_like_quantifiers: true,
633 supports_decode_case: true,
634 set_op_modifiers: true,
635 update_statement_supports_from: true,
636
637 collate_is_func: false,
639
640 duplicate_key_update_with_set: true,
642 insert_overwrite: " OVERWRITE TABLE",
643
644 returning_end: true,
646
647 matched_by_source: true,
649
650 create_function_return_as: true,
652 parameter_default_equals: false,
653
654 computed_column_with_type: true,
656
657 unpivot_aliases_are_identifiers: true,
659
660 star_except: "EXCEPT",
662
663 hex_func: "HEX",
665
666 with_properties_prefix: "WITH",
668
669 pad_fill_pattern_is_required: false,
671
672 index_on: "ON",
674
675 groupings_sep: ",",
677
678 struct_delimiter: ("<", ">"),
680 struct_curly_brace_notation: false,
681 array_bracket_only: false,
682 struct_field_sep: " ",
683
684 except_intersect_support_all_clause: true,
686
687 parameter_token: "@",
689 named_placeholder_token: ":",
690
691 data_type_specifiers_allowed: false,
693
694 schema_comment_with_eq: true,
696 }
697 }
698}
699
700mod reserved_keywords {
703 use std::collections::HashSet;
704 use std::sync::LazyLock;
705
706 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
708 [
709 "all",
710 "alter",
711 "and",
712 "any",
713 "array",
714 "as",
715 "asc",
716 "at",
717 "authorization",
718 "begin",
719 "between",
720 "both",
721 "by",
722 "case",
723 "cast",
724 "check",
725 "collate",
726 "column",
727 "commit",
728 "constraint",
729 "create",
730 "cross",
731 "cube",
732 "current",
733 "current_date",
734 "current_time",
735 "current_timestamp",
736 "current_user",
737 "default",
738 "delete",
739 "desc",
740 "distinct",
741 "drop",
742 "else",
743 "end",
744 "escape",
745 "except",
746 "execute",
747 "exists",
748 "external",
749 "false",
750 "fetch",
751 "filter",
752 "for",
753 "foreign",
754 "from",
755 "full",
756 "function",
757 "grant",
758 "group",
759 "grouping",
760 "having",
761 "if",
762 "in",
763 "index",
764 "inner",
765 "insert",
766 "intersect",
767 "interval",
768 "into",
769 "is",
770 "join",
771 "key",
772 "leading",
773 "left",
774 "like",
775 "limit",
776 "local",
777 "localtime",
778 "localtimestamp",
779 "match",
780 "merge",
781 "natural",
782 "no",
783 "not",
784 "null",
785 "of",
786 "offset",
787 "on",
788 "only",
789 "or",
790 "order",
791 "outer",
792 "over",
793 "partition",
794 "primary",
795 "procedure",
796 "range",
797 "references",
798 "right",
799 "rollback",
800 "rollup",
801 "row",
802 "rows",
803 "select",
804 "session_user",
805 "set",
806 "some",
807 "table",
808 "tablesample",
809 "then",
810 "to",
811 "trailing",
812 "true",
813 "truncate",
814 "union",
815 "unique",
816 "unknown",
817 "update",
818 "user",
819 "using",
820 "values",
821 "view",
822 "when",
823 "where",
824 "window",
825 "with",
826 ]
827 .into_iter()
828 .collect()
829 });
830
831 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
834 let mut set = SQL_RESERVED.clone();
835 set.extend([
836 "assert_rows_modified",
837 "at",
838 "contains",
839 "cube",
840 "current",
841 "define",
842 "enum",
843 "escape",
844 "exclude",
845 "following",
846 "for",
847 "groups",
848 "hash",
849 "ignore",
850 "lateral",
851 "lookup",
852 "new",
853 "no",
854 "nulls",
855 "of",
856 "over",
857 "preceding",
858 "proto",
859 "qualify",
860 "recursive",
861 "respect",
862 "struct",
863 "tablesample",
864 "treat",
865 "unbounded",
866 "unnest",
867 "window",
868 "within",
869 ]);
870 set.remove("grant");
872 set.remove("key");
873 set.remove("index");
874 set.remove("offset");
875 set.remove("values");
876 set.remove("table");
877 set
878 });
879
880 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
882 let mut set = SQL_RESERVED.clone();
883 set.extend([
884 "accessible",
885 "add",
886 "analyze",
887 "asensitive",
888 "before",
889 "bigint",
890 "binary",
891 "blob",
892 "call",
893 "cascade",
894 "change",
895 "char",
896 "character",
897 "condition",
898 "continue",
899 "convert",
900 "current_date",
901 "current_time",
902 "current_timestamp",
903 "current_user",
904 "cursor",
905 "database",
906 "databases",
907 "day_hour",
908 "day_microsecond",
909 "day_minute",
910 "day_second",
911 "dec",
912 "decimal",
913 "declare",
914 "delayed",
915 "describe",
916 "deterministic",
917 "distinctrow",
918 "div",
919 "double",
920 "dual",
921 "each",
922 "elseif",
923 "enclosed",
924 "escaped",
925 "exit",
926 "explain",
927 "float",
928 "float4",
929 "float8",
930 "force",
931 "get",
932 "high_priority",
933 "hour_microsecond",
934 "hour_minute",
935 "hour_second",
936 "ignore",
937 "infile",
938 "inout",
939 "insensitive",
940 "int",
941 "int1",
942 "int2",
943 "int3",
944 "int4",
945 "int8",
946 "integer",
947 "iterate",
948 "keys",
949 "kill",
950 "leave",
951 "linear",
952 "lines",
953 "load",
954 "lock",
955 "long",
956 "longblob",
957 "longtext",
958 "loop",
959 "low_priority",
960 "master_ssl_verify_server_cert",
961 "maxvalue",
962 "mediumblob",
963 "mediumint",
964 "mediumtext",
965 "middleint",
966 "minute_microsecond",
967 "minute_second",
968 "mod",
969 "modifies",
970 "no_write_to_binlog",
971 "numeric",
972 "optimize",
973 "option",
974 "optionally",
975 "out",
976 "outfile",
977 "precision",
978 "purge",
979 "read",
980 "reads",
981 "real",
982 "regexp",
983 "release",
984 "rename",
985 "repeat",
986 "replace",
987 "require",
988 "resignal",
989 "restrict",
990 "return",
991 "revoke",
992 "rlike",
993 "schema",
994 "schemas",
995 "second_microsecond",
996 "sensitive",
997 "separator",
998 "show",
999 "signal",
1000 "smallint",
1001 "spatial",
1002 "specific",
1003 "sql",
1004 "sql_big_result",
1005 "sql_calc_found_rows",
1006 "sql_small_result",
1007 "sqlexception",
1008 "sqlstate",
1009 "sqlwarning",
1010 "ssl",
1011 "starting",
1012 "straight_join",
1013 "terminated",
1014 "text",
1015 "tinyblob",
1016 "tinyint",
1017 "tinytext",
1018 "trigger",
1019 "undo",
1020 "unlock",
1021 "unsigned",
1022 "usage",
1023 "utc_date",
1024 "utc_time",
1025 "utc_timestamp",
1026 "varbinary",
1027 "varchar",
1028 "varcharacter",
1029 "varying",
1030 "while",
1031 "write",
1032 "xor",
1033 "year_month",
1034 "zerofill",
1035 ]);
1036 set.remove("table");
1037 set
1038 });
1039
1040 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1043 let mut set = MYSQL_RESERVED.clone();
1044 set.extend([
1045 "aggregate",
1046 "anti",
1047 "array",
1048 "backend",
1049 "backup",
1050 "begin",
1051 "bitmap",
1052 "boolean",
1053 "broker",
1054 "buckets",
1055 "cached",
1056 "cancel",
1057 "cast",
1058 "catalog",
1059 "charset",
1060 "cluster",
1061 "collation",
1062 "columns",
1063 "comment",
1064 "commit",
1065 "config",
1066 "connection",
1067 "count",
1068 "current",
1069 "data",
1070 "date",
1071 "datetime",
1072 "day",
1073 "deferred",
1074 "distributed",
1075 "dynamic",
1076 "enable",
1077 "end",
1078 "events",
1079 "export",
1080 "external",
1081 "fields",
1082 "first",
1083 "follower",
1084 "format",
1085 "free",
1086 "frontend",
1087 "full",
1088 "functions",
1089 "global",
1090 "grants",
1091 "hash",
1092 "help",
1093 "hour",
1094 "install",
1095 "intermediate",
1096 "json",
1097 "label",
1098 "last",
1099 "less",
1100 "level",
1101 "link",
1102 "local",
1103 "location",
1104 "max",
1105 "merge",
1106 "min",
1107 "minute",
1108 "modify",
1109 "month",
1110 "name",
1111 "names",
1112 "negative",
1113 "nulls",
1114 "observer",
1115 "offset",
1116 "only",
1117 "open",
1118 "overwrite",
1119 "password",
1120 "path",
1121 "plan",
1122 "plugin",
1123 "plugins",
1124 "policy",
1125 "process",
1126 "properties",
1127 "property",
1128 "query",
1129 "quota",
1130 "recover",
1131 "refresh",
1132 "repair",
1133 "replica",
1134 "repository",
1135 "resource",
1136 "restore",
1137 "resume",
1138 "role",
1139 "roles",
1140 "rollback",
1141 "rollup",
1142 "routine",
1143 "sample",
1144 "second",
1145 "semi",
1146 "session",
1147 "signed",
1148 "snapshot",
1149 "start",
1150 "stats",
1151 "status",
1152 "stop",
1153 "stream",
1154 "string",
1155 "sum",
1156 "tables",
1157 "tablet",
1158 "temporary",
1159 "text",
1160 "timestamp",
1161 "transaction",
1162 "trash",
1163 "trim",
1164 "truncate",
1165 "type",
1166 "user",
1167 "value",
1168 "variables",
1169 "verbose",
1170 "version",
1171 "view",
1172 "warnings",
1173 "week",
1174 "work",
1175 "year",
1176 ]);
1177 set
1178 });
1179
1180 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1182 let mut set = SQL_RESERVED.clone();
1183 set.extend([
1184 "analyse",
1185 "analyze",
1186 "asymmetric",
1187 "binary",
1188 "collation",
1189 "concurrently",
1190 "current_catalog",
1191 "current_role",
1192 "current_schema",
1193 "deferrable",
1194 "do",
1195 "freeze",
1196 "ilike",
1197 "initially",
1198 "isnull",
1199 "lateral",
1200 "notnull",
1201 "placing",
1202 "returning",
1203 "similar",
1204 "symmetric",
1205 "variadic",
1206 "verbose",
1207 ]);
1208 set.remove("default");
1210 set.remove("interval");
1211 set.remove("match");
1212 set.remove("offset");
1213 set.remove("table");
1214 set
1215 });
1216
1217 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1221 [
1222 "aes128",
1223 "aes256",
1224 "all",
1225 "allowoverwrite",
1226 "analyse",
1227 "analyze",
1228 "and",
1229 "any",
1230 "array",
1231 "as",
1232 "asc",
1233 "authorization",
1234 "az64",
1235 "backup",
1236 "between",
1237 "binary",
1238 "blanksasnull",
1239 "both",
1240 "bytedict",
1241 "bzip2",
1242 "case",
1243 "cast",
1244 "check",
1245 "collate",
1246 "column",
1247 "constraint",
1248 "create",
1249 "credentials",
1250 "cross",
1251 "current_date",
1252 "current_time",
1253 "current_timestamp",
1254 "current_user",
1255 "current_user_id",
1256 "default",
1257 "deferrable",
1258 "deflate",
1259 "defrag",
1260 "delta",
1261 "delta32k",
1262 "desc",
1263 "disable",
1264 "distinct",
1265 "do",
1266 "else",
1267 "emptyasnull",
1268 "enable",
1269 "encode",
1270 "encrypt",
1271 "encryption",
1272 "end",
1273 "except",
1274 "explicit",
1275 "false",
1276 "for",
1277 "foreign",
1278 "freeze",
1279 "from",
1280 "full",
1281 "globaldict256",
1282 "globaldict64k",
1283 "grant",
1284 "group",
1285 "gzip",
1286 "having",
1287 "identity",
1288 "ignore",
1289 "ilike",
1290 "in",
1291 "initially",
1292 "inner",
1293 "intersect",
1294 "interval",
1295 "into",
1296 "is",
1297 "isnull",
1298 "join",
1299 "leading",
1300 "left",
1301 "like",
1302 "limit",
1303 "localtime",
1304 "localtimestamp",
1305 "lun",
1306 "luns",
1307 "lzo",
1308 "lzop",
1309 "minus",
1310 "mostly16",
1311 "mostly32",
1312 "mostly8",
1313 "natural",
1314 "new",
1315 "not",
1316 "notnull",
1317 "null",
1318 "nulls",
1319 "off",
1320 "offline",
1321 "offset",
1322 "oid",
1323 "old",
1324 "on",
1325 "only",
1326 "open",
1327 "or",
1328 "order",
1329 "outer",
1330 "overlaps",
1331 "parallel",
1332 "partition",
1333 "percent",
1334 "permissions",
1335 "pivot",
1336 "placing",
1337 "primary",
1338 "raw",
1339 "readratio",
1340 "recover",
1341 "references",
1342 "rejectlog",
1343 "resort",
1344 "respect",
1345 "restore",
1346 "right",
1347 "select",
1348 "session_user",
1349 "similar",
1350 "snapshot",
1351 "some",
1352 "sysdate",
1353 "system",
1354 "table",
1355 "tag",
1356 "tdes",
1357 "text255",
1358 "text32k",
1359 "then",
1360 "timestamp",
1361 "to",
1362 "top",
1363 "trailing",
1364 "true",
1365 "truncatecolumns",
1366 "type",
1367 "union",
1368 "unique",
1369 "unnest",
1370 "unpivot",
1371 "user",
1372 "using",
1373 "verbose",
1374 "wallet",
1375 "when",
1376 "where",
1377 "with",
1378 "without",
1379 ]
1380 .into_iter()
1381 .collect()
1382 });
1383
1384 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1386 let mut set = POSTGRES_RESERVED.clone();
1387 set.extend([
1388 "anti",
1389 "asof",
1390 "columns",
1391 "describe",
1392 "groups",
1393 "macro",
1394 "pivot",
1395 "pivot_longer",
1396 "pivot_wider",
1397 "qualify",
1398 "replace",
1399 "respect",
1400 "semi",
1401 "show",
1402 "table",
1403 "unpivot",
1404 ]);
1405 set.remove("at");
1406 set.remove("key");
1407 set.remove("range");
1408 set.remove("row");
1409 set.remove("values");
1410 set
1411 });
1412
1413 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1415 let mut set = SQL_RESERVED.clone();
1416 set.extend([
1417 "alter",
1418 "and",
1419 "as",
1420 "between",
1421 "by",
1422 "case",
1423 "cast",
1424 "constraint",
1425 "create",
1426 "cross",
1427 "cube",
1428 "current_catalog",
1429 "current_date",
1430 "current_path",
1431 "current_role",
1432 "current_schema",
1433 "current_time",
1434 "current_timestamp",
1435 "current_user",
1436 "deallocate",
1437 "delete",
1438 "describe",
1439 "distinct",
1440 "drop",
1441 "else",
1442 "end",
1443 "escape",
1444 "except",
1445 "execute",
1446 "exists",
1447 "extract",
1448 "false",
1449 "for",
1450 "from",
1451 "full",
1452 "group",
1453 "grouping",
1454 "having",
1455 "in",
1456 "inner",
1457 "insert",
1458 "intersect",
1459 "into",
1460 "is",
1461 "join",
1462 "json_array",
1463 "json_exists",
1464 "json_object",
1465 "json_query",
1466 "json_table",
1467 "json_value",
1468 "left",
1469 "like",
1470 "listagg",
1471 "localtime",
1472 "localtimestamp",
1473 "natural",
1474 "normalize",
1475 "not",
1476 "null",
1477 "on",
1478 "or",
1479 "order",
1480 "outer",
1481 "prepare",
1482 "recursive",
1483 "right",
1484 "rollup",
1485 "select",
1486 "skip",
1487 "table",
1488 "then",
1489 "trim",
1490 "true",
1491 "uescape",
1492 "union",
1493 "unnest",
1494 "using",
1495 "values",
1496 "when",
1497 "where",
1498 "with",
1499 ]);
1500 set.remove("key");
1502 set
1503 });
1504
1505 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1508 [
1509 "add",
1510 "all",
1511 "alter",
1512 "analyze",
1513 "and",
1514 "array",
1515 "as",
1516 "asc",
1517 "between",
1518 "bigint",
1519 "bitmap",
1520 "both",
1521 "by",
1522 "case",
1523 "char",
1524 "character",
1525 "check",
1526 "collate",
1527 "column",
1528 "compaction",
1529 "convert",
1530 "create",
1531 "cross",
1532 "cube",
1533 "current_date",
1534 "current_role",
1535 "current_time",
1536 "current_timestamp",
1537 "current_user",
1538 "database",
1539 "databases",
1540 "decimal",
1541 "decimalv2",
1542 "decimal32",
1543 "decimal64",
1544 "decimal128",
1545 "default",
1546 "deferred",
1547 "delete",
1548 "dense_rank",
1549 "desc",
1550 "describe",
1551 "distinct",
1552 "double",
1553 "drop",
1554 "dual",
1555 "else",
1556 "except",
1557 "exists",
1558 "explain",
1559 "false",
1560 "first_value",
1561 "float",
1562 "for",
1563 "force",
1564 "from",
1565 "full",
1566 "function",
1567 "grant",
1568 "group",
1569 "grouping",
1570 "grouping_id",
1571 "groups",
1572 "having",
1573 "hll",
1574 "host",
1575 "if",
1576 "ignore",
1577 "immediate",
1578 "in",
1579 "index",
1580 "infile",
1581 "inner",
1582 "insert",
1583 "int",
1584 "integer",
1585 "intersect",
1586 "into",
1587 "is",
1588 "join",
1589 "json",
1590 "key",
1591 "keys",
1592 "kill",
1593 "lag",
1594 "largeint",
1595 "last_value",
1596 "lateral",
1597 "lead",
1598 "left",
1599 "like",
1600 "limit",
1601 "load",
1602 "localtime",
1603 "localtimestamp",
1604 "maxvalue",
1605 "minus",
1606 "mod",
1607 "not",
1608 "ntile",
1609 "null",
1610 "on",
1611 "or",
1612 "order",
1613 "outer",
1614 "outfile",
1615 "over",
1616 "partition",
1617 "percentile",
1618 "primary",
1619 "procedure",
1620 "qualify",
1621 "range",
1622 "rank",
1623 "read",
1624 "regexp",
1625 "release",
1626 "rename",
1627 "replace",
1628 "revoke",
1629 "right",
1630 "rlike",
1631 "row",
1632 "row_number",
1633 "rows",
1634 "schema",
1635 "schemas",
1636 "select",
1637 "set",
1638 "set_var",
1639 "show",
1640 "smallint",
1641 "system",
1642 "table",
1643 "terminated",
1644 "text",
1645 "then",
1646 "tinyint",
1647 "to",
1648 "true",
1649 "union",
1650 "unique",
1651 "unsigned",
1652 "update",
1653 "use",
1654 "using",
1655 "values",
1656 "varchar",
1657 "when",
1658 "where",
1659 "with",
1660 ]
1661 .into_iter()
1662 .collect()
1663 });
1664
1665 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1668 let mut set = MYSQL_RESERVED.clone();
1669 set.extend([
1670 "abs",
1673 "account",
1674 "acos",
1675 "adddate",
1676 "addtime",
1677 "admin",
1678 "aes_decrypt",
1679 "aes_encrypt",
1680 "aggregate",
1681 "aggregates",
1682 "aggregator",
1683 "anti_join",
1684 "any_value",
1685 "approx_count_distinct",
1686 "approx_percentile",
1687 "arrange",
1688 "arrangement",
1689 "asin",
1690 "atan",
1691 "atan2",
1692 "attach",
1693 "autostats",
1694 "avro",
1695 "background",
1696 "backup",
1697 "batch",
1698 "batches",
1699 "boot_strapping",
1700 "ceil",
1701 "ceiling",
1702 "coercibility",
1703 "columnar",
1704 "columnstore",
1705 "compile",
1706 "concurrent",
1707 "connection_id",
1708 "cos",
1709 "cot",
1710 "current_security_groups",
1711 "current_security_roles",
1712 "dayname",
1713 "dayofmonth",
1714 "dayofweek",
1715 "dayofyear",
1716 "degrees",
1717 "dot_product",
1718 "dump",
1719 "durability",
1720 "earliest",
1721 "echo",
1722 "election",
1723 "euclidean_distance",
1724 "exp",
1725 "extractor",
1726 "extractors",
1727 "floor",
1728 "foreground",
1729 "found_rows",
1730 "from_base64",
1731 "from_days",
1732 "from_unixtime",
1733 "fs",
1734 "fulltext",
1735 "gc",
1736 "gcs",
1737 "geography",
1738 "geography_area",
1739 "geography_contains",
1740 "geography_distance",
1741 "geography_intersects",
1742 "geography_latitude",
1743 "geography_length",
1744 "geography_longitude",
1745 "geographypoint",
1746 "geography_point",
1747 "geography_within_distance",
1748 "geometry",
1749 "geometry_area",
1750 "geometry_contains",
1751 "geometry_distance",
1752 "geometry_filter",
1753 "geometry_intersects",
1754 "geometry_length",
1755 "geometrypoint",
1756 "geometry_point",
1757 "geometry_within_distance",
1758 "geometry_x",
1759 "geometry_y",
1760 "greatest",
1761 "groups",
1762 "group_concat",
1763 "gzip",
1764 "hdfs",
1765 "hex",
1766 "highlight",
1767 "ifnull",
1768 "ilike",
1769 "inet_aton",
1770 "inet_ntoa",
1771 "inet6_aton",
1772 "inet6_ntoa",
1773 "initcap",
1774 "instr",
1775 "interpreter_mode",
1776 "isnull",
1777 "json",
1778 "json_agg",
1779 "json_array_contains_double",
1780 "json_array_contains_json",
1781 "json_array_contains_string",
1782 "json_delete_key",
1783 "json_extract_double",
1784 "json_extract_json",
1785 "json_extract_string",
1786 "json_extract_bigint",
1787 "json_get_type",
1788 "json_length",
1789 "json_set_double",
1790 "json_set_json",
1791 "json_set_string",
1792 "kafka",
1793 "lag",
1794 "last_day",
1795 "last_insert_id",
1796 "latest",
1797 "lcase",
1798 "lead",
1799 "leaf",
1800 "least",
1801 "leaves",
1802 "length",
1803 "license",
1804 "links",
1805 "llvm",
1806 "ln",
1807 "load",
1808 "locate",
1809 "log",
1810 "log10",
1811 "log2",
1812 "lpad",
1813 "lz4",
1814 "management",
1815 "match",
1816 "mbc",
1817 "md5",
1818 "median",
1819 "memsql",
1820 "memsql_deserialize",
1821 "memsql_serialize",
1822 "metadata",
1823 "microsecond",
1824 "minute",
1825 "model",
1826 "monthname",
1827 "months_between",
1828 "mpl",
1829 "namespace",
1830 "node",
1831 "noparam",
1832 "now",
1833 "nth_value",
1834 "ntile",
1835 "nullcols",
1836 "nullif",
1837 "object",
1838 "octet_length",
1839 "offsets",
1840 "online",
1841 "optimizer",
1842 "orphan",
1843 "parquet",
1844 "partitions",
1845 "pause",
1846 "percentile_cont",
1847 "percentile_disc",
1848 "periodic",
1849 "persisted",
1850 "pi",
1851 "pipeline",
1852 "pipelines",
1853 "plancache",
1854 "plugins",
1855 "pool",
1856 "pools",
1857 "pow",
1858 "power",
1859 "process",
1860 "processlist",
1861 "profile",
1862 "profiles",
1863 "quarter",
1864 "queries",
1865 "query",
1866 "radians",
1867 "rand",
1868 "record",
1869 "reduce",
1870 "redundancy",
1871 "regexp_match",
1872 "regexp_substr",
1873 "remote",
1874 "replication",
1875 "resource",
1876 "resource_pool",
1877 "restore",
1878 "retry",
1879 "role",
1880 "roles",
1881 "round",
1882 "rpad",
1883 "rtrim",
1884 "running",
1885 "s3",
1886 "scalar",
1887 "sec_to_time",
1888 "second",
1889 "security_lists_intersect",
1890 "semi_join",
1891 "sha",
1892 "sha1",
1893 "sha2",
1894 "shard",
1895 "sharded",
1896 "sharded_id",
1897 "sigmoid",
1898 "sign",
1899 "sin",
1900 "skip",
1901 "sleep",
1902 "snapshot",
1903 "soname",
1904 "sparse",
1905 "spatial_check_index",
1906 "split",
1907 "sqrt",
1908 "standalone",
1909 "std",
1910 "stddev",
1911 "stddev_pop",
1912 "stddev_samp",
1913 "stop",
1914 "str_to_date",
1915 "subdate",
1916 "substr",
1917 "substring_index",
1918 "success",
1919 "synchronize",
1920 "table_checksum",
1921 "tan",
1922 "task",
1923 "timediff",
1924 "time_bucket",
1925 "time_format",
1926 "time_to_sec",
1927 "timestampadd",
1928 "timestampdiff",
1929 "to_base64",
1930 "to_char",
1931 "to_date",
1932 "to_days",
1933 "to_json",
1934 "to_number",
1935 "to_seconds",
1936 "to_timestamp",
1937 "tracelogs",
1938 "transform",
1939 "trim",
1940 "trunc",
1941 "truncate",
1942 "ucase",
1943 "unhex",
1944 "unix_timestamp",
1945 "utc_date",
1946 "utc_time",
1947 "utc_timestamp",
1948 "vacuum",
1949 "variance",
1950 "var_pop",
1951 "var_samp",
1952 "vector_sub",
1953 "voting",
1954 "week",
1955 "weekday",
1956 "weekofyear",
1957 "workload",
1958 "year",
1959 ]);
1960 set.remove("all");
1962 set
1963 });
1964
1965 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1969 [
1971 "abort",
1972 "action",
1973 "add",
1974 "after",
1975 "all",
1976 "alter",
1977 "always",
1978 "analyze",
1979 "and",
1980 "as",
1981 "asc",
1982 "attach",
1983 "autoincrement",
1984 "before",
1985 "begin",
1986 "between",
1987 "by",
1988 "cascade",
1989 "case",
1990 "cast",
1991 "check",
1992 "collate",
1993 "column",
1994 "commit",
1995 "conflict",
1996 "constraint",
1997 "create",
1998 "cross",
1999 "current",
2000 "current_date",
2001 "current_time",
2002 "current_timestamp",
2003 "database",
2004 "default",
2005 "deferrable",
2006 "deferred",
2007 "delete",
2008 "desc",
2009 "detach",
2010 "distinct",
2011 "do",
2012 "drop",
2013 "each",
2014 "else",
2015 "end",
2016 "escape",
2017 "except",
2018 "exclude",
2019 "exclusive",
2020 "exists",
2021 "explain",
2022 "fail",
2023 "filter",
2024 "first",
2025 "following",
2026 "for",
2027 "foreign",
2028 "from",
2029 "full",
2030 "generated",
2031 "glob",
2032 "group",
2033 "groups",
2034 "having",
2035 "if",
2036 "ignore",
2037 "immediate",
2038 "in",
2039 "index",
2040 "indexed",
2041 "initially",
2042 "inner",
2043 "insert",
2044 "instead",
2045 "intersect",
2046 "into",
2047 "is",
2048 "isnull",
2049 "join",
2050 "key",
2051 "last",
2052 "left",
2053 "like",
2054 "limit",
2055 "natural",
2056 "no",
2057 "not",
2058 "nothing",
2059 "notnull",
2060 "null",
2061 "nulls",
2062 "of",
2063 "offset",
2064 "on",
2065 "or",
2066 "order",
2067 "others",
2068 "outer",
2069 "partition",
2070 "plan",
2071 "pragma",
2072 "preceding",
2073 "primary",
2074 "query",
2075 "raise",
2076 "range",
2077 "recursive",
2078 "references",
2079 "regexp",
2080 "reindex",
2081 "release",
2082 "rename",
2083 "replace",
2084 "restrict",
2085 "returning",
2086 "right",
2087 "rollback",
2088 "row",
2089 "rows",
2090 "savepoint",
2091 "select",
2092 "set",
2093 "table",
2094 "temp",
2095 "temporary",
2096 "then",
2097 "ties",
2098 "to",
2099 "transaction",
2100 "trigger",
2101 "unbounded",
2102 "union",
2103 "unique",
2104 "update",
2105 "using",
2106 "vacuum",
2107 "values",
2108 "view",
2109 "virtual",
2110 "when",
2111 "where",
2112 "window",
2113 "with",
2114 "without",
2115 ]
2116 .into_iter()
2117 .collect()
2118 });
2119}
2120
2121impl Generator {
2122 pub fn new() -> Self {
2128 Self::with_config(GeneratorConfig::default())
2129 }
2130
2131 pub fn with_config(config: GeneratorConfig) -> Self {
2136 Self::with_arc_config(Arc::new(config))
2137 }
2138
2139 pub(crate) fn with_arc_config(config: Arc<GeneratorConfig>) -> Self {
2144 Self {
2145 config,
2146 output: String::new(),
2147 unsupported_messages: Vec::new(),
2148 indent_level: 0,
2149 athena_hive_context: false,
2150 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2151 merge_strip_qualifiers: Vec::new(),
2152 clickhouse_nullable_depth: 0,
2153 }
2154 }
2155
2156 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2160 match expr {
2161 Expression::Select(mut select) => {
2162 select.expressions = select
2164 .expressions
2165 .into_iter()
2166 .map(|e| Self::add_alias_to_expression(e))
2167 .collect();
2168
2169 if let Some(ref mut from) = select.from {
2171 from.expressions = from
2172 .expressions
2173 .iter()
2174 .cloned()
2175 .map(|e| Self::add_column_aliases_to_query(e))
2176 .collect();
2177 }
2178
2179 Expression::Select(select)
2180 }
2181 Expression::Subquery(mut sq) => {
2182 sq.this = Self::add_column_aliases_to_query(sq.this);
2183 Expression::Subquery(sq)
2184 }
2185 Expression::Paren(mut p) => {
2186 p.this = Self::add_column_aliases_to_query(p.this);
2187 Expression::Paren(p)
2188 }
2189 other => other,
2191 }
2192 }
2193
2194 fn add_alias_to_expression(expr: Expression) -> Expression {
2197 use crate::expressions::Alias;
2198
2199 match &expr {
2200 Expression::Alias(_) => expr,
2202
2203 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2205 this: expr.clone(),
2206 alias: col.name.clone(),
2207 column_aliases: Vec::new(),
2208 alias_explicit_as: false,
2209 alias_keyword: None,
2210 pre_alias_comments: Vec::new(),
2211 trailing_comments: Vec::new(),
2212 inferred_type: None,
2213 })),
2214
2215 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2217 this: expr.clone(),
2218 alias: ident.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::Subquery(sq) => {
2229 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2230 if sq.alias.is_some() {
2232 processed
2233 } else {
2234 processed
2236 }
2237 }
2238
2239 Expression::Star(_) => expr,
2241
2242 _ => expr,
2245 }
2246 }
2247
2248 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2252 match expr {
2253 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
2254 let Literal::Number(n) = lit.as_ref() else {
2255 unreachable!()
2256 };
2257 n.parse::<i64>().ok()
2258 }
2259 Expression::Add(op) => {
2260 let left = Self::try_evaluate_constant(&op.left)?;
2261 let right = Self::try_evaluate_constant(&op.right)?;
2262 Some(left + right)
2263 }
2264 Expression::Sub(op) => {
2265 let left = Self::try_evaluate_constant(&op.left)?;
2266 let right = Self::try_evaluate_constant(&op.right)?;
2267 Some(left - right)
2268 }
2269 Expression::Mul(op) => {
2270 let left = Self::try_evaluate_constant(&op.left)?;
2271 let right = Self::try_evaluate_constant(&op.right)?;
2272 Some(left * right)
2273 }
2274 Expression::Div(op) => {
2275 let left = Self::try_evaluate_constant(&op.left)?;
2276 let right = Self::try_evaluate_constant(&op.right)?;
2277 if right != 0 {
2278 Some(left / right)
2279 } else {
2280 None
2281 }
2282 }
2283 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2284 _ => None,
2285 }
2286 }
2287
2288 fn is_reserved_keyword(&self, name: &str) -> bool {
2290 use crate::dialects::DialectType;
2291 let mut buf = [0u8; 128];
2292 let lower_ref: &str = if name.len() <= 128 {
2293 for (i, b) in name.bytes().enumerate() {
2294 buf[i] = b.to_ascii_lowercase();
2295 }
2296 std::str::from_utf8(&buf[..name.len()]).unwrap_or(name)
2298 } else {
2299 return false;
2300 };
2301
2302 match self.config.dialect {
2303 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2304 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2305 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2306 }
2307 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2308 Some(DialectType::SingleStore) => {
2309 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2310 }
2311 Some(DialectType::StarRocks) => {
2312 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2313 }
2314 Some(DialectType::PostgreSQL)
2315 | Some(DialectType::CockroachDB)
2316 | Some(DialectType::Materialize)
2317 | Some(DialectType::RisingWave) => {
2318 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2319 }
2320 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2321 Some(DialectType::Snowflake) => false,
2324 Some(DialectType::ClickHouse) => false,
2326 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2327 Some(DialectType::Teradata) => false,
2329 Some(DialectType::TSQL)
2331 | Some(DialectType::Fabric)
2332 | Some(DialectType::Oracle)
2333 | Some(DialectType::Spark)
2334 | Some(DialectType::Databricks)
2335 | Some(DialectType::Hive)
2336 | Some(DialectType::Solr) => false,
2337 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2338 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2339 }
2340 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2341 Some(DialectType::Generic) | None => false,
2343 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2345 }
2346 }
2347
2348 fn normalize_func_name<'a>(&self, name: &'a str) -> Cow<'a, str> {
2350 match self.config.normalize_functions {
2351 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
2352 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
2353 NormalizeFunctions::None => Cow::Borrowed(name),
2354 }
2355 }
2356
2357 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2366 self.output.clear();
2367 self.unsupported_messages.clear();
2368 self.generate_expression(expr)?;
2369 if self.config.unsupported_level == UnsupportedLevel::Raise
2370 && !self.unsupported_messages.is_empty()
2371 {
2372 return Err(crate::error::Error::generate(
2373 self.format_unsupported_messages(),
2374 ));
2375 }
2376 Ok(std::mem::take(&mut self.output))
2377 }
2378
2379 pub fn unsupported_messages(&self) -> &[String] {
2381 &self.unsupported_messages
2382 }
2383
2384 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2385 let message = message.into();
2386 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2387 return Err(crate::error::Error::generate(message));
2388 }
2389 self.unsupported_messages.push(message);
2390 Ok(())
2391 }
2392
2393 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2394 self.unsupported(message.to_string())?;
2395 self.write("/* ");
2396 self.write(message);
2397 self.write(" */");
2398 Ok(())
2399 }
2400
2401 fn format_unsupported_messages(&self) -> String {
2402 let limit = self.config.max_unsupported.max(1);
2403 if self.unsupported_messages.len() <= limit {
2404 return self.unsupported_messages.join("; ");
2405 }
2406
2407 let mut messages = self
2408 .unsupported_messages
2409 .iter()
2410 .take(limit)
2411 .cloned()
2412 .collect::<Vec<_>>();
2413 messages.push(format!(
2414 "... and {} more",
2415 self.unsupported_messages.len() - limit
2416 ));
2417 messages.join("; ")
2418 }
2419
2420 pub fn sql(expr: &Expression) -> Result<String> {
2426 let mut gen = Generator::new();
2427 gen.generate(expr)
2428 }
2429
2430 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2435 let config = GeneratorConfig {
2436 pretty: true,
2437 ..Default::default()
2438 };
2439 let mut gen = Generator::with_config(config);
2440 let mut sql = gen.generate(expr)?;
2441 if !sql.ends_with(';') {
2443 sql.push(';');
2444 }
2445 Ok(sql)
2446 }
2447
2448 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2449 #[cfg(feature = "stacker")]
2450 {
2451 let red_zone = if cfg!(debug_assertions) {
2452 4 * 1024 * 1024
2453 } else {
2454 1024 * 1024
2455 };
2456 stacker::maybe_grow(red_zone, 8 * 1024 * 1024, || {
2457 self.generate_expression_inner(expr)
2458 })
2459 }
2460 #[cfg(not(feature = "stacker"))]
2461 {
2462 self.generate_expression_inner(expr)
2463 }
2464 }
2465
2466 fn generate_expression_inner(&mut self, expr: &Expression) -> Result<()> {
2467 match expr {
2468 Expression::Select(select) => self.generate_select(select),
2469 Expression::Union(union) => self.generate_union(union),
2470 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2471 Expression::Except(except) => self.generate_except(except),
2472 Expression::Insert(insert) => self.generate_insert(insert),
2473 Expression::Update(update) => self.generate_update(update),
2474 Expression::Delete(delete) => self.generate_delete(delete),
2475 Expression::Literal(lit) => self.generate_literal(lit),
2476 Expression::Boolean(b) => self.generate_boolean(b),
2477 Expression::Null(_) => {
2478 self.write_keyword("NULL");
2479 Ok(())
2480 }
2481 Expression::Identifier(id) => self.generate_identifier(id),
2482 Expression::Column(col) => self.generate_column(col),
2483 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2484 Expression::Connect(c) => self.generate_connect_expr(c),
2485 Expression::Prior(p) => self.generate_prior(p),
2486 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2487 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2488 Expression::Table(table) => self.generate_table(table),
2489 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2490 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2491 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2492 Expression::Star(star) => self.generate_star(star),
2493 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2494 Expression::Alias(alias) => self.generate_alias(alias),
2495 Expression::Cast(cast) => self.generate_cast(cast),
2496 Expression::Collation(coll) => self.generate_collation(coll),
2497 Expression::Case(case) => self.generate_case(case),
2498 Expression::Function(func) => self.generate_function(func),
2499 Expression::FunctionEmits(fe) => self.generate_function_emits(fe),
2500 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2501 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2502 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2503 Expression::Interval(interval) => self.generate_interval(interval),
2504
2505 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2507 Expression::Substring(f) => self.generate_substring(f),
2508 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2509 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2510 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2511 Expression::Trim(f) => self.generate_trim(f),
2512 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2513 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2514 Expression::Replace(f) => self.generate_replace(f),
2515 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2516 Expression::Left(f) => self.generate_left_right("LEFT", f),
2517 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2518 Expression::Repeat(f) => self.generate_repeat(f),
2519 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2520 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2521 Expression::Split(f) => self.generate_split(f),
2522 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2523 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2524 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2525 Expression::Overlay(f) => self.generate_overlay(f),
2526
2527 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2529 Expression::Round(f) => self.generate_round(f),
2530 Expression::Floor(f) => self.generate_floor(f),
2531 Expression::Ceil(f) => self.generate_ceil(f),
2532 Expression::Power(f) => self.generate_power(f),
2533 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2534 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2535 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2536 Expression::Log(f) => self.generate_log(f),
2537 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2538 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2539 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2540 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2541
2542 Expression::CurrentDate(_) => {
2544 self.write_keyword("CURRENT_DATE");
2545 Ok(())
2546 }
2547 Expression::CurrentTime(f) => self.generate_current_time(f),
2548 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2549 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2550 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2551 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2552 Expression::DateDiff(f) => self.generate_datediff(f),
2553 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2554 Expression::Extract(f) => self.generate_extract(f),
2555 Expression::ToDate(f) => self.generate_to_date(f),
2556 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2557
2558 Expression::Coalesce(f) => {
2560 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2562 self.generate_vararg_func(func_name, &f.expressions)
2563 }
2564 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2565 Expression::IfFunc(f) => self.generate_if_func(f),
2566 Expression::IfNull(f) => self.generate_ifnull(f),
2567 Expression::Nvl(f) => self.generate_nvl(f),
2568 Expression::Nvl2(f) => self.generate_nvl2(f),
2569
2570 Expression::TryCast(cast) => self.generate_try_cast(cast),
2572 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2573
2574 Expression::Count(f) => self.generate_count(f),
2576 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2577 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2578 Expression::Min(f) => self.generate_agg_func("MIN", f),
2579 Expression::Max(f) => self.generate_agg_func("MAX", f),
2580 Expression::GroupConcat(f) => self.generate_group_concat(f),
2581 Expression::StringAgg(f) => self.generate_string_agg(f),
2582 Expression::ListAgg(f) => self.generate_listagg(f),
2583 Expression::ArrayAgg(f) => {
2584 let override_name = f
2587 .name
2588 .as_ref()
2589 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2590 .map(|n| n.to_ascii_uppercase());
2591 match override_name {
2592 Some(name) => self.generate_agg_func(&name, f),
2593 None => self.generate_agg_func("ARRAY_AGG", f),
2594 }
2595 }
2596 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2597 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2598 Expression::SumIf(f) => self.generate_sum_if(f),
2599 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2600 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2601 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2602 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2603 Expression::VarPop(f) => {
2604 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2605 "VARIANCE_POP"
2606 } else {
2607 "VAR_POP"
2608 };
2609 self.generate_agg_func(name, f)
2610 }
2611 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2612 Expression::Skewness(f) => {
2613 let name = match self.config.dialect {
2614 Some(DialectType::Snowflake) => "SKEW",
2615 _ => "SKEWNESS",
2616 };
2617 self.generate_agg_func(name, f)
2618 }
2619 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2620 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2621 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2622 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2623 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2624 Expression::ApproxDistinct(f) => {
2625 match self.config.dialect {
2626 Some(DialectType::Hive)
2627 | Some(DialectType::Spark)
2628 | Some(DialectType::Databricks)
2629 | Some(DialectType::BigQuery) => {
2630 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2632 }
2633 Some(DialectType::Redshift) => {
2634 self.write_keyword("APPROXIMATE COUNT");
2636 self.write("(");
2637 self.write_keyword("DISTINCT");
2638 self.write(" ");
2639 self.generate_expression(&f.this)?;
2640 self.write(")");
2641 Ok(())
2642 }
2643 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2644 }
2645 }
2646 Expression::ApproxCountDistinct(f) => {
2647 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2648 }
2649 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2650 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2651 Expression::LogicalAnd(f) => {
2652 let name = match self.config.dialect {
2653 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2654 Some(DialectType::Spark)
2655 | Some(DialectType::Databricks)
2656 | Some(DialectType::PostgreSQL)
2657 | Some(DialectType::DuckDB)
2658 | Some(DialectType::Redshift) => "BOOL_AND",
2659 Some(DialectType::Oracle)
2660 | Some(DialectType::SQLite)
2661 | Some(DialectType::MySQL) => "MIN",
2662 _ => "BOOL_AND",
2663 };
2664 self.generate_agg_func(name, f)
2665 }
2666 Expression::LogicalOr(f) => {
2667 let name = match self.config.dialect {
2668 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2669 Some(DialectType::Spark)
2670 | Some(DialectType::Databricks)
2671 | Some(DialectType::PostgreSQL)
2672 | Some(DialectType::DuckDB)
2673 | Some(DialectType::Redshift) => "BOOL_OR",
2674 Some(DialectType::Oracle)
2675 | Some(DialectType::SQLite)
2676 | Some(DialectType::MySQL) => "MAX",
2677 _ => "BOOL_OR",
2678 };
2679 self.generate_agg_func(name, f)
2680 }
2681
2682 Expression::RowNumber(_) => {
2684 if self.config.dialect == Some(DialectType::ClickHouse) {
2685 self.write("row_number");
2686 } else {
2687 self.write_keyword("ROW_NUMBER");
2688 }
2689 self.write("()");
2690 Ok(())
2691 }
2692 Expression::Rank(r) => {
2693 self.write_keyword("RANK");
2694 self.write("(");
2695 if !r.args.is_empty() {
2697 for (i, arg) in r.args.iter().enumerate() {
2698 if i > 0 {
2699 self.write(", ");
2700 }
2701 self.generate_expression(arg)?;
2702 }
2703 } else if let Some(order_by) = &r.order_by {
2704 self.write_keyword(" ORDER BY ");
2706 for (i, ob) in order_by.iter().enumerate() {
2707 if i > 0 {
2708 self.write(", ");
2709 }
2710 self.generate_ordered(ob)?;
2711 }
2712 }
2713 self.write(")");
2714 Ok(())
2715 }
2716 Expression::DenseRank(dr) => {
2717 self.write_keyword("DENSE_RANK");
2718 self.write("(");
2719 for (i, arg) in dr.args.iter().enumerate() {
2721 if i > 0 {
2722 self.write(", ");
2723 }
2724 self.generate_expression(arg)?;
2725 }
2726 self.write(")");
2727 Ok(())
2728 }
2729 Expression::NTile(f) => self.generate_ntile(f),
2730 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2731 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2732 Expression::FirstValue(f) => {
2733 self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f)
2734 }
2735 Expression::LastValue(f) => {
2736 self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f)
2737 }
2738 Expression::NthValue(f) => self.generate_nth_value(f),
2739 Expression::PercentRank(pr) => {
2740 self.write_keyword("PERCENT_RANK");
2741 self.write("(");
2742 if !pr.args.is_empty() {
2744 for (i, arg) in pr.args.iter().enumerate() {
2745 if i > 0 {
2746 self.write(", ");
2747 }
2748 self.generate_expression(arg)?;
2749 }
2750 } else if let Some(order_by) = &pr.order_by {
2751 self.write_keyword(" ORDER BY ");
2753 for (i, ob) in order_by.iter().enumerate() {
2754 if i > 0 {
2755 self.write(", ");
2756 }
2757 self.generate_ordered(ob)?;
2758 }
2759 }
2760 self.write(")");
2761 Ok(())
2762 }
2763 Expression::CumeDist(cd) => {
2764 self.write_keyword("CUME_DIST");
2765 self.write("(");
2766 if !cd.args.is_empty() {
2768 for (i, arg) in cd.args.iter().enumerate() {
2769 if i > 0 {
2770 self.write(", ");
2771 }
2772 self.generate_expression(arg)?;
2773 }
2774 } else if let Some(order_by) = &cd.order_by {
2775 self.write_keyword(" ORDER BY ");
2777 for (i, ob) in order_by.iter().enumerate() {
2778 if i > 0 {
2779 self.write(", ");
2780 }
2781 self.generate_ordered(ob)?;
2782 }
2783 }
2784 self.write(")");
2785 Ok(())
2786 }
2787 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2788 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2789
2790 Expression::Contains(f) => {
2792 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2793 }
2794 Expression::StartsWith(f) => {
2795 let name = match self.config.dialect {
2796 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2797 _ => "STARTS_WITH",
2798 };
2799 self.generate_binary_func(name, &f.this, &f.expression)
2800 }
2801 Expression::EndsWith(f) => {
2802 let name = match self.config.dialect {
2803 Some(DialectType::Snowflake) => "ENDSWITH",
2804 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2805 Some(DialectType::ClickHouse) => "endsWith",
2806 _ => "ENDS_WITH",
2807 };
2808 self.generate_binary_func(name, &f.this, &f.expression)
2809 }
2810 Expression::Position(f) => self.generate_position(f),
2811 Expression::Initcap(f) => match self.config.dialect {
2812 Some(DialectType::Presto)
2813 | Some(DialectType::Trino)
2814 | Some(DialectType::Athena) => {
2815 self.write_keyword("REGEXP_REPLACE");
2816 self.write("(");
2817 self.generate_expression(&f.this)?;
2818 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2819 Ok(())
2820 }
2821 _ => self.generate_simple_func("INITCAP", &f.this),
2822 },
2823 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2824 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2825 Expression::CharFunc(f) => self.generate_char_func(f),
2826 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2827 Expression::Levenshtein(f) => {
2828 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2829 }
2830
2831 Expression::ModFunc(f) => self.generate_mod_func(f),
2833 Expression::Random(_) => {
2834 self.write_keyword("RANDOM");
2835 self.write("()");
2836 Ok(())
2837 }
2838 Expression::Rand(f) => self.generate_rand(f),
2839 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2840 Expression::Pi(_) => {
2841 self.write_keyword("PI");
2842 self.write("()");
2843 Ok(())
2844 }
2845 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2846 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2847 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2848 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2849 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2850 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2851 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2852 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2853 Expression::Atan2(f) => {
2854 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2855 self.generate_binary_func(name, &f.this, &f.expression)
2856 }
2857
2858 Expression::Decode(f) => self.generate_decode(f),
2860
2861 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2863 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2864 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2865 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2866 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2867 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2868 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2869 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2870 Expression::DayOfWeek(f) => {
2871 let name = match self.config.dialect {
2872 Some(DialectType::Presto)
2873 | Some(DialectType::Trino)
2874 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2875 Some(DialectType::DuckDB) => "ISODOW",
2876 _ => "DAYOFWEEK",
2877 };
2878 self.generate_simple_func(name, &f.this)
2879 }
2880 Expression::DayOfMonth(f) => {
2881 let name = match self.config.dialect {
2882 Some(DialectType::Presto)
2883 | Some(DialectType::Trino)
2884 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2885 _ => "DAYOFMONTH",
2886 };
2887 self.generate_simple_func(name, &f.this)
2888 }
2889 Expression::DayOfYear(f) => {
2890 let name = match self.config.dialect {
2891 Some(DialectType::Presto)
2892 | Some(DialectType::Trino)
2893 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2894 _ => "DAYOFYEAR",
2895 };
2896 self.generate_simple_func(name, &f.this)
2897 }
2898 Expression::WeekOfYear(f) => {
2899 let name = match self.config.dialect {
2901 Some(DialectType::Hive)
2902 | Some(DialectType::DuckDB)
2903 | Some(DialectType::Spark)
2904 | Some(DialectType::Databricks)
2905 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2906 _ => "WEEK_OF_YEAR",
2907 };
2908 self.generate_simple_func(name, &f.this)
2909 }
2910 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2911 Expression::AddMonths(f) => {
2912 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2913 }
2914 Expression::MonthsBetween(f) => {
2915 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2916 }
2917 Expression::LastDay(f) => self.generate_last_day(f),
2918 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2919 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2920 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2921 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2922 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2923 Expression::MakeDate(f) => self.generate_make_date(f),
2924 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2925 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2926
2927 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2929 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2930 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2931 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2932 Expression::ArrayContains(f) => {
2933 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2934 }
2935 Expression::ArrayPosition(f) => {
2936 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2937 }
2938 Expression::ArrayAppend(f) => {
2939 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2940 }
2941 Expression::ArrayPrepend(f) => {
2942 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2943 }
2944 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2945 Expression::ArraySort(f) => self.generate_array_sort(f),
2946 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2947 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2948 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2949 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2950 Expression::Unnest(f) => self.generate_unnest(f),
2951 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2952 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2953 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2954 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2955 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2956 Expression::ArrayCompact(f) => {
2957 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2958 self.write("LIST_FILTER(");
2960 self.generate_expression(&f.this)?;
2961 self.write(", _u -> NOT _u IS NULL)");
2962 Ok(())
2963 } else {
2964 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2965 }
2966 }
2967 Expression::ArrayIntersect(f) => {
2968 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2969 self.generate_vararg_func(func_name, &f.expressions)
2970 }
2971 Expression::ArrayUnion(f) => {
2972 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2973 }
2974 Expression::ArrayExcept(f) => {
2975 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2976 }
2977 Expression::ArrayRemove(f) => {
2978 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2979 }
2980 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2981 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2982 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2983
2984 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2986 Expression::StructExtract(f) => self.generate_struct_extract(f),
2987 Expression::NamedStruct(f) => self.generate_named_struct(f),
2988
2989 Expression::MapFunc(f) => self.generate_map_constructor(f),
2991 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2992 Expression::MapFromArrays(f) => {
2993 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2994 }
2995 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2996 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2997 Expression::MapContainsKey(f) => {
2998 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2999 }
3000 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
3001 Expression::ElementAt(f) => {
3002 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
3003 }
3004 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
3005 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
3006
3007 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
3009 Expression::JsonExtractScalar(f) => {
3010 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
3011 }
3012 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
3013 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
3014 Expression::JsonObject(f) => self.generate_json_object(f),
3015 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
3016 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
3017 Expression::JsonArrayLength(f) => {
3018 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
3019 }
3020 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
3021 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
3022 Expression::ParseJson(f) => {
3023 let name = match self.config.dialect {
3024 Some(DialectType::Presto)
3025 | Some(DialectType::Trino)
3026 | Some(DialectType::Athena) => "JSON_PARSE",
3027 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
3028 self.write_keyword("CAST");
3030 self.write("(");
3031 self.generate_expression(&f.this)?;
3032 self.write_keyword(" AS ");
3033 self.write_keyword("JSON");
3034 self.write(")");
3035 return Ok(());
3036 }
3037 Some(DialectType::Hive)
3038 | Some(DialectType::Spark)
3039 | Some(DialectType::MySQL)
3040 | Some(DialectType::SingleStore)
3041 | Some(DialectType::TiDB)
3042 | Some(DialectType::TSQL) => {
3043 self.generate_expression(&f.this)?;
3045 return Ok(());
3046 }
3047 Some(DialectType::DuckDB) => "JSON",
3048 _ => "PARSE_JSON",
3049 };
3050 self.generate_simple_func(name, &f.this)
3051 }
3052 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3053 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3054 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3055 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3056 Expression::JsonMergePatch(f) => {
3057 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3058 }
3059 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3060 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3061
3062 Expression::Convert(f) => self.generate_convert(f),
3064 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3065
3066 Expression::Lambda(f) => self.generate_lambda(f),
3068 Expression::Parameter(f) => self.generate_parameter(f),
3069 Expression::Placeholder(f) => self.generate_placeholder(f),
3070 Expression::NamedArgument(f) => self.generate_named_argument(f),
3071 Expression::TableArgument(f) => self.generate_table_argument(f),
3072 Expression::SqlComment(f) => self.generate_sql_comment(f),
3073
3074 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3076 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3077 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3078 Expression::SimilarTo(f) => self.generate_similar_to(f),
3079 Expression::Any(f) => self.generate_quantified("ANY", f),
3080 Expression::All(f) => self.generate_quantified("ALL", f),
3081 Expression::Overlaps(f) => self.generate_overlaps(f),
3082
3083 Expression::BitwiseLeftShift(op) => {
3085 if matches!(
3086 self.config.dialect,
3087 Some(DialectType::Presto) | Some(DialectType::Trino)
3088 ) {
3089 self.write_keyword("BITWISE_LEFT_SHIFT");
3090 self.write("(");
3091 self.generate_expression(&op.left)?;
3092 self.write(", ");
3093 self.generate_expression(&op.right)?;
3094 self.write(")");
3095 Ok(())
3096 } else if matches!(
3097 self.config.dialect,
3098 Some(DialectType::Spark) | Some(DialectType::Databricks)
3099 ) {
3100 self.write_keyword("SHIFTLEFT");
3101 self.write("(");
3102 self.generate_expression(&op.left)?;
3103 self.write(", ");
3104 self.generate_expression(&op.right)?;
3105 self.write(")");
3106 Ok(())
3107 } else {
3108 self.generate_binary_op(op, "<<")
3109 }
3110 }
3111 Expression::BitwiseRightShift(op) => {
3112 if matches!(
3113 self.config.dialect,
3114 Some(DialectType::Presto) | Some(DialectType::Trino)
3115 ) {
3116 self.write_keyword("BITWISE_RIGHT_SHIFT");
3117 self.write("(");
3118 self.generate_expression(&op.left)?;
3119 self.write(", ");
3120 self.generate_expression(&op.right)?;
3121 self.write(")");
3122 Ok(())
3123 } else if matches!(
3124 self.config.dialect,
3125 Some(DialectType::Spark) | Some(DialectType::Databricks)
3126 ) {
3127 self.write_keyword("SHIFTRIGHT");
3128 self.write("(");
3129 self.generate_expression(&op.left)?;
3130 self.write(", ");
3131 self.generate_expression(&op.right)?;
3132 self.write(")");
3133 Ok(())
3134 } else {
3135 self.generate_binary_op(op, ">>")
3136 }
3137 }
3138 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3139 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3140 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3141
3142 Expression::Subscript(s) => self.generate_subscript(s),
3144 Expression::Dot(d) => self.generate_dot_access(d),
3145 Expression::MethodCall(m) => self.generate_method_call(m),
3146 Expression::ArraySlice(s) => self.generate_array_slice(s),
3147
3148 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3149 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3150 Expression::Add(op) => self.generate_binary_op(op, "+"),
3151 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3152 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3153 Expression::Div(op) => self.generate_binary_op(op, "/"),
3154 Expression::IntDiv(f) => {
3155 use crate::dialects::DialectType;
3156 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3157 self.generate_expression(&f.this)?;
3159 self.write(" // ");
3160 self.generate_expression(&f.expression)?;
3161 Ok(())
3162 } else if matches!(
3163 self.config.dialect,
3164 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3165 ) {
3166 self.generate_expression(&f.this)?;
3168 self.write(" ");
3169 self.write_keyword("DIV");
3170 self.write(" ");
3171 self.generate_expression(&f.expression)?;
3172 Ok(())
3173 } else {
3174 self.write_keyword("DIV");
3176 self.write("(");
3177 self.generate_expression(&f.this)?;
3178 self.write(", ");
3179 self.generate_expression(&f.expression)?;
3180 self.write(")");
3181 Ok(())
3182 }
3183 }
3184 Expression::Mod(op) => {
3185 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3186 self.generate_binary_op(op, "MOD")
3187 } else {
3188 self.generate_binary_op(op, "%")
3189 }
3190 }
3191 Expression::Eq(op) => self.generate_binary_op(op, "="),
3192 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3193 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3194 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3195 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3196 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3197 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3198 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3199 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3200 Expression::Concat(op) => {
3201 if self.config.dialect == Some(DialectType::Solr) {
3203 self.generate_binary_op(op, "OR")
3204 } else if self.config.dialect == Some(DialectType::MySQL) {
3205 self.generate_mysql_concat_from_concat(op)
3206 } else {
3207 self.generate_binary_op(op, "||")
3208 }
3209 }
3210 Expression::BitwiseAnd(op) => {
3211 if matches!(
3213 self.config.dialect,
3214 Some(DialectType::Presto) | Some(DialectType::Trino)
3215 ) {
3216 self.write_keyword("BITWISE_AND");
3217 self.write("(");
3218 self.generate_expression(&op.left)?;
3219 self.write(", ");
3220 self.generate_expression(&op.right)?;
3221 self.write(")");
3222 Ok(())
3223 } else {
3224 self.generate_binary_op(op, "&")
3225 }
3226 }
3227 Expression::BitwiseOr(op) => {
3228 if matches!(
3230 self.config.dialect,
3231 Some(DialectType::Presto) | Some(DialectType::Trino)
3232 ) {
3233 self.write_keyword("BITWISE_OR");
3234 self.write("(");
3235 self.generate_expression(&op.left)?;
3236 self.write(", ");
3237 self.generate_expression(&op.right)?;
3238 self.write(")");
3239 Ok(())
3240 } else {
3241 self.generate_binary_op(op, "|")
3242 }
3243 }
3244 Expression::BitwiseXor(op) => {
3245 if matches!(
3247 self.config.dialect,
3248 Some(DialectType::Presto) | Some(DialectType::Trino)
3249 ) {
3250 self.write_keyword("BITWISE_XOR");
3251 self.write("(");
3252 self.generate_expression(&op.left)?;
3253 self.write(", ");
3254 self.generate_expression(&op.right)?;
3255 self.write(")");
3256 Ok(())
3257 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3258 self.generate_binary_op(op, "#")
3259 } else {
3260 self.generate_binary_op(op, "^")
3261 }
3262 }
3263 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3264 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3265 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3266 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3267 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3268 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3269 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3270 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3271 Expression::JSONBContains(f) => {
3272 self.generate_expression(&f.this)?;
3274 self.write_space();
3275 self.write("?");
3276 self.write_space();
3277 self.generate_expression(&f.expression)
3278 }
3279 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3280 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3281 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3282 Expression::Not(op) => match &op.this {
3283 Expression::Like(like) => self.generate_like_op_negated(like, "LIKE"),
3284 Expression::ILike(like) => self.generate_like_op_negated(like, "ILIKE"),
3285 _ => self.generate_unary_op(op, "NOT"),
3286 },
3287 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3288 Expression::BitwiseNot(op) => {
3289 if matches!(
3291 self.config.dialect,
3292 Some(DialectType::Presto) | Some(DialectType::Trino)
3293 ) {
3294 self.write_keyword("BITWISE_NOT");
3295 self.write("(");
3296 self.generate_expression(&op.this)?;
3297 self.write(")");
3298 Ok(())
3299 } else {
3300 self.generate_unary_op(op, "~")
3301 }
3302 }
3303 Expression::In(in_expr) => self.generate_in(in_expr),
3304 Expression::Between(between) => self.generate_between(between),
3305 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3306 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3307 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3308 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3309 Expression::Is(is_expr) => self.generate_is(is_expr),
3310 Expression::Exists(exists) => self.generate_exists(exists),
3311 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3312 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3313 Expression::Paren(paren) => {
3314 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3316
3317 if !skip_parens {
3318 self.write("(");
3319 if self.config.pretty {
3320 self.write_newline();
3321 self.indent_level += 1;
3322 self.write_indent();
3323 }
3324 }
3325 self.generate_expression(&paren.this)?;
3326 if !skip_parens {
3327 if self.config.pretty {
3328 self.write_newline();
3329 self.indent_level -= 1;
3330 self.write_indent();
3331 }
3332 self.write(")");
3333 }
3334 for comment in &paren.trailing_comments {
3336 self.write(" ");
3337 self.write_formatted_comment(comment);
3338 }
3339 Ok(())
3340 }
3341 Expression::Array(arr) => self.generate_array(arr),
3342 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3343 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3344 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3345 Expression::DataType(dt) => self.generate_data_type(dt),
3346 Expression::Raw(raw) => {
3347 self.write(&raw.sql);
3348 Ok(())
3349 }
3350 Expression::CreateTask(task) => self.generate_create_task(task),
3351 Expression::TryCatch(try_catch) => self.generate_try_catch(try_catch),
3352 Expression::Command(cmd) => {
3353 self.write(&cmd.this);
3354 Ok(())
3355 }
3356 Expression::Kill(kill) => {
3357 self.write_keyword("KILL");
3358 if let Some(kind) = &kill.kind {
3359 self.write_space();
3360 self.write_keyword(kind);
3361 }
3362 self.write_space();
3363 self.generate_expression(&kill.this)?;
3364 Ok(())
3365 }
3366 Expression::Prepare(prepare) => self.generate_prepare(prepare),
3367 Expression::Execute(exec) => {
3368 self.write_keyword("EXECUTE");
3369 self.write_space();
3370 self.generate_expression(&exec.this)?;
3371 if exec.prepared {
3372 if !exec.arguments.is_empty() {
3373 self.write("(");
3374 for (i, argument) in exec.arguments.iter().enumerate() {
3375 if i > 0 {
3376 self.write(", ");
3377 }
3378 self.generate_expression(argument)?;
3379 }
3380 self.write(")");
3381 }
3382 return Ok(());
3383 }
3384 for (i, param) in exec.parameters.iter().enumerate() {
3385 if i == 0 {
3386 self.write_space();
3387 } else {
3388 self.write(", ");
3389 }
3390 self.write(¶m.name);
3391 if !param.positional {
3393 self.write(" = ");
3394 self.generate_expression(¶m.value)?;
3395 }
3396 if param.output {
3397 self.write_space();
3398 self.write_keyword("OUTPUT");
3399 }
3400 }
3401 if let Some(ref suffix) = exec.suffix {
3402 self.write_space();
3403 self.write(suffix);
3404 }
3405 Ok(())
3406 }
3407 Expression::Annotated(annotated) => {
3408 self.generate_expression(&annotated.this)?;
3409 for comment in &annotated.trailing_comments {
3410 self.write(" ");
3411 self.write_formatted_comment(comment);
3412 }
3413 Ok(())
3414 }
3415
3416 Expression::CreateTable(ct) => self.generate_create_table(ct),
3418 Expression::DropTable(dt) => self.generate_drop_table(dt),
3419 Expression::Undrop(u) => self.generate_undrop(u),
3420 Expression::AlterTable(at) => self.generate_alter_table(at),
3421 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3422 Expression::DropIndex(di) => self.generate_drop_index(di),
3423 Expression::CreateView(cv) => self.generate_create_view(cv),
3424 Expression::DropView(dv) => self.generate_drop_view(dv),
3425 Expression::AlterView(av) => self.generate_alter_view(av),
3426 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3427 Expression::Truncate(tr) => self.generate_truncate(tr),
3428 Expression::Use(u) => self.generate_use(u),
3429 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3431 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3432 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3433 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3434 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3435 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3436 Expression::DropFunction(df) => self.generate_drop_function(df),
3437 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3438 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3439 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3440 Expression::CreateSynonym(cs) => {
3441 self.write_keyword("CREATE SYNONYM");
3442 self.write_space();
3443 self.generate_table(&cs.name)?;
3444 self.write_space();
3445 self.write_keyword("FOR");
3446 self.write_space();
3447 self.generate_table(&cs.target)?;
3448 Ok(())
3449 }
3450 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3451 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3452 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3453 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3454 Expression::CreateType(ct) => self.generate_create_type(ct),
3455 Expression::DropType(dt) => self.generate_drop_type(dt),
3456 Expression::Describe(d) => self.generate_describe(d),
3457 Expression::Show(s) => self.generate_show(s),
3458
3459 Expression::Cache(c) => self.generate_cache(c),
3461 Expression::Uncache(u) => self.generate_uncache(u),
3462 Expression::LoadData(l) => self.generate_load_data(l),
3463 Expression::Pragma(p) => self.generate_pragma(p),
3464 Expression::Grant(g) => self.generate_grant(g),
3465 Expression::Revoke(r) => self.generate_revoke(r),
3466 Expression::Comment(c) => self.generate_comment(c),
3467 Expression::SetStatement(s) => self.generate_set_statement(s),
3468
3469 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3471 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3472
3473 Expression::Values(values) => self.generate_values(values),
3475
3476 Expression::AIAgg(e) => self.generate_ai_agg(e),
3478 Expression::AIClassify(e) => self.generate_ai_classify(e),
3479 Expression::AddPartition(e) => self.generate_add_partition(e),
3480 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3481 Expression::Aliases(e) => self.generate_aliases(e),
3482 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3483 Expression::AlterColumn(e) => self.generate_alter_column(e),
3484 Expression::AlterSession(e) => self.generate_alter_session(e),
3485 Expression::AlterSet(e) => self.generate_alter_set(e),
3486 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3487 Expression::Analyze(e) => self.generate_analyze(e),
3488 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3489 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3490 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3491 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3492 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3493 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3494 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3495 Expression::Anonymous(e) => self.generate_anonymous(e),
3496 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3497 Expression::Apply(e) => self.generate_apply(e),
3498 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3499 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3500 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3501 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3502 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3503 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3504 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3505 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3506 Expression::ArgMax(e) => self.generate_arg_max(e),
3507 Expression::ArgMin(e) => self.generate_arg_min(e),
3508 Expression::ArrayAll(e) => self.generate_array_all(e),
3509 Expression::ArrayAny(e) => self.generate_array_any(e),
3510 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3511 Expression::ArraySum(e) => self.generate_array_sum(e),
3512 Expression::AtIndex(e) => self.generate_at_index(e),
3513 Expression::Attach(e) => self.generate_attach(e),
3514 Expression::AttachOption(e) => self.generate_attach_option(e),
3515 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3516 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3517 Expression::BackupProperty(e) => self.generate_backup_property(e),
3518 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3519 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3520 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3521 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3522 Expression::Booland(e) => self.generate_booland(e),
3523 Expression::Boolor(e) => self.generate_boolor(e),
3524 Expression::BuildProperty(e) => self.generate_build_property(e),
3525 Expression::ByteString(e) => self.generate_byte_string(e),
3526 Expression::CaseSpecificColumnConstraint(e) => {
3527 self.generate_case_specific_column_constraint(e)
3528 }
3529 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3530 Expression::Changes(e) => self.generate_changes(e),
3531 Expression::CharacterSetColumnConstraint(e) => {
3532 self.generate_character_set_column_constraint(e)
3533 }
3534 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3535 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3536 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3537 Expression::CheckJson(e) => self.generate_check_json(e),
3538 Expression::CheckXml(e) => self.generate_check_xml(e),
3539 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3540 Expression::Clone(e) => self.generate_clone(e),
3541 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3542 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3543 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3544 Expression::CollateProperty(e) => self.generate_collate_property(e),
3545 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3546 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3547 Expression::ColumnPosition(e) => self.generate_column_position(e),
3548 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3549 Expression::Columns(e) => self.generate_columns(e),
3550 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3551 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3552 Expression::Commit(e) => self.generate_commit(e),
3553 Expression::Comprehension(e) => self.generate_comprehension(e),
3554 Expression::Compress(e) => self.generate_compress(e),
3555 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3556 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3557 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3558 Expression::Constraint(e) => self.generate_constraint(e),
3559 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3560 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3561 Expression::Copy(e) => self.generate_copy(e),
3562 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3563 Expression::Corr(e) => self.generate_corr(e),
3564 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3565 Expression::CovarPop(e) => self.generate_covar_pop(e),
3566 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3567 Expression::Credentials(e) => self.generate_credentials(e),
3568 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3569 Expression::Cte(e) => self.generate_cte(e),
3570 Expression::Cube(e) => self.generate_cube(e),
3571 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3572 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3573 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3574 Expression::CurrentUser(e) => self.generate_current_user(e),
3575 Expression::DPipe(e) => self.generate_d_pipe(e),
3576 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3577 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3578 Expression::Date(e) => self.generate_date_func(e),
3579 Expression::DateBin(e) => self.generate_date_bin(e),
3580 Expression::DateFormatColumnConstraint(e) => {
3581 self.generate_date_format_column_constraint(e)
3582 }
3583 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3584 Expression::Datetime(e) => self.generate_datetime(e),
3585 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3586 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3587 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3588 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3589 Expression::Dayname(e) => self.generate_dayname(e),
3590 Expression::Declare(e) => self.generate_declare(e),
3591 Expression::DeclareItem(e) => self.generate_declare_item(e),
3592 Expression::DecodeCase(e) => self.generate_decode_case(e),
3593 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3594 Expression::DecompressString(e) => self.generate_decompress_string(e),
3595 Expression::Decrypt(e) => self.generate_decrypt(e),
3596 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3597 Expression::DefaultColumnConstraint(e) => {
3598 self.write_keyword("DEFAULT");
3599 self.write_space();
3600 self.generate_expression(&e.this)?;
3601 if let Some(ref col) = e.for_column {
3602 self.write_space();
3603 self.write_keyword("FOR");
3604 self.write_space();
3605 self.generate_identifier(col)?;
3606 }
3607 Ok(())
3608 }
3609 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3610 Expression::Detach(e) => self.generate_detach(e),
3611 Expression::DictProperty(e) => self.generate_dict_property(e),
3612 Expression::DictRange(e) => self.generate_dict_range(e),
3613 Expression::Directory(e) => self.generate_directory(e),
3614 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3615 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3616 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3617 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3618 Expression::DotProduct(e) => self.generate_dot_product(e),
3619 Expression::DropPartition(e) => self.generate_drop_partition(e),
3620 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3621 Expression::Elt(e) => self.generate_elt(e),
3622 Expression::Encode(e) => self.generate_encode(e),
3623 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3624 Expression::Encrypt(e) => self.generate_encrypt(e),
3625 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3626 Expression::EngineProperty(e) => self.generate_engine_property(e),
3627 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3628 Expression::EphemeralColumnConstraint(e) => {
3629 self.generate_ephemeral_column_constraint(e)
3630 }
3631 Expression::EqualNull(e) => self.generate_equal_null(e),
3632 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3633 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3634 Expression::Export(e) => self.generate_export(e),
3635 Expression::ExternalProperty(e) => self.generate_external_property(e),
3636 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3637 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3638 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3639 Expression::Fetch(e) => self.generate_fetch(e),
3640 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3641 Expression::Filter(e) => self.generate_filter(e),
3642 Expression::Float64(e) => self.generate_float64(e),
3643 Expression::ForIn(e) => self.generate_for_in(e),
3644 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3645 Expression::Format(e) => self.generate_format(e),
3646 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3647 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3648 Expression::From(e) => self.generate_from(e),
3649 Expression::FromBase(e) => self.generate_from_base(e),
3650 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3651 Expression::GapFill(e) => self.generate_gap_fill(e),
3652 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3653 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3654 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3655 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3656 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3657 self.generate_generated_as_identity_column_constraint(e)
3658 }
3659 Expression::GeneratedAsRowColumnConstraint(e) => {
3660 self.generate_generated_as_row_column_constraint(e)
3661 }
3662 Expression::Get(e) => self.generate_get(e),
3663 Expression::GetExtract(e) => self.generate_get_extract(e),
3664 Expression::Getbit(e) => self.generate_getbit(e),
3665 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3666 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3667 Expression::Group(e) => self.generate_group(e),
3668 Expression::GroupBy(e) => self.generate_group_by(e),
3669 Expression::Grouping(e) => self.generate_grouping(e),
3670 Expression::GroupingId(e) => self.generate_grouping_id(e),
3671 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3672 Expression::HashAgg(e) => self.generate_hash_agg(e),
3673 Expression::Having(e) => self.generate_having(e),
3674 Expression::HavingMax(e) => self.generate_having_max(e),
3675 Expression::Heredoc(e) => self.generate_heredoc(e),
3676 Expression::HexEncode(e) => self.generate_hex_encode(e),
3677 Expression::Hll(e) => self.generate_hll(e),
3678 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3679 Expression::IncludeProperty(e) => self.generate_include_property(e),
3680 Expression::Index(e) => self.generate_index(e),
3681 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3682 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3683 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3684 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3685 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3686 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3687 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3688 Expression::Install(e) => self.generate_install(e),
3689 Expression::IntervalOp(e) => self.generate_interval_op(e),
3690 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3691 Expression::IntoClause(e) => self.generate_into_clause(e),
3692 Expression::Introducer(e) => self.generate_introducer(e),
3693 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3694 Expression::JSON(e) => self.generate_json(e),
3695 Expression::JSONArray(e) => self.generate_json_array(e),
3696 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3697 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3698 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3699 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3700 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3701 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3702 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3703 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3704 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3705 Expression::JSONExists(e) => self.generate_json_exists(e),
3706 Expression::JSONCast(e) => self.generate_json_cast(e),
3707 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3708 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3709 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3710 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3711 Expression::JSONFormat(e) => self.generate_json_format(e),
3712 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3713 Expression::JSONKeys(e) => self.generate_json_keys(e),
3714 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3715 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3716 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3717 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3718 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3719 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3720 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3721 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3722 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3723 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3724 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3725 Expression::JSONRemove(e) => self.generate_json_remove(e),
3726 Expression::JSONSchema(e) => self.generate_json_schema(e),
3727 Expression::JSONSet(e) => self.generate_json_set(e),
3728 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3729 Expression::JSONTable(e) => self.generate_json_table(e),
3730 Expression::JSONType(e) => self.generate_json_type(e),
3731 Expression::JSONValue(e) => self.generate_json_value(e),
3732 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3733 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3734 Expression::JoinHint(e) => self.generate_join_hint(e),
3735 Expression::JournalProperty(e) => self.generate_journal_property(e),
3736 Expression::LanguageProperty(e) => self.generate_language_property(e),
3737 Expression::Lateral(e) => self.generate_lateral(e),
3738 Expression::LikeProperty(e) => self.generate_like_property(e),
3739 Expression::Limit(e) => self.generate_limit(e),
3740 Expression::LimitOptions(e) => self.generate_limit_options(e),
3741 Expression::List(e) => self.generate_list(e),
3742 Expression::ToMap(e) => self.generate_tomap(e),
3743 Expression::Localtime(e) => self.generate_localtime(e),
3744 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3745 Expression::LocationProperty(e) => self.generate_location_property(e),
3746 Expression::Lock(e) => self.generate_lock(e),
3747 Expression::LockProperty(e) => self.generate_lock_property(e),
3748 Expression::LockingProperty(e) => self.generate_locking_property(e),
3749 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3750 Expression::LogProperty(e) => self.generate_log_property(e),
3751 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3752 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3753 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3754 Expression::MakeInterval(e) => self.generate_make_interval(e),
3755 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3756 Expression::Map(e) => self.generate_map(e),
3757 Expression::MapCat(e) => self.generate_map_cat(e),
3758 Expression::MapDelete(e) => self.generate_map_delete(e),
3759 Expression::MapInsert(e) => self.generate_map_insert(e),
3760 Expression::MapPick(e) => self.generate_map_pick(e),
3761 Expression::MaskingPolicyColumnConstraint(e) => {
3762 self.generate_masking_policy_column_constraint(e)
3763 }
3764 Expression::MatchAgainst(e) => self.generate_match_against(e),
3765 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3766 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3767 Expression::Merge(e) => self.generate_merge(e),
3768 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3769 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3770 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3771 Expression::Minhash(e) => self.generate_minhash(e),
3772 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3773 Expression::Monthname(e) => self.generate_monthname(e),
3774 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3775 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3776 Expression::Normal(e) => self.generate_normal(e),
3777 Expression::Normalize(e) => self.generate_normalize(e),
3778 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3779 Expression::Nullif(e) => self.generate_nullif(e),
3780 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3781 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3782 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3783 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3784 Expression::Offset(e) => self.generate_offset(e),
3785 Expression::Qualify(e) => self.generate_qualify(e),
3786 Expression::OnCluster(e) => self.generate_on_cluster(e),
3787 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3788 Expression::OnCondition(e) => self.generate_on_condition(e),
3789 Expression::OnConflict(e) => self.generate_on_conflict(e),
3790 Expression::OnProperty(e) => self.generate_on_property(e),
3791 Expression::Opclass(e) => self.generate_opclass(e),
3792 Expression::OpenJSON(e) => self.generate_open_json(e),
3793 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3794 Expression::Operator(e) => self.generate_operator(e),
3795 Expression::OrderBy(e) => self.generate_order_by(e),
3796 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3797 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3798 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3799 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3800 Expression::ParseIp(e) => self.generate_parse_ip(e),
3801 Expression::ParseJSON(e) => self.generate_parse_json(e),
3802 Expression::ParseTime(e) => self.generate_parse_time(e),
3803 Expression::ParseUrl(e) => self.generate_parse_url(e),
3804 Expression::Partition(e) => self.generate_partition_expr(e),
3805 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3806 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3807 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3808 Expression::PartitionByRangePropertyDynamic(e) => {
3809 self.generate_partition_by_range_property_dynamic(e)
3810 }
3811 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3812 Expression::PartitionList(e) => self.generate_partition_list(e),
3813 Expression::PartitionRange(e) => self.generate_partition_range(e),
3814 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3815 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3816 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3817 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3818 Expression::PeriodForSystemTimeConstraint(e) => {
3819 self.generate_period_for_system_time_constraint(e)
3820 }
3821 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3822 Expression::PivotAny(e) => self.generate_pivot_any(e),
3823 Expression::Predict(e) => self.generate_predict(e),
3824 Expression::PreviousDay(e) => self.generate_previous_day(e),
3825 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3826 Expression::PrimaryKeyColumnConstraint(e) => {
3827 self.generate_primary_key_column_constraint(e)
3828 }
3829 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3830 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3831 Expression::OptionsProperty(e) => self.generate_options_property(e),
3832 Expression::Properties(e) => self.generate_properties(e),
3833 Expression::Property(e) => self.generate_property(e),
3834 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3835 Expression::Put(e) => self.generate_put(e),
3836 Expression::Quantile(e) => self.generate_quantile(e),
3837 Expression::QueryBand(e) => self.generate_query_band(e),
3838 Expression::QueryOption(e) => self.generate_query_option(e),
3839 Expression::QueryTransform(e) => self.generate_query_transform(e),
3840 Expression::Randn(e) => self.generate_randn(e),
3841 Expression::Randstr(e) => self.generate_randstr(e),
3842 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3843 Expression::RangeN(e) => self.generate_range_n(e),
3844 Expression::ReadCSV(e) => self.generate_read_csv(e),
3845 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3846 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3847 Expression::Reduce(e) => self.generate_reduce(e),
3848 Expression::Reference(e) => self.generate_reference(e),
3849 Expression::Refresh(e) => self.generate_refresh(e),
3850 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3851 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3852 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3853 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3854 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3855 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3856 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3857 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3858 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3859 Expression::RegrCount(e) => self.generate_regr_count(e),
3860 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3861 Expression::RegrR2(e) => self.generate_regr_r2(e),
3862 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3863 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3864 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3865 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3866 Expression::RegrValx(e) => self.generate_regr_valx(e),
3867 Expression::RegrValy(e) => self.generate_regr_valy(e),
3868 Expression::RemoteWithConnectionModelProperty(e) => {
3869 self.generate_remote_with_connection_model_property(e)
3870 }
3871 Expression::RenameColumn(e) => self.generate_rename_column(e),
3872 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3873 Expression::Returning(e) => self.generate_returning(e),
3874 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3875 Expression::Rollback(e) => self.generate_rollback(e),
3876 Expression::Rollup(e) => self.generate_rollup(e),
3877 Expression::RowFormatDelimitedProperty(e) => {
3878 self.generate_row_format_delimited_property(e)
3879 }
3880 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3881 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3882 Expression::SHA2(e) => self.generate_sha2(e),
3883 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3884 Expression::SafeAdd(e) => self.generate_safe_add(e),
3885 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3886 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3887 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3888 Expression::SampleProperty(e) => self.generate_sample_property(e),
3889 Expression::Schema(e) => self.generate_schema(e),
3890 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3891 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3892 Expression::Search(e) => self.generate_search(e),
3893 Expression::SearchIp(e) => self.generate_search_ip(e),
3894 Expression::SecurityProperty(e) => self.generate_security_property(e),
3895 Expression::SemanticView(e) => self.generate_semantic_view(e),
3896 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3897 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3898 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3899 Expression::Set(e) => self.generate_set(e),
3900 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3901 Expression::SetItem(e) => self.generate_set_item(e),
3902 Expression::SetOperation(e) => self.generate_set_operation(e),
3903 Expression::SetProperty(e) => self.generate_set_property(e),
3904 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3905 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3906 Expression::Slice(e) => self.generate_slice(e),
3907 Expression::SortArray(e) => self.generate_sort_array(e),
3908 Expression::SortBy(e) => self.generate_sort_by(e),
3909 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3910 Expression::SplitPart(e) => self.generate_split_part(e),
3911 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3912 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3913 Expression::StDistance(e) => self.generate_st_distance(e),
3914 Expression::StPoint(e) => self.generate_st_point(e),
3915 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3916 Expression::StandardHash(e) => self.generate_standard_hash(e),
3917 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3918 Expression::StrPosition(e) => self.generate_str_position(e),
3919 Expression::StrToDate(e) => self.generate_str_to_date(e),
3920 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3921 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3922 Expression::StrToMap(e) => self.generate_str_to_map(e),
3923 Expression::StrToTime(e) => self.generate_str_to_time(e),
3924 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3925 Expression::StringToArray(e) => self.generate_string_to_array(e),
3926 Expression::Struct(e) => self.generate_struct(e),
3927 Expression::Stuff(e) => self.generate_stuff(e),
3928 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3929 Expression::Summarize(e) => self.generate_summarize(e),
3930 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3931 Expression::TableAlias(e) => self.generate_table_alias(e),
3932 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3933 Expression::RowsFrom(e) => self.generate_rows_from(e),
3934 Expression::TableSample(e) => self.generate_table_sample(e),
3935 Expression::Tag(e) => self.generate_tag(e),
3936 Expression::Tags(e) => self.generate_tags(e),
3937 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3938 Expression::Time(e) => self.generate_time_func(e),
3939 Expression::TimeAdd(e) => self.generate_time_add(e),
3940 Expression::TimeDiff(e) => self.generate_time_diff(e),
3941 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3942 Expression::TimeSlice(e) => self.generate_time_slice(e),
3943 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3944 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3945 Expression::TimeSub(e) => self.generate_time_sub(e),
3946 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3947 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3948 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3949 Expression::TimeUnit(e) => self.generate_time_unit(e),
3950 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3951 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3952 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3953 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3954 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3955 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3956 Expression::ToBinary(e) => self.generate_to_binary(e),
3957 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3958 Expression::ToChar(e) => self.generate_to_char(e),
3959 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3960 Expression::ToDouble(e) => self.generate_to_double(e),
3961 Expression::ToFile(e) => self.generate_to_file(e),
3962 Expression::ToNumber(e) => self.generate_to_number(e),
3963 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3964 Expression::Transaction(e) => self.generate_transaction(e),
3965 Expression::Transform(e) => self.generate_transform(e),
3966 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3967 Expression::TransientProperty(e) => self.generate_transient_property(e),
3968 Expression::Translate(e) => self.generate_translate(e),
3969 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3970 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3971 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3972 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3973 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3974 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3975 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3976 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3977 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3978 Expression::Unhex(e) => self.generate_unhex(e),
3979 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3980 Expression::Uniform(e) => self.generate_uniform(e),
3981 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3982 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3983 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3984 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3985 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3986 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3987 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3988 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3989 Expression::UtcTime(e) => self.generate_utc_time(e),
3990 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3991 Expression::Uuid(e) => self.generate_uuid(e),
3992 Expression::Var(v) => {
3993 if matches!(self.config.dialect, Some(DialectType::MySQL))
3994 && v.this.len() > 2
3995 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3996 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3997 {
3998 return self.generate_identifier(&Identifier {
3999 name: v.this.clone(),
4000 quoted: true,
4001 trailing_comments: Vec::new(),
4002 span: None,
4003 });
4004 }
4005 self.write(&v.this);
4006 Ok(())
4007 }
4008 Expression::Variadic(e) => {
4009 self.write_keyword("VARIADIC");
4010 self.write_space();
4011 self.generate_expression(&e.this)?;
4012 Ok(())
4013 }
4014 Expression::VarMap(e) => self.generate_var_map(e),
4015 Expression::VectorSearch(e) => self.generate_vector_search(e),
4016 Expression::Version(e) => self.generate_version(e),
4017 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
4018 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
4019 Expression::WatermarkColumnConstraint(e) => {
4020 self.generate_watermark_column_constraint(e)
4021 }
4022 Expression::Week(e) => self.generate_week(e),
4023 Expression::When(e) => self.generate_when(e),
4024 Expression::Whens(e) => self.generate_whens(e),
4025 Expression::Where(e) => self.generate_where(e),
4026 Expression::WidthBucket(e) => self.generate_width_bucket(e),
4027 Expression::Window(e) => self.generate_window(e),
4028 Expression::WindowSpec(e) => self.generate_window_spec(e),
4029 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
4030 Expression::WithFill(e) => self.generate_with_fill(e),
4031 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
4032 Expression::WithOperator(e) => self.generate_with_operator(e),
4033 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
4034 Expression::WithSchemaBindingProperty(e) => {
4035 self.generate_with_schema_binding_property(e)
4036 }
4037 Expression::WithSystemVersioningProperty(e) => {
4038 self.generate_with_system_versioning_property(e)
4039 }
4040 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
4041 Expression::XMLElement(e) => self.generate_xml_element(e),
4042 Expression::XMLGet(e) => self.generate_xml_get(e),
4043 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
4044 Expression::XMLTable(e) => self.generate_xml_table(e),
4045 Expression::Xor(e) => self.generate_xor(e),
4046 Expression::Zipf(e) => self.generate_zipf(e),
4047 _ => self.write_unsupported_comment("unsupported expression"),
4048 }
4049 }
4050
4051 fn generate_select(&mut self, select: &Select) -> Result<()> {
4052 use crate::dialects::DialectType;
4053
4054 if let Some(exclude) = &select.exclude {
4058 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4059 let mut inner_select = select.clone();
4061 inner_select.exclude = None;
4062 let inner_expr = Expression::Select(Box::new(inner_select));
4063
4064 let subquery = crate::expressions::Subquery {
4066 this: inner_expr,
4067 alias: None,
4068 column_aliases: Vec::new(),
4069 alias_explicit_as: false,
4070 alias_keyword: None,
4071 order_by: None,
4072 limit: None,
4073 offset: None,
4074 distribute_by: None,
4075 sort_by: None,
4076 cluster_by: None,
4077 lateral: false,
4078 modifiers_inside: false,
4079 trailing_comments: Vec::new(),
4080 inferred_type: None,
4081 };
4082
4083 let star = Expression::Star(crate::expressions::Star {
4085 table: None,
4086 except: Some(
4087 exclude
4088 .iter()
4089 .map(|e| match e {
4090 Expression::Column(col) => col.name.clone(),
4091 Expression::Identifier(id) => id.clone(),
4092 _ => crate::expressions::Identifier::new("unknown".to_string()),
4093 })
4094 .collect(),
4095 ),
4096 replace: None,
4097 rename: None,
4098 trailing_comments: Vec::new(),
4099 span: None,
4100 });
4101
4102 let outer_select = Select {
4103 expressions: vec![star],
4104 from: Some(crate::expressions::From {
4105 expressions: vec![Expression::Subquery(Box::new(subquery))],
4106 }),
4107 ..Select::new()
4108 };
4109
4110 return self.generate_select(&outer_select);
4111 }
4112 }
4113
4114 for comment in &select.leading_comments {
4116 self.write_formatted_comment(comment);
4117 self.write(" ");
4118 }
4119
4120 if let Some(with) = &select.with {
4122 self.generate_with(with)?;
4123 if self.config.pretty {
4124 self.write_newline();
4125 self.write_indent();
4126 } else {
4127 self.write_space();
4128 }
4129 }
4130
4131 for comment in &select.post_select_comments {
4134 self.write_formatted_comment(comment);
4135 self.write(" ");
4136 }
4137
4138 self.write_keyword("SELECT");
4139
4140 if let Some(hint) = &select.hint {
4142 self.generate_hint(hint)?;
4143 }
4144
4145 let use_top_from_limit = matches!(
4149 self.config.dialect,
4150 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4151 ) && select.top.is_none()
4152 && select.limit.is_some()
4153 && select.offset.is_none(); let is_top_dialect = matches!(
4158 self.config.dialect,
4159 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4160 );
4161 let keep_top_verbatim = !is_top_dialect
4162 && select.limit.is_none()
4163 && select
4164 .top
4165 .as_ref()
4166 .map_or(false, |top| top.percent || top.with_ties);
4167
4168 if select.distinct && (is_top_dialect || select.top.is_some()) {
4169 self.write_space();
4170 self.write_keyword("DISTINCT");
4171 }
4172
4173 if is_top_dialect || keep_top_verbatim {
4174 if let Some(top) = &select.top {
4175 self.write_space();
4176 self.write_keyword("TOP");
4177 if top.parenthesized {
4178 if matches!(&top.this, Expression::Subquery(_) | Expression::Paren(_)) {
4179 self.write_space();
4180 self.generate_expression(&top.this)?;
4181 } else {
4182 self.write(" (");
4183 self.generate_expression(&top.this)?;
4184 self.write(")");
4185 }
4186 } else {
4187 self.write_space();
4188 self.generate_expression(&top.this)?;
4189 }
4190 if top.percent {
4191 self.write_space();
4192 self.write_keyword("PERCENT");
4193 }
4194 if top.with_ties {
4195 self.write_space();
4196 self.write_keyword("WITH TIES");
4197 }
4198 } else if use_top_from_limit {
4199 if let Some(limit) = &select.limit {
4201 self.write_space();
4202 self.write_keyword("TOP");
4203 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4205 if is_simple_literal {
4206 self.write_space();
4207 self.generate_expression(&limit.this)?;
4208 } else {
4209 self.write(" (");
4210 self.generate_expression(&limit.this)?;
4211 self.write(")");
4212 }
4213 }
4214 }
4215 }
4216
4217 if select.distinct && !is_top_dialect && select.top.is_none() {
4218 self.write_space();
4219 self.write_keyword("DISTINCT");
4220 }
4221
4222 if let Some(distinct_on) = &select.distinct_on {
4224 self.write_space();
4225 self.write_keyword("ON");
4226 self.write(" (");
4227 for (i, expr) in distinct_on.iter().enumerate() {
4228 if i > 0 {
4229 self.write(", ");
4230 }
4231 self.generate_expression(expr)?;
4232 }
4233 self.write(")");
4234 }
4235
4236 for modifier in &select.operation_modifiers {
4238 self.write_space();
4239 self.write_keyword(modifier);
4240 }
4241
4242 if let Some(kind) = &select.kind {
4244 self.write_space();
4245 self.write_keyword("AS");
4246 self.write_space();
4247 self.write_keyword(kind);
4248 }
4249
4250 if !select.expressions.is_empty() {
4252 if self.config.pretty {
4253 self.write_newline();
4254 self.indent_level += 1;
4255 } else {
4256 self.write_space();
4257 }
4258 }
4259
4260 for (i, expr) in select.expressions.iter().enumerate() {
4261 if i > 0 {
4262 self.write(",");
4263 if self.config.pretty {
4264 self.write_newline();
4265 } else {
4266 self.write_space();
4267 }
4268 }
4269 if self.config.pretty {
4270 self.write_indent();
4271 }
4272 self.generate_expression(expr)?;
4273 }
4274
4275 if self.config.pretty && !select.expressions.is_empty() {
4276 self.indent_level -= 1;
4277 }
4278
4279 if let Some(exclude) = &select.exclude {
4284 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4285 self.write_space();
4286 self.write_keyword("EXCLUDE");
4287 self.write(" (");
4288 for (i, col) in exclude.iter().enumerate() {
4289 if i > 0 {
4290 self.write(", ");
4291 }
4292 self.generate_expression(col)?;
4293 }
4294 self.write(")");
4295 }
4296 }
4297
4298 if let Some(into) = &select.into {
4301 if self.config.pretty {
4302 self.write_newline();
4303 self.write_indent();
4304 } else {
4305 self.write_space();
4306 }
4307 if into.bulk_collect {
4308 self.write_keyword("BULK COLLECT INTO");
4309 } else {
4310 self.write_keyword("INTO");
4311 }
4312 if into.temporary {
4313 self.write_space();
4314 self.write_keyword("TEMPORARY");
4315 }
4316 if into.unlogged {
4317 self.write_space();
4318 self.write_keyword("UNLOGGED");
4319 }
4320 self.write_space();
4321 if !into.expressions.is_empty() {
4323 for (i, expr) in into.expressions.iter().enumerate() {
4324 if i > 0 {
4325 self.write(", ");
4326 }
4327 self.generate_expression(expr)?;
4328 }
4329 } else {
4330 self.generate_expression(&into.this)?;
4331 }
4332 }
4333
4334 if let Some(from) = &select.from {
4336 if self.config.pretty {
4337 self.write_newline();
4338 self.write_indent();
4339 } else {
4340 self.write_space();
4341 }
4342 self.write_keyword("FROM");
4343 self.write_space();
4344
4345 let has_tablesample = from
4350 .expressions
4351 .iter()
4352 .any(|e| matches!(e, Expression::TableSample(_)));
4353 let is_cross_join_dialect = matches!(
4354 self.config.dialect,
4355 Some(DialectType::BigQuery)
4356 | Some(DialectType::Hive)
4357 | Some(DialectType::Spark)
4358 | Some(DialectType::Databricks)
4359 | Some(DialectType::SQLite)
4360 | Some(DialectType::ClickHouse)
4361 );
4362 let source_is_same_as_target = self.config.source_dialect.is_some()
4365 && self.config.source_dialect == self.config.dialect;
4366 let source_is_cross_join_dialect = matches!(
4367 self.config.source_dialect,
4368 Some(DialectType::BigQuery)
4369 | Some(DialectType::Hive)
4370 | Some(DialectType::Spark)
4371 | Some(DialectType::Databricks)
4372 | Some(DialectType::SQLite)
4373 | Some(DialectType::ClickHouse)
4374 );
4375 let use_cross_join = !has_tablesample
4376 && is_cross_join_dialect
4377 && (source_is_same_as_target
4378 || source_is_cross_join_dialect
4379 || self.config.source_dialect.is_none());
4380
4381 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4383
4384 for (i, expr) in from.expressions.iter().enumerate() {
4385 if i > 0 {
4386 if use_cross_join {
4387 self.write(" CROSS JOIN ");
4388 } else {
4389 self.write(", ");
4390 }
4391 }
4392 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4393 self.write("(");
4394 self.generate_expression(expr)?;
4395 self.write(")");
4396 } else {
4397 self.generate_expression(expr)?;
4398 }
4399 let leading = Self::extract_table_leading_comments(expr);
4402 for comment in &leading {
4403 self.write_space();
4404 self.write_formatted_comment(comment);
4405 }
4406 }
4407 }
4408
4409 if self.config.pretty {
4413 self.generate_joins_with_nesting(&select.joins)?;
4414 } else {
4415 for join in &select.joins {
4416 self.generate_join(join)?;
4417 }
4418 for join in select.joins.iter().rev() {
4420 if join.deferred_condition {
4421 self.generate_join_condition(join)?;
4422 }
4423 }
4424 }
4425
4426 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4428 self.generate_lateral_view(lateral_view, lv_idx)?;
4429 }
4430
4431 if let Some(prewhere) = &select.prewhere {
4433 self.write_clause_condition("PREWHERE", prewhere)?;
4434 }
4435
4436 if let Some(where_clause) = &select.where_clause {
4438 self.write_clause_condition("WHERE", &where_clause.this)?;
4439 }
4440
4441 if let Some(connect) = &select.connect {
4443 self.generate_connect(connect)?;
4444 }
4445
4446 if let Some(group_by) = &select.group_by {
4448 if self.config.pretty {
4449 for comment in &group_by.comments {
4451 self.write_newline();
4452 self.write_indent();
4453 self.write_formatted_comment(comment);
4454 }
4455 self.write_newline();
4456 self.write_indent();
4457 } else {
4458 self.write_space();
4459 for comment in &group_by.comments {
4461 self.write_formatted_comment(comment);
4462 self.write_space();
4463 }
4464 }
4465 let clickhouse_bare_modifiers =
4466 matches!(self.config.dialect, Some(DialectType::ClickHouse))
4467 && group_by.all.is_none()
4468 && (group_by.totals || !group_by.expressions.is_empty())
4469 && group_by.expressions.iter().all(|expr| match expr {
4470 Expression::Cube(c) => c.expressions.is_empty(),
4471 Expression::Rollup(r) => r.expressions.is_empty(),
4472 _ => false,
4473 });
4474
4475 if clickhouse_bare_modifiers {
4476 let trailing_cube = group_by
4477 .expressions
4478 .iter()
4479 .any(|expr| matches!(expr, Expression::Cube(c) if c.expressions.is_empty()));
4480 let trailing_rollup = group_by
4481 .expressions
4482 .iter()
4483 .any(|expr| matches!(expr, Expression::Rollup(r) if r.expressions.is_empty()));
4484
4485 if trailing_cube {
4486 self.write_keyword("WITH CUBE");
4487 } else if trailing_rollup {
4488 self.write_keyword("WITH ROLLUP");
4489 }
4490
4491 if group_by.totals {
4492 if trailing_cube || trailing_rollup {
4493 self.write_space();
4494 }
4495 self.write_keyword("WITH TOTALS");
4496 }
4497 } else {
4498 self.write_keyword("GROUP BY");
4499 match group_by.all {
4501 Some(true) => {
4502 self.write_space();
4503 self.write_keyword("ALL");
4504 }
4505 Some(false) => {
4506 self.write_space();
4507 self.write_keyword("DISTINCT");
4508 }
4509 None => {}
4510 }
4511 if !group_by.expressions.is_empty() {
4512 let mut trailing_cube = false;
4515 let mut trailing_rollup = false;
4516 let mut plain_expressions: Vec<&Expression> = Vec::new();
4517 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4518 let mut cube_expressions: Vec<&Expression> = Vec::new();
4519 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4520
4521 for expr in &group_by.expressions {
4522 match expr {
4523 Expression::Cube(c) if c.expressions.is_empty() => {
4524 trailing_cube = true;
4525 }
4526 Expression::Rollup(r) if r.expressions.is_empty() => {
4527 trailing_rollup = true;
4528 }
4529 Expression::Function(f) if f.name == "CUBE" => {
4530 cube_expressions.push(expr);
4531 }
4532 Expression::Function(f) if f.name == "ROLLUP" => {
4533 rollup_expressions.push(expr);
4534 }
4535 Expression::Function(f) if f.name == "GROUPING SETS" => {
4536 grouping_sets_expressions.push(expr);
4537 }
4538 _ => {
4539 plain_expressions.push(expr);
4540 }
4541 }
4542 }
4543
4544 let mut regular_expressions: Vec<&Expression> = Vec::new();
4546 regular_expressions.extend(plain_expressions);
4547 regular_expressions.extend(grouping_sets_expressions);
4548 regular_expressions.extend(cube_expressions);
4549 regular_expressions.extend(rollup_expressions);
4550
4551 if self.config.pretty {
4552 self.write_newline();
4553 self.indent_level += 1;
4554 self.write_indent();
4555 } else {
4556 self.write_space();
4557 }
4558
4559 for (i, expr) in regular_expressions.iter().enumerate() {
4560 if i > 0 {
4561 if self.config.pretty {
4562 self.write(",");
4563 self.write_newline();
4564 self.write_indent();
4565 } else {
4566 self.write(", ");
4567 }
4568 }
4569 self.generate_expression(expr)?;
4570 }
4571
4572 if self.config.pretty {
4573 self.indent_level -= 1;
4574 }
4575
4576 if trailing_cube {
4578 self.write_space();
4579 self.write_keyword("WITH CUBE");
4580 } else if trailing_rollup {
4581 self.write_space();
4582 self.write_keyword("WITH ROLLUP");
4583 }
4584 }
4585
4586 if group_by.totals {
4588 self.write_space();
4589 self.write_keyword("WITH TOTALS");
4590 }
4591 }
4592 }
4593
4594 if let Some(having) = &select.having {
4596 if self.config.pretty {
4597 for comment in &having.comments {
4599 self.write_newline();
4600 self.write_indent();
4601 self.write_formatted_comment(comment);
4602 }
4603 } else {
4604 for comment in &having.comments {
4605 self.write_space();
4606 self.write_formatted_comment(comment);
4607 }
4608 }
4609 self.write_clause_condition("HAVING", &having.this)?;
4610 }
4611
4612 if select.qualify_after_window {
4614 if let Some(windows) = &select.windows {
4616 self.write_window_clause(windows)?;
4617 }
4618 if let Some(qualify) = &select.qualify {
4619 self.write_clause_condition("QUALIFY", &qualify.this)?;
4620 }
4621 } else {
4622 if let Some(qualify) = &select.qualify {
4624 self.write_clause_condition("QUALIFY", &qualify.this)?;
4625 }
4626 if let Some(windows) = &select.windows {
4627 self.write_window_clause(windows)?;
4628 }
4629 }
4630
4631 if let Some(distribute_by) = &select.distribute_by {
4633 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4634 }
4635
4636 if let Some(cluster_by) = &select.cluster_by {
4638 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4639 }
4640
4641 if let Some(sort_by) = &select.sort_by {
4643 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4644 }
4645
4646 if let Some(order_by) = &select.order_by {
4648 if self.config.pretty {
4649 for comment in &order_by.comments {
4651 self.write_newline();
4652 self.write_indent();
4653 self.write_formatted_comment(comment);
4654 }
4655 } else {
4656 for comment in &order_by.comments {
4657 self.write_space();
4658 self.write_formatted_comment(comment);
4659 }
4660 }
4661 let keyword = if order_by.siblings {
4662 "ORDER SIBLINGS BY"
4663 } else {
4664 "ORDER BY"
4665 };
4666 self.write_order_clause(keyword, &order_by.expressions)?;
4667 }
4668
4669 if select.order_by.is_none()
4671 && select.fetch.is_some()
4672 && matches!(
4673 self.config.dialect,
4674 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4675 )
4676 {
4677 if self.config.pretty {
4678 self.write_newline();
4679 self.write_indent();
4680 } else {
4681 self.write_space();
4682 }
4683 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4684 }
4685
4686 let is_presto_like = matches!(
4691 self.config.dialect,
4692 Some(DialectType::Presto) | Some(DialectType::Trino)
4693 );
4694
4695 if is_presto_like && select.offset.is_some() {
4696 if let Some(offset) = &select.offset {
4698 if self.config.pretty {
4699 self.write_newline();
4700 self.write_indent();
4701 } else {
4702 self.write_space();
4703 }
4704 self.write_keyword("OFFSET");
4705 self.write_space();
4706 self.write_limit_expr(&offset.this)?;
4707 if offset.rows == Some(true) {
4708 self.write_space();
4709 self.write_keyword("ROWS");
4710 }
4711 }
4712 if let Some(limit) = &select.limit {
4713 if self.config.pretty {
4714 self.write_newline();
4715 self.write_indent();
4716 } else {
4717 self.write_space();
4718 }
4719 self.write_keyword("LIMIT");
4720 self.write_space();
4721 self.write_limit_expr(&limit.this)?;
4722 if limit.percent {
4723 self.write_space();
4724 self.write_keyword("PERCENT");
4725 }
4726 for comment in &limit.comments {
4728 self.write(" ");
4729 self.write_formatted_comment(comment);
4730 }
4731 }
4732 } else {
4733 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4735 !fetch.percent
4736 && !fetch.with_ties
4737 && fetch.count.is_some()
4738 && matches!(
4739 self.config.dialect,
4740 Some(DialectType::Spark)
4741 | Some(DialectType::Hive)
4742 | Some(DialectType::DuckDB)
4743 | Some(DialectType::SQLite)
4744 | Some(DialectType::MySQL)
4745 | Some(DialectType::BigQuery)
4746 | Some(DialectType::Databricks)
4747 | Some(DialectType::StarRocks)
4748 | Some(DialectType::Doris)
4749 | Some(DialectType::Athena)
4750 | Some(DialectType::ClickHouse)
4751 | Some(DialectType::Redshift)
4752 )
4753 });
4754
4755 if let Some(limit) = &select.limit {
4757 if !matches!(
4759 self.config.dialect,
4760 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4761 ) {
4762 if self.config.pretty {
4763 self.write_newline();
4764 self.write_indent();
4765 } else {
4766 self.write_space();
4767 }
4768 self.write_keyword("LIMIT");
4769 self.write_space();
4770 self.write_limit_expr(&limit.this)?;
4771 if limit.percent {
4772 self.write_space();
4773 self.write_keyword("PERCENT");
4774 }
4775 for comment in &limit.comments {
4777 self.write(" ");
4778 self.write_formatted_comment(comment);
4779 }
4780 }
4781 }
4782
4783 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4785 if let Some(top) = &select.top {
4786 if !top.percent && !top.with_ties {
4787 if self.config.pretty {
4788 self.write_newline();
4789 self.write_indent();
4790 } else {
4791 self.write_space();
4792 }
4793 self.write_keyword("LIMIT");
4794 self.write_space();
4795 self.generate_expression(&top.this)?;
4796 }
4797 }
4798 }
4799
4800 if fetch_as_limit && select.offset.is_some() {
4803 if let Some(fetch) = &select.fetch {
4804 if self.config.pretty {
4805 self.write_newline();
4806 self.write_indent();
4807 } else {
4808 self.write_space();
4809 }
4810 self.write_keyword("LIMIT");
4811 self.write_space();
4812 self.generate_expression(fetch.count.as_ref().unwrap())?;
4813 }
4814 }
4815
4816 if let Some(offset) = &select.offset {
4820 if self.config.pretty {
4821 self.write_newline();
4822 self.write_indent();
4823 } else {
4824 self.write_space();
4825 }
4826 if matches!(
4827 self.config.dialect,
4828 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4829 ) {
4830 self.write_keyword("OFFSET");
4832 self.write_space();
4833 self.write_limit_expr(&offset.this)?;
4834 self.write_space();
4835 self.write_keyword("ROWS");
4836 if let Some(limit) = &select.limit {
4838 self.write_space();
4839 self.write_keyword("FETCH NEXT");
4840 self.write_space();
4841 self.write_limit_expr(&limit.this)?;
4842 self.write_space();
4843 self.write_keyword("ROWS ONLY");
4844 }
4845 } else {
4846 self.write_keyword("OFFSET");
4847 self.write_space();
4848 self.write_limit_expr(&offset.this)?;
4849 if offset.rows == Some(true) {
4851 self.write_space();
4852 self.write_keyword("ROWS");
4853 }
4854 }
4855 }
4856 }
4857
4858 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4860 if let Some(limit_by) = &select.limit_by {
4861 if !limit_by.is_empty() {
4862 self.write_space();
4863 self.write_keyword("BY");
4864 self.write_space();
4865 for (i, expr) in limit_by.iter().enumerate() {
4866 if i > 0 {
4867 self.write(", ");
4868 }
4869 self.generate_expression(expr)?;
4870 }
4871 }
4872 }
4873 }
4874
4875 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4877 if let Some(settings) = &select.settings {
4878 if self.config.pretty {
4879 self.write_newline();
4880 self.write_indent();
4881 } else {
4882 self.write_space();
4883 }
4884 self.write_keyword("SETTINGS");
4885 self.write_space();
4886 for (i, expr) in settings.iter().enumerate() {
4887 if i > 0 {
4888 self.write(", ");
4889 }
4890 self.generate_expression(expr)?;
4891 }
4892 }
4893
4894 if let Some(format_expr) = &select.format {
4895 if self.config.pretty {
4896 self.write_newline();
4897 self.write_indent();
4898 } else {
4899 self.write_space();
4900 }
4901 self.write_keyword("FORMAT");
4902 self.write_space();
4903 self.generate_expression(format_expr)?;
4904 }
4905 }
4906
4907 if let Some(fetch) = &select.fetch {
4909 let fetch_already_as_limit = select.offset.is_some()
4911 && !fetch.percent
4912 && !fetch.with_ties
4913 && fetch.count.is_some()
4914 && matches!(
4915 self.config.dialect,
4916 Some(DialectType::Spark)
4917 | Some(DialectType::Hive)
4918 | Some(DialectType::DuckDB)
4919 | Some(DialectType::SQLite)
4920 | Some(DialectType::MySQL)
4921 | Some(DialectType::BigQuery)
4922 | Some(DialectType::Databricks)
4923 | Some(DialectType::StarRocks)
4924 | Some(DialectType::Doris)
4925 | Some(DialectType::Athena)
4926 | Some(DialectType::ClickHouse)
4927 | Some(DialectType::Redshift)
4928 );
4929
4930 if fetch_already_as_limit {
4931 } else {
4933 if self.config.pretty {
4934 self.write_newline();
4935 self.write_indent();
4936 } else {
4937 self.write_space();
4938 }
4939
4940 let use_limit = !fetch.percent
4942 && !fetch.with_ties
4943 && fetch.count.is_some()
4944 && matches!(
4945 self.config.dialect,
4946 Some(DialectType::Spark)
4947 | Some(DialectType::Hive)
4948 | Some(DialectType::DuckDB)
4949 | Some(DialectType::SQLite)
4950 | Some(DialectType::MySQL)
4951 | Some(DialectType::BigQuery)
4952 | Some(DialectType::Databricks)
4953 | Some(DialectType::StarRocks)
4954 | Some(DialectType::Doris)
4955 | Some(DialectType::Athena)
4956 | Some(DialectType::ClickHouse)
4957 | Some(DialectType::Redshift)
4958 );
4959
4960 if use_limit {
4961 self.write_keyword("LIMIT");
4962 self.write_space();
4963 self.generate_expression(fetch.count.as_ref().unwrap())?;
4964 } else {
4965 self.write_keyword("FETCH");
4966 self.write_space();
4967 self.write_keyword(&fetch.direction);
4968 if let Some(ref count) = fetch.count {
4969 self.write_space();
4970 self.generate_expression(count)?;
4971 }
4972 if fetch.percent {
4973 self.write_space();
4974 self.write_keyword("PERCENT");
4975 }
4976 if fetch.rows {
4977 self.write_space();
4978 self.write_keyword("ROWS");
4979 }
4980 if fetch.with_ties {
4981 self.write_space();
4982 self.write_keyword("WITH TIES");
4983 } else {
4984 self.write_space();
4985 self.write_keyword("ONLY");
4986 }
4987 }
4988 } }
4990
4991 if let Some(sample) = &select.sample {
4993 use crate::dialects::DialectType;
4994 if self.config.pretty {
4995 self.write_newline();
4996 } else {
4997 self.write_space();
4998 }
4999
5000 if sample.is_using_sample {
5001 self.write_keyword("USING SAMPLE");
5003 self.generate_sample_body(sample)?;
5004 } else {
5005 self.write_keyword("TABLESAMPLE");
5006
5007 let snowflake_bernoulli =
5009 matches!(self.config.dialect, Some(DialectType::Snowflake))
5010 && !sample.explicit_method;
5011 if snowflake_bernoulli {
5012 self.write_space();
5013 self.write_keyword("BERNOULLI");
5014 }
5015
5016 if matches!(sample.method, SampleMethod::Bucket) {
5018 self.write_space();
5019 self.write("(");
5020 self.write_keyword("BUCKET");
5021 self.write_space();
5022 if let Some(ref num) = sample.bucket_numerator {
5023 self.generate_expression(num)?;
5024 }
5025 self.write_space();
5026 self.write_keyword("OUT OF");
5027 self.write_space();
5028 if let Some(ref denom) = sample.bucket_denominator {
5029 self.generate_expression(denom)?;
5030 }
5031 if let Some(ref field) = sample.bucket_field {
5032 self.write_space();
5033 self.write_keyword("ON");
5034 self.write_space();
5035 self.generate_expression(field)?;
5036 }
5037 self.write(")");
5038 } else if sample.unit_after_size {
5039 if sample.explicit_method && sample.method_before_size {
5041 self.write_space();
5042 match sample.method {
5043 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5044 SampleMethod::System => self.write_keyword("SYSTEM"),
5045 SampleMethod::Block => self.write_keyword("BLOCK"),
5046 SampleMethod::Row => self.write_keyword("ROW"),
5047 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5048 _ => {}
5049 }
5050 }
5051 self.write(" (");
5052 self.generate_expression(&sample.size)?;
5053 self.write_space();
5054 match sample.method {
5055 SampleMethod::Percent => self.write_keyword("PERCENT"),
5056 SampleMethod::Row => self.write_keyword("ROWS"),
5057 SampleMethod::Reservoir => self.write_keyword("ROWS"),
5058 _ => {
5059 self.write_keyword("PERCENT");
5060 }
5061 }
5062 self.write(")");
5063 } else {
5064 self.write_space();
5066 match sample.method {
5067 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5068 SampleMethod::System => self.write_keyword("SYSTEM"),
5069 SampleMethod::Block => self.write_keyword("BLOCK"),
5070 SampleMethod::Row => self.write_keyword("ROW"),
5071 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
5072 SampleMethod::Bucket => {}
5073 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5074 }
5075 self.write(" (");
5076 self.generate_expression(&sample.size)?;
5077 if matches!(sample.method, SampleMethod::Percent) {
5078 self.write_space();
5079 self.write_keyword("PERCENT");
5080 }
5081 self.write(")");
5082 }
5083 }
5084
5085 if let Some(seed) = &sample.seed {
5086 self.write_space();
5087 let use_seed = sample.use_seed_keyword
5089 && !matches!(
5090 self.config.dialect,
5091 Some(crate::dialects::DialectType::Databricks)
5092 | Some(crate::dialects::DialectType::Spark)
5093 );
5094 if use_seed {
5095 self.write_keyword("SEED");
5096 } else {
5097 self.write_keyword("REPEATABLE");
5098 }
5099 self.write(" (");
5100 self.generate_expression(seed)?;
5101 self.write(")");
5102 }
5103 }
5104
5105 if self.config.locking_reads_supported {
5108 for lock in &select.locks {
5109 if self.config.pretty {
5110 self.write_newline();
5111 self.write_indent();
5112 } else {
5113 self.write_space();
5114 }
5115 self.generate_lock(lock)?;
5116 }
5117 }
5118
5119 if !select.for_xml.is_empty() {
5121 if self.config.pretty {
5122 self.write_newline();
5123 self.write_indent();
5124 } else {
5125 self.write_space();
5126 }
5127 self.write_keyword("FOR XML");
5128 for (i, opt) in select.for_xml.iter().enumerate() {
5129 if self.config.pretty {
5130 if i > 0 {
5131 self.write(",");
5132 }
5133 self.write_newline();
5134 self.write_indent();
5135 self.write(" "); } else {
5137 if i > 0 {
5138 self.write(",");
5139 }
5140 self.write_space();
5141 }
5142 self.generate_for_xml_option(opt)?;
5143 }
5144 }
5145
5146 if !select.for_json.is_empty()
5148 && matches!(
5149 self.config.dialect,
5150 None | Some(DialectType::TSQL) | Some(DialectType::Fabric)
5151 )
5152 {
5153 if self.config.pretty {
5154 self.write_newline();
5155 self.write_indent();
5156 } else {
5157 self.write_space();
5158 }
5159 self.write_keyword("FOR JSON");
5160 for (i, opt) in select.for_json.iter().enumerate() {
5161 if self.config.pretty {
5162 if i > 0 {
5163 self.write(",");
5164 }
5165 self.write_newline();
5166 self.write_indent();
5167 self.write(" "); } else {
5169 if i > 0 {
5170 self.write(",");
5171 }
5172 self.write_space();
5173 }
5174 self.generate_for_xml_option(opt)?;
5175 }
5176 }
5177
5178 if let Some(ref option) = select.option {
5180 if matches!(
5181 self.config.dialect,
5182 Some(crate::dialects::DialectType::TSQL)
5183 | Some(crate::dialects::DialectType::Fabric)
5184 ) {
5185 self.write_space();
5186 self.write(option);
5187 }
5188 }
5189
5190 Ok(())
5191 }
5192
5193 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5195 match opt {
5196 Expression::QueryOption(qo) => {
5197 if let Expression::Var(var) = &*qo.this {
5199 self.write(&var.this);
5200 } else {
5201 self.generate_expression(&qo.this)?;
5202 }
5203 if let Some(expr) = &qo.expression {
5205 self.write("(");
5206 self.generate_expression(expr)?;
5207 self.write(")");
5208 }
5209 }
5210 _ => {
5211 self.generate_expression(opt)?;
5212 }
5213 }
5214 Ok(())
5215 }
5216
5217 fn generate_with(&mut self, with: &With) -> Result<()> {
5218 use crate::dialects::DialectType;
5219
5220 for comment in &with.leading_comments {
5222 self.write_formatted_comment(comment);
5223 self.write(" ");
5224 }
5225 self.write_keyword("WITH");
5226 if with.recursive && self.config.cte_recursive_keyword_required {
5227 self.write_space();
5228 self.write_keyword("RECURSIVE");
5229 }
5230 self.write_space();
5231
5232 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5234
5235 for (i, cte) in with.ctes.iter().enumerate() {
5236 if i > 0 {
5237 self.write(",");
5238 if self.config.pretty {
5239 self.write_space();
5240 } else {
5241 self.write(" ");
5242 }
5243 }
5244 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5245 self.generate_expression(&cte.this)?;
5246 self.write_space();
5247 self.write_keyword("AS");
5248 self.write_space();
5249 self.generate_identifier(&cte.alias)?;
5250 continue;
5251 }
5252 self.generate_identifier(&cte.alias)?;
5253 for comment in &cte.comments {
5255 self.write_space();
5256 self.write_formatted_comment(comment);
5257 }
5258 if !cte.columns.is_empty() && !skip_cte_columns {
5259 self.write("(");
5260 for (j, col) in cte.columns.iter().enumerate() {
5261 if j > 0 {
5262 self.write(", ");
5263 }
5264 self.generate_identifier(col)?;
5265 }
5266 self.write(")");
5267 }
5268 if !cte.key_expressions.is_empty() {
5270 self.write_space();
5271 self.write_keyword("USING KEY");
5272 self.write(" (");
5273 for (i, key) in cte.key_expressions.iter().enumerate() {
5274 if i > 0 {
5275 self.write(", ");
5276 }
5277 self.generate_identifier(key)?;
5278 }
5279 self.write(")");
5280 }
5281 self.write_space();
5282 self.write_keyword("AS");
5283 if let Some(materialized) = cte.materialized {
5285 self.write_space();
5286 if materialized {
5287 self.write_keyword("MATERIALIZED");
5288 } else {
5289 self.write_keyword("NOT MATERIALIZED");
5290 }
5291 }
5292 self.write(" (");
5293 if self.config.pretty {
5294 self.write_newline();
5295 self.indent_level += 1;
5296 self.write_indent();
5297 }
5298 let wrap_values_in_select = matches!(
5301 self.config.dialect,
5302 Some(DialectType::Spark) | Some(DialectType::Databricks)
5303 ) && matches!(&cte.this, Expression::Values(_));
5304
5305 if wrap_values_in_select {
5306 self.write_keyword("SELECT");
5307 self.write(" * ");
5308 self.write_keyword("FROM");
5309 self.write_space();
5310 }
5311 self.generate_expression(&cte.this)?;
5312 if self.config.pretty {
5313 self.write_newline();
5314 self.indent_level -= 1;
5315 self.write_indent();
5316 }
5317 self.write(")");
5318 }
5319
5320 if let Some(search) = &with.search {
5322 self.write_space();
5323 self.generate_expression(search)?;
5324 }
5325
5326 Ok(())
5327 }
5328
5329 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5333 let mut i = 0;
5334 while i < joins.len() {
5335 if joins[i].deferred_condition {
5336 let parent_group = joins[i].nesting_group;
5337
5338 self.generate_join_without_condition(&joins[i])?;
5341
5342 let child_start = i + 1;
5344 let mut child_end = child_start;
5345 while child_end < joins.len()
5346 && !joins[child_end].deferred_condition
5347 && joins[child_end].nesting_group == parent_group
5348 {
5349 child_end += 1;
5350 }
5351
5352 if child_start < child_end {
5354 self.indent_level += 1;
5355 for j in child_start..child_end {
5356 self.generate_join(&joins[j])?;
5357 }
5358 self.indent_level -= 1;
5359 }
5360
5361 self.generate_join_condition(&joins[i])?;
5363
5364 i = child_end;
5365 } else {
5366 self.generate_join(&joins[i])?;
5368 i += 1;
5369 }
5370 }
5371 Ok(())
5372 }
5373
5374 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5377 let mut join_copy = join.clone();
5380 join_copy.on = None;
5381 join_copy.using = Vec::new();
5382 join_copy.deferred_condition = false;
5383 self.generate_join(&join_copy)
5384 }
5385
5386 fn generate_join(&mut self, join: &Join) -> Result<()> {
5387 if join.kind == JoinKind::Implicit {
5389 self.write(",");
5390 if self.config.pretty {
5391 self.write_newline();
5392 self.write_indent();
5393 } else {
5394 self.write_space();
5395 }
5396 self.generate_expression(&join.this)?;
5397 return Ok(());
5398 }
5399
5400 if self.config.pretty {
5401 self.write_newline();
5402 self.write_indent();
5403 } else {
5404 self.write_space();
5405 }
5406
5407 let hint_str = if self.config.join_hints {
5410 join.join_hint
5411 .as_ref()
5412 .map(|h| format!(" {}", h))
5413 .unwrap_or_default()
5414 } else {
5415 String::new()
5416 };
5417
5418 let clickhouse_join_keyword =
5419 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5420 if let Some(hint) = &join.join_hint {
5421 let mut global = false;
5422 let mut strictness: Option<&'static str> = None;
5423 for part in hint.split_whitespace() {
5424 if part.eq_ignore_ascii_case("GLOBAL") {
5425 global = true;
5426 } else if part.eq_ignore_ascii_case("ALL") {
5427 strictness = Some("ALL");
5428 } else if part.eq_ignore_ascii_case("ANY") {
5429 strictness = Some("ANY");
5430 } else if part.eq_ignore_ascii_case("ASOF") {
5431 strictness = Some("ASOF");
5432 } else if part.eq_ignore_ascii_case("SEMI") {
5433 strictness = Some("SEMI");
5434 } else if part.eq_ignore_ascii_case("ANTI") {
5435 strictness = Some("ANTI");
5436 }
5437 }
5438
5439 if global || strictness.is_some() {
5440 let join_type = match join.kind {
5441 JoinKind::Left => {
5442 if join.use_outer_keyword {
5443 "LEFT OUTER"
5444 } else if join.use_inner_keyword {
5445 "LEFT INNER"
5446 } else {
5447 "LEFT"
5448 }
5449 }
5450 JoinKind::Right => {
5451 if join.use_outer_keyword {
5452 "RIGHT OUTER"
5453 } else if join.use_inner_keyword {
5454 "RIGHT INNER"
5455 } else {
5456 "RIGHT"
5457 }
5458 }
5459 JoinKind::Full => {
5460 if join.use_outer_keyword {
5461 "FULL OUTER"
5462 } else {
5463 "FULL"
5464 }
5465 }
5466 JoinKind::Inner => {
5467 if join.use_inner_keyword {
5468 "INNER"
5469 } else {
5470 ""
5471 }
5472 }
5473 _ => "",
5474 };
5475
5476 let mut parts = Vec::new();
5477 if global {
5478 parts.push("GLOBAL");
5479 }
5480 if !join_type.is_empty() {
5481 parts.push(join_type);
5482 }
5483 if let Some(strict) = strictness {
5484 parts.push(strict);
5485 }
5486 parts.push("JOIN");
5487 Some(parts.join(" "))
5488 } else {
5489 None
5490 }
5491 } else {
5492 None
5493 }
5494 } else {
5495 None
5496 };
5497
5498 if !join.comments.is_empty() {
5502 if self.config.pretty {
5503 let trimmed = self.output.trim_end().len();
5508 self.output.truncate(trimmed);
5509 for comment in &join.comments {
5510 self.write_newline();
5511 self.write_indent();
5512 self.write_formatted_comment(comment);
5513 }
5514 self.write_newline();
5515 self.write_indent();
5516 } else {
5517 for comment in &join.comments {
5518 self.write_formatted_comment(comment);
5519 self.write_space();
5520 }
5521 }
5522 }
5523
5524 let directed_str = if join.directed { " DIRECTED" } else { "" };
5525
5526 if let Some(keyword) = clickhouse_join_keyword {
5527 self.write_keyword(&keyword);
5528 } else {
5529 match join.kind {
5530 JoinKind::Inner => {
5531 if join.use_inner_keyword {
5532 if hint_str.is_empty() && directed_str.is_empty() {
5533 self.write_keyword("INNER JOIN");
5534 } else {
5535 self.write_keyword("INNER");
5536 if !hint_str.is_empty() {
5537 self.write_keyword(&hint_str);
5538 }
5539 if !directed_str.is_empty() {
5540 self.write_keyword(directed_str);
5541 }
5542 self.write_keyword(" JOIN");
5543 }
5544 } else {
5545 if !hint_str.is_empty() {
5546 self.write_keyword(hint_str.trim());
5547 self.write_keyword(" ");
5548 }
5549 if !directed_str.is_empty() {
5550 self.write_keyword("DIRECTED ");
5551 }
5552 self.write_keyword("JOIN");
5553 }
5554 }
5555 JoinKind::Left => {
5556 if join.use_outer_keyword {
5557 if hint_str.is_empty() && directed_str.is_empty() {
5558 self.write_keyword("LEFT OUTER JOIN");
5559 } else {
5560 self.write_keyword("LEFT OUTER");
5561 if !hint_str.is_empty() {
5562 self.write_keyword(&hint_str);
5563 }
5564 if !directed_str.is_empty() {
5565 self.write_keyword(directed_str);
5566 }
5567 self.write_keyword(" JOIN");
5568 }
5569 } else if join.use_inner_keyword {
5570 if hint_str.is_empty() && directed_str.is_empty() {
5571 self.write_keyword("LEFT INNER JOIN");
5572 } else {
5573 self.write_keyword("LEFT INNER");
5574 if !hint_str.is_empty() {
5575 self.write_keyword(&hint_str);
5576 }
5577 if !directed_str.is_empty() {
5578 self.write_keyword(directed_str);
5579 }
5580 self.write_keyword(" JOIN");
5581 }
5582 } else {
5583 if hint_str.is_empty() && directed_str.is_empty() {
5584 self.write_keyword("LEFT JOIN");
5585 } else {
5586 self.write_keyword("LEFT");
5587 if !hint_str.is_empty() {
5588 self.write_keyword(&hint_str);
5589 }
5590 if !directed_str.is_empty() {
5591 self.write_keyword(directed_str);
5592 }
5593 self.write_keyword(" JOIN");
5594 }
5595 }
5596 }
5597 JoinKind::Right => {
5598 if join.use_outer_keyword {
5599 if hint_str.is_empty() && directed_str.is_empty() {
5600 self.write_keyword("RIGHT OUTER JOIN");
5601 } else {
5602 self.write_keyword("RIGHT OUTER");
5603 if !hint_str.is_empty() {
5604 self.write_keyword(&hint_str);
5605 }
5606 if !directed_str.is_empty() {
5607 self.write_keyword(directed_str);
5608 }
5609 self.write_keyword(" JOIN");
5610 }
5611 } else if join.use_inner_keyword {
5612 if hint_str.is_empty() && directed_str.is_empty() {
5613 self.write_keyword("RIGHT INNER JOIN");
5614 } else {
5615 self.write_keyword("RIGHT INNER");
5616 if !hint_str.is_empty() {
5617 self.write_keyword(&hint_str);
5618 }
5619 if !directed_str.is_empty() {
5620 self.write_keyword(directed_str);
5621 }
5622 self.write_keyword(" JOIN");
5623 }
5624 } else {
5625 if hint_str.is_empty() && directed_str.is_empty() {
5626 self.write_keyword("RIGHT JOIN");
5627 } else {
5628 self.write_keyword("RIGHT");
5629 if !hint_str.is_empty() {
5630 self.write_keyword(&hint_str);
5631 }
5632 if !directed_str.is_empty() {
5633 self.write_keyword(directed_str);
5634 }
5635 self.write_keyword(" JOIN");
5636 }
5637 }
5638 }
5639 JoinKind::Full => {
5640 if join.use_outer_keyword {
5641 if hint_str.is_empty() && directed_str.is_empty() {
5642 self.write_keyword("FULL OUTER JOIN");
5643 } else {
5644 self.write_keyword("FULL OUTER");
5645 if !hint_str.is_empty() {
5646 self.write_keyword(&hint_str);
5647 }
5648 if !directed_str.is_empty() {
5649 self.write_keyword(directed_str);
5650 }
5651 self.write_keyword(" JOIN");
5652 }
5653 } else {
5654 if hint_str.is_empty() && directed_str.is_empty() {
5655 self.write_keyword("FULL JOIN");
5656 } else {
5657 self.write_keyword("FULL");
5658 if !hint_str.is_empty() {
5659 self.write_keyword(&hint_str);
5660 }
5661 if !directed_str.is_empty() {
5662 self.write_keyword(directed_str);
5663 }
5664 self.write_keyword(" JOIN");
5665 }
5666 }
5667 }
5668 JoinKind::Outer => {
5669 if directed_str.is_empty() {
5670 self.write_keyword("OUTER JOIN");
5671 } else {
5672 self.write_keyword("OUTER");
5673 self.write_keyword(directed_str);
5674 self.write_keyword(" JOIN");
5675 }
5676 }
5677 JoinKind::Cross => {
5678 if directed_str.is_empty() {
5679 self.write_keyword("CROSS JOIN");
5680 } else {
5681 self.write_keyword("CROSS");
5682 self.write_keyword(directed_str);
5683 self.write_keyword(" JOIN");
5684 }
5685 }
5686 JoinKind::Natural => {
5687 if join.use_inner_keyword {
5688 if directed_str.is_empty() {
5689 self.write_keyword("NATURAL INNER JOIN");
5690 } else {
5691 self.write_keyword("NATURAL INNER");
5692 self.write_keyword(directed_str);
5693 self.write_keyword(" JOIN");
5694 }
5695 } else {
5696 if directed_str.is_empty() {
5697 self.write_keyword("NATURAL JOIN");
5698 } else {
5699 self.write_keyword("NATURAL");
5700 self.write_keyword(directed_str);
5701 self.write_keyword(" JOIN");
5702 }
5703 }
5704 }
5705 JoinKind::NaturalLeft => {
5706 if join.use_outer_keyword {
5707 if directed_str.is_empty() {
5708 self.write_keyword("NATURAL LEFT OUTER JOIN");
5709 } else {
5710 self.write_keyword("NATURAL LEFT OUTER");
5711 self.write_keyword(directed_str);
5712 self.write_keyword(" JOIN");
5713 }
5714 } else {
5715 if directed_str.is_empty() {
5716 self.write_keyword("NATURAL LEFT JOIN");
5717 } else {
5718 self.write_keyword("NATURAL LEFT");
5719 self.write_keyword(directed_str);
5720 self.write_keyword(" JOIN");
5721 }
5722 }
5723 }
5724 JoinKind::NaturalRight => {
5725 if join.use_outer_keyword {
5726 if directed_str.is_empty() {
5727 self.write_keyword("NATURAL RIGHT OUTER JOIN");
5728 } else {
5729 self.write_keyword("NATURAL RIGHT OUTER");
5730 self.write_keyword(directed_str);
5731 self.write_keyword(" JOIN");
5732 }
5733 } else {
5734 if directed_str.is_empty() {
5735 self.write_keyword("NATURAL RIGHT JOIN");
5736 } else {
5737 self.write_keyword("NATURAL RIGHT");
5738 self.write_keyword(directed_str);
5739 self.write_keyword(" JOIN");
5740 }
5741 }
5742 }
5743 JoinKind::NaturalFull => {
5744 if join.use_outer_keyword {
5745 if directed_str.is_empty() {
5746 self.write_keyword("NATURAL FULL OUTER JOIN");
5747 } else {
5748 self.write_keyword("NATURAL FULL OUTER");
5749 self.write_keyword(directed_str);
5750 self.write_keyword(" JOIN");
5751 }
5752 } else {
5753 if directed_str.is_empty() {
5754 self.write_keyword("NATURAL FULL JOIN");
5755 } else {
5756 self.write_keyword("NATURAL FULL");
5757 self.write_keyword(directed_str);
5758 self.write_keyword(" JOIN");
5759 }
5760 }
5761 }
5762 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5763 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5764 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5765 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5766 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5767 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5768 JoinKind::CrossApply => {
5769 if matches!(
5771 self.config.dialect,
5772 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
5773 ) {
5774 self.write_keyword("CROSS APPLY");
5775 } else {
5776 self.write_keyword("INNER JOIN LATERAL");
5777 }
5778 }
5779 JoinKind::OuterApply => {
5780 if matches!(
5782 self.config.dialect,
5783 Some(DialectType::TSQL) | Some(DialectType::Fabric) | None
5784 ) {
5785 self.write_keyword("OUTER APPLY");
5786 } else {
5787 self.write_keyword("LEFT JOIN LATERAL");
5788 }
5789 }
5790 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5791 JoinKind::AsOfLeft => {
5792 if join.use_outer_keyword {
5793 self.write_keyword("ASOF LEFT OUTER JOIN");
5794 } else {
5795 self.write_keyword("ASOF LEFT JOIN");
5796 }
5797 }
5798 JoinKind::AsOfRight => {
5799 if join.use_outer_keyword {
5800 self.write_keyword("ASOF RIGHT OUTER JOIN");
5801 } else {
5802 self.write_keyword("ASOF RIGHT JOIN");
5803 }
5804 }
5805 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5806 JoinKind::LeftLateral => {
5807 if join.use_outer_keyword {
5808 self.write_keyword("LEFT OUTER LATERAL JOIN");
5809 } else {
5810 self.write_keyword("LEFT LATERAL JOIN");
5811 }
5812 }
5813 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5814 JoinKind::Implicit => {
5815 use crate::dialects::DialectType;
5819 let is_cj_dialect = matches!(
5820 self.config.dialect,
5821 Some(DialectType::BigQuery)
5822 | Some(DialectType::Hive)
5823 | Some(DialectType::Spark)
5824 | Some(DialectType::Databricks)
5825 );
5826 let source_is_same = self.config.source_dialect.is_some()
5827 && self.config.source_dialect == self.config.dialect;
5828 let source_is_cj = matches!(
5829 self.config.source_dialect,
5830 Some(DialectType::BigQuery)
5831 | Some(DialectType::Hive)
5832 | Some(DialectType::Spark)
5833 | Some(DialectType::Databricks)
5834 );
5835 if is_cj_dialect
5836 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5837 {
5838 self.write_keyword("CROSS JOIN");
5839 } else {
5840 self.output.truncate(self.output.trim_end().len());
5844 self.write(",");
5845 }
5846 }
5847 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5848 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5849 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5850 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
5851 }
5852 }
5853
5854 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5856 match &join.this {
5857 Expression::Tuple(t) if t.expressions.is_empty() => {}
5858 Expression::Tuple(t) => {
5859 self.write_space();
5860 for (i, item) in t.expressions.iter().enumerate() {
5861 if i > 0 {
5862 self.write(", ");
5863 }
5864 self.generate_expression(item)?;
5865 }
5866 }
5867 other => {
5868 self.write_space();
5869 self.generate_expression(other)?;
5870 }
5871 }
5872 } else {
5873 self.write_space();
5874 self.generate_expression(&join.this)?;
5875 }
5876
5877 if !join.deferred_condition {
5879 if let Some(match_cond) = &join.match_condition {
5881 self.write_space();
5882 self.write_keyword("MATCH_CONDITION");
5883 self.write(" (");
5884 self.generate_expression(match_cond)?;
5885 self.write(")");
5886 }
5887
5888 if let Some(on) = &join.on {
5889 if self.config.pretty {
5890 self.write_newline();
5891 self.indent_level += 1;
5892 self.write_indent();
5893 self.write_keyword("ON");
5894 self.write_space();
5895 self.generate_join_on_condition(on)?;
5896 self.indent_level -= 1;
5897 } else {
5898 self.write_space();
5899 self.write_keyword("ON");
5900 self.write_space();
5901 self.generate_expression(on)?;
5902 }
5903 }
5904
5905 if !join.using.is_empty() {
5906 if self.config.pretty {
5907 self.write_newline();
5908 self.indent_level += 1;
5909 self.write_indent();
5910 self.write_keyword("USING");
5911 self.write(" (");
5912 for (i, col) in join.using.iter().enumerate() {
5913 if i > 0 {
5914 self.write(", ");
5915 }
5916 self.generate_identifier(col)?;
5917 }
5918 self.write(")");
5919 self.indent_level -= 1;
5920 } else {
5921 self.write_space();
5922 self.write_keyword("USING");
5923 self.write(" (");
5924 for (i, col) in join.using.iter().enumerate() {
5925 if i > 0 {
5926 self.write(", ");
5927 }
5928 self.generate_identifier(col)?;
5929 }
5930 self.write(")");
5931 }
5932 }
5933 }
5934
5935 for pivot in &join.pivots {
5937 self.write_space();
5938 self.generate_expression(pivot)?;
5939 }
5940
5941 Ok(())
5942 }
5943
5944 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5946 if let Some(match_cond) = &join.match_condition {
5948 self.write_space();
5949 self.write_keyword("MATCH_CONDITION");
5950 self.write(" (");
5951 self.generate_expression(match_cond)?;
5952 self.write(")");
5953 }
5954
5955 if let Some(on) = &join.on {
5956 if self.config.pretty {
5957 self.write_newline();
5958 self.indent_level += 1;
5959 self.write_indent();
5960 self.write_keyword("ON");
5961 self.write_space();
5962 self.generate_join_on_condition(on)?;
5964 self.indent_level -= 1;
5965 } else {
5966 self.write_space();
5967 self.write_keyword("ON");
5968 self.write_space();
5969 self.generate_expression(on)?;
5970 }
5971 }
5972
5973 if !join.using.is_empty() {
5974 if self.config.pretty {
5975 self.write_newline();
5976 self.indent_level += 1;
5977 self.write_indent();
5978 self.write_keyword("USING");
5979 self.write(" (");
5980 for (i, col) in join.using.iter().enumerate() {
5981 if i > 0 {
5982 self.write(", ");
5983 }
5984 self.generate_identifier(col)?;
5985 }
5986 self.write(")");
5987 self.indent_level -= 1;
5988 } else {
5989 self.write_space();
5990 self.write_keyword("USING");
5991 self.write(" (");
5992 for (i, col) in join.using.iter().enumerate() {
5993 if i > 0 {
5994 self.write(", ");
5995 }
5996 self.generate_identifier(col)?;
5997 }
5998 self.write(")");
5999 }
6000 }
6001
6002 for pivot in &join.pivots {
6004 self.write_space();
6005 self.generate_expression(pivot)?;
6006 }
6007
6008 Ok(())
6009 }
6010
6011 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
6013 if let Expression::And(and_op) = expr {
6014 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
6015 self.generate_expression(conditions[0])?;
6016 for condition in conditions.iter().skip(1) {
6017 self.write_newline();
6018 self.write_indent();
6019 self.write_keyword("AND");
6020 self.write_space();
6021 self.generate_expression(condition)?;
6022 }
6023 return Ok(());
6024 }
6025 }
6026
6027 self.generate_expression(expr)
6028 }
6029
6030 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
6031 self.write("(");
6033 self.generate_expression(&jt.left)?;
6034
6035 for join in &jt.joins {
6037 self.generate_join(join)?;
6038 }
6039
6040 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
6042 self.generate_lateral_view(lv, lv_idx)?;
6043 }
6044
6045 self.write(")");
6046
6047 if let Some(alias) = &jt.alias {
6049 self.write_space();
6050 self.write_keyword("AS");
6051 self.write_space();
6052 self.generate_identifier(alias)?;
6053 }
6054
6055 Ok(())
6056 }
6057
6058 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
6059 use crate::dialects::DialectType;
6060
6061 if self.config.pretty {
6062 self.write_newline();
6063 self.write_indent();
6064 } else {
6065 self.write_space();
6066 }
6067
6068 let use_lateral_join = matches!(
6071 self.config.dialect,
6072 Some(DialectType::PostgreSQL)
6073 | Some(DialectType::DuckDB)
6074 | Some(DialectType::Snowflake)
6075 | Some(DialectType::TSQL)
6076 | Some(DialectType::Presto)
6077 | Some(DialectType::Trino)
6078 | Some(DialectType::Athena)
6079 );
6080
6081 let use_unnest = matches!(
6083 self.config.dialect,
6084 Some(DialectType::DuckDB)
6085 | Some(DialectType::Presto)
6086 | Some(DialectType::Trino)
6087 | Some(DialectType::Athena)
6088 );
6089
6090 let (is_posexplode, is_inline, func_args) = match &lv.this {
6092 Expression::Explode(uf) => {
6093 (false, false, vec![uf.this.clone()])
6095 }
6096 Expression::Unnest(uf) => {
6097 let mut args = vec![uf.this.clone()];
6098 args.extend(uf.expressions.clone());
6099 (false, false, args)
6100 }
6101 Expression::Function(func) => {
6102 if func.name.eq_ignore_ascii_case("POSEXPLODE")
6103 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
6104 {
6105 (true, false, func.args.clone())
6106 } else if func.name.eq_ignore_ascii_case("INLINE") {
6107 (false, true, func.args.clone())
6108 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6109 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6110 {
6111 (false, false, func.args.clone())
6112 } else {
6113 (false, false, vec![])
6114 }
6115 }
6116 _ => (false, false, vec![]),
6117 };
6118
6119 if use_lateral_join {
6120 if lv.outer {
6122 self.write_keyword("LEFT JOIN LATERAL");
6123 } else {
6124 self.write_keyword("CROSS JOIN");
6125 }
6126 self.write_space();
6127
6128 if use_unnest && !func_args.is_empty() {
6129 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6132 func_args
6134 .iter()
6135 .map(|a| {
6136 if let Expression::Function(ref f) = a {
6137 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6138 return Expression::ArrayFunc(Box::new(
6139 crate::expressions::ArrayConstructor {
6140 expressions: f.args.clone(),
6141 bracket_notation: true,
6142 use_list_keyword: false,
6143 },
6144 ));
6145 }
6146 }
6147 a.clone()
6148 })
6149 .collect::<Vec<_>>()
6150 } else if matches!(
6151 self.config.dialect,
6152 Some(DialectType::Presto)
6153 | Some(DialectType::Trino)
6154 | Some(DialectType::Athena)
6155 ) {
6156 func_args
6158 .iter()
6159 .map(|a| {
6160 if let Expression::Function(ref f) = a {
6161 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6162 return Expression::ArrayFunc(Box::new(
6163 crate::expressions::ArrayConstructor {
6164 expressions: f.args.clone(),
6165 bracket_notation: true,
6166 use_list_keyword: false,
6167 },
6168 ));
6169 }
6170 }
6171 a.clone()
6172 })
6173 .collect::<Vec<_>>()
6174 } else {
6175 func_args
6176 };
6177
6178 if is_posexplode {
6180 self.write_keyword("LATERAL");
6181 self.write(" (");
6182 self.write_keyword("SELECT");
6183 self.write_space();
6184
6185 let pos_alias = if !lv.column_aliases.is_empty() {
6188 lv.column_aliases[0].clone()
6189 } else {
6190 Identifier::new("pos")
6191 };
6192 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6193 lv.column_aliases[1..].to_vec()
6194 } else {
6195 vec![Identifier::new("col")]
6196 };
6197
6198 self.generate_identifier(&pos_alias)?;
6200 self.write(" - 1");
6201 self.write_space();
6202 self.write_keyword("AS");
6203 self.write_space();
6204 self.generate_identifier(&pos_alias)?;
6205
6206 for data_col in &data_aliases {
6208 self.write(", ");
6209 self.generate_identifier(data_col)?;
6210 }
6211
6212 self.write_space();
6213 self.write_keyword("FROM");
6214 self.write_space();
6215 self.write_keyword("UNNEST");
6216 self.write("(");
6217 for (i, arg) in unnest_args.iter().enumerate() {
6218 if i > 0 {
6219 self.write(", ");
6220 }
6221 self.generate_expression(arg)?;
6222 }
6223 self.write(")");
6224 self.write_space();
6225 self.write_keyword("WITH ORDINALITY");
6226 self.write_space();
6227 self.write_keyword("AS");
6228 self.write_space();
6229
6230 let table_alias_ident = lv
6232 .table_alias
6233 .clone()
6234 .unwrap_or_else(|| Identifier::new("t"));
6235 self.generate_identifier(&table_alias_ident)?;
6236 self.write("(");
6237 for (i, data_col) in data_aliases.iter().enumerate() {
6238 if i > 0 {
6239 self.write(", ");
6240 }
6241 self.generate_identifier(data_col)?;
6242 }
6243 self.write(", ");
6244 self.generate_identifier(&pos_alias)?;
6245 self.write("))");
6246 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6247 self.write_keyword("LATERAL");
6249 self.write(" (");
6250 self.write_keyword("SELECT");
6251 self.write_space();
6252 self.write_keyword("UNNEST");
6253 self.write("(");
6254 for (i, arg) in unnest_args.iter().enumerate() {
6255 if i > 0 {
6256 self.write(", ");
6257 }
6258 self.generate_expression(arg)?;
6259 }
6260 self.write(", ");
6261 self.write_keyword("max_depth");
6262 self.write(" => 2))");
6263
6264 if let Some(alias) = &lv.table_alias {
6266 self.write_space();
6267 self.write_keyword("AS");
6268 self.write_space();
6269 self.generate_identifier(alias)?;
6270 if !lv.column_aliases.is_empty() {
6271 self.write("(");
6272 for (i, col) in lv.column_aliases.iter().enumerate() {
6273 if i > 0 {
6274 self.write(", ");
6275 }
6276 self.generate_identifier(col)?;
6277 }
6278 self.write(")");
6279 }
6280 } else if !lv.column_aliases.is_empty() {
6281 self.write_space();
6283 self.write_keyword("AS");
6284 self.write_space();
6285 self.write(&format!("_u_{}", lv_index));
6286 self.write("(");
6287 for (i, col) in lv.column_aliases.iter().enumerate() {
6288 if i > 0 {
6289 self.write(", ");
6290 }
6291 self.generate_identifier(col)?;
6292 }
6293 self.write(")");
6294 }
6295 } else {
6296 self.write_keyword("UNNEST");
6297 self.write("(");
6298 for (i, arg) in unnest_args.iter().enumerate() {
6299 if i > 0 {
6300 self.write(", ");
6301 }
6302 self.generate_expression(arg)?;
6303 }
6304 self.write(")");
6305
6306 if let Some(alias) = &lv.table_alias {
6308 self.write_space();
6309 self.write_keyword("AS");
6310 self.write_space();
6311 self.generate_identifier(alias)?;
6312 if !lv.column_aliases.is_empty() {
6313 self.write("(");
6314 for (i, col) in lv.column_aliases.iter().enumerate() {
6315 if i > 0 {
6316 self.write(", ");
6317 }
6318 self.generate_identifier(col)?;
6319 }
6320 self.write(")");
6321 }
6322 } else if !lv.column_aliases.is_empty() {
6323 self.write_space();
6324 self.write_keyword("AS");
6325 self.write(" t(");
6326 for (i, col) in lv.column_aliases.iter().enumerate() {
6327 if i > 0 {
6328 self.write(", ");
6329 }
6330 self.generate_identifier(col)?;
6331 }
6332 self.write(")");
6333 }
6334 }
6335 } else {
6336 if !lv.outer {
6338 self.write_keyword("LATERAL");
6339 self.write_space();
6340 }
6341 self.generate_expression(&lv.this)?;
6342
6343 if let Some(alias) = &lv.table_alias {
6345 self.write_space();
6346 self.write_keyword("AS");
6347 self.write_space();
6348 self.generate_identifier(alias)?;
6349 if !lv.column_aliases.is_empty() {
6350 self.write("(");
6351 for (i, col) in lv.column_aliases.iter().enumerate() {
6352 if i > 0 {
6353 self.write(", ");
6354 }
6355 self.generate_identifier(col)?;
6356 }
6357 self.write(")");
6358 }
6359 } else if !lv.column_aliases.is_empty() {
6360 self.write_space();
6361 self.write_keyword("AS");
6362 self.write(" t(");
6363 for (i, col) in lv.column_aliases.iter().enumerate() {
6364 if i > 0 {
6365 self.write(", ");
6366 }
6367 self.generate_identifier(col)?;
6368 }
6369 self.write(")");
6370 }
6371 }
6372
6373 if lv.outer {
6375 self.write_space();
6376 self.write_keyword("ON TRUE");
6377 }
6378 } else {
6379 self.write_keyword("LATERAL VIEW");
6381 if lv.outer {
6382 self.write_space();
6383 self.write_keyword("OUTER");
6384 }
6385 if self.config.pretty {
6386 self.write_newline();
6387 self.write_indent();
6388 } else {
6389 self.write_space();
6390 }
6391 self.generate_expression(&lv.this)?;
6392
6393 if let Some(alias) = &lv.table_alias {
6395 self.write_space();
6396 self.generate_identifier(alias)?;
6397 }
6398
6399 if !lv.column_aliases.is_empty() {
6401 self.write_space();
6402 self.write_keyword("AS");
6403 self.write_space();
6404 for (i, col) in lv.column_aliases.iter().enumerate() {
6405 if i > 0 {
6406 self.write(", ");
6407 }
6408 self.generate_identifier(col)?;
6409 }
6410 }
6411 }
6412
6413 Ok(())
6414 }
6415
6416 fn should_wrap_set_operation_modifiers(
6417 &self,
6418 order_by: &Option<OrderBy>,
6419 limit: &Option<Box<Expression>>,
6420 offset: &Option<Box<Expression>>,
6421 ) -> bool {
6422 let has_row_limit = limit.is_some() || offset.is_some();
6423 let has_emulated_null_ordering = order_by.as_ref().map_or(false, |order_by| {
6424 order_by
6425 .expressions
6426 .iter()
6427 .any(|ordered| ordered.nulls_first.is_some())
6428 });
6429
6430 (has_row_limit || has_emulated_null_ordering)
6431 && matches!(
6432 self.config.dialect,
6433 Some(DialectType::TSQL) | Some(DialectType::Fabric)
6434 )
6435 }
6436
6437 fn generate_tsql_wrapped_set_operation(
6438 &mut self,
6439 inner: Expression,
6440 with: Option<With>,
6441 order_by: Option<OrderBy>,
6442 limit: Option<Box<Expression>>,
6443 offset: Option<Box<Expression>>,
6444 ) -> Result<()> {
6445 let subquery = Subquery {
6446 this: inner,
6447 alias: Some(Identifier::new("_l_0".to_string())),
6448 column_aliases: Vec::new(),
6449 alias_explicit_as: true,
6450 alias_keyword: None,
6451 order_by: None,
6452 limit: None,
6453 offset: None,
6454 lateral: false,
6455 modifiers_inside: false,
6456 trailing_comments: Vec::new(),
6457 distribute_by: None,
6458 sort_by: None,
6459 cluster_by: None,
6460 inferred_type: None,
6461 };
6462
6463 let mut outer_select = Select {
6464 expressions: vec![Expression::Star(Star {
6465 table: None,
6466 except: None,
6467 replace: None,
6468 rename: None,
6469 trailing_comments: Vec::new(),
6470 span: None,
6471 })],
6472 from: Some(From {
6473 expressions: vec![Expression::Subquery(Box::new(subquery))],
6474 }),
6475 with,
6476 order_by,
6477 limit: limit.map(|limit| Limit {
6478 this: *limit,
6479 percent: false,
6480 comments: Vec::new(),
6481 }),
6482 offset: offset.map(|offset| Offset {
6483 this: *offset,
6484 rows: Some(true),
6485 }),
6486 ..Select::new()
6487 };
6488
6489 if outer_select.offset.is_some() && outer_select.order_by.is_none() {
6490 outer_select.order_by = Some(Self::dummy_tsql_order_by());
6491 }
6492
6493 self.generate_select(&outer_select)
6494 }
6495
6496 fn dummy_tsql_order_by() -> OrderBy {
6497 let null_select = Expression::Select(Box::new(Select {
6498 expressions: vec![Expression::Null(Null)],
6499 ..Select::new()
6500 }));
6501
6502 OrderBy {
6503 expressions: vec![Ordered {
6504 this: Expression::Subquery(Box::new(Subquery {
6505 this: null_select,
6506 alias: None,
6507 column_aliases: Vec::new(),
6508 alias_explicit_as: false,
6509 alias_keyword: None,
6510 order_by: None,
6511 limit: None,
6512 offset: None,
6513 lateral: false,
6514 modifiers_inside: false,
6515 trailing_comments: Vec::new(),
6516 distribute_by: None,
6517 sort_by: None,
6518 cluster_by: None,
6519 inferred_type: None,
6520 })),
6521 desc: false,
6522 nulls_first: None,
6523 explicit_asc: false,
6524 with_fill: None,
6525 }],
6526 siblings: false,
6527 comments: Vec::new(),
6528 }
6529 }
6530
6531 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
6532 if self.should_wrap_set_operation_modifiers(
6533 &outermost.order_by,
6534 &outermost.limit,
6535 &outermost.offset,
6536 ) {
6537 let mut inner = outermost.clone();
6538 let with = inner.with.take();
6539 let order_by = inner.order_by.take();
6540 let limit = inner.limit.take();
6541 let offset = inner.offset.take();
6542
6543 return self.generate_tsql_wrapped_set_operation(
6544 Expression::Union(Box::new(inner)),
6545 with,
6546 order_by,
6547 limit,
6548 offset,
6549 );
6550 }
6551
6552 let mut chain: Vec<&Union> = vec![outermost];
6557 let mut leftmost: &Expression = &outermost.left;
6558 while let Expression::Union(inner) = leftmost {
6559 chain.push(inner);
6560 leftmost = &inner.left;
6561 }
6562 if let Some(with) = &outermost.with {
6567 self.generate_with(with)?;
6568 self.write_space();
6569 }
6570
6571 self.generate_expression(leftmost)?;
6573
6574 for union in chain.iter().rev() {
6576 self.generate_union_step(union)?;
6577 }
6578 Ok(())
6579 }
6580
6581 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
6583 if self.config.pretty {
6584 self.write_newline();
6585 self.write_indent();
6586 } else {
6587 self.write_space();
6588 }
6589
6590 if let Some(side) = &union.side {
6592 self.write_keyword(side);
6593 self.write_space();
6594 }
6595 if let Some(kind) = &union.kind {
6596 self.write_keyword(kind);
6597 self.write_space();
6598 }
6599
6600 self.write_keyword("UNION");
6601 if union.all {
6602 self.write_space();
6603 self.write_keyword("ALL");
6604 } else if union.distinct {
6605 self.write_space();
6606 self.write_keyword("DISTINCT");
6607 }
6608
6609 if union.corresponding || union.by_name {
6612 self.write_space();
6613 self.write_keyword("BY NAME");
6614 }
6615 if !union.on_columns.is_empty() {
6616 self.write_space();
6617 self.write_keyword("ON");
6618 self.write(" (");
6619 for (i, col) in union.on_columns.iter().enumerate() {
6620 if i > 0 {
6621 self.write(", ");
6622 }
6623 self.generate_expression(col)?;
6624 }
6625 self.write(")");
6626 }
6627
6628 if self.config.pretty {
6629 self.write_newline();
6630 self.write_indent();
6631 } else {
6632 self.write_space();
6633 }
6634 self.generate_expression(&union.right)?;
6635 if let Some(order_by) = &union.order_by {
6637 if self.config.pretty {
6638 self.write_newline();
6639 } else {
6640 self.write_space();
6641 }
6642 self.write_keyword("ORDER BY");
6643 self.write_space();
6644 for (i, ordered) in order_by.expressions.iter().enumerate() {
6645 if i > 0 {
6646 self.write(", ");
6647 }
6648 self.generate_ordered(ordered)?;
6649 }
6650 }
6651 if let Some(limit) = &union.limit {
6652 if self.config.pretty {
6653 self.write_newline();
6654 } else {
6655 self.write_space();
6656 }
6657 self.write_keyword("LIMIT");
6658 self.write_space();
6659 self.generate_expression(limit)?;
6660 }
6661 if let Some(offset) = &union.offset {
6662 if self.config.pretty {
6663 self.write_newline();
6664 } else {
6665 self.write_space();
6666 }
6667 self.write_keyword("OFFSET");
6668 self.write_space();
6669 self.generate_expression(offset)?;
6670 }
6671 if let Some(distribute_by) = &union.distribute_by {
6673 self.write_space();
6674 self.write_keyword("DISTRIBUTE BY");
6675 self.write_space();
6676 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6677 if i > 0 {
6678 self.write(", ");
6679 }
6680 self.generate_expression(expr)?;
6681 }
6682 }
6683 if let Some(sort_by) = &union.sort_by {
6685 self.write_space();
6686 self.write_keyword("SORT BY");
6687 self.write_space();
6688 for (i, ord) in sort_by.expressions.iter().enumerate() {
6689 if i > 0 {
6690 self.write(", ");
6691 }
6692 self.generate_ordered(ord)?;
6693 }
6694 }
6695 if let Some(cluster_by) = &union.cluster_by {
6697 self.write_space();
6698 self.write_keyword("CLUSTER BY");
6699 self.write_space();
6700 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6701 if i > 0 {
6702 self.write(", ");
6703 }
6704 self.generate_ordered(ord)?;
6705 }
6706 }
6707 Ok(())
6708 }
6709
6710 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
6711 if self.should_wrap_set_operation_modifiers(
6712 &outermost.order_by,
6713 &outermost.limit,
6714 &outermost.offset,
6715 ) {
6716 let mut inner = outermost.clone();
6717 let with = inner.with.take();
6718 let order_by = inner.order_by.take();
6719 let limit = inner.limit.take();
6720 let offset = inner.offset.take();
6721
6722 return self.generate_tsql_wrapped_set_operation(
6723 Expression::Intersect(Box::new(inner)),
6724 with,
6725 order_by,
6726 limit,
6727 offset,
6728 );
6729 }
6730
6731 let mut chain: Vec<&Intersect> = vec![outermost];
6733 let mut leftmost: &Expression = &outermost.left;
6734 while let Expression::Intersect(inner) = leftmost {
6735 chain.push(inner);
6736 leftmost = &inner.left;
6737 }
6738
6739 if let Some(with) = &outermost.with {
6740 self.generate_with(with)?;
6741 self.write_space();
6742 }
6743
6744 self.generate_expression(leftmost)?;
6745
6746 for intersect in chain.iter().rev() {
6747 self.generate_intersect_step(intersect)?;
6748 }
6749 Ok(())
6750 }
6751
6752 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
6754 if self.config.pretty {
6755 self.write_newline();
6756 self.write_indent();
6757 } else {
6758 self.write_space();
6759 }
6760
6761 if let Some(side) = &intersect.side {
6763 self.write_keyword(side);
6764 self.write_space();
6765 }
6766 if let Some(kind) = &intersect.kind {
6767 self.write_keyword(kind);
6768 self.write_space();
6769 }
6770
6771 self.write_keyword("INTERSECT");
6772 if intersect.all {
6773 self.write_space();
6774 self.write_keyword("ALL");
6775 } else if intersect.distinct {
6776 self.write_space();
6777 self.write_keyword("DISTINCT");
6778 }
6779
6780 if intersect.corresponding || intersect.by_name {
6783 self.write_space();
6784 self.write_keyword("BY NAME");
6785 }
6786 if !intersect.on_columns.is_empty() {
6787 self.write_space();
6788 self.write_keyword("ON");
6789 self.write(" (");
6790 for (i, col) in intersect.on_columns.iter().enumerate() {
6791 if i > 0 {
6792 self.write(", ");
6793 }
6794 self.generate_expression(col)?;
6795 }
6796 self.write(")");
6797 }
6798
6799 if self.config.pretty {
6800 self.write_newline();
6801 self.write_indent();
6802 } else {
6803 self.write_space();
6804 }
6805 self.generate_expression(&intersect.right)?;
6806 if let Some(order_by) = &intersect.order_by {
6808 if self.config.pretty {
6809 self.write_newline();
6810 } else {
6811 self.write_space();
6812 }
6813 self.write_keyword("ORDER BY");
6814 self.write_space();
6815 for (i, ordered) in order_by.expressions.iter().enumerate() {
6816 if i > 0 {
6817 self.write(", ");
6818 }
6819 self.generate_ordered(ordered)?;
6820 }
6821 }
6822 if let Some(limit) = &intersect.limit {
6823 if self.config.pretty {
6824 self.write_newline();
6825 } else {
6826 self.write_space();
6827 }
6828 self.write_keyword("LIMIT");
6829 self.write_space();
6830 self.generate_expression(limit)?;
6831 }
6832 if let Some(offset) = &intersect.offset {
6833 if self.config.pretty {
6834 self.write_newline();
6835 } else {
6836 self.write_space();
6837 }
6838 self.write_keyword("OFFSET");
6839 self.write_space();
6840 self.generate_expression(offset)?;
6841 }
6842 if let Some(distribute_by) = &intersect.distribute_by {
6844 self.write_space();
6845 self.write_keyword("DISTRIBUTE BY");
6846 self.write_space();
6847 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6848 if i > 0 {
6849 self.write(", ");
6850 }
6851 self.generate_expression(expr)?;
6852 }
6853 }
6854 if let Some(sort_by) = &intersect.sort_by {
6856 self.write_space();
6857 self.write_keyword("SORT BY");
6858 self.write_space();
6859 for (i, ord) in sort_by.expressions.iter().enumerate() {
6860 if i > 0 {
6861 self.write(", ");
6862 }
6863 self.generate_ordered(ord)?;
6864 }
6865 }
6866 if let Some(cluster_by) = &intersect.cluster_by {
6868 self.write_space();
6869 self.write_keyword("CLUSTER BY");
6870 self.write_space();
6871 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6872 if i > 0 {
6873 self.write(", ");
6874 }
6875 self.generate_ordered(ord)?;
6876 }
6877 }
6878 Ok(())
6879 }
6880
6881 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
6882 if self.should_wrap_set_operation_modifiers(
6883 &outermost.order_by,
6884 &outermost.limit,
6885 &outermost.offset,
6886 ) {
6887 let mut inner = outermost.clone();
6888 let with = inner.with.take();
6889 let order_by = inner.order_by.take();
6890 let limit = inner.limit.take();
6891 let offset = inner.offset.take();
6892
6893 return self.generate_tsql_wrapped_set_operation(
6894 Expression::Except(Box::new(inner)),
6895 with,
6896 order_by,
6897 limit,
6898 offset,
6899 );
6900 }
6901
6902 let mut chain: Vec<&Except> = vec![outermost];
6904 let mut leftmost: &Expression = &outermost.left;
6905 while let Expression::Except(inner) = leftmost {
6906 chain.push(inner);
6907 leftmost = &inner.left;
6908 }
6909
6910 if let Some(with) = &outermost.with {
6911 self.generate_with(with)?;
6912 self.write_space();
6913 }
6914
6915 self.generate_expression(leftmost)?;
6916
6917 for except in chain.iter().rev() {
6918 self.generate_except_step(except)?;
6919 }
6920 Ok(())
6921 }
6922
6923 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
6925 use crate::dialects::DialectType;
6926
6927 if self.config.pretty {
6928 self.write_newline();
6929 self.write_indent();
6930 } else {
6931 self.write_space();
6932 }
6933
6934 if let Some(side) = &except.side {
6936 self.write_keyword(side);
6937 self.write_space();
6938 }
6939 if let Some(kind) = &except.kind {
6940 self.write_keyword(kind);
6941 self.write_space();
6942 }
6943
6944 match self.config.dialect {
6946 Some(DialectType::Oracle) if !except.all => {
6947 self.write_keyword("MINUS");
6948 }
6949 Some(DialectType::ClickHouse) => {
6950 self.write_keyword("EXCEPT");
6951 let preserve_all = self.config.source_dialect.is_none()
6952 || matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
6953 if except.all && preserve_all {
6954 self.write_space();
6955 self.write_keyword("ALL");
6956 }
6957 if except.distinct {
6958 self.write_space();
6959 self.write_keyword("DISTINCT");
6960 }
6961 }
6962 Some(DialectType::BigQuery) => {
6963 self.write_keyword("EXCEPT");
6965 if except.all {
6966 self.write_space();
6967 self.write_keyword("ALL");
6968 } else {
6969 self.write_space();
6970 self.write_keyword("DISTINCT");
6971 }
6972 }
6973 _ => {
6974 self.write_keyword("EXCEPT");
6975 if except.all {
6976 self.write_space();
6977 self.write_keyword("ALL");
6978 } else if except.distinct {
6979 self.write_space();
6980 self.write_keyword("DISTINCT");
6981 }
6982 }
6983 }
6984
6985 if except.corresponding || except.by_name {
6988 self.write_space();
6989 self.write_keyword("BY NAME");
6990 }
6991 if !except.on_columns.is_empty() {
6992 self.write_space();
6993 self.write_keyword("ON");
6994 self.write(" (");
6995 for (i, col) in except.on_columns.iter().enumerate() {
6996 if i > 0 {
6997 self.write(", ");
6998 }
6999 self.generate_expression(col)?;
7000 }
7001 self.write(")");
7002 }
7003
7004 if self.config.pretty {
7005 self.write_newline();
7006 self.write_indent();
7007 } else {
7008 self.write_space();
7009 }
7010 self.generate_expression(&except.right)?;
7011 if let Some(order_by) = &except.order_by {
7013 if self.config.pretty {
7014 self.write_newline();
7015 } else {
7016 self.write_space();
7017 }
7018 self.write_keyword("ORDER BY");
7019 self.write_space();
7020 for (i, ordered) in order_by.expressions.iter().enumerate() {
7021 if i > 0 {
7022 self.write(", ");
7023 }
7024 self.generate_ordered(ordered)?;
7025 }
7026 }
7027 if let Some(limit) = &except.limit {
7028 if self.config.pretty {
7029 self.write_newline();
7030 } else {
7031 self.write_space();
7032 }
7033 self.write_keyword("LIMIT");
7034 self.write_space();
7035 self.generate_expression(limit)?;
7036 }
7037 if let Some(offset) = &except.offset {
7038 if self.config.pretty {
7039 self.write_newline();
7040 } else {
7041 self.write_space();
7042 }
7043 self.write_keyword("OFFSET");
7044 self.write_space();
7045 self.generate_expression(offset)?;
7046 }
7047 if let Some(distribute_by) = &except.distribute_by {
7049 self.write_space();
7050 self.write_keyword("DISTRIBUTE BY");
7051 self.write_space();
7052 for (i, expr) in distribute_by.expressions.iter().enumerate() {
7053 if i > 0 {
7054 self.write(", ");
7055 }
7056 self.generate_expression(expr)?;
7057 }
7058 }
7059 if let Some(sort_by) = &except.sort_by {
7061 self.write_space();
7062 self.write_keyword("SORT BY");
7063 self.write_space();
7064 for (i, ord) in sort_by.expressions.iter().enumerate() {
7065 if i > 0 {
7066 self.write(", ");
7067 }
7068 self.generate_ordered(ord)?;
7069 }
7070 }
7071 if let Some(cluster_by) = &except.cluster_by {
7073 self.write_space();
7074 self.write_keyword("CLUSTER BY");
7075 self.write_space();
7076 for (i, ord) in cluster_by.expressions.iter().enumerate() {
7077 if i > 0 {
7078 self.write(", ");
7079 }
7080 self.generate_ordered(ord)?;
7081 }
7082 }
7083 Ok(())
7084 }
7085
7086 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
7087 let prepend_query_cte = if insert.with.is_none() {
7089 use crate::dialects::DialectType;
7090 let should_prepend = matches!(
7091 self.config.dialect,
7092 Some(DialectType::TSQL)
7093 | Some(DialectType::Fabric)
7094 | Some(DialectType::Spark)
7095 | Some(DialectType::Databricks)
7096 | Some(DialectType::Hive)
7097 );
7098 if should_prepend {
7099 if let Some(Expression::Select(select)) = &insert.query {
7100 select.with.clone()
7101 } else {
7102 None
7103 }
7104 } else {
7105 None
7106 }
7107 } else {
7108 None
7109 };
7110
7111 if let Some(with) = &insert.with {
7113 self.generate_with(with)?;
7114 self.write_space();
7115 } else if let Some(with) = &prepend_query_cte {
7116 self.generate_with(with)?;
7117 self.write_space();
7118 }
7119
7120 for comment in &insert.leading_comments {
7122 self.write_formatted_comment(comment);
7123 self.write(" ");
7124 }
7125
7126 if let Some(dir) = &insert.directory {
7128 self.write_keyword("INSERT OVERWRITE");
7129 if dir.local {
7130 self.write_space();
7131 self.write_keyword("LOCAL");
7132 }
7133 self.write_space();
7134 self.write_keyword("DIRECTORY");
7135 self.write_space();
7136 self.write("'");
7137 self.write(&dir.path);
7138 self.write("'");
7139
7140 if let Some(row_format) = &dir.row_format {
7142 self.write_space();
7143 self.write_keyword("ROW FORMAT");
7144 if row_format.delimited {
7145 self.write_space();
7146 self.write_keyword("DELIMITED");
7147 }
7148 if let Some(val) = &row_format.fields_terminated_by {
7149 self.write_space();
7150 self.write_keyword("FIELDS TERMINATED BY");
7151 self.write_space();
7152 self.generate_string_literal(val)?;
7153 }
7154 if let Some(val) = &row_format.collection_items_terminated_by {
7155 self.write_space();
7156 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
7157 self.write_space();
7158 self.write("'");
7159 self.write(val);
7160 self.write("'");
7161 }
7162 if let Some(val) = &row_format.map_keys_terminated_by {
7163 self.write_space();
7164 self.write_keyword("MAP KEYS TERMINATED BY");
7165 self.write_space();
7166 self.write("'");
7167 self.write(val);
7168 self.write("'");
7169 }
7170 if let Some(val) = &row_format.lines_terminated_by {
7171 self.write_space();
7172 self.write_keyword("LINES TERMINATED BY");
7173 self.write_space();
7174 self.write("'");
7175 self.write(val);
7176 self.write("'");
7177 }
7178 if let Some(val) = &row_format.null_defined_as {
7179 self.write_space();
7180 self.write_keyword("NULL DEFINED AS");
7181 self.write_space();
7182 self.write("'");
7183 self.write(val);
7184 self.write("'");
7185 }
7186 }
7187
7188 if let Some(format) = &dir.stored_as {
7190 self.write_space();
7191 self.write_keyword("STORED AS");
7192 self.write_space();
7193 self.write_keyword(format);
7194 }
7195
7196 if let Some(query) = &insert.query {
7198 self.write_space();
7199 self.generate_expression(query)?;
7200 }
7201
7202 return Ok(());
7203 }
7204
7205 if insert.is_replace {
7206 self.write_keyword("REPLACE INTO");
7208 } else if insert.overwrite {
7209 self.write_keyword("INSERT");
7211 if let Some(ref hint) = insert.hint {
7213 self.generate_hint(hint)?;
7214 }
7215 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
7216 } else if let Some(ref action) = insert.conflict_action {
7217 self.write_keyword("INSERT OR");
7219 self.write_space();
7220 self.write_keyword(action);
7221 self.write_space();
7222 self.write_keyword("INTO");
7223 } else if insert.ignore {
7224 self.write_keyword("INSERT IGNORE INTO");
7226 } else {
7227 self.write_keyword("INSERT");
7228 if let Some(ref hint) = insert.hint {
7230 self.generate_hint(hint)?;
7231 }
7232 self.write_space();
7233 self.write_keyword("INTO");
7234 }
7235 if let Some(ref func) = insert.function_target {
7237 self.write_space();
7238 self.write_keyword("FUNCTION");
7239 self.write_space();
7240 self.generate_expression(func)?;
7241 } else {
7242 self.write_space();
7243 self.generate_table(&insert.table)?;
7244 }
7245
7246 if let Some(ref alias) = insert.alias {
7248 self.write_space();
7249 if insert.alias_explicit_as {
7250 self.write_keyword("AS");
7251 self.write_space();
7252 }
7253 self.generate_identifier(alias)?;
7254 }
7255
7256 if insert.if_exists {
7258 self.write_space();
7259 self.write_keyword("IF EXISTS");
7260 }
7261
7262 if let Some(ref replace_where) = insert.replace_where {
7264 if self.config.pretty {
7265 self.write_newline();
7266 self.write_indent();
7267 } else {
7268 self.write_space();
7269 }
7270 self.write_keyword("REPLACE WHERE");
7271 self.write_space();
7272 self.generate_expression(replace_where)?;
7273 }
7274
7275 if !insert.partition.is_empty() {
7277 self.write_space();
7278 self.write_keyword("PARTITION");
7279 self.write("(");
7280 for (i, (col, val)) in insert.partition.iter().enumerate() {
7281 if i > 0 {
7282 self.write(", ");
7283 }
7284 self.generate_identifier(col)?;
7285 if let Some(v) = val {
7286 self.write(" = ");
7287 self.generate_expression(v)?;
7288 }
7289 }
7290 self.write(")");
7291 }
7292
7293 if let Some(ref partition_by) = insert.partition_by {
7295 self.write_space();
7296 self.write_keyword("PARTITION BY");
7297 self.write_space();
7298 self.generate_expression(partition_by)?;
7299 }
7300
7301 if !insert.settings.is_empty() {
7303 self.write_space();
7304 self.write_keyword("SETTINGS");
7305 self.write_space();
7306 for (i, setting) in insert.settings.iter().enumerate() {
7307 if i > 0 {
7308 self.write(", ");
7309 }
7310 self.generate_expression(setting)?;
7311 }
7312 }
7313
7314 if !insert.columns.is_empty() {
7315 if insert.alias.is_some() && insert.alias_explicit_as {
7316 self.write("(");
7318 } else {
7319 self.write(" (");
7321 }
7322 for (i, col) in insert.columns.iter().enumerate() {
7323 if i > 0 {
7324 self.write(", ");
7325 }
7326 self.generate_identifier(col)?;
7327 }
7328 self.write(")");
7329 }
7330
7331 if let Some(ref output) = insert.output {
7333 self.generate_output_clause(output)?;
7334 }
7335
7336 if insert.by_name {
7338 self.write_space();
7339 self.write_keyword("BY NAME");
7340 }
7341
7342 if insert.default_values {
7343 self.write_space();
7344 self.write_keyword("DEFAULT VALUES");
7345 } else if let Some(query) = &insert.query {
7346 if self.config.pretty {
7347 self.write_newline();
7348 } else {
7349 self.write_space();
7350 }
7351 if prepend_query_cte.is_some() {
7353 if let Expression::Select(select) = query {
7354 let mut select_no_with = select.clone();
7355 select_no_with.with = None;
7356 self.generate_select(&select_no_with)?;
7357 } else {
7358 self.generate_expression(query)?;
7359 }
7360 } else {
7361 self.generate_expression(query)?;
7362 }
7363 } else if !insert.values.is_empty() {
7364 if self.config.pretty {
7365 self.write_newline();
7367 self.write_keyword("VALUES");
7368 self.write_newline();
7369 self.indent_level += 1;
7370 for (i, row) in insert.values.iter().enumerate() {
7371 if i > 0 {
7372 self.write(",");
7373 self.write_newline();
7374 }
7375 self.write_indent();
7376 self.write("(");
7377 for (j, val) in row.iter().enumerate() {
7378 if j > 0 {
7379 self.write(", ");
7380 }
7381 self.generate_expression(val)?;
7382 }
7383 self.write(")");
7384 }
7385 self.indent_level -= 1;
7386 } else {
7387 self.write_space();
7389 self.write_keyword("VALUES");
7390 for (i, row) in insert.values.iter().enumerate() {
7391 if i > 0 {
7392 self.write(",");
7393 }
7394 self.write(" (");
7395 for (j, val) in row.iter().enumerate() {
7396 if j > 0 {
7397 self.write(", ");
7398 }
7399 self.generate_expression(val)?;
7400 }
7401 self.write(")");
7402 }
7403 }
7404 }
7405
7406 if let Some(ref source) = insert.source {
7408 self.write_space();
7409 self.write_keyword("TABLE");
7410 self.write_space();
7411 self.generate_expression(source)?;
7412 }
7413
7414 if let Some(alias) = &insert.source_alias {
7416 self.write_space();
7417 self.write_keyword("AS");
7418 self.write_space();
7419 self.generate_identifier(alias)?;
7420 }
7421
7422 if let Some(on_conflict) = &insert.on_conflict {
7424 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7425 self.write_space();
7426 self.generate_expression(on_conflict)?;
7427 }
7428 }
7429
7430 if !insert.returning.is_empty() {
7432 self.write_space();
7433 self.write_keyword("RETURNING");
7434 self.write_space();
7435 for (i, expr) in insert.returning.iter().enumerate() {
7436 if i > 0 {
7437 self.write(", ");
7438 }
7439 self.generate_expression(expr)?;
7440 }
7441 }
7442
7443 Ok(())
7444 }
7445
7446 fn generate_update(&mut self, update: &Update) -> Result<()> {
7447 for comment in &update.leading_comments {
7449 self.write_formatted_comment(comment);
7450 self.write(" ");
7451 }
7452
7453 if let Some(ref with) = update.with {
7455 self.generate_with(with)?;
7456 self.write_space();
7457 }
7458
7459 self.write_keyword("UPDATE");
7460 if let Some(hint) = &update.hint {
7461 self.generate_hint(hint)?;
7462 }
7463 self.write_space();
7464 self.generate_table(&update.table)?;
7465
7466 let mysql_like_update_from = matches!(
7467 self.config.dialect,
7468 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
7469 ) && update.from_clause.is_some();
7470
7471 let mut set_pairs = update.set.clone();
7472
7473 let mut pre_set_joins = update.table_joins.clone();
7475 if mysql_like_update_from {
7476 let target_name = update
7477 .table
7478 .alias
7479 .as_ref()
7480 .map(|a| a.name.clone())
7481 .unwrap_or_else(|| update.table.name.name.clone());
7482
7483 for (col, _) in &mut set_pairs {
7484 if !col.name.contains('.') {
7485 col.name = format!("{}.{}", target_name, col.name);
7486 }
7487 }
7488
7489 if let Some(from_clause) = &update.from_clause {
7490 for table_expr in &from_clause.expressions {
7491 pre_set_joins.push(crate::expressions::Join {
7492 this: table_expr.clone(),
7493 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7494 value: true,
7495 })),
7496 using: Vec::new(),
7497 kind: crate::expressions::JoinKind::Inner,
7498 use_inner_keyword: false,
7499 use_outer_keyword: false,
7500 deferred_condition: false,
7501 join_hint: None,
7502 match_condition: None,
7503 pivots: Vec::new(),
7504 comments: Vec::new(),
7505 nesting_group: 0,
7506 directed: false,
7507 });
7508 }
7509 }
7510 for join in &update.from_joins {
7511 let mut join = join.clone();
7512 if join.on.is_none() && join.using.is_empty() {
7513 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7514 value: true,
7515 }));
7516 }
7517 pre_set_joins.push(join);
7518 }
7519 }
7520
7521 for extra_table in &update.extra_tables {
7523 self.write(", ");
7524 self.generate_table(extra_table)?;
7525 }
7526
7527 for join in &pre_set_joins {
7529 self.generate_join(join)?;
7531 }
7532
7533 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
7535 if teradata_from_before_set && !mysql_like_update_from {
7536 if let Some(ref from_clause) = update.from_clause {
7537 self.write_space();
7538 self.write_keyword("FROM");
7539 self.write_space();
7540 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7541 if i > 0 {
7542 self.write(", ");
7543 }
7544 self.generate_expression(table_expr)?;
7545 }
7546 }
7547 for join in &update.from_joins {
7548 self.generate_join(join)?;
7549 }
7550 }
7551
7552 self.write_space();
7553 self.write_keyword("SET");
7554 self.write_space();
7555
7556 for (i, (col, val)) in set_pairs.iter().enumerate() {
7557 if i > 0 {
7558 self.write(", ");
7559 }
7560 self.generate_identifier(col)?;
7561 self.write(" = ");
7562 self.generate_expression(val)?;
7563 }
7564
7565 if let Some(ref output) = update.output {
7567 self.generate_output_clause(output)?;
7568 }
7569
7570 if !mysql_like_update_from && !teradata_from_before_set {
7572 if let Some(ref from_clause) = update.from_clause {
7573 self.write_space();
7574 self.write_keyword("FROM");
7575 self.write_space();
7576 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7578 if i > 0 {
7579 self.write(", ");
7580 }
7581 self.generate_expression(table_expr)?;
7582 }
7583 }
7584 }
7585
7586 if !mysql_like_update_from && !teradata_from_before_set {
7587 for join in &update.from_joins {
7589 self.generate_join(join)?;
7590 }
7591 }
7592
7593 if let Some(where_clause) = &update.where_clause {
7594 self.write_space();
7595 self.write_keyword("WHERE");
7596 self.write_space();
7597 self.generate_expression(&where_clause.this)?;
7598 }
7599
7600 if !update.returning.is_empty() {
7602 self.write_space();
7603 self.write_keyword("RETURNING");
7604 self.write_space();
7605 for (i, expr) in update.returning.iter().enumerate() {
7606 if i > 0 {
7607 self.write(", ");
7608 }
7609 self.generate_expression(expr)?;
7610 }
7611 }
7612
7613 if let Some(ref order_by) = update.order_by {
7615 self.write_space();
7616 self.generate_order_by(order_by)?;
7617 }
7618
7619 if let Some(ref limit) = update.limit {
7621 self.write_space();
7622 self.write_keyword("LIMIT");
7623 self.write_space();
7624 self.generate_expression(limit)?;
7625 }
7626
7627 Ok(())
7628 }
7629
7630 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
7631 if let Some(with) = &delete.with {
7633 self.generate_with(with)?;
7634 self.write_space();
7635 }
7636
7637 for comment in &delete.leading_comments {
7639 self.write_formatted_comment(comment);
7640 self.write(" ");
7641 }
7642
7643 if !delete.tables.is_empty() && !delete.tables_from_using {
7645 self.write_keyword("DELETE");
7647 if let Some(hint) = &delete.hint {
7648 self.generate_hint(hint)?;
7649 }
7650 self.write_space();
7651 for (i, tbl) in delete.tables.iter().enumerate() {
7652 if i > 0 {
7653 self.write(", ");
7654 }
7655 self.generate_table(tbl)?;
7656 }
7657 if let Some(ref output) = delete.output {
7659 self.generate_output_clause(output)?;
7660 }
7661 self.write_space();
7662 self.write_keyword("FROM");
7663 self.write_space();
7664 self.generate_table(&delete.table)?;
7665 } else if !delete.tables.is_empty() && delete.tables_from_using {
7666 self.write_keyword("DELETE");
7668 if let Some(hint) = &delete.hint {
7669 self.generate_hint(hint)?;
7670 }
7671 self.write_space();
7672 self.write_keyword("FROM");
7673 self.write_space();
7674 for (i, tbl) in delete.tables.iter().enumerate() {
7675 if i > 0 {
7676 self.write(", ");
7677 }
7678 self.generate_table(tbl)?;
7679 }
7680 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
7681 self.write_keyword("DELETE");
7683 if let Some(hint) = &delete.hint {
7684 self.generate_hint(hint)?;
7685 }
7686 self.write_space();
7687 self.generate_table(&delete.table)?;
7688 } else {
7689 self.write_keyword("DELETE");
7690 if let Some(hint) = &delete.hint {
7691 self.generate_hint(hint)?;
7692 }
7693 self.write_space();
7694 self.write_keyword("FROM");
7695 self.write_space();
7696 self.generate_table(&delete.table)?;
7697 }
7698
7699 if let Some(ref on_cluster) = delete.on_cluster {
7701 self.write_space();
7702 self.generate_on_cluster(on_cluster)?;
7703 }
7704
7705 if let Some(ref idx) = delete.force_index {
7707 self.write_space();
7708 self.write_keyword("FORCE INDEX");
7709 self.write(" (");
7710 self.write(idx);
7711 self.write(")");
7712 }
7713
7714 if let Some(ref alias) = delete.alias {
7716 self.write_space();
7717 if delete.alias_explicit_as
7718 || matches!(self.config.dialect, Some(DialectType::BigQuery))
7719 {
7720 self.write_keyword("AS");
7721 self.write_space();
7722 }
7723 self.generate_identifier(alias)?;
7724 }
7725
7726 if !delete.tables_from_using {
7728 for join in &delete.joins {
7729 self.generate_join(join)?;
7730 }
7731 }
7732
7733 if !delete.using.is_empty() {
7735 self.write_space();
7736 self.write_keyword("USING");
7737 for (i, table) in delete.using.iter().enumerate() {
7738 if i > 0 {
7739 self.write(",");
7740 }
7741 self.write_space();
7742 if !table.hints.is_empty() && table.name.is_empty() {
7744 self.generate_expression(&table.hints[0])?;
7746 if let Some(ref alias) = table.alias {
7747 self.write_space();
7748 if table.alias_explicit_as {
7749 self.write_keyword("AS");
7750 self.write_space();
7751 }
7752 self.generate_identifier(alias)?;
7753 if !table.column_aliases.is_empty() {
7754 self.write("(");
7755 for (j, col_alias) in table.column_aliases.iter().enumerate() {
7756 if j > 0 {
7757 self.write(", ");
7758 }
7759 self.generate_identifier(col_alias)?;
7760 }
7761 self.write(")");
7762 }
7763 }
7764 } else {
7765 self.generate_table(table)?;
7766 }
7767 }
7768 }
7769
7770 if delete.tables_from_using {
7772 for join in &delete.joins {
7773 self.generate_join(join)?;
7774 }
7775 }
7776
7777 let output_already_emitted =
7779 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
7780 if !output_already_emitted {
7781 if let Some(ref output) = delete.output {
7782 self.generate_output_clause(output)?;
7783 }
7784 }
7785
7786 if let Some(where_clause) = &delete.where_clause {
7787 self.write_space();
7788 self.write_keyword("WHERE");
7789 self.write_space();
7790 self.generate_expression(&where_clause.this)?;
7791 }
7792
7793 if let Some(ref order_by) = delete.order_by {
7795 self.write_space();
7796 self.generate_order_by(order_by)?;
7797 }
7798
7799 if let Some(ref limit) = delete.limit {
7801 self.write_space();
7802 self.write_keyword("LIMIT");
7803 self.write_space();
7804 self.generate_expression(limit)?;
7805 }
7806
7807 if !delete.returning.is_empty() {
7809 self.write_space();
7810 self.write_keyword("RETURNING");
7811 self.write_space();
7812 for (i, expr) in delete.returning.iter().enumerate() {
7813 if i > 0 {
7814 self.write(", ");
7815 }
7816 self.generate_expression(expr)?;
7817 }
7818 }
7819
7820 Ok(())
7821 }
7822
7823 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7826 let saved_athena_hive_context = self.athena_hive_context;
7830 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7831 if matches!(
7832 self.config.dialect,
7833 Some(crate::dialects::DialectType::Athena)
7834 ) {
7835 let is_external = ct
7839 .table_modifier
7840 .as_ref()
7841 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7842 .unwrap_or(false);
7843 let has_as_select = ct.as_select.is_some();
7844 self.athena_hive_context = is_external || !has_as_select;
7845 }
7846
7847 if matches!(
7849 self.config.dialect,
7850 Some(crate::dialects::DialectType::TSQL)
7851 ) {
7852 if let Some(ref query) = ct.as_select {
7853 if let Some(with_cte) = &ct.with_cte {
7855 self.generate_with(with_cte)?;
7856 self.write_space();
7857 }
7858
7859 self.write_keyword("SELECT");
7861 self.write(" * ");
7862 self.write_keyword("INTO");
7863 self.write_space();
7864
7865 if ct.temporary {
7867 self.write("#");
7868 }
7869 self.generate_table(&ct.name)?;
7870
7871 self.write_space();
7872 self.write_keyword("FROM");
7873 self.write(" (");
7874 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7876 self.generate_expression(&aliased_query)?;
7877 self.write(") ");
7878 self.write_keyword("AS");
7879 self.write(" temp");
7880 return Ok(());
7881 }
7882 }
7883
7884 if let Some(with_cte) = &ct.with_cte {
7886 self.generate_with(with_cte)?;
7887 self.write_space();
7888 }
7889
7890 for comment in &ct.leading_comments {
7892 self.write_formatted_comment(comment);
7893 self.write(" ");
7894 }
7895 self.write_keyword("CREATE");
7896
7897 if ct.or_replace {
7898 self.write_space();
7899 self.write_keyword("OR REPLACE");
7900 }
7901
7902 if ct.temporary {
7903 self.write_space();
7904 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7906 self.write_keyword("GLOBAL TEMPORARY");
7907 } else {
7908 self.write_keyword("TEMPORARY");
7909 }
7910 }
7911
7912 let is_dictionary = ct
7914 .table_modifier
7915 .as_ref()
7916 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7917 .unwrap_or(false);
7918 if let Some(ref modifier) = ct.table_modifier {
7919 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7921 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7922 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7924 || modifier.eq_ignore_ascii_case("SET")
7925 || modifier.eq_ignore_ascii_case("MULTISET")
7926 || modifier.to_ascii_uppercase().contains("VOLATILE")
7927 || modifier.to_ascii_uppercase().starts_with("SET ")
7928 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
7929 let skip_teradata =
7930 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7931 if !skip_transient && !skip_teradata {
7932 self.write_space();
7933 self.write_keyword(modifier);
7934 }
7935 }
7936
7937 if !is_dictionary {
7938 self.write_space();
7939 self.write_keyword("TABLE");
7940 }
7941
7942 if ct.if_not_exists {
7943 self.write_space();
7944 self.write_keyword("IF NOT EXISTS");
7945 }
7946
7947 self.write_space();
7948 self.generate_table(&ct.name)?;
7949
7950 if let Some(ref uuid) = ct.uuid {
7952 self.write_space();
7953 self.write_keyword("UUID");
7954 self.write(" '");
7955 self.write(uuid);
7956 self.write("'");
7957 }
7958
7959 if let Some(ref on_cluster) = ct.on_cluster {
7961 self.write_space();
7962 self.generate_on_cluster(on_cluster)?;
7963 }
7964
7965 if matches!(
7967 self.config.dialect,
7968 Some(crate::dialects::DialectType::Teradata)
7969 ) && !ct.teradata_post_name_options.is_empty()
7970 {
7971 for opt in &ct.teradata_post_name_options {
7972 self.write(", ");
7973 self.write(opt);
7974 }
7975 }
7976
7977 if ct.copy_grants {
7979 self.write_space();
7980 self.write_keyword("COPY GRANTS");
7981 }
7982
7983 if let Some(ref using_template) = ct.using_template {
7985 self.write_space();
7986 self.write_keyword("USING TEMPLATE");
7987 self.write_space();
7988 self.generate_expression(using_template)?;
7989 return Ok(());
7990 }
7991
7992 if is_clickhouse {
7996 if let Some(ref clone_source) = ct.clone_source {
7997 if ct.columns.is_empty() && ct.constraints.is_empty() {
7998 self.write_space();
7999 self.write_keyword("AS");
8000 self.write_space();
8001 self.generate_table(clone_source)?;
8002 }
8003 }
8004 }
8005
8006 if !is_clickhouse {
8008 if let Some(ref clone_source) = ct.clone_source {
8009 self.write_space();
8010 if ct.is_copy && self.config.supports_table_copy {
8011 self.write_keyword("COPY");
8013 } else if ct.shallow_clone {
8014 self.write_keyword("SHALLOW CLONE");
8015 } else if ct.deep_clone {
8016 self.write_keyword("DEEP CLONE");
8017 } else {
8018 self.write_keyword("CLONE");
8019 }
8020 self.write_space();
8021 self.generate_table(clone_source)?;
8022 if let Some(ref at_clause) = ct.clone_at_clause {
8024 self.write_space();
8025 self.generate_expression(at_clause)?;
8026 }
8027 return Ok(());
8028 }
8029 }
8030
8031 if let Some(ref partition_of) = ct.partition_of {
8035 self.write_space();
8036
8037 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
8039 self.write_keyword("PARTITION OF");
8041 self.write_space();
8042 self.generate_expression(&pop.this)?;
8043
8044 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8046 self.write(" (");
8047 let mut first = true;
8048 for col in &ct.columns {
8049 if !first {
8050 self.write(", ");
8051 }
8052 first = false;
8053 self.generate_column_def(col)?;
8054 }
8055 for constraint in &ct.constraints {
8056 if !first {
8057 self.write(", ");
8058 }
8059 first = false;
8060 self.generate_table_constraint(constraint)?;
8061 }
8062 self.write(")");
8063 }
8064
8065 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
8067 self.write_space();
8068 self.write_keyword("FOR VALUES");
8069 self.write_space();
8070 self.generate_expression(&pop.expression)?;
8071 } else {
8072 self.write_space();
8073 self.write_keyword("DEFAULT");
8074 }
8075 } else {
8076 self.generate_expression(partition_of)?;
8078
8079 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
8081 self.write(" (");
8082 let mut first = true;
8083 for col in &ct.columns {
8084 if !first {
8085 self.write(", ");
8086 }
8087 first = false;
8088 self.generate_column_def(col)?;
8089 }
8090 for constraint in &ct.constraints {
8091 if !first {
8092 self.write(", ");
8093 }
8094 first = false;
8095 self.generate_table_constraint(constraint)?;
8096 }
8097 self.write(")");
8098 }
8099 }
8100
8101 for prop in &ct.properties {
8103 self.write_space();
8104 self.generate_expression(prop)?;
8105 }
8106
8107 return Ok(());
8108 }
8109
8110 self.sqlite_inline_pk_columns.clear();
8113 if matches!(
8114 self.config.dialect,
8115 Some(crate::dialects::DialectType::SQLite)
8116 ) {
8117 for constraint in &ct.constraints {
8118 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8119 if columns.len() == 1 && name.is_none() {
8121 let pk_col_name = columns[0].name.to_ascii_lowercase();
8122 if ct
8124 .columns
8125 .iter()
8126 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
8127 {
8128 self.sqlite_inline_pk_columns.insert(pk_col_name);
8129 }
8130 }
8131 }
8132 }
8133 }
8134
8135 if !ct.columns.is_empty() {
8137 if self.config.pretty {
8138 self.write(" (");
8140 self.write_newline();
8141 self.indent_level += 1;
8142 for (i, col) in ct.columns.iter().enumerate() {
8143 if i > 0 {
8144 self.write(",");
8145 self.write_newline();
8146 }
8147 self.write_indent();
8148 self.generate_column_def(col)?;
8149 }
8150 for constraint in &ct.constraints {
8152 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8154 if columns.len() == 1
8155 && name.is_none()
8156 && self
8157 .sqlite_inline_pk_columns
8158 .contains(&columns[0].name.to_ascii_lowercase())
8159 {
8160 continue;
8161 }
8162 }
8163 self.write(",");
8164 self.write_newline();
8165 self.write_indent();
8166 self.generate_table_constraint(constraint)?;
8167 }
8168 self.indent_level -= 1;
8169 self.write_newline();
8170 self.write(")");
8171 } else {
8172 self.write(" (");
8173 for (i, col) in ct.columns.iter().enumerate() {
8174 if i > 0 {
8175 self.write(", ");
8176 }
8177 self.generate_column_def(col)?;
8178 }
8179 let mut first_constraint = true;
8181 for constraint in &ct.constraints {
8182 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
8184 if columns.len() == 1
8185 && name.is_none()
8186 && self
8187 .sqlite_inline_pk_columns
8188 .contains(&columns[0].name.to_ascii_lowercase())
8189 {
8190 continue;
8191 }
8192 }
8193 if first_constraint {
8194 self.write(", ");
8195 first_constraint = false;
8196 } else {
8197 self.write(", ");
8198 }
8199 self.generate_table_constraint(constraint)?;
8200 }
8201 self.write(")");
8202 }
8203 } else if !ct.constraints.is_empty() {
8204 let has_like_only = ct
8206 .constraints
8207 .iter()
8208 .all(|c| matches!(c, TableConstraint::Like { .. }));
8209 let has_tags_only = ct
8210 .constraints
8211 .iter()
8212 .all(|c| matches!(c, TableConstraint::Tags(_)));
8213 let is_pg_like = matches!(
8217 self.config.dialect,
8218 Some(crate::dialects::DialectType::PostgreSQL)
8219 | Some(crate::dialects::DialectType::CockroachDB)
8220 | Some(crate::dialects::DialectType::Materialize)
8221 | Some(crate::dialects::DialectType::RisingWave)
8222 | Some(crate::dialects::DialectType::Redshift)
8223 | Some(crate::dialects::DialectType::Presto)
8224 | Some(crate::dialects::DialectType::Trino)
8225 | Some(crate::dialects::DialectType::Athena)
8226 );
8227 let use_parens = if has_like_only {
8228 is_pg_like
8229 } else {
8230 !has_tags_only
8231 };
8232 if self.config.pretty && use_parens {
8233 self.write(" (");
8234 self.write_newline();
8235 self.indent_level += 1;
8236 for (i, constraint) in ct.constraints.iter().enumerate() {
8237 if i > 0 {
8238 self.write(",");
8239 self.write_newline();
8240 }
8241 self.write_indent();
8242 self.generate_table_constraint(constraint)?;
8243 }
8244 self.indent_level -= 1;
8245 self.write_newline();
8246 self.write(")");
8247 } else {
8248 if use_parens {
8249 self.write(" (");
8250 } else {
8251 self.write_space();
8252 }
8253 for (i, constraint) in ct.constraints.iter().enumerate() {
8254 if i > 0 {
8255 self.write(", ");
8256 }
8257 self.generate_table_constraint(constraint)?;
8258 }
8259 if use_parens {
8260 self.write(")");
8261 }
8262 }
8263 }
8264
8265 if is_clickhouse && (!ct.columns.is_empty() || !ct.constraints.is_empty()) {
8266 if let Some(ref clone_source) = ct.clone_source {
8267 self.write_space();
8268 self.write_keyword("AS");
8269 self.write_space();
8270 self.generate_table(clone_source)?;
8271 }
8272 }
8273
8274 if let Some(ref on_prop) = ct.on_property {
8276 self.write(" ");
8277 self.write_keyword("ON");
8278 self.write(" ");
8279 self.generate_expression(&on_prop.this)?;
8280 }
8281
8282 if !ct.with_partition_columns.is_empty() {
8284 if self.config.pretty {
8285 self.write_newline();
8286 } else {
8287 self.write_space();
8288 }
8289 self.write_keyword("WITH PARTITION COLUMNS");
8290 self.write(" (");
8291 if self.config.pretty {
8292 self.write_newline();
8293 self.indent_level += 1;
8294 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8295 if i > 0 {
8296 self.write(",");
8297 self.write_newline();
8298 }
8299 self.write_indent();
8300 self.generate_column_def(col)?;
8301 }
8302 self.indent_level -= 1;
8303 self.write_newline();
8304 } else {
8305 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8306 if i > 0 {
8307 self.write(", ");
8308 }
8309 self.generate_column_def(col)?;
8310 }
8311 }
8312 self.write(")");
8313 }
8314
8315 if let Some(ref conn) = ct.with_connection {
8317 if self.config.pretty {
8318 self.write_newline();
8319 } else {
8320 self.write_space();
8321 }
8322 self.write_keyword("WITH CONNECTION");
8323 self.write_space();
8324 self.generate_table(conn)?;
8325 }
8326
8327 if !is_clickhouse {
8330 for prop in &ct.properties {
8331 if let Expression::SchemaCommentProperty(_) = prop {
8332 if self.config.pretty {
8333 self.write_newline();
8334 } else {
8335 self.write_space();
8336 }
8337 self.generate_expression(prop)?;
8338 }
8339 }
8340 }
8341
8342 if !ct.with_properties.is_empty() {
8344 let is_snowflake_special_table = matches!(
8346 self.config.dialect,
8347 Some(crate::dialects::DialectType::Snowflake)
8348 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8349 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8350 if is_snowflake_special_table {
8351 for (key, value) in &ct.with_properties {
8352 self.write_space();
8353 self.write(key);
8354 self.write("=");
8355 self.write(value);
8356 }
8357 } else if self.config.pretty {
8358 self.write_newline();
8359 self.write_keyword("WITH");
8360 self.write(" (");
8361 self.write_newline();
8362 self.indent_level += 1;
8363 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8364 if i > 0 {
8365 self.write(",");
8366 self.write_newline();
8367 }
8368 self.write_indent();
8369 self.write(key);
8370 self.write("=");
8371 self.write(value);
8372 }
8373 self.indent_level -= 1;
8374 self.write_newline();
8375 self.write(")");
8376 } else {
8377 self.write_space();
8378 self.write_keyword("WITH");
8379 self.write(" (");
8380 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8381 if i > 0 {
8382 self.write(", ");
8383 }
8384 self.write(key);
8385 self.write("=");
8386 self.write(value);
8387 }
8388 self.write(")");
8389 }
8390 }
8391
8392 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8393 if is_clickhouse && ct.as_select.is_some() {
8394 let mut pre = Vec::new();
8395 let mut post = Vec::new();
8396 for prop in &ct.properties {
8397 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8398 post.push(prop);
8399 } else {
8400 pre.push(prop);
8401 }
8402 }
8403 (pre, post)
8404 } else {
8405 (ct.properties.iter().collect(), Vec::new())
8406 };
8407
8408 for prop in pre_as_properties {
8410 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8412 continue;
8413 }
8414 if self.config.pretty {
8415 self.write_newline();
8416 } else {
8417 self.write_space();
8418 }
8419 if let Expression::Properties(props) = prop {
8423 let is_hive_dialect = matches!(
8424 self.config.dialect,
8425 Some(crate::dialects::DialectType::Hive)
8426 | Some(crate::dialects::DialectType::Spark)
8427 | Some(crate::dialects::DialectType::Databricks)
8428 | Some(crate::dialects::DialectType::Athena)
8429 );
8430 let is_doris_starrocks = matches!(
8431 self.config.dialect,
8432 Some(crate::dialects::DialectType::Doris)
8433 | Some(crate::dialects::DialectType::StarRocks)
8434 );
8435 if is_hive_dialect {
8436 self.generate_tblproperties_clause(&props.expressions)?;
8437 } else if is_doris_starrocks {
8438 self.generate_properties_clause(&props.expressions)?;
8439 } else {
8440 self.generate_options_clause(&props.expressions)?;
8441 }
8442 } else {
8443 self.generate_expression(prop)?;
8444 }
8445 }
8446
8447 for prop in &ct.post_table_properties {
8449 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
8450 self.write(" WITH(");
8451 self.generate_system_versioning_content(svp)?;
8452 self.write(")");
8453 } else if let Expression::Properties(props) = prop {
8454 let is_doris_starrocks = matches!(
8456 self.config.dialect,
8457 Some(crate::dialects::DialectType::Doris)
8458 | Some(crate::dialects::DialectType::StarRocks)
8459 );
8460 self.write_space();
8461 if is_doris_starrocks {
8462 self.generate_properties_clause(&props.expressions)?;
8463 } else {
8464 self.generate_options_clause(&props.expressions)?;
8465 }
8466 } else {
8467 self.write_space();
8468 self.generate_expression(prop)?;
8469 }
8470 }
8471
8472 if let Some(ref rollup) = ct.rollup {
8475 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
8476 self.write_space();
8477 self.generate_rollup_property(rollup)?;
8478 }
8479 }
8480
8481 let is_mysql_compatible = matches!(
8485 self.config.dialect,
8486 Some(DialectType::MySQL)
8487 | Some(DialectType::SingleStore)
8488 | Some(DialectType::Doris)
8489 | Some(DialectType::StarRocks)
8490 | None
8491 );
8492 let is_hive_compatible = matches!(
8493 self.config.dialect,
8494 Some(DialectType::Hive)
8495 | Some(DialectType::Spark)
8496 | Some(DialectType::Databricks)
8497 | Some(DialectType::Athena)
8498 );
8499 let mysql_pretty_options =
8500 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
8501 for (key, value) in &ct.mysql_table_options {
8502 let should_output = if is_mysql_compatible {
8504 true
8505 } else if is_hive_compatible && key == "COMMENT" {
8506 true } else {
8508 false
8509 };
8510 if should_output {
8511 if mysql_pretty_options {
8512 self.write_newline();
8513 self.write_indent();
8514 } else {
8515 self.write_space();
8516 }
8517 self.write_keyword(key);
8518 if key == "COMMENT" && !self.config.schema_comment_with_eq {
8520 self.write_space();
8521 } else {
8522 self.write("=");
8523 }
8524 self.write(value);
8525 }
8526 }
8527
8528 if ct.temporary
8530 && matches!(
8531 self.config.dialect,
8532 Some(DialectType::Spark) | Some(DialectType::Databricks)
8533 )
8534 && ct.as_select.is_none()
8535 {
8536 self.write_space();
8537 self.write_keyword("USING PARQUET");
8538 }
8539
8540 if !ct.inherits.is_empty() {
8542 self.write_space();
8543 self.write_keyword("INHERITS");
8544 self.write(" (");
8545 for (i, parent) in ct.inherits.iter().enumerate() {
8546 if i > 0 {
8547 self.write(", ");
8548 }
8549 self.generate_table(parent)?;
8550 }
8551 self.write(")");
8552 }
8553
8554 if let Some(ref query) = ct.as_select {
8556 self.write_space();
8557 self.write_keyword("AS");
8558 self.write_space();
8559 let source_is_clickhouse =
8560 matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
8561 let wrap_as_select =
8562 ct.as_select_parenthesized && !(is_clickhouse && source_is_clickhouse);
8563 if wrap_as_select {
8564 self.write("(");
8565 }
8566 self.generate_expression(query)?;
8567 if wrap_as_select {
8568 self.write(")");
8569 }
8570
8571 if let Some(with_data) = ct.with_data {
8573 self.write_space();
8574 self.write_keyword("WITH");
8575 if !with_data {
8576 self.write_space();
8577 self.write_keyword("NO");
8578 }
8579 self.write_space();
8580 self.write_keyword("DATA");
8581 }
8582
8583 if let Some(with_statistics) = ct.with_statistics {
8585 self.write_space();
8586 self.write_keyword("AND");
8587 if !with_statistics {
8588 self.write_space();
8589 self.write_keyword("NO");
8590 }
8591 self.write_space();
8592 self.write_keyword("STATISTICS");
8593 }
8594
8595 for index in &ct.teradata_indexes {
8597 self.write_space();
8598 match index.kind {
8599 TeradataIndexKind::NoPrimary => {
8600 self.write_keyword("NO PRIMARY INDEX");
8601 }
8602 TeradataIndexKind::Primary => {
8603 self.write_keyword("PRIMARY INDEX");
8604 }
8605 TeradataIndexKind::PrimaryAmp => {
8606 self.write_keyword("PRIMARY AMP INDEX");
8607 }
8608 TeradataIndexKind::Unique => {
8609 self.write_keyword("UNIQUE INDEX");
8610 }
8611 TeradataIndexKind::UniquePrimary => {
8612 self.write_keyword("UNIQUE PRIMARY INDEX");
8613 }
8614 TeradataIndexKind::Secondary => {
8615 self.write_keyword("INDEX");
8616 }
8617 }
8618 if let Some(ref name) = index.name {
8620 self.write_space();
8621 self.write(name);
8622 }
8623 if !index.columns.is_empty() {
8625 self.write(" (");
8626 for (i, col) in index.columns.iter().enumerate() {
8627 if i > 0 {
8628 self.write(", ");
8629 }
8630 self.write(col);
8631 }
8632 self.write(")");
8633 }
8634 }
8635
8636 if let Some(ref on_commit) = ct.on_commit {
8638 self.write_space();
8639 self.write_keyword("ON COMMIT");
8640 self.write_space();
8641 match on_commit {
8642 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8643 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8644 }
8645 }
8646
8647 if !post_as_properties.is_empty() {
8648 for prop in post_as_properties {
8649 self.write_space();
8650 self.generate_expression(prop)?;
8651 }
8652 }
8653
8654 self.athena_hive_context = saved_athena_hive_context;
8656 return Ok(());
8657 }
8658
8659 if let Some(ref on_commit) = ct.on_commit {
8661 self.write_space();
8662 self.write_keyword("ON COMMIT");
8663 self.write_space();
8664 match on_commit {
8665 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8666 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8667 }
8668 }
8669
8670 self.athena_hive_context = saved_athena_hive_context;
8672
8673 Ok(())
8674 }
8675
8676 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8679 self.generate_identifier(&col.name)?;
8681 if !matches!(col.data_type, DataType::Unknown) {
8683 self.write_space();
8684 self.generate_data_type(&col.data_type)?;
8685 }
8686 for constraint in &col.constraints {
8688 if let ColumnConstraint::Path(path_expr) = constraint {
8689 self.write_space();
8690 self.write_keyword("PATH");
8691 self.write_space();
8692 self.generate_expression(path_expr)?;
8693 }
8694 }
8695 Ok(())
8696 }
8697
8698 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8699 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8701 && col
8702 .constraints
8703 .iter()
8704 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8705 let omit_computed_type = !self.config.computed_column_with_type
8707 && col
8708 .constraints
8709 .iter()
8710 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8711
8712 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8715
8716 let has_no_type = col.no_type
8719 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8720 && col.constraints.is_empty());
8721
8722 self.generate_identifier(&col.name)?;
8723
8724 let serial_expansion = if matches!(
8726 self.config.dialect,
8727 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
8728 ) {
8729 if let DataType::Custom { ref name } = col.data_type {
8730 if name.eq_ignore_ascii_case("SERIAL") {
8731 Some("INT")
8732 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
8733 Some("BIGINT")
8734 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
8735 Some("SMALLINT")
8736 } else {
8737 None
8738 }
8739 } else {
8740 None
8741 }
8742 } else {
8743 None
8744 };
8745
8746 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
8747 {
8748 self.write_space();
8749 let saved_nullable_depth = self.clickhouse_nullable_depth;
8752 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
8753 self.clickhouse_nullable_depth = -1;
8754 }
8755 if let Some(int_type) = serial_expansion {
8756 self.write_keyword(int_type);
8758 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8759 let unsigned_type = match &col.data_type {
8761 DataType::Int { .. } => Some("UINTEGER"),
8762 DataType::BigInt { .. } => Some("UBIGINT"),
8763 DataType::SmallInt { .. } => Some("USMALLINT"),
8764 DataType::TinyInt { .. } => Some("UTINYINT"),
8765 _ => None,
8766 };
8767 if let Some(utype) = unsigned_type {
8768 self.write_keyword(utype);
8769 } else {
8770 self.generate_data_type(&col.data_type)?;
8771 }
8772 } else {
8773 self.generate_data_type(&col.data_type)?;
8774 }
8775 self.clickhouse_nullable_depth = saved_nullable_depth;
8776 }
8777
8778 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8781 self.write_space();
8782 self.write_keyword("UNSIGNED");
8783 }
8784 if col.zerofill {
8785 self.write_space();
8786 self.write_keyword("ZEROFILL");
8787 }
8788
8789 if let Some(ref charset) = col.character_set {
8793 self.write_space();
8794 self.write_keyword("CHARACTER SET");
8795 self.write_space();
8796 self.write(charset);
8797 }
8798
8799 if col.uppercase {
8800 self.write_space();
8801 self.write_keyword("UPPERCASE");
8802 }
8803
8804 if let Some(casespecific) = col.casespecific {
8805 self.write_space();
8806 if casespecific {
8807 self.write_keyword("CASESPECIFIC");
8808 } else {
8809 self.write_keyword("NOT CASESPECIFIC");
8810 }
8811 }
8812
8813 if let Some(ref format) = col.format {
8814 self.write_space();
8815 self.write_keyword("FORMAT");
8816 self.write(" '");
8817 self.write(format);
8818 self.write("'");
8819 }
8820
8821 if let Some(ref title) = col.title {
8822 self.write_space();
8823 self.write_keyword("TITLE");
8824 self.write(" '");
8825 self.write(title);
8826 self.write("'");
8827 }
8828
8829 if let Some(length) = col.inline_length {
8830 self.write_space();
8831 self.write_keyword("INLINE LENGTH");
8832 self.write(" ");
8833 self.write(&length.to_string());
8834 }
8835
8836 if let Some(ref compress) = col.compress {
8837 self.write_space();
8838 self.write_keyword("COMPRESS");
8839 if !compress.is_empty() {
8840 if compress.len() == 1 {
8842 if let Expression::Literal(lit) = &compress[0] {
8843 if let Literal::String(_) = lit.as_ref() {
8844 self.write_space();
8845 self.generate_expression(&compress[0])?;
8846 }
8847 } else {
8848 self.write(" (");
8849 self.generate_expression(&compress[0])?;
8850 self.write(")");
8851 }
8852 } else {
8853 self.write(" (");
8854 for (i, val) in compress.iter().enumerate() {
8855 if i > 0 {
8856 self.write(", ");
8857 }
8858 self.generate_expression(val)?;
8859 }
8860 self.write(")");
8861 }
8862 }
8863 }
8864
8865 if !col.constraint_order.is_empty() {
8868 let mut references_idx = 0;
8871 let mut check_idx = 0;
8872 let mut generated_idx = 0;
8873 let mut collate_idx = 0;
8874 let mut comment_idx = 0;
8875 let defer_not_null_after_identity = false;
8878 let mut pending_not_null_after_identity = false;
8879
8880 for constraint_type in &col.constraint_order {
8881 match constraint_type {
8882 ConstraintType::PrimaryKey => {
8883 if col.primary_key
8885 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8886 {
8887 if let Some(ref cname) = col.primary_key_constraint_name {
8888 self.write_space();
8889 self.write_keyword("CONSTRAINT");
8890 self.write_space();
8891 self.write(cname);
8892 }
8893 self.write_space();
8894 self.write_keyword("PRIMARY KEY");
8895 if let Some(ref order) = col.primary_key_order {
8896 self.write_space();
8897 match order {
8898 SortOrder::Asc => self.write_keyword("ASC"),
8899 SortOrder::Desc => self.write_keyword("DESC"),
8900 }
8901 }
8902 }
8903 }
8904 ConstraintType::Unique => {
8905 if col.unique {
8906 if let Some(ref cname) = col.unique_constraint_name {
8907 self.write_space();
8908 self.write_keyword("CONSTRAINT");
8909 self.write_space();
8910 self.write(cname);
8911 }
8912 self.write_space();
8913 self.write_keyword("UNIQUE");
8914 if col.unique_nulls_not_distinct {
8916 self.write(" NULLS NOT DISTINCT");
8917 }
8918 }
8919 }
8920 ConstraintType::NotNull => {
8921 if col.nullable == Some(false) {
8922 if defer_not_null_after_identity {
8923 pending_not_null_after_identity = true;
8924 continue;
8925 }
8926 if let Some(ref cname) = col.not_null_constraint_name {
8927 self.write_space();
8928 self.write_keyword("CONSTRAINT");
8929 self.write_space();
8930 self.write(cname);
8931 }
8932 self.write_space();
8933 self.write_keyword("NOT NULL");
8934 }
8935 }
8936 ConstraintType::Null => {
8937 if col.nullable == Some(true) {
8938 self.write_space();
8939 self.write_keyword("NULL");
8940 }
8941 }
8942 ConstraintType::Default => {
8943 if let Some(ref default) = col.default {
8944 self.write_space();
8945 self.write_keyword("DEFAULT");
8946 self.write_space();
8947 self.generate_expression(default)?;
8948 }
8949 }
8950 ConstraintType::AutoIncrement => {
8951 if col.auto_increment {
8952 if matches!(
8954 self.config.dialect,
8955 Some(crate::dialects::DialectType::DuckDB)
8956 ) {
8957 } else if matches!(
8959 self.config.dialect,
8960 Some(crate::dialects::DialectType::Materialize)
8961 ) {
8962 if !matches!(col.nullable, Some(false)) {
8964 self.write_space();
8965 self.write_keyword("NOT NULL");
8966 }
8967 } else if matches!(
8968 self.config.dialect,
8969 Some(crate::dialects::DialectType::PostgreSQL)
8970 ) {
8971 self.write_space();
8973 self.generate_auto_increment_keyword(col)?;
8974 } else if matches!(
8975 self.config.dialect,
8976 Some(crate::dialects::DialectType::SQLite)
8977 ) && !col.primary_key
8978 && self
8979 .sqlite_inline_pk_columns
8980 .contains(&col.name.name.to_ascii_lowercase())
8981 {
8982 } else {
8985 self.write_space();
8986 self.generate_auto_increment_keyword(col)?;
8987 if pending_not_null_after_identity {
8988 self.write_space();
8989 self.write_keyword("NOT NULL");
8990 pending_not_null_after_identity = false;
8991 }
8992 }
8993 } }
8995 ConstraintType::References => {
8996 while references_idx < col.constraints.len() {
8998 if let ColumnConstraint::References(fk_ref) =
8999 &col.constraints[references_idx]
9000 {
9001 if let Some(ref name) = fk_ref.constraint_name {
9003 self.write_space();
9004 self.write_keyword("CONSTRAINT");
9005 self.write_space();
9006 self.write(name);
9007 }
9008 self.write_space();
9009 if fk_ref.has_foreign_key_keywords {
9010 self.write_keyword("FOREIGN KEY");
9011 self.write_space();
9012 }
9013 self.write_keyword("REFERENCES");
9014 self.write_space();
9015 self.generate_table(&fk_ref.table)?;
9016 if !fk_ref.columns.is_empty() {
9017 self.write(" (");
9018 for (i, c) in fk_ref.columns.iter().enumerate() {
9019 if i > 0 {
9020 self.write(", ");
9021 }
9022 self.generate_identifier(c)?;
9023 }
9024 self.write(")");
9025 }
9026 self.generate_referential_actions(fk_ref)?;
9027 references_idx += 1;
9028 break;
9029 }
9030 references_idx += 1;
9031 }
9032 }
9033 ConstraintType::Check => {
9034 while check_idx < col.constraints.len() {
9036 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
9037 if check_idx == 0 {
9039 if let Some(ref cname) = col.check_constraint_name {
9040 self.write_space();
9041 self.write_keyword("CONSTRAINT");
9042 self.write_space();
9043 self.write(cname);
9044 }
9045 }
9046 self.write_space();
9047 self.write_keyword("CHECK");
9048 self.write(" (");
9049 self.generate_expression(expr)?;
9050 self.write(")");
9051 check_idx += 1;
9052 break;
9053 }
9054 check_idx += 1;
9055 }
9056 }
9057 ConstraintType::GeneratedAsIdentity => {
9058 while generated_idx < col.constraints.len() {
9060 if let ColumnConstraint::GeneratedAsIdentity(gen) =
9061 &col.constraints[generated_idx]
9062 {
9063 self.write_space();
9064 if matches!(
9066 self.config.dialect,
9067 Some(crate::dialects::DialectType::Redshift)
9068 ) {
9069 self.write_keyword("IDENTITY");
9070 self.write("(");
9071 if let Some(ref start) = gen.start {
9072 self.generate_expression(start)?;
9073 } else {
9074 self.write("0");
9075 }
9076 self.write(", ");
9077 if let Some(ref incr) = gen.increment {
9078 self.generate_expression(incr)?;
9079 } else {
9080 self.write("1");
9081 }
9082 self.write(")");
9083 } else {
9084 self.write_keyword("GENERATED");
9085 if gen.always {
9086 self.write_space();
9087 self.write_keyword("ALWAYS");
9088 } else {
9089 self.write_space();
9090 self.write_keyword("BY DEFAULT");
9091 if gen.on_null {
9092 self.write_space();
9093 self.write_keyword("ON NULL");
9094 }
9095 }
9096 self.write_space();
9097 self.write_keyword("AS IDENTITY");
9098
9099 let has_options = gen.start.is_some()
9100 || gen.increment.is_some()
9101 || gen.minvalue.is_some()
9102 || gen.maxvalue.is_some()
9103 || gen.cycle.is_some();
9104 if has_options {
9105 self.write(" (");
9106 let mut first = true;
9107 if let Some(ref start) = gen.start {
9108 if !first {
9109 self.write(" ");
9110 }
9111 first = false;
9112 self.write_keyword("START WITH");
9113 self.write_space();
9114 self.generate_expression(start)?;
9115 }
9116 if let Some(ref incr) = gen.increment {
9117 if !first {
9118 self.write(" ");
9119 }
9120 first = false;
9121 self.write_keyword("INCREMENT BY");
9122 self.write_space();
9123 self.generate_expression(incr)?;
9124 }
9125 if let Some(ref minv) = gen.minvalue {
9126 if !first {
9127 self.write(" ");
9128 }
9129 first = false;
9130 self.write_keyword("MINVALUE");
9131 self.write_space();
9132 self.generate_expression(minv)?;
9133 }
9134 if let Some(ref maxv) = gen.maxvalue {
9135 if !first {
9136 self.write(" ");
9137 }
9138 first = false;
9139 self.write_keyword("MAXVALUE");
9140 self.write_space();
9141 self.generate_expression(maxv)?;
9142 }
9143 if let Some(cycle) = gen.cycle {
9144 if !first {
9145 self.write(" ");
9146 }
9147 if cycle {
9148 self.write_keyword("CYCLE");
9149 } else {
9150 self.write_keyword("NO CYCLE");
9151 }
9152 }
9153 self.write(")");
9154 }
9155 }
9156 generated_idx += 1;
9157 break;
9158 }
9159 generated_idx += 1;
9160 }
9161 }
9162 ConstraintType::Collate => {
9163 while collate_idx < col.constraints.len() {
9165 if let ColumnConstraint::Collate(collation) =
9166 &col.constraints[collate_idx]
9167 {
9168 self.write_space();
9169 self.write_keyword("COLLATE");
9170 self.write_space();
9171 self.generate_identifier(collation)?;
9172 collate_idx += 1;
9173 break;
9174 }
9175 collate_idx += 1;
9176 }
9177 }
9178 ConstraintType::Comment => {
9179 while comment_idx < col.constraints.len() {
9181 if let ColumnConstraint::Comment(comment) =
9182 &col.constraints[comment_idx]
9183 {
9184 self.write_space();
9185 self.write_keyword("COMMENT");
9186 self.write_space();
9187 self.generate_string_literal(comment)?;
9188 comment_idx += 1;
9189 break;
9190 }
9191 comment_idx += 1;
9192 }
9193 }
9194 ConstraintType::Tags => {
9195 for constraint in &col.constraints {
9197 if let ColumnConstraint::Tags(tags) = constraint {
9198 self.write_space();
9199 self.write_keyword("TAG");
9200 self.write(" (");
9201 for (i, expr) in tags.expressions.iter().enumerate() {
9202 if i > 0 {
9203 self.write(", ");
9204 }
9205 self.generate_expression(expr)?;
9206 }
9207 self.write(")");
9208 break;
9209 }
9210 }
9211 }
9212 ConstraintType::ComputedColumn => {
9213 for constraint in &col.constraints {
9215 if let ColumnConstraint::ComputedColumn(cc) = constraint {
9216 self.write_space();
9217 self.generate_computed_column_inline(cc)?;
9218 break;
9219 }
9220 }
9221 }
9222 ConstraintType::GeneratedAsRow => {
9223 for constraint in &col.constraints {
9225 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
9226 self.write_space();
9227 self.generate_generated_as_row_inline(gar)?;
9228 break;
9229 }
9230 }
9231 }
9232 ConstraintType::OnUpdate => {
9233 if let Some(ref expr) = col.on_update {
9234 self.write_space();
9235 self.write_keyword("ON UPDATE");
9236 self.write_space();
9237 self.generate_expression(expr)?;
9238 }
9239 }
9240 ConstraintType::Encode => {
9241 if let Some(ref encoding) = col.encoding {
9242 self.write_space();
9243 self.write_keyword("ENCODE");
9244 self.write_space();
9245 self.write(encoding);
9246 }
9247 }
9248 ConstraintType::Path => {
9249 for constraint in &col.constraints {
9251 if let ColumnConstraint::Path(path_expr) = constraint {
9252 self.write_space();
9253 self.write_keyword("PATH");
9254 self.write_space();
9255 self.generate_expression(path_expr)?;
9256 break;
9257 }
9258 }
9259 }
9260 }
9261 }
9262 if pending_not_null_after_identity {
9263 self.write_space();
9264 self.write_keyword("NOT NULL");
9265 }
9266 } else {
9267 if col.primary_key {
9269 self.write_space();
9270 self.write_keyword("PRIMARY KEY");
9271 if let Some(ref order) = col.primary_key_order {
9272 self.write_space();
9273 match order {
9274 SortOrder::Asc => self.write_keyword("ASC"),
9275 SortOrder::Desc => self.write_keyword("DESC"),
9276 }
9277 }
9278 }
9279
9280 if col.unique {
9281 self.write_space();
9282 self.write_keyword("UNIQUE");
9283 if col.unique_nulls_not_distinct {
9285 self.write(" NULLS NOT DISTINCT");
9286 }
9287 }
9288
9289 match col.nullable {
9290 Some(false) => {
9291 self.write_space();
9292 self.write_keyword("NOT NULL");
9293 }
9294 Some(true) => {
9295 self.write_space();
9296 self.write_keyword("NULL");
9297 }
9298 None => {}
9299 }
9300
9301 if let Some(ref default) = col.default {
9302 self.write_space();
9303 self.write_keyword("DEFAULT");
9304 self.write_space();
9305 self.generate_expression(default)?;
9306 }
9307
9308 if col.auto_increment {
9309 self.write_space();
9310 self.generate_auto_increment_keyword(col)?;
9311 }
9312
9313 for constraint in &col.constraints {
9315 match constraint {
9316 ColumnConstraint::References(fk_ref) => {
9317 self.write_space();
9318 if fk_ref.has_foreign_key_keywords {
9319 self.write_keyword("FOREIGN KEY");
9320 self.write_space();
9321 }
9322 self.write_keyword("REFERENCES");
9323 self.write_space();
9324 self.generate_table(&fk_ref.table)?;
9325 if !fk_ref.columns.is_empty() {
9326 self.write(" (");
9327 for (i, c) in fk_ref.columns.iter().enumerate() {
9328 if i > 0 {
9329 self.write(", ");
9330 }
9331 self.generate_identifier(c)?;
9332 }
9333 self.write(")");
9334 }
9335 self.generate_referential_actions(fk_ref)?;
9336 }
9337 ColumnConstraint::Check(expr) => {
9338 self.write_space();
9339 self.write_keyword("CHECK");
9340 self.write(" (");
9341 self.generate_expression(expr)?;
9342 self.write(")");
9343 }
9344 ColumnConstraint::GeneratedAsIdentity(gen) => {
9345 self.write_space();
9346 if matches!(
9348 self.config.dialect,
9349 Some(crate::dialects::DialectType::Redshift)
9350 ) {
9351 self.write_keyword("IDENTITY");
9352 self.write("(");
9353 if let Some(ref start) = gen.start {
9354 self.generate_expression(start)?;
9355 } else {
9356 self.write("0");
9357 }
9358 self.write(", ");
9359 if let Some(ref incr) = gen.increment {
9360 self.generate_expression(incr)?;
9361 } else {
9362 self.write("1");
9363 }
9364 self.write(")");
9365 } else {
9366 self.write_keyword("GENERATED");
9367 if gen.always {
9368 self.write_space();
9369 self.write_keyword("ALWAYS");
9370 } else {
9371 self.write_space();
9372 self.write_keyword("BY DEFAULT");
9373 if gen.on_null {
9374 self.write_space();
9375 self.write_keyword("ON NULL");
9376 }
9377 }
9378 self.write_space();
9379 self.write_keyword("AS IDENTITY");
9380
9381 let has_options = gen.start.is_some()
9382 || gen.increment.is_some()
9383 || gen.minvalue.is_some()
9384 || gen.maxvalue.is_some()
9385 || gen.cycle.is_some();
9386 if has_options {
9387 self.write(" (");
9388 let mut first = true;
9389 if let Some(ref start) = gen.start {
9390 if !first {
9391 self.write(" ");
9392 }
9393 first = false;
9394 self.write_keyword("START WITH");
9395 self.write_space();
9396 self.generate_expression(start)?;
9397 }
9398 if let Some(ref incr) = gen.increment {
9399 if !first {
9400 self.write(" ");
9401 }
9402 first = false;
9403 self.write_keyword("INCREMENT BY");
9404 self.write_space();
9405 self.generate_expression(incr)?;
9406 }
9407 if let Some(ref minv) = gen.minvalue {
9408 if !first {
9409 self.write(" ");
9410 }
9411 first = false;
9412 self.write_keyword("MINVALUE");
9413 self.write_space();
9414 self.generate_expression(minv)?;
9415 }
9416 if let Some(ref maxv) = gen.maxvalue {
9417 if !first {
9418 self.write(" ");
9419 }
9420 first = false;
9421 self.write_keyword("MAXVALUE");
9422 self.write_space();
9423 self.generate_expression(maxv)?;
9424 }
9425 if let Some(cycle) = gen.cycle {
9426 if !first {
9427 self.write(" ");
9428 }
9429 if cycle {
9430 self.write_keyword("CYCLE");
9431 } else {
9432 self.write_keyword("NO CYCLE");
9433 }
9434 }
9435 self.write(")");
9436 }
9437 }
9438 }
9439 ColumnConstraint::Collate(collation) => {
9440 self.write_space();
9441 self.write_keyword("COLLATE");
9442 self.write_space();
9443 self.generate_identifier(collation)?;
9444 }
9445 ColumnConstraint::Comment(comment) => {
9446 self.write_space();
9447 self.write_keyword("COMMENT");
9448 self.write_space();
9449 self.generate_string_literal(comment)?;
9450 }
9451 ColumnConstraint::Path(path_expr) => {
9452 self.write_space();
9453 self.write_keyword("PATH");
9454 self.write_space();
9455 self.generate_expression(path_expr)?;
9456 }
9457 _ => {} }
9459 }
9460
9461 if let Some(ref encoding) = col.encoding {
9463 self.write_space();
9464 self.write_keyword("ENCODE");
9465 self.write_space();
9466 self.write(encoding);
9467 }
9468 }
9469
9470 if let Some(ref codec) = col.codec {
9472 self.write_space();
9473 self.write_keyword("CODEC");
9474 self.write("(");
9475 self.write(codec);
9476 self.write(")");
9477 }
9478
9479 if let Some(visible) = col.visible {
9480 self.write_space();
9481 if visible {
9482 self.write_keyword("VISIBLE");
9483 } else {
9484 self.write_keyword("INVISIBLE");
9485 }
9486 }
9487
9488 if let Some(ref ephemeral) = col.ephemeral {
9490 self.write_space();
9491 self.write_keyword("EPHEMERAL");
9492 if let Some(ref expr) = ephemeral {
9493 self.write_space();
9494 self.generate_expression(expr)?;
9495 }
9496 }
9497
9498 if let Some(ref mat_expr) = col.materialized_expr {
9500 self.write_space();
9501 self.write_keyword("MATERIALIZED");
9502 self.write_space();
9503 self.generate_expression(mat_expr)?;
9504 }
9505
9506 if let Some(ref alias_expr) = col.alias_expr {
9508 self.write_space();
9509 self.write_keyword("ALIAS");
9510 self.write_space();
9511 self.generate_expression(alias_expr)?;
9512 }
9513
9514 if let Some(ref ttl_expr) = col.ttl_expr {
9516 self.write_space();
9517 self.write_keyword("TTL");
9518 self.write_space();
9519 self.generate_expression(ttl_expr)?;
9520 }
9521
9522 if col.not_for_replication
9524 && matches!(
9525 self.config.dialect,
9526 Some(crate::dialects::DialectType::TSQL)
9527 | Some(crate::dialects::DialectType::Fabric)
9528 )
9529 {
9530 self.write_space();
9531 self.write_keyword("NOT FOR REPLICATION");
9532 }
9533
9534 if !col.options.is_empty() {
9536 self.write_space();
9537 self.generate_options_clause(&col.options)?;
9538 }
9539
9540 if !col.primary_key
9543 && self
9544 .sqlite_inline_pk_columns
9545 .contains(&col.name.name.to_ascii_lowercase())
9546 {
9547 self.write_space();
9548 self.write_keyword("PRIMARY KEY");
9549 if matches!(self.config.dialect, Some(DialectType::SQLite)) && col.auto_increment {
9550 self.write_space();
9551 self.generate_auto_increment_keyword(col)?;
9552 }
9553 }
9554
9555 if serial_expansion.is_some() {
9558 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
9559 self.write_space();
9560 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
9561 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
9562 self.write_space();
9563 self.write_keyword("NOT NULL");
9564 }
9565 }
9566
9567 Ok(())
9568 }
9569
9570 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
9571 match constraint {
9572 TableConstraint::PrimaryKey {
9573 name,
9574 columns,
9575 include_columns,
9576 modifiers,
9577 has_constraint_keyword,
9578 } => {
9579 if let Some(ref n) = name {
9580 if *has_constraint_keyword {
9581 self.write_keyword("CONSTRAINT");
9582 self.write_space();
9583 self.generate_identifier(n)?;
9584 self.write_space();
9585 }
9586 }
9587 self.write_keyword("PRIMARY KEY");
9588 if let Some(ref clustered) = modifiers.clustered {
9590 self.write_space();
9591 self.write_keyword(clustered);
9592 }
9593 if let Some(ref n) = name {
9595 if !*has_constraint_keyword {
9596 self.write_space();
9597 self.generate_identifier(n)?;
9598 }
9599 }
9600 self.write(" (");
9601 for (i, col) in columns.iter().enumerate() {
9602 if i > 0 {
9603 self.write(", ");
9604 }
9605 self.generate_identifier(col)?;
9606 }
9607 self.write(")");
9608 if !include_columns.is_empty() {
9609 self.write_space();
9610 self.write_keyword("INCLUDE");
9611 self.write(" (");
9612 for (i, col) in include_columns.iter().enumerate() {
9613 if i > 0 {
9614 self.write(", ");
9615 }
9616 self.generate_identifier(col)?;
9617 }
9618 self.write(")");
9619 }
9620 self.generate_constraint_modifiers(modifiers);
9621 }
9622 TableConstraint::Unique {
9623 name,
9624 columns,
9625 columns_parenthesized,
9626 modifiers,
9627 has_constraint_keyword,
9628 nulls_not_distinct,
9629 } => {
9630 if let Some(ref n) = name {
9631 if *has_constraint_keyword {
9632 self.write_keyword("CONSTRAINT");
9633 self.write_space();
9634 self.generate_identifier(n)?;
9635 self.write_space();
9636 }
9637 }
9638 self.write_keyword("UNIQUE");
9639 if let Some(ref clustered) = modifiers.clustered {
9641 self.write_space();
9642 self.write_keyword(clustered);
9643 }
9644 if *nulls_not_distinct {
9646 self.write(" NULLS NOT DISTINCT");
9647 }
9648 if let Some(ref n) = name {
9650 if !*has_constraint_keyword {
9651 self.write_space();
9652 self.generate_identifier(n)?;
9653 }
9654 }
9655 if *columns_parenthesized {
9656 self.write(" (");
9657 for (i, col) in columns.iter().enumerate() {
9658 if i > 0 {
9659 self.write(", ");
9660 }
9661 self.generate_identifier(col)?;
9662 }
9663 self.write(")");
9664 } else {
9665 for col in columns.iter() {
9667 self.write_space();
9668 self.generate_identifier(col)?;
9669 }
9670 }
9671 self.generate_constraint_modifiers(modifiers);
9672 }
9673 TableConstraint::ForeignKey {
9674 name,
9675 columns,
9676 references,
9677 on_delete,
9678 on_update,
9679 modifiers,
9680 } => {
9681 if let Some(ref n) = name {
9682 self.write_keyword("CONSTRAINT");
9683 self.write_space();
9684 self.generate_identifier(n)?;
9685 self.write_space();
9686 }
9687 self.write_keyword("FOREIGN KEY");
9688 self.write(" (");
9689 for (i, col) in columns.iter().enumerate() {
9690 if i > 0 {
9691 self.write(", ");
9692 }
9693 self.generate_identifier(col)?;
9694 }
9695 self.write(")");
9696 if let Some(ref refs) = references {
9697 self.write(" ");
9698 self.write_keyword("REFERENCES");
9699 self.write_space();
9700 self.generate_table(&refs.table)?;
9701 if !refs.columns.is_empty() {
9702 if self.config.pretty {
9703 self.write(" (");
9704 self.write_newline();
9705 self.indent_level += 1;
9706 for (i, col) in refs.columns.iter().enumerate() {
9707 if i > 0 {
9708 self.write(",");
9709 self.write_newline();
9710 }
9711 self.write_indent();
9712 self.generate_identifier(col)?;
9713 }
9714 self.indent_level -= 1;
9715 self.write_newline();
9716 self.write_indent();
9717 self.write(")");
9718 } else {
9719 self.write(" (");
9720 for (i, col) in refs.columns.iter().enumerate() {
9721 if i > 0 {
9722 self.write(", ");
9723 }
9724 self.generate_identifier(col)?;
9725 }
9726 self.write(")");
9727 }
9728 }
9729 self.generate_referential_actions(refs)?;
9730 } else {
9731 if let Some(ref action) = on_delete {
9733 self.write_space();
9734 self.write_keyword("ON DELETE");
9735 self.write_space();
9736 self.generate_referential_action(action);
9737 }
9738 if let Some(ref action) = on_update {
9739 self.write_space();
9740 self.write_keyword("ON UPDATE");
9741 self.write_space();
9742 self.generate_referential_action(action);
9743 }
9744 }
9745 self.generate_constraint_modifiers(modifiers);
9746 }
9747 TableConstraint::Check {
9748 name,
9749 expression,
9750 modifiers,
9751 } => {
9752 if let Some(ref n) = name {
9753 self.write_keyword("CONSTRAINT");
9754 self.write_space();
9755 self.generate_identifier(n)?;
9756 self.write_space();
9757 }
9758 self.write_keyword("CHECK");
9759 self.write(" (");
9760 self.generate_expression(expression)?;
9761 self.write(")");
9762 self.generate_constraint_modifiers(modifiers);
9763 }
9764 TableConstraint::Assume { name, expression } => {
9765 if let Some(ref n) = name {
9766 self.write_keyword("CONSTRAINT");
9767 self.write_space();
9768 self.generate_identifier(n)?;
9769 self.write_space();
9770 }
9771 self.write_keyword("ASSUME");
9772 self.write(" (");
9773 self.generate_expression(expression)?;
9774 self.write(")");
9775 }
9776 TableConstraint::Default {
9777 name,
9778 expression,
9779 column,
9780 } => {
9781 if let Some(ref n) = name {
9782 self.write_keyword("CONSTRAINT");
9783 self.write_space();
9784 self.generate_identifier(n)?;
9785 self.write_space();
9786 }
9787 self.write_keyword("DEFAULT");
9788 self.write_space();
9789 self.generate_expression(expression)?;
9790 self.write_space();
9791 self.write_keyword("FOR");
9792 self.write_space();
9793 self.generate_identifier(column)?;
9794 }
9795 TableConstraint::Index {
9796 name,
9797 columns,
9798 kind,
9799 modifiers,
9800 use_key_keyword,
9801 expression,
9802 index_type,
9803 granularity,
9804 } => {
9805 if expression.is_some() {
9807 self.write_keyword("INDEX");
9808 if let Some(ref n) = name {
9809 self.write_space();
9810 self.generate_identifier(n)?;
9811 }
9812 if let Some(ref expr) = expression {
9813 self.write_space();
9814 self.generate_expression(expr)?;
9815 }
9816 if let Some(ref idx_type) = index_type {
9817 self.write_space();
9818 self.write_keyword("TYPE");
9819 self.write_space();
9820 self.generate_expression(idx_type)?;
9821 }
9822 if let Some(ref gran) = granularity {
9823 self.write_space();
9824 self.write_keyword("GRANULARITY");
9825 self.write_space();
9826 self.generate_expression(gran)?;
9827 }
9828 } else {
9829 use crate::dialects::DialectType;
9833 let index_keyword = if *use_key_keyword
9834 && !matches!(self.config.dialect, Some(DialectType::MySQL))
9835 {
9836 "KEY"
9837 } else {
9838 "INDEX"
9839 };
9840
9841 if let Some(ref k) = kind {
9843 self.write_keyword(k);
9844 if k != "UNIQUE" {
9846 self.write_space();
9847 self.write_keyword(index_keyword);
9848 }
9849 } else {
9850 self.write_keyword(index_keyword);
9851 }
9852
9853 if modifiers.using_before_columns && name.is_none() {
9855 if let Some(ref using) = modifiers.using {
9856 self.write_space();
9857 self.write_keyword("USING");
9858 self.write_space();
9859 self.write_keyword(using);
9860 }
9861 }
9862
9863 if let Some(ref n) = name {
9865 self.write_space();
9866 self.generate_identifier(n)?;
9867 }
9868
9869 if modifiers.using_before_columns && name.is_some() {
9871 if let Some(ref using) = modifiers.using {
9872 self.write_space();
9873 self.write_keyword("USING");
9874 self.write_space();
9875 self.write_keyword(using);
9876 }
9877 }
9878
9879 self.write(" (");
9881 for (i, col) in columns.iter().enumerate() {
9882 if i > 0 {
9883 self.write(", ");
9884 }
9885 self.generate_identifier(col)?;
9886 }
9887 self.write(")");
9888
9889 if !modifiers.using_before_columns {
9891 if let Some(ref using) = modifiers.using {
9892 self.write_space();
9893 self.write_keyword("USING");
9894 self.write_space();
9895 self.write_keyword(using);
9896 }
9897 }
9898
9899 self.generate_constraint_modifiers_without_using(modifiers);
9901 }
9902 }
9903 TableConstraint::Projection { name, expression } => {
9904 self.write_keyword("PROJECTION");
9906 self.write_space();
9907 self.generate_identifier(name)?;
9908 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
9909 if let Expression::Raw(raw) = expression {
9910 if raw
9911 .sql
9912 .trim_start()
9913 .to_ascii_uppercase()
9914 .starts_with("INDEX ")
9915 {
9916 self.write_space();
9917 self.write(raw.sql.trim());
9918 return Ok(());
9919 }
9920 }
9921 }
9922 self.write(" (");
9923 self.generate_expression(expression)?;
9924 self.write(")");
9925 }
9926 TableConstraint::Like { source, options } => {
9927 self.write_keyword("LIKE");
9928 self.write_space();
9929 self.generate_table(source)?;
9930 for (action, prop) in options {
9931 self.write_space();
9932 match action {
9933 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9934 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9935 }
9936 self.write_space();
9937 self.write_keyword(prop);
9938 }
9939 }
9940 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9941 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9942 self.write(" (");
9943 self.generate_identifier(start_col)?;
9944 self.write(", ");
9945 self.generate_identifier(end_col)?;
9946 self.write(")");
9947 }
9948 TableConstraint::Exclude {
9949 name,
9950 using,
9951 elements,
9952 include_columns,
9953 where_clause,
9954 with_params,
9955 using_index_tablespace,
9956 modifiers: _,
9957 } => {
9958 if let Some(ref n) = name {
9959 self.write_keyword("CONSTRAINT");
9960 self.write_space();
9961 self.generate_identifier(n)?;
9962 self.write_space();
9963 }
9964 self.write_keyword("EXCLUDE");
9965 if let Some(ref method) = using {
9966 self.write_space();
9967 self.write_keyword("USING");
9968 self.write_space();
9969 self.write(method);
9970 self.write("(");
9971 } else {
9972 self.write(" (");
9973 }
9974 for (i, elem) in elements.iter().enumerate() {
9975 if i > 0 {
9976 self.write(", ");
9977 }
9978 self.write(&elem.expression);
9979 self.write_space();
9980 self.write_keyword("WITH");
9981 self.write_space();
9982 self.write(&elem.operator);
9983 }
9984 self.write(")");
9985 if !include_columns.is_empty() {
9986 self.write_space();
9987 self.write_keyword("INCLUDE");
9988 self.write(" (");
9989 for (i, col) in include_columns.iter().enumerate() {
9990 if i > 0 {
9991 self.write(", ");
9992 }
9993 self.generate_identifier(col)?;
9994 }
9995 self.write(")");
9996 }
9997 if !with_params.is_empty() {
9998 self.write_space();
9999 self.write_keyword("WITH");
10000 self.write(" (");
10001 for (i, (key, val)) in with_params.iter().enumerate() {
10002 if i > 0 {
10003 self.write(", ");
10004 }
10005 self.write(key);
10006 self.write("=");
10007 self.write(val);
10008 }
10009 self.write(")");
10010 }
10011 if let Some(ref tablespace) = using_index_tablespace {
10012 self.write_space();
10013 self.write_keyword("USING INDEX TABLESPACE");
10014 self.write_space();
10015 self.write(tablespace);
10016 }
10017 if let Some(ref where_expr) = where_clause {
10018 self.write_space();
10019 self.write_keyword("WHERE");
10020 self.write(" (");
10021 self.generate_expression(where_expr)?;
10022 self.write(")");
10023 }
10024 }
10025 TableConstraint::Tags(tags) => {
10026 self.write_keyword("TAG");
10027 self.write(" (");
10028 for (i, expr) in tags.expressions.iter().enumerate() {
10029 if i > 0 {
10030 self.write(", ");
10031 }
10032 self.generate_expression(expr)?;
10033 }
10034 self.write(")");
10035 }
10036 TableConstraint::InitiallyDeferred { deferred } => {
10037 self.write_keyword("INITIALLY");
10038 self.write_space();
10039 if *deferred {
10040 self.write_keyword("DEFERRED");
10041 } else {
10042 self.write_keyword("IMMEDIATE");
10043 }
10044 }
10045 }
10046 Ok(())
10047 }
10048
10049 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10050 if let Some(using) = &modifiers.using {
10052 self.write_space();
10053 self.write_keyword("USING");
10054 self.write_space();
10055 self.write_keyword(using);
10056 }
10057 if let Some(enforced) = modifiers.enforced {
10059 self.write_space();
10060 if enforced {
10061 self.write_keyword("ENFORCED");
10062 } else {
10063 self.write_keyword("NOT ENFORCED");
10064 }
10065 }
10066 if let Some(deferrable) = modifiers.deferrable {
10068 self.write_space();
10069 if deferrable {
10070 self.write_keyword("DEFERRABLE");
10071 } else {
10072 self.write_keyword("NOT DEFERRABLE");
10073 }
10074 }
10075 if let Some(initially_deferred) = modifiers.initially_deferred {
10077 self.write_space();
10078 if initially_deferred {
10079 self.write_keyword("INITIALLY DEFERRED");
10080 } else {
10081 self.write_keyword("INITIALLY IMMEDIATE");
10082 }
10083 }
10084 if modifiers.norely {
10086 self.write_space();
10087 self.write_keyword("NORELY");
10088 }
10089 if modifiers.rely {
10091 self.write_space();
10092 self.write_keyword("RELY");
10093 }
10094 if modifiers.not_valid {
10096 self.write_space();
10097 self.write_keyword("NOT VALID");
10098 }
10099 if let Some(on_conflict) = &modifiers.on_conflict {
10101 self.write_space();
10102 self.write_keyword("ON CONFLICT");
10103 self.write_space();
10104 self.write_keyword(on_conflict);
10105 }
10106 if !modifiers.with_options.is_empty() {
10108 self.write_space();
10109 self.write_keyword("WITH");
10110 self.write(" (");
10111 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
10112 if i > 0 {
10113 self.write(", ");
10114 }
10115 self.write(key);
10116 self.write("=");
10117 self.write(value);
10118 }
10119 self.write(")");
10120 }
10121 if let Some(ref fg) = modifiers.on_filegroup {
10123 self.write_space();
10124 self.write_keyword("ON");
10125 self.write_space();
10126 let _ = self.generate_identifier(fg);
10127 }
10128 }
10129
10130 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
10132 if let Some(enforced) = modifiers.enforced {
10134 self.write_space();
10135 if enforced {
10136 self.write_keyword("ENFORCED");
10137 } else {
10138 self.write_keyword("NOT ENFORCED");
10139 }
10140 }
10141 if let Some(deferrable) = modifiers.deferrable {
10143 self.write_space();
10144 if deferrable {
10145 self.write_keyword("DEFERRABLE");
10146 } else {
10147 self.write_keyword("NOT DEFERRABLE");
10148 }
10149 }
10150 if let Some(initially_deferred) = modifiers.initially_deferred {
10152 self.write_space();
10153 if initially_deferred {
10154 self.write_keyword("INITIALLY DEFERRED");
10155 } else {
10156 self.write_keyword("INITIALLY IMMEDIATE");
10157 }
10158 }
10159 if modifiers.norely {
10161 self.write_space();
10162 self.write_keyword("NORELY");
10163 }
10164 if modifiers.rely {
10166 self.write_space();
10167 self.write_keyword("RELY");
10168 }
10169 if modifiers.not_valid {
10171 self.write_space();
10172 self.write_keyword("NOT VALID");
10173 }
10174 if let Some(on_conflict) = &modifiers.on_conflict {
10176 self.write_space();
10177 self.write_keyword("ON CONFLICT");
10178 self.write_space();
10179 self.write_keyword(on_conflict);
10180 }
10181 self.generate_index_specific_modifiers(modifiers);
10183 }
10184
10185 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
10187 if let Some(ref comment) = modifiers.comment {
10188 self.write_space();
10189 self.write_keyword("COMMENT");
10190 self.write(" '");
10191 self.write(comment);
10192 self.write("'");
10193 }
10194 if let Some(visible) = modifiers.visible {
10195 self.write_space();
10196 if visible {
10197 self.write_keyword("VISIBLE");
10198 } else {
10199 self.write_keyword("INVISIBLE");
10200 }
10201 }
10202 if let Some(ref attr) = modifiers.engine_attribute {
10203 self.write_space();
10204 self.write_keyword("ENGINE_ATTRIBUTE");
10205 self.write(" = '");
10206 self.write(attr);
10207 self.write("'");
10208 }
10209 if let Some(ref parser) = modifiers.with_parser {
10210 self.write_space();
10211 self.write_keyword("WITH PARSER");
10212 self.write_space();
10213 self.write(parser);
10214 }
10215 }
10216
10217 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
10218 if !fk_ref.match_after_actions {
10220 if let Some(ref match_type) = fk_ref.match_type {
10221 self.write_space();
10222 self.write_keyword("MATCH");
10223 self.write_space();
10224 match match_type {
10225 MatchType::Full => self.write_keyword("FULL"),
10226 MatchType::Partial => self.write_keyword("PARTIAL"),
10227 MatchType::Simple => self.write_keyword("SIMPLE"),
10228 }
10229 }
10230 }
10231
10232 if fk_ref.on_update_first {
10234 if let Some(ref action) = fk_ref.on_update {
10235 self.write_space();
10236 self.write_keyword("ON UPDATE");
10237 self.write_space();
10238 self.generate_referential_action(action);
10239 }
10240 if let Some(ref action) = fk_ref.on_delete {
10241 self.write_space();
10242 self.write_keyword("ON DELETE");
10243 self.write_space();
10244 self.generate_referential_action(action);
10245 }
10246 } else {
10247 if let Some(ref action) = fk_ref.on_delete {
10248 self.write_space();
10249 self.write_keyword("ON DELETE");
10250 self.write_space();
10251 self.generate_referential_action(action);
10252 }
10253 if let Some(ref action) = fk_ref.on_update {
10254 self.write_space();
10255 self.write_keyword("ON UPDATE");
10256 self.write_space();
10257 self.generate_referential_action(action);
10258 }
10259 }
10260
10261 if fk_ref.match_after_actions {
10263 if let Some(ref match_type) = fk_ref.match_type {
10264 self.write_space();
10265 self.write_keyword("MATCH");
10266 self.write_space();
10267 match match_type {
10268 MatchType::Full => self.write_keyword("FULL"),
10269 MatchType::Partial => self.write_keyword("PARTIAL"),
10270 MatchType::Simple => self.write_keyword("SIMPLE"),
10271 }
10272 }
10273 }
10274
10275 if let Some(deferrable) = fk_ref.deferrable {
10277 self.write_space();
10278 if deferrable {
10279 self.write_keyword("DEFERRABLE");
10280 } else {
10281 self.write_keyword("NOT DEFERRABLE");
10282 }
10283 }
10284
10285 Ok(())
10286 }
10287
10288 fn generate_referential_action(&mut self, action: &ReferentialAction) {
10289 match action {
10290 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
10291 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
10292 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
10293 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
10294 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
10295 }
10296 }
10297
10298 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
10299 if let Some(ref object_id_args) = dt.object_id_args {
10301 if matches!(
10302 self.config.dialect,
10303 Some(crate::dialects::DialectType::TSQL)
10304 | Some(crate::dialects::DialectType::Fabric)
10305 ) {
10306 self.write_keyword("IF NOT OBJECT_ID");
10307 self.write("(");
10308 self.write(object_id_args);
10309 self.write(")");
10310 self.write_space();
10311 self.write_keyword("IS NULL BEGIN DROP TABLE");
10312 self.write_space();
10313 for (i, table) in dt.names.iter().enumerate() {
10314 if i > 0 {
10315 self.write(", ");
10316 }
10317 self.generate_table(table)?;
10318 }
10319 self.write("; ");
10320 self.write_keyword("END");
10321 return Ok(());
10322 }
10323 }
10324
10325 let saved_athena_hive_context = self.athena_hive_context;
10327 if matches!(
10328 self.config.dialect,
10329 Some(crate::dialects::DialectType::Athena)
10330 ) {
10331 self.athena_hive_context = true;
10332 }
10333
10334 for comment in &dt.leading_comments {
10336 self.write_formatted_comment(comment);
10337 self.write_space();
10338 }
10339 if dt.iceberg {
10340 self.write_keyword("DROP ICEBERG TABLE");
10341 } else {
10342 self.write_keyword("DROP TABLE");
10343 }
10344
10345 if dt.if_exists {
10346 self.write_space();
10347 self.write_keyword("IF EXISTS");
10348 }
10349
10350 self.write_space();
10351 for (i, table) in dt.names.iter().enumerate() {
10352 if i > 0 {
10353 self.write(", ");
10354 }
10355 self.generate_table(table)?;
10356 }
10357
10358 if dt.cascade_constraints {
10359 self.write_space();
10360 self.write_keyword("CASCADE CONSTRAINTS");
10361 } else if dt.cascade {
10362 self.write_space();
10363 self.write_keyword("CASCADE");
10364 }
10365
10366 if dt.restrict {
10367 self.write_space();
10368 self.write_keyword("RESTRICT");
10369 }
10370
10371 if dt.purge {
10372 self.write_space();
10373 self.write_keyword("PURGE");
10374 }
10375
10376 if dt.sync {
10377 self.write_space();
10378 self.write_keyword("SYNC");
10379 }
10380
10381 self.athena_hive_context = saved_athena_hive_context;
10383
10384 Ok(())
10385 }
10386
10387 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10388 self.write_keyword("UNDROP");
10389 self.write_space();
10390 self.write_keyword(&u.kind);
10391 if u.if_exists {
10392 self.write_space();
10393 self.write_keyword("IF EXISTS");
10394 }
10395 self.write_space();
10396 self.generate_table(&u.name)?;
10397 Ok(())
10398 }
10399
10400 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
10401 let saved_athena_hive_context = self.athena_hive_context;
10403 if matches!(
10404 self.config.dialect,
10405 Some(crate::dialects::DialectType::Athena)
10406 ) {
10407 self.athena_hive_context = true;
10408 }
10409
10410 self.write_keyword("ALTER");
10411 if let Some(ref modifier) = at.table_modifier {
10413 if !matches!(
10414 self.config.dialect,
10415 Some(crate::dialects::DialectType::DuckDB)
10416 ) {
10417 self.write_space();
10418 self.write_keyword(modifier);
10419 }
10420 }
10421 self.write(" ");
10422 self.write_keyword("TABLE");
10423 if at.if_exists {
10424 self.write_space();
10425 self.write_keyword("IF EXISTS");
10426 }
10427 self.write_space();
10428 self.generate_table(&at.name)?;
10429
10430 if let Some(ref on_cluster) = at.on_cluster {
10432 self.write_space();
10433 self.generate_on_cluster(on_cluster)?;
10434 }
10435
10436 if let Some(ref partition) = at.partition {
10438 self.write_space();
10439 self.write_keyword("PARTITION");
10440 self.write("(");
10441 for (i, (key, value)) in partition.iter().enumerate() {
10442 if i > 0 {
10443 self.write(", ");
10444 }
10445 self.generate_identifier(key)?;
10446 self.write(" = ");
10447 self.generate_expression(value)?;
10448 }
10449 self.write(")");
10450 }
10451
10452 if let Some(ref with_check) = at.with_check {
10454 self.write_space();
10455 self.write_keyword(with_check);
10456 }
10457
10458 if self.config.pretty {
10459 self.write_newline();
10461 self.indent_level += 1;
10462 for (i, action) in at.actions.iter().enumerate() {
10463 let is_continuation = i > 0
10465 && matches!(
10466 (&at.actions[i - 1], action),
10467 (
10468 AlterTableAction::AddColumn { .. },
10469 AlterTableAction::AddColumn { .. }
10470 ) | (
10471 AlterTableAction::AddConstraint(_),
10472 AlterTableAction::AddConstraint(_)
10473 )
10474 );
10475 if i > 0 {
10476 self.write(",");
10477 self.write_newline();
10478 }
10479 self.write_indent();
10480 self.generate_alter_action_with_continuation(action, is_continuation)?;
10481 }
10482 self.indent_level -= 1;
10483 } else {
10484 for (i, action) in at.actions.iter().enumerate() {
10485 let is_continuation = i > 0
10487 && matches!(
10488 (&at.actions[i - 1], action),
10489 (
10490 AlterTableAction::AddColumn { .. },
10491 AlterTableAction::AddColumn { .. }
10492 ) | (
10493 AlterTableAction::AddConstraint(_),
10494 AlterTableAction::AddConstraint(_)
10495 )
10496 );
10497 if i > 0 {
10498 self.write(",");
10499 }
10500 self.write_space();
10501 self.generate_alter_action_with_continuation(action, is_continuation)?;
10502 }
10503 }
10504
10505 if let Some(ref algorithm) = at.algorithm {
10507 self.write(", ");
10508 self.write_keyword("ALGORITHM");
10509 self.write("=");
10510 self.write_keyword(algorithm);
10511 }
10512 if let Some(ref lock) = at.lock {
10513 self.write(", ");
10514 self.write_keyword("LOCK");
10515 self.write("=");
10516 self.write_keyword(lock);
10517 }
10518
10519 self.athena_hive_context = saved_athena_hive_context;
10521
10522 Ok(())
10523 }
10524
10525 fn generate_alter_action_with_continuation(
10526 &mut self,
10527 action: &AlterTableAction,
10528 is_continuation: bool,
10529 ) -> Result<()> {
10530 match action {
10531 AlterTableAction::AddColumn {
10532 column,
10533 if_not_exists,
10534 position,
10535 } => {
10536 use crate::dialects::DialectType;
10537 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
10541 let is_tsql_like = matches!(
10542 self.config.dialect,
10543 Some(DialectType::TSQL) | Some(DialectType::Fabric)
10544 );
10545 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
10547
10548 if is_continuation && (is_snowflake || is_tsql_like) {
10549 } else if is_snowflake {
10551 self.write_keyword("ADD");
10552 self.write_space();
10553 } else if is_athena {
10554 self.write_keyword("ADD COLUMNS");
10556 self.write(" (");
10557 } else if self.config.alter_table_include_column_keyword {
10558 self.write_keyword("ADD COLUMN");
10559 self.write_space();
10560 } else {
10561 self.write_keyword("ADD");
10563 self.write_space();
10564 }
10565
10566 if *if_not_exists {
10567 self.write_keyword("IF NOT EXISTS");
10568 self.write_space();
10569 }
10570 self.generate_column_def(column)?;
10571
10572 if is_athena {
10574 self.write(")");
10575 }
10576
10577 if let Some(pos) = position {
10579 self.write_space();
10580 match pos {
10581 ColumnPosition::First => self.write_keyword("FIRST"),
10582 ColumnPosition::After(col_name) => {
10583 self.write_keyword("AFTER");
10584 self.write_space();
10585 self.generate_identifier(col_name)?;
10586 }
10587 }
10588 }
10589 }
10590 AlterTableAction::DropColumn {
10591 name,
10592 if_exists,
10593 cascade,
10594 } => {
10595 self.write_keyword("DROP COLUMN");
10596 if *if_exists {
10597 self.write_space();
10598 self.write_keyword("IF EXISTS");
10599 }
10600 self.write_space();
10601 self.generate_identifier(name)?;
10602 if *cascade {
10603 self.write_space();
10604 self.write_keyword("CASCADE");
10605 }
10606 }
10607 AlterTableAction::DropColumns { names } => {
10608 self.write_keyword("DROP COLUMNS");
10609 self.write(" (");
10610 for (i, name) in names.iter().enumerate() {
10611 if i > 0 {
10612 self.write(", ");
10613 }
10614 self.generate_identifier(name)?;
10615 }
10616 self.write(")");
10617 }
10618 AlterTableAction::RenameColumn {
10619 old_name,
10620 new_name,
10621 if_exists,
10622 } => {
10623 self.write_keyword("RENAME COLUMN");
10624 if *if_exists {
10625 self.write_space();
10626 self.write_keyword("IF EXISTS");
10627 }
10628 self.write_space();
10629 self.generate_identifier(old_name)?;
10630 self.write_space();
10631 self.write_keyword("TO");
10632 self.write_space();
10633 self.generate_identifier(new_name)?;
10634 }
10635 AlterTableAction::AlterColumn {
10636 name,
10637 action,
10638 use_modify_keyword,
10639 } => {
10640 use crate::dialects::DialectType;
10641 let use_modify = *use_modify_keyword
10644 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10645 && matches!(action, AlterColumnAction::SetDataType { .. }));
10646 if use_modify {
10647 self.write_keyword("MODIFY COLUMN");
10648 self.write_space();
10649 self.generate_identifier(name)?;
10650 if let AlterColumnAction::SetDataType {
10652 data_type,
10653 using: _,
10654 collate,
10655 } = action
10656 {
10657 self.write_space();
10658 self.generate_data_type(data_type)?;
10659 if let Some(collate_name) = collate {
10661 self.write_space();
10662 self.write_keyword("COLLATE");
10663 self.write_space();
10664 self.write(&format!("'{}'", collate_name));
10666 }
10667 } else {
10668 self.write_space();
10669 self.generate_alter_column_action(action)?;
10670 }
10671 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10672 && matches!(action, AlterColumnAction::SetDataType { .. })
10673 {
10674 self.write_keyword("CHANGE COLUMN");
10676 self.write_space();
10677 self.generate_identifier(name)?;
10678 self.write_space();
10679 self.generate_identifier(name)?;
10680 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10681 self.write_space();
10682 self.generate_data_type(data_type)?;
10683 }
10684 } else {
10685 self.write_keyword("ALTER COLUMN");
10686 self.write_space();
10687 self.generate_identifier(name)?;
10688 self.write_space();
10689 self.generate_alter_column_action(action)?;
10690 }
10691 }
10692 AlterTableAction::RenameTable(new_name) => {
10693 let mysql_like = matches!(
10695 self.config.dialect,
10696 Some(DialectType::MySQL)
10697 | Some(DialectType::Doris)
10698 | Some(DialectType::StarRocks)
10699 | Some(DialectType::SingleStore)
10700 );
10701 if mysql_like {
10702 self.write_keyword("RENAME");
10703 } else {
10704 self.write_keyword("RENAME TO");
10705 }
10706 self.write_space();
10707 let rename_table_with_db = !matches!(
10709 self.config.dialect,
10710 Some(DialectType::Doris)
10711 | Some(DialectType::DuckDB)
10712 | Some(DialectType::BigQuery)
10713 | Some(DialectType::PostgreSQL)
10714 );
10715 if !rename_table_with_db {
10716 let mut stripped = new_name.clone();
10717 stripped.schema = None;
10718 stripped.catalog = None;
10719 self.generate_table(&stripped)?;
10720 } else {
10721 self.generate_table(new_name)?;
10722 }
10723 }
10724 AlterTableAction::AddConstraint(constraint) => {
10725 if !is_continuation {
10728 self.write_keyword("ADD");
10729 self.write_space();
10730 }
10731 self.generate_table_constraint(constraint)?;
10732 }
10733 AlterTableAction::DropConstraint { name, if_exists } => {
10734 self.write_keyword("DROP CONSTRAINT");
10735 if *if_exists {
10736 self.write_space();
10737 self.write_keyword("IF EXISTS");
10738 }
10739 self.write_space();
10740 self.generate_identifier(name)?;
10741 }
10742 AlterTableAction::DropForeignKey { name } => {
10743 self.write_keyword("DROP FOREIGN KEY");
10744 self.write_space();
10745 self.generate_identifier(name)?;
10746 }
10747 AlterTableAction::DropPartition {
10748 partitions,
10749 if_exists,
10750 } => {
10751 self.write_keyword("DROP");
10752 if *if_exists {
10753 self.write_space();
10754 self.write_keyword("IF EXISTS");
10755 }
10756 for (i, partition) in partitions.iter().enumerate() {
10757 if i > 0 {
10758 self.write(",");
10759 }
10760 self.write_space();
10761 self.write_keyword("PARTITION");
10762 if partition.len() == 1 && partition[0].0.name == "__expr__" {
10764 self.write_space();
10766 self.generate_expression(&partition[0].1)?;
10767 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
10768 self.write_space();
10770 self.write_keyword("ALL");
10771 } else if partition.len() == 1 && partition[0].0.name == "ID" {
10772 self.write_space();
10774 self.write_keyword("ID");
10775 self.write_space();
10776 self.generate_expression(&partition[0].1)?;
10777 } else {
10778 self.write("(");
10780 for (j, (key, value)) in partition.iter().enumerate() {
10781 if j > 0 {
10782 self.write(", ");
10783 }
10784 self.generate_identifier(key)?;
10785 self.write(" = ");
10786 self.generate_expression(value)?;
10787 }
10788 self.write(")");
10789 }
10790 }
10791 }
10792 AlterTableAction::Delete { where_clause } => {
10793 self.write_keyword("DELETE");
10794 self.write_space();
10795 self.write_keyword("WHERE");
10796 self.write_space();
10797 self.generate_expression(where_clause)?;
10798 }
10799 AlterTableAction::SwapWith(target) => {
10800 self.write_keyword("SWAP WITH");
10801 self.write_space();
10802 self.generate_table(target)?;
10803 }
10804 AlterTableAction::SetProperty { properties } => {
10805 use crate::dialects::DialectType;
10806 self.write_keyword("SET");
10807 let is_trino_presto = matches!(
10809 self.config.dialect,
10810 Some(DialectType::Trino) | Some(DialectType::Presto)
10811 );
10812 if is_trino_presto {
10813 self.write_space();
10814 self.write_keyword("PROPERTIES");
10815 }
10816 let eq = if is_trino_presto { " = " } else { "=" };
10817 for (i, (key, value)) in properties.iter().enumerate() {
10818 if i > 0 {
10819 self.write(",");
10820 }
10821 self.write_space();
10822 if key.contains(' ') {
10824 self.generate_string_literal(key)?;
10825 } else {
10826 self.write(key);
10827 }
10828 self.write(eq);
10829 self.generate_expression(value)?;
10830 }
10831 }
10832 AlterTableAction::UnsetProperty { properties } => {
10833 self.write_keyword("UNSET");
10834 for (i, name) in properties.iter().enumerate() {
10835 if i > 0 {
10836 self.write(",");
10837 }
10838 self.write_space();
10839 self.write(name);
10840 }
10841 }
10842 AlterTableAction::ClusterBy { expressions } => {
10843 self.write_keyword("CLUSTER BY");
10844 self.write(" (");
10845 for (i, expr) in expressions.iter().enumerate() {
10846 if i > 0 {
10847 self.write(", ");
10848 }
10849 self.generate_expression(expr)?;
10850 }
10851 self.write(")");
10852 }
10853 AlterTableAction::SetTag { expressions } => {
10854 self.write_keyword("SET TAG");
10855 for (i, (key, value)) in expressions.iter().enumerate() {
10856 if i > 0 {
10857 self.write(",");
10858 }
10859 self.write_space();
10860 self.write(key);
10861 self.write(" = ");
10862 self.generate_expression(value)?;
10863 }
10864 }
10865 AlterTableAction::UnsetTag { names } => {
10866 self.write_keyword("UNSET TAG");
10867 for (i, name) in names.iter().enumerate() {
10868 if i > 0 {
10869 self.write(",");
10870 }
10871 self.write_space();
10872 self.write(name);
10873 }
10874 }
10875 AlterTableAction::SetOptions { expressions } => {
10876 self.write_keyword("SET");
10877 self.write(" (");
10878 for (i, expr) in expressions.iter().enumerate() {
10879 if i > 0 {
10880 self.write(", ");
10881 }
10882 self.generate_expression(expr)?;
10883 }
10884 self.write(")");
10885 }
10886 AlterTableAction::AlterIndex { name, visible } => {
10887 self.write_keyword("ALTER INDEX");
10888 self.write_space();
10889 self.generate_identifier(name)?;
10890 self.write_space();
10891 if *visible {
10892 self.write_keyword("VISIBLE");
10893 } else {
10894 self.write_keyword("INVISIBLE");
10895 }
10896 }
10897 AlterTableAction::SetAttribute { attribute } => {
10898 self.write_keyword("SET");
10899 self.write_space();
10900 self.write_keyword(attribute);
10901 }
10902 AlterTableAction::SetStageFileFormat { options } => {
10903 self.write_keyword("SET");
10904 self.write_space();
10905 self.write_keyword("STAGE_FILE_FORMAT");
10906 self.write(" = (");
10907 if let Some(opts) = options {
10908 self.generate_space_separated_properties(opts)?;
10909 }
10910 self.write(")");
10911 }
10912 AlterTableAction::SetStageCopyOptions { options } => {
10913 self.write_keyword("SET");
10914 self.write_space();
10915 self.write_keyword("STAGE_COPY_OPTIONS");
10916 self.write(" = (");
10917 if let Some(opts) = options {
10918 self.generate_space_separated_properties(opts)?;
10919 }
10920 self.write(")");
10921 }
10922 AlterTableAction::AddColumns { columns, cascade } => {
10923 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
10926 if is_oracle {
10927 self.write_keyword("ADD");
10928 } else {
10929 self.write_keyword("ADD COLUMNS");
10930 }
10931 self.write(" (");
10932 for (i, col) in columns.iter().enumerate() {
10933 if i > 0 {
10934 self.write(", ");
10935 }
10936 self.generate_column_def(col)?;
10937 }
10938 self.write(")");
10939 if *cascade {
10940 self.write_space();
10941 self.write_keyword("CASCADE");
10942 }
10943 }
10944 AlterTableAction::ChangeColumn {
10945 old_name,
10946 new_name,
10947 data_type,
10948 comment,
10949 cascade,
10950 } => {
10951 use crate::dialects::DialectType;
10952 let is_spark = matches!(
10953 self.config.dialect,
10954 Some(DialectType::Spark) | Some(DialectType::Databricks)
10955 );
10956 let is_rename = old_name.name != new_name.name;
10957
10958 if is_spark {
10959 if is_rename {
10960 self.write_keyword("RENAME COLUMN");
10962 self.write_space();
10963 self.generate_identifier(old_name)?;
10964 self.write_space();
10965 self.write_keyword("TO");
10966 self.write_space();
10967 self.generate_identifier(new_name)?;
10968 } else if comment.is_some() {
10969 self.write_keyword("ALTER COLUMN");
10971 self.write_space();
10972 self.generate_identifier(old_name)?;
10973 self.write_space();
10974 self.write_keyword("COMMENT");
10975 self.write_space();
10976 self.write("'");
10977 self.write(comment.as_ref().unwrap());
10978 self.write("'");
10979 } else if data_type.is_some() {
10980 self.write_keyword("ALTER COLUMN");
10982 self.write_space();
10983 self.generate_identifier(old_name)?;
10984 self.write_space();
10985 self.write_keyword("TYPE");
10986 self.write_space();
10987 self.generate_data_type(data_type.as_ref().unwrap())?;
10988 } else {
10989 self.write_keyword("CHANGE COLUMN");
10991 self.write_space();
10992 self.generate_identifier(old_name)?;
10993 self.write_space();
10994 self.generate_identifier(new_name)?;
10995 }
10996 } else {
10997 if data_type.is_some() {
10999 self.write_keyword("CHANGE COLUMN");
11000 } else {
11001 self.write_keyword("CHANGE");
11002 }
11003 self.write_space();
11004 self.generate_identifier(old_name)?;
11005 self.write_space();
11006 self.generate_identifier(new_name)?;
11007 if let Some(ref dt) = data_type {
11008 self.write_space();
11009 self.generate_data_type(dt)?;
11010 }
11011 if let Some(ref c) = comment {
11012 self.write_space();
11013 self.write_keyword("COMMENT");
11014 self.write_space();
11015 self.write("'");
11016 self.write(c);
11017 self.write("'");
11018 }
11019 if *cascade {
11020 self.write_space();
11021 self.write_keyword("CASCADE");
11022 }
11023 }
11024 }
11025 AlterTableAction::AddPartition {
11026 partition,
11027 if_not_exists,
11028 location,
11029 } => {
11030 self.write_keyword("ADD");
11031 self.write_space();
11032 if *if_not_exists {
11033 self.write_keyword("IF NOT EXISTS");
11034 self.write_space();
11035 }
11036 self.generate_expression(partition)?;
11037 if let Some(ref loc) = location {
11038 self.write_space();
11039 self.write_keyword("LOCATION");
11040 self.write_space();
11041 self.generate_expression(loc)?;
11042 }
11043 }
11044 AlterTableAction::AlterSortKey {
11045 this,
11046 expressions,
11047 compound,
11048 } => {
11049 self.write_keyword("ALTER");
11051 if *compound {
11052 self.write_space();
11053 self.write_keyword("COMPOUND");
11054 }
11055 self.write_space();
11056 self.write_keyword("SORTKEY");
11057 self.write_space();
11058 if let Some(style) = this {
11059 self.write_keyword(style);
11060 } else if !expressions.is_empty() {
11061 self.write("(");
11062 for (i, expr) in expressions.iter().enumerate() {
11063 if i > 0 {
11064 self.write(", ");
11065 }
11066 self.generate_expression(expr)?;
11067 }
11068 self.write(")");
11069 }
11070 }
11071 AlterTableAction::AlterDistStyle { style, distkey } => {
11072 self.write_keyword("ALTER");
11074 self.write_space();
11075 self.write_keyword("DISTSTYLE");
11076 self.write_space();
11077 self.write_keyword(style);
11078 if let Some(col) = distkey {
11079 self.write_space();
11080 self.write_keyword("DISTKEY");
11081 self.write_space();
11082 self.generate_identifier(col)?;
11083 }
11084 }
11085 AlterTableAction::SetTableProperties { properties } => {
11086 self.write_keyword("SET TABLE PROPERTIES");
11088 self.write(" (");
11089 for (i, (key, value)) in properties.iter().enumerate() {
11090 if i > 0 {
11091 self.write(", ");
11092 }
11093 self.generate_expression(key)?;
11094 self.write(" = ");
11095 self.generate_expression(value)?;
11096 }
11097 self.write(")");
11098 }
11099 AlterTableAction::SetLocation { location } => {
11100 self.write_keyword("SET LOCATION");
11102 self.write_space();
11103 self.write("'");
11104 self.write(location);
11105 self.write("'");
11106 }
11107 AlterTableAction::SetFileFormat { format } => {
11108 self.write_keyword("SET FILE FORMAT");
11110 self.write_space();
11111 self.write_keyword(format);
11112 }
11113 AlterTableAction::ReplacePartition { partition, source } => {
11114 self.write_keyword("REPLACE PARTITION");
11116 self.write_space();
11117 self.generate_expression(partition)?;
11118 if let Some(src) = source {
11119 self.write_space();
11120 self.write_keyword("FROM");
11121 self.write_space();
11122 self.generate_expression(src)?;
11123 }
11124 }
11125 AlterTableAction::Raw { sql } => {
11126 self.write(sql);
11127 }
11128 }
11129 Ok(())
11130 }
11131
11132 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
11133 match action {
11134 AlterColumnAction::SetDataType {
11135 data_type,
11136 using,
11137 collate,
11138 } => {
11139 use crate::dialects::DialectType;
11140 let is_no_prefix = matches!(
11145 self.config.dialect,
11146 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
11147 );
11148 let is_type_only = matches!(
11149 self.config.dialect,
11150 Some(DialectType::Redshift)
11151 | Some(DialectType::Spark)
11152 | Some(DialectType::Databricks)
11153 );
11154 if is_type_only {
11155 self.write_keyword("TYPE");
11156 self.write_space();
11157 } else if !is_no_prefix {
11158 self.write_keyword("SET DATA TYPE");
11159 self.write_space();
11160 }
11161 self.generate_data_type(data_type)?;
11162 if let Some(ref collation) = collate {
11163 self.write_space();
11164 self.write_keyword("COLLATE");
11165 self.write_space();
11166 self.write(collation);
11167 }
11168 if let Some(ref using_expr) = using {
11169 self.write_space();
11170 self.write_keyword("USING");
11171 self.write_space();
11172 self.generate_expression(using_expr)?;
11173 }
11174 }
11175 AlterColumnAction::SetDefault(expr) => {
11176 self.write_keyword("SET DEFAULT");
11177 self.write_space();
11178 self.generate_expression(expr)?;
11179 }
11180 AlterColumnAction::DropDefault => {
11181 self.write_keyword("DROP DEFAULT");
11182 }
11183 AlterColumnAction::SetNotNull => {
11184 self.write_keyword("SET NOT NULL");
11185 }
11186 AlterColumnAction::DropNotNull => {
11187 self.write_keyword("DROP NOT NULL");
11188 }
11189 AlterColumnAction::Comment(comment) => {
11190 self.write_keyword("COMMENT");
11191 self.write_space();
11192 self.generate_string_literal(comment)?;
11193 }
11194 AlterColumnAction::SetVisible => {
11195 self.write_keyword("SET VISIBLE");
11196 }
11197 AlterColumnAction::SetInvisible => {
11198 self.write_keyword("SET INVISIBLE");
11199 }
11200 }
11201 Ok(())
11202 }
11203
11204 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
11205 self.write_keyword("CREATE");
11206
11207 if ci.unique {
11208 self.write_space();
11209 self.write_keyword("UNIQUE");
11210 }
11211
11212 if let Some(ref clustered) = ci.clustered {
11214 self.write_space();
11215 self.write_keyword(clustered);
11216 }
11217
11218 self.write_space();
11219 self.write_keyword("INDEX");
11220
11221 if ci.concurrently {
11223 self.write_space();
11224 self.write_keyword("CONCURRENTLY");
11225 }
11226
11227 if ci.if_not_exists {
11228 self.write_space();
11229 self.write_keyword("IF NOT EXISTS");
11230 }
11231
11232 if !ci.name.name.is_empty() {
11234 self.write_space();
11235 self.generate_identifier(&ci.name)?;
11236 }
11237 self.write_space();
11238 self.write_keyword("ON");
11239 if matches!(self.config.dialect, Some(DialectType::Hive)) {
11241 self.write_space();
11242 self.write_keyword("TABLE");
11243 }
11244 self.write_space();
11245 self.generate_table(&ci.table)?;
11246
11247 if !ci.columns.is_empty() || ci.using.is_some() {
11250 let space_before_paren = false;
11251
11252 if let Some(ref using) = ci.using {
11253 self.write_space();
11254 self.write_keyword("USING");
11255 self.write_space();
11256 self.write(using);
11257 if space_before_paren {
11258 self.write(" (");
11259 } else {
11260 self.write("(");
11261 }
11262 } else {
11263 if space_before_paren {
11264 self.write(" (");
11265 } else {
11266 self.write("(");
11267 }
11268 }
11269 for (i, col) in ci.columns.iter().enumerate() {
11270 if i > 0 {
11271 self.write(", ");
11272 }
11273 self.generate_identifier(&col.column)?;
11274 if let Some(ref opclass) = col.opclass {
11275 self.write_space();
11276 self.write(opclass);
11277 }
11278 if col.desc {
11279 self.write_space();
11280 self.write_keyword("DESC");
11281 } else if col.asc {
11282 self.write_space();
11283 self.write_keyword("ASC");
11284 }
11285 if let Some(nulls_first) = col.nulls_first {
11286 self.write_space();
11287 self.write_keyword("NULLS");
11288 self.write_space();
11289 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
11290 }
11291 }
11292 self.write(")");
11293 }
11294
11295 if !ci.include_columns.is_empty() {
11297 self.write_space();
11298 self.write_keyword("INCLUDE");
11299 self.write(" (");
11300 for (i, col) in ci.include_columns.iter().enumerate() {
11301 if i > 0 {
11302 self.write(", ");
11303 }
11304 self.generate_identifier(col)?;
11305 }
11306 self.write(")");
11307 }
11308
11309 if !ci.with_options.is_empty() {
11311 self.write_space();
11312 self.write_keyword("WITH");
11313 self.write(" (");
11314 for (i, (key, value)) in ci.with_options.iter().enumerate() {
11315 if i > 0 {
11316 self.write(", ");
11317 }
11318 self.write(key);
11319 self.write("=");
11320 self.write(value);
11321 }
11322 self.write(")");
11323 }
11324
11325 if let Some(ref where_clause) = ci.where_clause {
11327 self.write_space();
11328 self.write_keyword("WHERE");
11329 self.write_space();
11330 self.generate_expression(where_clause)?;
11331 }
11332
11333 if let Some(ref on_fg) = ci.on_filegroup {
11335 self.write_space();
11336 self.write_keyword("ON");
11337 self.write_space();
11338 self.write(on_fg);
11339 }
11340
11341 Ok(())
11342 }
11343
11344 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
11345 self.write_keyword("DROP INDEX");
11346
11347 if di.concurrently {
11348 self.write_space();
11349 self.write_keyword("CONCURRENTLY");
11350 }
11351
11352 if di.if_exists {
11353 self.write_space();
11354 self.write_keyword("IF EXISTS");
11355 }
11356
11357 self.write_space();
11358 self.generate_table(&di.name)?;
11359
11360 if let Some(ref table) = di.table {
11361 self.write_space();
11362 self.write_keyword("ON");
11363 self.write_space();
11364 self.generate_table(table)?;
11365 }
11366
11367 Ok(())
11368 }
11369
11370 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
11371 self.write_keyword("CREATE");
11372
11373 if let Some(ref algorithm) = cv.algorithm {
11375 self.write_space();
11376 self.write_keyword("ALGORITHM");
11377 self.write("=");
11378 self.write_keyword(algorithm);
11379 }
11380
11381 if let Some(ref definer) = cv.definer {
11383 self.write_space();
11384 self.write_keyword("DEFINER");
11385 self.write("=");
11386 self.write(definer);
11387 }
11388
11389 if cv.security_sql_style && !cv.security_after_name {
11391 if let Some(ref security) = cv.security {
11392 self.write_space();
11393 self.write_keyword("SQL SECURITY");
11394 self.write_space();
11395 match security {
11396 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11397 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11398 FunctionSecurity::None => self.write_keyword("NONE"),
11399 }
11400 }
11401 }
11402
11403 if cv.or_alter {
11404 self.write_space();
11405 self.write_keyword("OR ALTER");
11406 } else if cv.or_replace {
11407 self.write_space();
11408 self.write_keyword("OR REPLACE");
11409 }
11410
11411 if cv.temporary {
11412 self.write_space();
11413 self.write_keyword("TEMPORARY");
11414 }
11415
11416 if cv.materialized {
11417 self.write_space();
11418 self.write_keyword("MATERIALIZED");
11419 }
11420
11421 if cv.secure {
11423 self.write_space();
11424 self.write_keyword("SECURE");
11425 }
11426
11427 self.write_space();
11428 self.write_keyword("VIEW");
11429
11430 if cv.if_not_exists {
11431 self.write_space();
11432 self.write_keyword("IF NOT EXISTS");
11433 }
11434
11435 self.write_space();
11436 self.generate_table(&cv.name)?;
11437
11438 if let Some(ref on_cluster) = cv.on_cluster {
11440 self.write_space();
11441 self.generate_on_cluster(on_cluster)?;
11442 }
11443
11444 if let Some(ref to_table) = cv.to_table {
11446 self.write_space();
11447 self.write_keyword("TO");
11448 self.write_space();
11449 self.generate_table(to_table)?;
11450 }
11451
11452 if !cv.materialized {
11455 if let Some(ref schema) = cv.schema {
11457 self.write(" (");
11458 for (i, expr) in schema.expressions.iter().enumerate() {
11459 if i > 0 {
11460 self.write(", ");
11461 }
11462 self.generate_expression(expr)?;
11463 }
11464 self.write(")");
11465 } else if !cv.columns.is_empty() {
11466 self.write(" (");
11467 for (i, col) in cv.columns.iter().enumerate() {
11468 if i > 0 {
11469 self.write(", ");
11470 }
11471 self.generate_identifier(&col.name)?;
11472 if !col.options.is_empty() {
11474 self.write_space();
11475 self.generate_options_clause(&col.options)?;
11476 }
11477 if let Some(ref comment) = col.comment {
11478 self.write_space();
11479 self.write_keyword("COMMENT");
11480 self.write_space();
11481 self.generate_string_literal(comment)?;
11482 }
11483 }
11484 self.write(")");
11485 }
11486
11487 if !cv.security_sql_style || cv.security_after_name {
11490 if let Some(ref security) = cv.security {
11491 self.write_space();
11492 if cv.security_sql_style {
11493 self.write_keyword("SQL SECURITY");
11494 } else {
11495 self.write_keyword("SECURITY");
11496 }
11497 self.write_space();
11498 match security {
11499 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11500 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11501 FunctionSecurity::None => self.write_keyword("NONE"),
11502 }
11503 }
11504 }
11505
11506 if cv.copy_grants {
11508 self.write_space();
11509 self.write_keyword("COPY GRANTS");
11510 }
11511 } else {
11512 if cv.copy_grants {
11514 self.write_space();
11515 self.write_keyword("COPY GRANTS");
11516 }
11517
11518 if let Some(ref schema) = cv.schema {
11520 self.write(" (");
11521 for (i, expr) in schema.expressions.iter().enumerate() {
11522 if i > 0 {
11523 self.write(", ");
11524 }
11525 self.generate_expression(expr)?;
11526 }
11527 self.write(")");
11528 } else if !cv.columns.is_empty() {
11529 self.write(" (");
11531 for (i, col) in cv.columns.iter().enumerate() {
11532 if i > 0 {
11533 self.write(", ");
11534 }
11535 self.generate_identifier(&col.name)?;
11536 if !col.options.is_empty() {
11538 self.write_space();
11539 self.generate_options_clause(&col.options)?;
11540 }
11541 if let Some(ref comment) = col.comment {
11542 self.write_space();
11543 self.write_keyword("COMMENT");
11544 self.write_space();
11545 self.generate_string_literal(comment)?;
11546 }
11547 }
11548 self.write(")");
11549 }
11550
11551 if let Some(ref unique_key) = cv.unique_key {
11553 self.write_space();
11554 self.write_keyword("KEY");
11555 self.write(" (");
11556 for (i, expr) in unique_key.expressions.iter().enumerate() {
11557 if i > 0 {
11558 self.write(", ");
11559 }
11560 self.generate_expression(expr)?;
11561 }
11562 self.write(")");
11563 }
11564 }
11565
11566 if let Some(ref row_access_policy) = cv.row_access_policy {
11567 self.write_space();
11568 self.write_keyword("WITH");
11569 self.write_space();
11570 self.write(row_access_policy);
11571 }
11572
11573 if let Some(ref comment) = cv.comment {
11575 self.write_space();
11576 self.write_keyword("COMMENT");
11577 self.write("=");
11578 self.generate_string_literal(comment)?;
11579 }
11580
11581 if !cv.tags.is_empty() {
11583 self.write_space();
11584 self.write_keyword("TAG");
11585 self.write(" (");
11586 for (i, (name, value)) in cv.tags.iter().enumerate() {
11587 if i > 0 {
11588 self.write(", ");
11589 }
11590 self.write(name);
11591 self.write("='");
11592 self.write(value);
11593 self.write("'");
11594 }
11595 self.write(")");
11596 }
11597
11598 if !cv.options.is_empty() {
11600 self.write_space();
11601 self.generate_options_clause(&cv.options)?;
11602 }
11603
11604 if let Some(ref build) = cv.build {
11606 self.write_space();
11607 self.write_keyword("BUILD");
11608 self.write_space();
11609 self.write_keyword(build);
11610 }
11611
11612 if let Some(ref refresh) = cv.refresh {
11614 self.write_space();
11615 self.generate_refresh_trigger_property(refresh)?;
11616 }
11617
11618 if let Some(auto_refresh) = cv.auto_refresh {
11620 self.write_space();
11621 self.write_keyword("AUTO REFRESH");
11622 self.write_space();
11623 if auto_refresh {
11624 self.write_keyword("YES");
11625 } else {
11626 self.write_keyword("NO");
11627 }
11628 }
11629
11630 for prop in &cv.table_properties {
11632 self.write_space();
11633 self.generate_expression(prop)?;
11634 }
11635
11636 if let Some(ref population) = cv.clickhouse_population {
11638 self.write_space();
11639 self.write_keyword(population);
11640 }
11641
11642 if !matches!(&cv.query, Expression::Null(_)) {
11644 self.write_space();
11645 self.write_keyword("AS");
11646 self.write_space();
11647
11648 if let Some(ref mode) = cv.locking_mode {
11650 self.write_keyword("LOCKING");
11651 self.write_space();
11652 self.write_keyword(mode);
11653 if let Some(ref access) = cv.locking_access {
11654 self.write_space();
11655 self.write_keyword("FOR");
11656 self.write_space();
11657 self.write_keyword(access);
11658 }
11659 self.write_space();
11660 }
11661
11662 if cv.query_parenthesized {
11663 self.write("(");
11664 }
11665 self.generate_expression(&cv.query)?;
11666 if cv.query_parenthesized {
11667 self.write(")");
11668 }
11669 }
11670
11671 if cv.no_schema_binding {
11673 self.write_space();
11674 self.write_keyword("WITH NO SCHEMA BINDING");
11675 }
11676
11677 Ok(())
11678 }
11679
11680 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11681 self.write_keyword("DROP");
11682
11683 if dv.materialized {
11684 self.write_space();
11685 self.write_keyword("MATERIALIZED");
11686 }
11687
11688 self.write_space();
11689 self.write_keyword("VIEW");
11690
11691 if dv.if_exists {
11692 self.write_space();
11693 self.write_keyword("IF EXISTS");
11694 }
11695
11696 self.write_space();
11697 self.generate_table(&dv.name)?;
11698
11699 Ok(())
11700 }
11701
11702 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11703 match tr.target {
11704 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11705 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11706 }
11707 if tr.if_exists {
11708 self.write_space();
11709 self.write_keyword("IF EXISTS");
11710 }
11711 self.write_space();
11712 self.generate_table(&tr.table)?;
11713
11714 if let Some(ref on_cluster) = tr.on_cluster {
11716 self.write_space();
11717 self.generate_on_cluster(on_cluster)?;
11718 }
11719
11720 if !tr.extra_tables.is_empty() {
11722 let skip_first = if let Some(first) = tr.extra_tables.first() {
11724 first.table.name == tr.table.name && first.star
11725 } else {
11726 false
11727 };
11728
11729 let strip_star = matches!(
11731 self.config.dialect,
11732 Some(crate::dialects::DialectType::PostgreSQL)
11733 | Some(crate::dialects::DialectType::Redshift)
11734 );
11735 if skip_first && !strip_star {
11736 self.write("*");
11737 }
11738
11739 for (i, entry) in tr.extra_tables.iter().enumerate() {
11741 if i == 0 && skip_first {
11742 continue; }
11744 self.write(", ");
11745 self.generate_table(&entry.table)?;
11746 if entry.star && !strip_star {
11747 self.write("*");
11748 }
11749 }
11750 }
11751
11752 if let Some(identity) = &tr.identity {
11754 self.write_space();
11755 match identity {
11756 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
11757 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
11758 }
11759 }
11760
11761 if tr.cascade {
11762 self.write_space();
11763 self.write_keyword("CASCADE");
11764 }
11765
11766 if tr.restrict {
11767 self.write_space();
11768 self.write_keyword("RESTRICT");
11769 }
11770
11771 if let Some(ref partition) = tr.partition {
11773 self.write_space();
11774 self.generate_expression(partition)?;
11775 }
11776
11777 Ok(())
11778 }
11779
11780 fn generate_use(&mut self, u: &Use) -> Result<()> {
11781 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
11783 self.write_keyword("DATABASE");
11784 self.write_space();
11785 self.generate_identifier(&u.this)?;
11786 return Ok(());
11787 }
11788
11789 self.write_keyword("USE");
11790
11791 if let Some(kind) = &u.kind {
11792 self.write_space();
11793 match kind {
11794 UseKind::Database => self.write_keyword("DATABASE"),
11795 UseKind::Schema => self.write_keyword("SCHEMA"),
11796 UseKind::Role => self.write_keyword("ROLE"),
11797 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
11798 UseKind::Catalog => self.write_keyword("CATALOG"),
11799 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
11800 }
11801 }
11802
11803 self.write_space();
11804 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
11807 self.write(&u.this.name);
11808 } else {
11809 self.generate_identifier(&u.this)?;
11810 }
11811 Ok(())
11812 }
11813
11814 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
11815 self.write_keyword("CACHE");
11816 if c.lazy {
11817 self.write_space();
11818 self.write_keyword("LAZY");
11819 }
11820 self.write_space();
11821 self.write_keyword("TABLE");
11822 self.write_space();
11823 self.generate_identifier(&c.table)?;
11824
11825 if !c.options.is_empty() {
11827 self.write_space();
11828 self.write_keyword("OPTIONS");
11829 self.write("(");
11830 for (i, (key, value)) in c.options.iter().enumerate() {
11831 if i > 0 {
11832 self.write(", ");
11833 }
11834 self.generate_expression(key)?;
11835 self.write(" = ");
11836 self.generate_expression(value)?;
11837 }
11838 self.write(")");
11839 }
11840
11841 if let Some(query) = &c.query {
11843 self.write_space();
11844 self.write_keyword("AS");
11845 self.write_space();
11846 self.generate_expression(query)?;
11847 }
11848
11849 Ok(())
11850 }
11851
11852 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
11853 self.write_keyword("UNCACHE TABLE");
11854 if u.if_exists {
11855 self.write_space();
11856 self.write_keyword("IF EXISTS");
11857 }
11858 self.write_space();
11859 self.generate_identifier(&u.table)?;
11860 Ok(())
11861 }
11862
11863 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
11864 self.write_keyword("LOAD DATA");
11865 if l.local {
11866 self.write_space();
11867 self.write_keyword("LOCAL");
11868 }
11869 self.write_space();
11870 self.write_keyword("INPATH");
11871 self.write_space();
11872 self.write("'");
11873 self.write(&l.inpath);
11874 self.write("'");
11875
11876 if l.overwrite {
11877 self.write_space();
11878 self.write_keyword("OVERWRITE");
11879 }
11880
11881 self.write_space();
11882 self.write_keyword("INTO TABLE");
11883 self.write_space();
11884 self.generate_expression(&l.table)?;
11885
11886 if !l.partition.is_empty() {
11888 self.write_space();
11889 self.write_keyword("PARTITION");
11890 self.write("(");
11891 for (i, (col, val)) in l.partition.iter().enumerate() {
11892 if i > 0 {
11893 self.write(", ");
11894 }
11895 self.generate_identifier(col)?;
11896 self.write(" = ");
11897 self.generate_expression(val)?;
11898 }
11899 self.write(")");
11900 }
11901
11902 if let Some(fmt) = &l.input_format {
11904 self.write_space();
11905 self.write_keyword("INPUTFORMAT");
11906 self.write_space();
11907 self.write("'");
11908 self.write(fmt);
11909 self.write("'");
11910 }
11911
11912 if let Some(serde) = &l.serde {
11914 self.write_space();
11915 self.write_keyword("SERDE");
11916 self.write_space();
11917 self.write("'");
11918 self.write(serde);
11919 self.write("'");
11920 }
11921
11922 Ok(())
11923 }
11924
11925 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
11926 self.write_keyword("PRAGMA");
11927 self.write_space();
11928
11929 if let Some(schema) = &p.schema {
11931 self.generate_identifier(schema)?;
11932 self.write(".");
11933 }
11934
11935 self.generate_identifier(&p.name)?;
11937
11938 if p.use_assignment_syntax {
11940 self.write(" = ");
11941 if let Some(value) = &p.value {
11942 self.generate_expression(value)?;
11943 } else if let Some(arg) = p.args.first() {
11944 self.generate_expression(arg)?;
11945 }
11946 } else if !p.args.is_empty() {
11947 self.write("(");
11948 for (i, arg) in p.args.iter().enumerate() {
11949 if i > 0 {
11950 self.write(", ");
11951 }
11952 self.generate_expression(arg)?;
11953 }
11954 self.write(")");
11955 }
11956
11957 Ok(())
11958 }
11959
11960 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
11961 self.write_keyword("GRANT");
11962 self.write_space();
11963
11964 for (i, privilege) in g.privileges.iter().enumerate() {
11966 if i > 0 {
11967 self.write(", ");
11968 }
11969 self.write_keyword(&privilege.name);
11970 if !privilege.columns.is_empty() {
11972 self.write("(");
11973 for (j, col) in privilege.columns.iter().enumerate() {
11974 if j > 0 {
11975 self.write(", ");
11976 }
11977 self.write(col);
11978 }
11979 self.write(")");
11980 }
11981 }
11982
11983 self.write_space();
11984 self.write_keyword("ON");
11985 self.write_space();
11986
11987 if let Some(kind) = &g.kind {
11989 self.write_keyword(kind);
11990 self.write_space();
11991 }
11992
11993 {
11995 use crate::dialects::DialectType;
11996 let should_upper = matches!(
11997 self.config.dialect,
11998 Some(DialectType::PostgreSQL)
11999 | Some(DialectType::CockroachDB)
12000 | Some(DialectType::Materialize)
12001 | Some(DialectType::RisingWave)
12002 ) && (g.kind.as_deref() == Some("FUNCTION")
12003 || g.kind.as_deref() == Some("PROCEDURE"));
12004 if should_upper {
12005 use crate::expressions::Identifier;
12006 let upper_id = Identifier {
12007 name: g.securable.name.to_ascii_uppercase(),
12008 quoted: g.securable.quoted,
12009 ..g.securable.clone()
12010 };
12011 self.generate_identifier(&upper_id)?;
12012 } else {
12013 self.generate_identifier(&g.securable)?;
12014 }
12015 }
12016
12017 if !g.function_params.is_empty() {
12019 self.write("(");
12020 for (i, param) in g.function_params.iter().enumerate() {
12021 if i > 0 {
12022 self.write(", ");
12023 }
12024 self.write(param);
12025 }
12026 self.write(")");
12027 }
12028
12029 self.write_space();
12030 self.write_keyword("TO");
12031 self.write_space();
12032
12033 for (i, principal) in g.principals.iter().enumerate() {
12035 if i > 0 {
12036 self.write(", ");
12037 }
12038 if principal.is_role {
12039 self.write_keyword("ROLE");
12040 self.write_space();
12041 } else if principal.is_group {
12042 self.write_keyword("GROUP");
12043 self.write_space();
12044 } else if principal.is_share {
12045 self.write_keyword("SHARE");
12046 self.write_space();
12047 }
12048 self.generate_identifier(&principal.name)?;
12049 }
12050
12051 if g.grant_option {
12053 self.write_space();
12054 self.write_keyword("WITH GRANT OPTION");
12055 }
12056
12057 if let Some(ref principal) = g.as_principal {
12059 self.write_space();
12060 self.write_keyword("AS");
12061 self.write_space();
12062 self.generate_identifier(principal)?;
12063 }
12064
12065 Ok(())
12066 }
12067
12068 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
12069 self.write_keyword("REVOKE");
12070 self.write_space();
12071
12072 if r.grant_option {
12074 self.write_keyword("GRANT OPTION FOR");
12075 self.write_space();
12076 }
12077
12078 for (i, privilege) in r.privileges.iter().enumerate() {
12080 if i > 0 {
12081 self.write(", ");
12082 }
12083 self.write_keyword(&privilege.name);
12084 if !privilege.columns.is_empty() {
12086 self.write("(");
12087 for (j, col) in privilege.columns.iter().enumerate() {
12088 if j > 0 {
12089 self.write(", ");
12090 }
12091 self.write(col);
12092 }
12093 self.write(")");
12094 }
12095 }
12096
12097 self.write_space();
12098 self.write_keyword("ON");
12099 self.write_space();
12100
12101 if let Some(kind) = &r.kind {
12103 self.write_keyword(kind);
12104 self.write_space();
12105 }
12106
12107 {
12109 use crate::dialects::DialectType;
12110 let should_upper = matches!(
12111 self.config.dialect,
12112 Some(DialectType::PostgreSQL)
12113 | Some(DialectType::CockroachDB)
12114 | Some(DialectType::Materialize)
12115 | Some(DialectType::RisingWave)
12116 ) && (r.kind.as_deref() == Some("FUNCTION")
12117 || r.kind.as_deref() == Some("PROCEDURE"));
12118 if should_upper {
12119 use crate::expressions::Identifier;
12120 let upper_id = Identifier {
12121 name: r.securable.name.to_ascii_uppercase(),
12122 quoted: r.securable.quoted,
12123 ..r.securable.clone()
12124 };
12125 self.generate_identifier(&upper_id)?;
12126 } else {
12127 self.generate_identifier(&r.securable)?;
12128 }
12129 }
12130
12131 if !r.function_params.is_empty() {
12133 self.write("(");
12134 for (i, param) in r.function_params.iter().enumerate() {
12135 if i > 0 {
12136 self.write(", ");
12137 }
12138 self.write(param);
12139 }
12140 self.write(")");
12141 }
12142
12143 self.write_space();
12144 self.write_keyword("FROM");
12145 self.write_space();
12146
12147 for (i, principal) in r.principals.iter().enumerate() {
12149 if i > 0 {
12150 self.write(", ");
12151 }
12152 if principal.is_role {
12153 self.write_keyword("ROLE");
12154 self.write_space();
12155 } else if principal.is_group {
12156 self.write_keyword("GROUP");
12157 self.write_space();
12158 } else if principal.is_share {
12159 self.write_keyword("SHARE");
12160 self.write_space();
12161 }
12162 self.generate_identifier(&principal.name)?;
12163 }
12164
12165 if r.cascade {
12167 self.write_space();
12168 self.write_keyword("CASCADE");
12169 } else if r.restrict {
12170 self.write_space();
12171 self.write_keyword("RESTRICT");
12172 }
12173
12174 Ok(())
12175 }
12176
12177 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
12178 self.write_keyword("COMMENT");
12179
12180 if c.exists {
12182 self.write_space();
12183 self.write_keyword("IF EXISTS");
12184 }
12185
12186 self.write_space();
12187 self.write_keyword("ON");
12188
12189 if c.materialized {
12191 self.write_space();
12192 self.write_keyword("MATERIALIZED");
12193 }
12194
12195 self.write_space();
12196 self.write_keyword(&c.kind);
12197 self.write_space();
12198
12199 self.generate_expression(&c.this)?;
12201
12202 self.write_space();
12203 self.write_keyword("IS");
12204 self.write_space();
12205
12206 self.generate_expression(&c.expression)?;
12208
12209 Ok(())
12210 }
12211
12212 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
12213 self.write_keyword("SET");
12214
12215 for (i, item) in s.items.iter().enumerate() {
12216 if i > 0 {
12217 self.write(",");
12218 }
12219 self.write_space();
12220
12221 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
12223 if let Some(ref kind) = item.kind {
12224 if has_variable_kind {
12228 if matches!(
12229 self.config.dialect,
12230 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
12231 ) {
12232 self.write_keyword("VARIABLE");
12233 self.write_space();
12234 }
12235 } else {
12236 self.write_keyword(kind);
12237 self.write_space();
12238 }
12239 }
12240
12241 let name_str = match &item.name {
12243 Expression::Identifier(id) => Some(id.name.as_str()),
12244 _ => None,
12245 };
12246
12247 let is_transaction = name_str == Some("TRANSACTION");
12248 let is_character_set = name_str == Some("CHARACTER SET");
12249 let is_names = name_str == Some("NAMES");
12250 let is_collate = name_str == Some("COLLATE");
12251 let is_identity_insert = name_str == Some("IDENTITY_INSERT");
12252 let is_value_only =
12253 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
12254
12255 if is_transaction {
12256 self.write_keyword("TRANSACTION");
12258 if let Expression::Identifier(id) = &item.value {
12259 if !id.name.is_empty() {
12260 self.write_space();
12261 self.write(&id.name);
12262 }
12263 }
12264 } else if is_character_set {
12265 self.write_keyword("CHARACTER SET");
12267 self.write_space();
12268 self.generate_set_value(&item.value)?;
12269 } else if is_names {
12270 self.write_keyword("NAMES");
12272 self.write_space();
12273 self.generate_set_value(&item.value)?;
12274 } else if is_collate {
12275 self.write_keyword("COLLATE");
12277 self.write_space();
12278 self.generate_set_value(&item.value)?;
12279 } else if is_identity_insert {
12280 self.write_keyword("IDENTITY_INSERT");
12282 self.write_space();
12283 self.generate_identity_insert_value(&item.value)?;
12284 } else if has_variable_kind {
12285 if let Some(ns) = name_str {
12288 self.write(ns);
12289 } else {
12290 self.generate_expression(&item.name)?;
12291 }
12292 self.write(" = ");
12293 self.generate_set_value(&item.value)?;
12294 } else if is_value_only {
12295 self.generate_expression(&item.name)?;
12297 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
12298 self.generate_expression(&item.name)?;
12300 self.write_space();
12301 self.generate_set_value(&item.value)?;
12302 } else {
12303 match &item.name {
12306 Expression::Identifier(id) => {
12307 self.write(&id.name);
12308 }
12309 _ => {
12310 self.generate_expression(&item.name)?;
12311 }
12312 }
12313 self.write(" = ");
12314 self.generate_set_value(&item.value)?;
12315 }
12316 }
12317
12318 Ok(())
12319 }
12320
12321 fn generate_identity_insert_value(&mut self, value: &Expression) -> Result<()> {
12322 if let Expression::Tuple(tuple) = value {
12323 if tuple.expressions.len() == 2 {
12324 self.generate_expression(&tuple.expressions[0])?;
12325 self.write_space();
12326 self.generate_set_value(&tuple.expressions[1])?;
12327 return Ok(());
12328 }
12329 }
12330
12331 self.generate_set_value(value)
12332 }
12333
12334 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
12337 if let Expression::Identifier(id) = value {
12338 match id.name.as_str() {
12339 "DEFAULT" | "ON" | "OFF" => {
12340 self.write_keyword(&id.name);
12341 return Ok(());
12342 }
12343 _ => {}
12344 }
12345 }
12346 self.generate_expression(value)
12347 }
12348
12349 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
12352 self.write_keyword("ALTER");
12353 if let Some(ref algorithm) = av.algorithm {
12355 self.write_space();
12356 self.write_keyword("ALGORITHM");
12357 self.write(" = ");
12358 self.write_keyword(algorithm);
12359 }
12360 if let Some(ref definer) = av.definer {
12361 self.write_space();
12362 self.write_keyword("DEFINER");
12363 self.write(" = ");
12364 self.write(definer);
12365 }
12366 if let Some(ref sql_security) = av.sql_security {
12367 self.write_space();
12368 self.write_keyword("SQL SECURITY");
12369 self.write(" = ");
12370 self.write_keyword(sql_security);
12371 }
12372 self.write_space();
12373 self.write_keyword("VIEW");
12374 self.write_space();
12375 self.generate_table(&av.name)?;
12376
12377 if !av.columns.is_empty() {
12379 self.write(" (");
12380 for (i, col) in av.columns.iter().enumerate() {
12381 if i > 0 {
12382 self.write(", ");
12383 }
12384 self.generate_identifier(&col.name)?;
12385 if let Some(ref comment) = col.comment {
12386 self.write_space();
12387 self.write_keyword("COMMENT");
12388 self.write(" ");
12389 self.generate_string_literal(comment)?;
12390 }
12391 }
12392 self.write(")");
12393 }
12394
12395 if let Some(ref opt) = av.with_option {
12397 self.write_space();
12398 self.write_keyword("WITH");
12399 self.write_space();
12400 self.write_keyword(opt);
12401 }
12402
12403 for action in &av.actions {
12404 self.write_space();
12405 match action {
12406 AlterViewAction::Rename(new_name) => {
12407 self.write_keyword("RENAME TO");
12408 self.write_space();
12409 self.generate_table(new_name)?;
12410 }
12411 AlterViewAction::OwnerTo(owner) => {
12412 self.write_keyword("OWNER TO");
12413 self.write_space();
12414 self.generate_identifier(owner)?;
12415 }
12416 AlterViewAction::SetSchema(schema) => {
12417 self.write_keyword("SET SCHEMA");
12418 self.write_space();
12419 self.generate_identifier(schema)?;
12420 }
12421 AlterViewAction::SetAuthorization(auth) => {
12422 self.write_keyword("SET AUTHORIZATION");
12423 self.write_space();
12424 self.write(auth);
12425 }
12426 AlterViewAction::AlterColumn { name, action } => {
12427 self.write_keyword("ALTER COLUMN");
12428 self.write_space();
12429 self.generate_identifier(name)?;
12430 self.write_space();
12431 self.generate_alter_column_action(action)?;
12432 }
12433 AlterViewAction::AsSelect(query) => {
12434 self.write_keyword("AS");
12435 self.write_space();
12436 self.generate_expression(query)?;
12437 }
12438 AlterViewAction::SetTblproperties(props) => {
12439 self.write_keyword("SET TBLPROPERTIES");
12440 self.write(" (");
12441 for (i, (key, value)) in props.iter().enumerate() {
12442 if i > 0 {
12443 self.write(", ");
12444 }
12445 self.generate_string_literal(key)?;
12446 self.write("=");
12447 self.generate_string_literal(value)?;
12448 }
12449 self.write(")");
12450 }
12451 AlterViewAction::UnsetTblproperties(keys) => {
12452 self.write_keyword("UNSET TBLPROPERTIES");
12453 self.write(" (");
12454 for (i, key) in keys.iter().enumerate() {
12455 if i > 0 {
12456 self.write(", ");
12457 }
12458 self.generate_string_literal(key)?;
12459 }
12460 self.write(")");
12461 }
12462 }
12463 }
12464
12465 Ok(())
12466 }
12467
12468 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
12469 self.write_keyword("ALTER INDEX");
12470 self.write_space();
12471 self.generate_identifier(&ai.name)?;
12472
12473 if let Some(table) = &ai.table {
12474 self.write_space();
12475 self.write_keyword("ON");
12476 self.write_space();
12477 self.generate_table(table)?;
12478 }
12479
12480 for action in &ai.actions {
12481 self.write_space();
12482 match action {
12483 AlterIndexAction::Rename(new_name) => {
12484 self.write_keyword("RENAME TO");
12485 self.write_space();
12486 self.generate_identifier(new_name)?;
12487 }
12488 AlterIndexAction::SetTablespace(tablespace) => {
12489 self.write_keyword("SET TABLESPACE");
12490 self.write_space();
12491 self.generate_identifier(tablespace)?;
12492 }
12493 AlterIndexAction::Visible(visible) => {
12494 if *visible {
12495 self.write_keyword("VISIBLE");
12496 } else {
12497 self.write_keyword("INVISIBLE");
12498 }
12499 }
12500 }
12501 }
12502
12503 Ok(())
12504 }
12505
12506 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
12507 for comment in &cs.leading_comments {
12509 self.write_formatted_comment(comment);
12510 self.write_space();
12511 }
12512
12513 let saved_athena_hive_context = self.athena_hive_context;
12515 if matches!(
12516 self.config.dialect,
12517 Some(crate::dialects::DialectType::Athena)
12518 ) {
12519 self.athena_hive_context = true;
12520 }
12521
12522 self.write_keyword("CREATE SCHEMA");
12523
12524 if cs.if_not_exists {
12525 self.write_space();
12526 self.write_keyword("IF NOT EXISTS");
12527 }
12528
12529 self.write_space();
12530 for (i, part) in cs.name.iter().enumerate() {
12531 if i > 0 {
12532 self.write(".");
12533 }
12534 self.generate_identifier(part)?;
12535 }
12536
12537 if let Some(ref clone_parts) = cs.clone_from {
12538 self.write_keyword(" CLONE ");
12539 for (i, part) in clone_parts.iter().enumerate() {
12540 if i > 0 {
12541 self.write(".");
12542 }
12543 self.generate_identifier(part)?;
12544 }
12545 }
12546
12547 if let Some(ref at_clause) = cs.at_clause {
12548 self.write_space();
12549 self.generate_expression(at_clause)?;
12550 }
12551
12552 if let Some(auth) = &cs.authorization {
12553 self.write_space();
12554 self.write_keyword("AUTHORIZATION");
12555 self.write_space();
12556 self.generate_identifier(auth)?;
12557 }
12558
12559 let with_properties: Vec<_> = cs
12562 .properties
12563 .iter()
12564 .filter(|p| matches!(p, Expression::Property(_)))
12565 .collect();
12566 let other_properties: Vec<_> = cs
12567 .properties
12568 .iter()
12569 .filter(|p| !matches!(p, Expression::Property(_)))
12570 .collect();
12571
12572 if !with_properties.is_empty() {
12574 self.write_space();
12575 self.write_keyword("WITH");
12576 self.write(" (");
12577 for (i, prop) in with_properties.iter().enumerate() {
12578 if i > 0 {
12579 self.write(", ");
12580 }
12581 self.generate_expression(prop)?;
12582 }
12583 self.write(")");
12584 }
12585
12586 for prop in other_properties {
12588 self.write_space();
12589 self.generate_expression(prop)?;
12590 }
12591
12592 self.athena_hive_context = saved_athena_hive_context;
12594
12595 Ok(())
12596 }
12597
12598 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
12599 self.write_keyword("DROP SCHEMA");
12600
12601 if ds.if_exists {
12602 self.write_space();
12603 self.write_keyword("IF EXISTS");
12604 }
12605
12606 self.write_space();
12607 self.generate_identifier(&ds.name)?;
12608
12609 if ds.cascade {
12610 self.write_space();
12611 self.write_keyword("CASCADE");
12612 }
12613
12614 Ok(())
12615 }
12616
12617 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
12618 self.write_keyword("DROP NAMESPACE");
12619
12620 if dn.if_exists {
12621 self.write_space();
12622 self.write_keyword("IF EXISTS");
12623 }
12624
12625 self.write_space();
12626 self.generate_identifier(&dn.name)?;
12627
12628 if dn.cascade {
12629 self.write_space();
12630 self.write_keyword("CASCADE");
12631 }
12632
12633 Ok(())
12634 }
12635
12636 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
12637 self.write_keyword("CREATE DATABASE");
12638
12639 if cd.if_not_exists {
12640 self.write_space();
12641 self.write_keyword("IF NOT EXISTS");
12642 }
12643
12644 self.write_space();
12645 self.generate_identifier(&cd.name)?;
12646
12647 if let Some(ref clone_src) = cd.clone_from {
12648 self.write_keyword(" CLONE ");
12649 self.generate_identifier(clone_src)?;
12650 }
12651
12652 if let Some(ref at_clause) = cd.at_clause {
12654 self.write_space();
12655 self.generate_expression(at_clause)?;
12656 }
12657
12658 for option in &cd.options {
12659 self.write_space();
12660 match option {
12661 DatabaseOption::CharacterSet(charset) => {
12662 self.write_keyword("CHARACTER SET");
12663 self.write(" = ");
12664 self.write(&format!("'{}'", charset));
12665 }
12666 DatabaseOption::Collate(collate) => {
12667 self.write_keyword("COLLATE");
12668 self.write(" = ");
12669 self.write(&format!("'{}'", collate));
12670 }
12671 DatabaseOption::Owner(owner) => {
12672 self.write_keyword("OWNER");
12673 self.write(" = ");
12674 self.generate_identifier(owner)?;
12675 }
12676 DatabaseOption::Template(template) => {
12677 self.write_keyword("TEMPLATE");
12678 self.write(" = ");
12679 self.generate_identifier(template)?;
12680 }
12681 DatabaseOption::Encoding(encoding) => {
12682 self.write_keyword("ENCODING");
12683 self.write(" = ");
12684 self.write(&format!("'{}'", encoding));
12685 }
12686 DatabaseOption::Location(location) => {
12687 self.write_keyword("LOCATION");
12688 self.write(" = ");
12689 self.write(&format!("'{}'", location));
12690 }
12691 }
12692 }
12693
12694 Ok(())
12695 }
12696
12697 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
12698 self.write_keyword("DROP DATABASE");
12699
12700 if dd.if_exists {
12701 self.write_space();
12702 self.write_keyword("IF EXISTS");
12703 }
12704
12705 self.write_space();
12706 self.generate_identifier(&dd.name)?;
12707
12708 if dd.sync {
12709 self.write_space();
12710 self.write_keyword("SYNC");
12711 }
12712
12713 Ok(())
12714 }
12715
12716 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
12717 self.write_keyword("CREATE");
12718
12719 if cf.or_alter {
12720 self.write_space();
12721 self.write_keyword("OR ALTER");
12722 } else if cf.or_replace {
12723 self.write_space();
12724 self.write_keyword("OR REPLACE");
12725 }
12726
12727 if cf.temporary {
12728 self.write_space();
12729 self.write_keyword("TEMPORARY");
12730 }
12731
12732 self.write_space();
12733 if cf.is_table_function {
12734 self.write_keyword("TABLE FUNCTION");
12735 } else {
12736 self.write_keyword("FUNCTION");
12737 }
12738
12739 if cf.if_not_exists {
12740 self.write_space();
12741 self.write_keyword("IF NOT EXISTS");
12742 }
12743
12744 self.write_space();
12745 self.generate_table(&cf.name)?;
12746 if cf.has_parens {
12747 let func_multiline = self.config.pretty
12748 && matches!(
12749 self.config.dialect,
12750 Some(crate::dialects::DialectType::TSQL)
12751 | Some(crate::dialects::DialectType::Fabric)
12752 )
12753 && !cf.parameters.is_empty();
12754 if func_multiline {
12755 self.write("(\n");
12756 self.indent_level += 2;
12757 self.write_indent();
12758 self.generate_function_parameters(&cf.parameters)?;
12759 self.write("\n");
12760 self.indent_level -= 2;
12761 self.write(")");
12762 } else {
12763 self.write("(");
12764 self.generate_function_parameters(&cf.parameters)?;
12765 self.write(")");
12766 }
12767 }
12768
12769 let use_multiline = self.config.pretty
12772 && matches!(
12773 self.config.dialect,
12774 Some(crate::dialects::DialectType::BigQuery)
12775 | Some(crate::dialects::DialectType::TSQL)
12776 | Some(crate::dialects::DialectType::Fabric)
12777 );
12778
12779 if cf.language_first {
12780 if let Some(lang) = &cf.language {
12782 if use_multiline {
12783 self.write_newline();
12784 } else {
12785 self.write_space();
12786 }
12787 self.write_keyword("LANGUAGE");
12788 self.write_space();
12789 self.write(lang);
12790 }
12791
12792 if let Some(sql_data) = &cf.sql_data_access {
12794 self.write_space();
12795 match sql_data {
12796 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12797 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12798 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12799 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12800 }
12801 }
12802
12803 if let Some(ref rtb) = cf.returns_table_body {
12804 if use_multiline {
12805 self.write_newline();
12806 } else {
12807 self.write_space();
12808 }
12809 self.write_keyword("RETURNS");
12810 self.write_space();
12811 self.write(rtb);
12812 } else if let Some(return_type) = &cf.return_type {
12813 if use_multiline {
12814 self.write_newline();
12815 } else {
12816 self.write_space();
12817 }
12818 self.write_keyword("RETURNS");
12819 self.write_space();
12820 self.generate_data_type(return_type)?;
12821 }
12822 } else {
12823 let is_duckdb = matches!(
12826 self.config.dialect,
12827 Some(crate::dialects::DialectType::DuckDB)
12828 );
12829 if let Some(ref rtb) = cf.returns_table_body {
12830 if !(is_duckdb && rtb.is_empty()) {
12831 if use_multiline {
12832 self.write_newline();
12833 } else {
12834 self.write_space();
12835 }
12836 self.write_keyword("RETURNS");
12837 self.write_space();
12838 self.write(rtb);
12839 }
12840 } else if let Some(return_type) = &cf.return_type {
12841 if !is_duckdb {
12843 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
12844 if use_multiline {
12845 self.write_newline();
12846 } else {
12847 self.write_space();
12848 }
12849 self.write_keyword("RETURNS");
12850 self.write_space();
12851 if is_table_return {
12852 self.write_keyword("TABLE");
12853 } else {
12854 self.generate_data_type(return_type)?;
12855 }
12856 }
12857 }
12858 }
12859
12860 if !cf.property_order.is_empty() {
12862 let is_bigquery = matches!(
12864 self.config.dialect,
12865 Some(crate::dialects::DialectType::BigQuery)
12866 );
12867 let property_order = if is_bigquery {
12868 let mut reordered = Vec::new();
12870 let mut has_as = false;
12871 let mut has_options = false;
12872 for prop in &cf.property_order {
12873 match prop {
12874 FunctionPropertyKind::As => has_as = true,
12875 FunctionPropertyKind::Options => has_options = true,
12876 _ => {}
12877 }
12878 }
12879 if has_as && has_options {
12880 for prop in &cf.property_order {
12882 if *prop != FunctionPropertyKind::As
12883 && *prop != FunctionPropertyKind::Options
12884 {
12885 reordered.push(*prop);
12886 }
12887 }
12888 reordered.push(FunctionPropertyKind::Options);
12889 reordered.push(FunctionPropertyKind::As);
12890 reordered
12891 } else {
12892 cf.property_order.clone()
12893 }
12894 } else {
12895 cf.property_order.clone()
12896 };
12897
12898 for prop in &property_order {
12899 match prop {
12900 FunctionPropertyKind::Set => {
12901 self.generate_function_set_options(cf)?;
12902 }
12903 FunctionPropertyKind::As => {
12904 self.generate_function_body(cf)?;
12905 }
12906 FunctionPropertyKind::Using => {
12907 self.generate_function_using_resources(cf)?;
12908 }
12909 FunctionPropertyKind::Language => {
12910 if !cf.language_first {
12911 if let Some(lang) = &cf.language {
12913 let use_multiline = self.config.pretty
12915 && matches!(
12916 self.config.dialect,
12917 Some(crate::dialects::DialectType::BigQuery)
12918 );
12919 if use_multiline {
12920 self.write_newline();
12921 } else {
12922 self.write_space();
12923 }
12924 self.write_keyword("LANGUAGE");
12925 self.write_space();
12926 self.write(lang);
12927 }
12928 }
12929 }
12930 FunctionPropertyKind::Determinism => {
12931 self.generate_function_determinism(cf)?;
12932 }
12933 FunctionPropertyKind::NullInput => {
12934 self.generate_function_null_input(cf)?;
12935 }
12936 FunctionPropertyKind::Security => {
12937 self.generate_function_security(cf)?;
12938 }
12939 FunctionPropertyKind::SqlDataAccess => {
12940 if !cf.language_first {
12941 self.generate_function_sql_data_access(cf)?;
12943 }
12944 }
12945 FunctionPropertyKind::Options => {
12946 if !cf.options.is_empty() {
12947 self.write_space();
12948 self.generate_options_clause(&cf.options)?;
12949 }
12950 }
12951 FunctionPropertyKind::Environment => {
12952 if !cf.environment.is_empty() {
12953 self.write_space();
12954 self.generate_environment_clause(&cf.environment)?;
12955 }
12956 }
12957 FunctionPropertyKind::Handler => {
12958 if let Some(ref h) = cf.handler {
12959 self.write_space();
12960 self.write_keyword("HANDLER");
12961 if cf.handler_uses_eq {
12962 self.write(" = ");
12963 } else {
12964 self.write_space();
12965 }
12966 self.write("'");
12967 self.write(h);
12968 self.write("'");
12969 }
12970 }
12971 FunctionPropertyKind::RuntimeVersion => {
12972 if let Some(ref runtime_version) = cf.runtime_version {
12973 self.write_space();
12974 self.write_keyword("RUNTIME_VERSION");
12975 self.write("='");
12976 self.write(runtime_version);
12977 self.write("'");
12978 }
12979 }
12980 FunctionPropertyKind::Packages => {
12981 if let Some(ref packages) = cf.packages {
12982 self.write_space();
12983 self.write_keyword("PACKAGES");
12984 self.write("=(");
12985 for (i, package) in packages.iter().enumerate() {
12986 if i > 0 {
12987 self.write(", ");
12988 }
12989 self.write("'");
12990 self.write(package);
12991 self.write("'");
12992 }
12993 self.write(")");
12994 }
12995 }
12996 FunctionPropertyKind::ParameterStyle => {
12997 if let Some(ref ps) = cf.parameter_style {
12998 self.write_space();
12999 self.write_keyword("PARAMETER STYLE");
13000 self.write_space();
13001 self.write_keyword(ps);
13002 }
13003 }
13004 }
13005 }
13006
13007 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
13009 {
13010 self.write_space();
13011 self.generate_options_clause(&cf.options)?;
13012 }
13013
13014 if !cf.environment.is_empty()
13016 && !cf
13017 .property_order
13018 .contains(&FunctionPropertyKind::Environment)
13019 {
13020 self.write_space();
13021 self.generate_environment_clause(&cf.environment)?;
13022 }
13023 } else {
13024 if matches!(
13027 self.config.dialect,
13028 Some(crate::dialects::DialectType::BigQuery)
13029 ) {
13030 self.generate_function_determinism(cf)?;
13031 }
13032
13033 let use_multiline = self.config.pretty
13035 && matches!(
13036 self.config.dialect,
13037 Some(crate::dialects::DialectType::BigQuery)
13038 );
13039
13040 if !cf.language_first {
13041 if let Some(lang) = &cf.language {
13042 if use_multiline {
13043 self.write_newline();
13044 } else {
13045 self.write_space();
13046 }
13047 self.write_keyword("LANGUAGE");
13048 self.write_space();
13049 self.write(lang);
13050 }
13051
13052 self.generate_function_sql_data_access(cf)?;
13054 }
13055
13056 if !matches!(
13058 self.config.dialect,
13059 Some(crate::dialects::DialectType::BigQuery)
13060 ) {
13061 self.generate_function_determinism(cf)?;
13062 }
13063
13064 self.generate_function_null_input(cf)?;
13065 self.generate_function_security(cf)?;
13066 self.generate_function_set_options(cf)?;
13067
13068 if !cf.options.is_empty() {
13070 self.write_space();
13071 self.generate_options_clause(&cf.options)?;
13072 }
13073
13074 if !cf.environment.is_empty() {
13076 self.write_space();
13077 self.generate_environment_clause(&cf.environment)?;
13078 }
13079
13080 if let Some(ref h) = cf.handler {
13081 self.write_space();
13082 self.write_keyword("HANDLER");
13083 if cf.handler_uses_eq {
13084 self.write(" = ");
13085 } else {
13086 self.write_space();
13087 }
13088 self.write("'");
13089 self.write(h);
13090 self.write("'");
13091 }
13092
13093 if let Some(ref runtime_version) = cf.runtime_version {
13094 self.write_space();
13095 self.write_keyword("RUNTIME_VERSION");
13096 self.write("='");
13097 self.write(runtime_version);
13098 self.write("'");
13099 }
13100
13101 if let Some(ref packages) = cf.packages {
13102 self.write_space();
13103 self.write_keyword("PACKAGES");
13104 self.write("=(");
13105 for (i, package) in packages.iter().enumerate() {
13106 if i > 0 {
13107 self.write(", ");
13108 }
13109 self.write("'");
13110 self.write(package);
13111 self.write("'");
13112 }
13113 self.write(")");
13114 }
13115
13116 self.generate_function_body(cf)?;
13117 self.generate_function_using_resources(cf)?;
13118 }
13119
13120 Ok(())
13121 }
13122
13123 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
13125 for opt in &cf.set_options {
13126 self.write_space();
13127 self.write_keyword("SET");
13128 self.write_space();
13129 self.write(&opt.name);
13130 match &opt.value {
13131 FunctionSetValue::Value { value, use_to } => {
13132 if *use_to {
13133 self.write(" TO ");
13134 } else {
13135 self.write(" = ");
13136 }
13137 self.write(value);
13138 }
13139 FunctionSetValue::FromCurrent => {
13140 self.write_space();
13141 self.write_keyword("FROM CURRENT");
13142 }
13143 }
13144 }
13145 Ok(())
13146 }
13147
13148 fn generate_function_using_resources(&mut self, cf: &CreateFunction) -> Result<()> {
13149 if cf.using_resources.is_empty() {
13150 return Ok(());
13151 }
13152
13153 self.write_space();
13154 self.write_keyword("USING");
13155 for resource in &cf.using_resources {
13156 self.write_space();
13157 self.write_keyword(&resource.kind);
13158 self.write_space();
13159 self.generate_string_literal(&resource.uri)?;
13160 }
13161 Ok(())
13162 }
13163
13164 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
13166 if let Some(body) = &cf.body {
13167 self.write_space();
13169 let use_multiline = self.config.pretty
13171 && matches!(
13172 self.config.dialect,
13173 Some(crate::dialects::DialectType::BigQuery)
13174 );
13175 match body {
13176 FunctionBody::Block(block) => {
13177 self.write_keyword("AS");
13178 if matches!(
13179 self.config.dialect,
13180 Some(crate::dialects::DialectType::TSQL)
13181 ) {
13182 self.write(" BEGIN ");
13183 self.write(block);
13184 self.write(" END");
13185 } else if matches!(
13186 self.config.dialect,
13187 Some(crate::dialects::DialectType::PostgreSQL)
13188 ) {
13189 self.write(" $$");
13190 self.write(block);
13191 self.write("$$");
13192 } else {
13193 let escaped = self.escape_block_for_single_quote(block);
13195 if use_multiline {
13197 self.write_newline();
13198 } else {
13199 self.write(" ");
13200 }
13201 self.write("'");
13202 self.write(&escaped);
13203 self.write("'");
13204 }
13205 }
13206 FunctionBody::StringLiteral(s) => {
13207 self.write_keyword("AS");
13208 if use_multiline {
13210 self.write_newline();
13211 } else {
13212 self.write(" ");
13213 }
13214 self.write("'");
13215 self.write(s);
13216 self.write("'");
13217 }
13218 FunctionBody::Expression(expr) => {
13219 self.write_keyword("AS");
13220 self.write_space();
13221 self.generate_expression(expr)?;
13222 }
13223 FunctionBody::External(name) => {
13224 self.write_keyword("EXTERNAL NAME");
13225 self.write(" '");
13226 self.write(name);
13227 self.write("'");
13228 }
13229 FunctionBody::Return(expr) => {
13230 if matches!(
13231 self.config.dialect,
13232 Some(crate::dialects::DialectType::DuckDB)
13233 ) {
13234 self.write_keyword("AS");
13236 self.write_space();
13237 let is_table_return = cf.returns_table_body.is_some()
13239 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
13240 if is_table_return {
13241 self.write_keyword("TABLE");
13242 self.write_space();
13243 }
13244 self.generate_expression(expr)?;
13245 } else {
13246 if self.config.create_function_return_as {
13247 self.write_keyword("AS");
13248 if self.config.pretty
13250 && matches!(
13251 self.config.dialect,
13252 Some(crate::dialects::DialectType::TSQL)
13253 | Some(crate::dialects::DialectType::Fabric)
13254 )
13255 {
13256 self.write_newline();
13257 } else {
13258 self.write_space();
13259 }
13260 }
13261 self.write_keyword("RETURN");
13262 self.write_space();
13263 self.generate_expression(expr)?;
13264 }
13265 }
13266 FunctionBody::Statements(stmts) => {
13267 self.write_keyword("AS");
13268 self.write(" BEGIN ");
13269 for (i, stmt) in stmts.iter().enumerate() {
13270 if i > 0 {
13271 self.write(" ");
13272 }
13273 self.generate_expression(stmt)?;
13274 self.write(";");
13275 }
13276 self.write(" END");
13277 }
13278 FunctionBody::RawBlock(text) => {
13279 self.write_newline();
13280 self.write(text);
13281 }
13282 FunctionBody::DollarQuoted { content, tag } => {
13283 self.write_keyword("AS");
13284 self.write(" ");
13285 let supports_dollar_quoting = matches!(
13287 self.config.dialect,
13288 Some(crate::dialects::DialectType::PostgreSQL)
13289 | Some(crate::dialects::DialectType::Databricks)
13290 | Some(crate::dialects::DialectType::Redshift)
13291 | Some(crate::dialects::DialectType::DuckDB)
13292 );
13293 if supports_dollar_quoting {
13294 self.write("$");
13296 if let Some(t) = tag {
13297 self.write(t);
13298 }
13299 self.write("$");
13300 self.write(content);
13301 self.write("$");
13302 if let Some(t) = tag {
13303 self.write(t);
13304 }
13305 self.write("$");
13306 } else {
13307 let escaped = self.escape_block_for_single_quote(content);
13309 self.write("'");
13310 self.write(&escaped);
13311 self.write("'");
13312 }
13313 }
13314 }
13315 }
13316 Ok(())
13317 }
13318
13319 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
13321 if let Some(det) = cf.deterministic {
13322 self.write_space();
13323 if matches!(
13324 self.config.dialect,
13325 Some(crate::dialects::DialectType::BigQuery)
13326 ) {
13327 if det {
13329 self.write_keyword("DETERMINISTIC");
13330 } else {
13331 self.write_keyword("NOT DETERMINISTIC");
13332 }
13333 } else {
13334 if det {
13336 self.write_keyword("IMMUTABLE");
13337 } else {
13338 self.write_keyword("VOLATILE");
13339 }
13340 }
13341 }
13342 Ok(())
13343 }
13344
13345 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
13347 if let Some(returns_null) = cf.returns_null_on_null_input {
13348 self.write_space();
13349 if returns_null {
13350 if cf.strict {
13351 self.write_keyword("STRICT");
13352 } else {
13353 self.write_keyword("RETURNS NULL ON NULL INPUT");
13354 }
13355 } else {
13356 self.write_keyword("CALLED ON NULL INPUT");
13357 }
13358 }
13359 Ok(())
13360 }
13361
13362 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
13364 if let Some(security) = &cf.security {
13365 self.write_space();
13366 if matches!(
13368 self.config.dialect,
13369 Some(crate::dialects::DialectType::MySQL)
13370 ) {
13371 self.write_keyword("SQL SECURITY");
13372 } else {
13373 self.write_keyword("SECURITY");
13374 }
13375 self.write_space();
13376 match security {
13377 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13378 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13379 FunctionSecurity::None => self.write_keyword("NONE"),
13380 }
13381 }
13382 Ok(())
13383 }
13384
13385 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
13387 if let Some(sql_data) = &cf.sql_data_access {
13388 self.write_space();
13389 match sql_data {
13390 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13391 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13392 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13393 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13394 }
13395 }
13396 Ok(())
13397 }
13398
13399 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
13400 for (i, param) in params.iter().enumerate() {
13401 if i > 0 {
13402 self.write(", ");
13403 }
13404
13405 if let Some(mode) = ¶m.mode {
13406 if let Some(text) = ¶m.mode_text {
13407 self.write(text);
13408 } else {
13409 match mode {
13410 ParameterMode::In => self.write_keyword("IN"),
13411 ParameterMode::Out => self.write_keyword("OUT"),
13412 ParameterMode::InOut => self.write_keyword("INOUT"),
13413 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
13414 }
13415 }
13416 self.write_space();
13417 }
13418
13419 if let Some(name) = ¶m.name {
13420 self.generate_identifier(name)?;
13421 let skip_type =
13423 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
13424 if !skip_type {
13425 self.write_space();
13426 self.generate_data_type(¶m.data_type)?;
13427 }
13428 } else {
13429 self.generate_data_type(¶m.data_type)?;
13430 }
13431
13432 if let Some(default) = ¶m.default {
13433 if self.config.parameter_default_equals {
13434 self.write(" = ");
13435 } else {
13436 self.write(" DEFAULT ");
13437 }
13438 self.generate_expression(default)?;
13439 }
13440 }
13441
13442 Ok(())
13443 }
13444
13445 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
13446 self.write_keyword("DROP FUNCTION");
13447
13448 if df.if_exists {
13449 self.write_space();
13450 self.write_keyword("IF EXISTS");
13451 }
13452
13453 self.write_space();
13454 self.generate_table(&df.name)?;
13455
13456 if let Some(params) = &df.parameters {
13457 self.write(" (");
13458 for (i, dt) in params.iter().enumerate() {
13459 if i > 0 {
13460 self.write(", ");
13461 }
13462 self.generate_data_type(dt)?;
13463 }
13464 self.write(")");
13465 }
13466
13467 if df.cascade {
13468 self.write_space();
13469 self.write_keyword("CASCADE");
13470 }
13471
13472 Ok(())
13473 }
13474
13475 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
13476 self.write_keyword("CREATE");
13477
13478 if cp.or_alter {
13479 self.write_space();
13480 self.write_keyword("OR ALTER");
13481 } else if cp.or_replace {
13482 self.write_space();
13483 self.write_keyword("OR REPLACE");
13484 }
13485
13486 self.write_space();
13487 if cp.use_proc_keyword {
13488 self.write_keyword("PROC");
13489 } else {
13490 self.write_keyword("PROCEDURE");
13491 }
13492
13493 if cp.if_not_exists {
13494 self.write_space();
13495 self.write_keyword("IF NOT EXISTS");
13496 }
13497
13498 self.write_space();
13499 self.generate_table(&cp.name)?;
13500 if cp.has_parens {
13501 self.write("(");
13502 self.generate_function_parameters(&cp.parameters)?;
13503 self.write(")");
13504 } else if !cp.parameters.is_empty() {
13505 self.write_space();
13507 self.generate_function_parameters(&cp.parameters)?;
13508 }
13509
13510 if let Some(return_type) = &cp.return_type {
13512 self.write_space();
13513 self.write_keyword("RETURNS");
13514 self.write_space();
13515 self.generate_data_type(return_type)?;
13516 }
13517
13518 if let Some(execute_as) = &cp.execute_as {
13520 self.write_space();
13521 self.write_keyword("EXECUTE AS");
13522 self.write_space();
13523 self.write_keyword(execute_as);
13524 }
13525
13526 if let Some(lang) = &cp.language {
13527 self.write_space();
13528 self.write_keyword("LANGUAGE");
13529 self.write_space();
13530 self.write(lang);
13531 }
13532
13533 if let Some(security) = &cp.security {
13534 self.write_space();
13535 self.write_keyword("SECURITY");
13536 self.write_space();
13537 match security {
13538 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13539 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13540 FunctionSecurity::None => self.write_keyword("NONE"),
13541 }
13542 }
13543
13544 if !cp.with_options.is_empty() {
13546 self.write_space();
13547 self.write_keyword("WITH");
13548 self.write_space();
13549 for (i, opt) in cp.with_options.iter().enumerate() {
13550 if i > 0 {
13551 self.write(", ");
13552 }
13553 self.write(opt);
13554 }
13555 }
13556
13557 if let Some(body) = &cp.body {
13558 self.write_space();
13559 match body {
13560 FunctionBody::Block(block) => {
13561 self.write_keyword("AS");
13562 if matches!(
13563 self.config.dialect,
13564 Some(crate::dialects::DialectType::TSQL)
13565 ) {
13566 self.write(" BEGIN ");
13567 self.write(block);
13568 self.write(" END");
13569 } else if matches!(
13570 self.config.dialect,
13571 Some(crate::dialects::DialectType::PostgreSQL)
13572 ) {
13573 self.write(" $$");
13574 self.write(block);
13575 self.write("$$");
13576 } else {
13577 let escaped = self.escape_block_for_single_quote(block);
13579 self.write(" '");
13580 self.write(&escaped);
13581 self.write("'");
13582 }
13583 }
13584 FunctionBody::StringLiteral(s) => {
13585 self.write_keyword("AS");
13586 self.write(" '");
13587 self.write(s);
13588 self.write("'");
13589 }
13590 FunctionBody::Expression(expr) => {
13591 self.write_keyword("AS");
13592 self.write_space();
13593 self.generate_expression(expr)?;
13594 }
13595 FunctionBody::External(name) => {
13596 self.write_keyword("EXTERNAL NAME");
13597 self.write(" '");
13598 self.write(name);
13599 self.write("'");
13600 }
13601 FunctionBody::Return(expr) => {
13602 self.write_keyword("RETURN");
13603 self.write_space();
13604 self.generate_expression(expr)?;
13605 }
13606 FunctionBody::Statements(stmts) => {
13607 self.write_keyword("AS");
13608 self.write(" BEGIN ");
13609 for (i, stmt) in stmts.iter().enumerate() {
13610 if i > 0 {
13611 self.write(" ");
13612 }
13613 self.generate_expression(stmt)?;
13614 self.write(";");
13615 }
13616 self.write(" END");
13617 }
13618 FunctionBody::RawBlock(text) => {
13619 self.write_newline();
13620 self.write(text);
13621 }
13622 FunctionBody::DollarQuoted { content, tag } => {
13623 self.write_keyword("AS");
13624 self.write(" ");
13625 let supports_dollar_quoting = matches!(
13627 self.config.dialect,
13628 Some(crate::dialects::DialectType::PostgreSQL)
13629 | Some(crate::dialects::DialectType::Databricks)
13630 | Some(crate::dialects::DialectType::Redshift)
13631 | Some(crate::dialects::DialectType::DuckDB)
13632 );
13633 if supports_dollar_quoting {
13634 self.write("$");
13636 if let Some(t) = tag {
13637 self.write(t);
13638 }
13639 self.write("$");
13640 self.write(content);
13641 self.write("$");
13642 if let Some(t) = tag {
13643 self.write(t);
13644 }
13645 self.write("$");
13646 } else {
13647 let escaped = self.escape_block_for_single_quote(content);
13649 self.write("'");
13650 self.write(&escaped);
13651 self.write("'");
13652 }
13653 }
13654 }
13655 }
13656
13657 Ok(())
13658 }
13659
13660 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
13661 self.write_keyword("DROP PROCEDURE");
13662
13663 if dp.if_exists {
13664 self.write_space();
13665 self.write_keyword("IF EXISTS");
13666 }
13667
13668 self.write_space();
13669 self.generate_table(&dp.name)?;
13670
13671 if let Some(params) = &dp.parameters {
13672 self.write(" (");
13673 for (i, dt) in params.iter().enumerate() {
13674 if i > 0 {
13675 self.write(", ");
13676 }
13677 self.generate_data_type(dt)?;
13678 }
13679 self.write(")");
13680 }
13681
13682 if dp.cascade {
13683 self.write_space();
13684 self.write_keyword("CASCADE");
13685 }
13686
13687 Ok(())
13688 }
13689
13690 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
13691 self.write_keyword("CREATE");
13692
13693 if cs.or_replace {
13694 self.write_space();
13695 self.write_keyword("OR REPLACE");
13696 }
13697
13698 if cs.temporary {
13699 self.write_space();
13700 self.write_keyword("TEMPORARY");
13701 }
13702
13703 self.write_space();
13704 self.write_keyword("SEQUENCE");
13705
13706 if cs.if_not_exists {
13707 self.write_space();
13708 self.write_keyword("IF NOT EXISTS");
13709 }
13710
13711 self.write_space();
13712 self.generate_table(&cs.name)?;
13713
13714 if let Some(as_type) = &cs.as_type {
13716 self.write_space();
13717 self.write_keyword("AS");
13718 self.write_space();
13719 self.generate_data_type(as_type)?;
13720 }
13721
13722 if let Some(comment) = &cs.comment {
13724 self.write_space();
13725 self.write_keyword("COMMENT");
13726 self.write("=");
13727 self.generate_string_literal(comment)?;
13728 }
13729
13730 if !cs.property_order.is_empty() {
13732 for prop in &cs.property_order {
13733 match prop {
13734 SeqPropKind::Start => {
13735 if let Some(start) = cs.start {
13736 self.write_space();
13737 self.write_keyword("START WITH");
13738 self.write(&format!(" {}", start));
13739 }
13740 }
13741 SeqPropKind::Increment => {
13742 if let Some(inc) = cs.increment {
13743 self.write_space();
13744 self.write_keyword("INCREMENT BY");
13745 self.write(&format!(" {}", inc));
13746 }
13747 }
13748 SeqPropKind::Minvalue => {
13749 if let Some(min) = &cs.minvalue {
13750 self.write_space();
13751 match min {
13752 SequenceBound::Value(v) => {
13753 self.write_keyword("MINVALUE");
13754 self.write(&format!(" {}", v));
13755 }
13756 SequenceBound::None => {
13757 self.write_keyword("NO MINVALUE");
13758 }
13759 }
13760 }
13761 }
13762 SeqPropKind::Maxvalue => {
13763 if let Some(max) = &cs.maxvalue {
13764 self.write_space();
13765 match max {
13766 SequenceBound::Value(v) => {
13767 self.write_keyword("MAXVALUE");
13768 self.write(&format!(" {}", v));
13769 }
13770 SequenceBound::None => {
13771 self.write_keyword("NO MAXVALUE");
13772 }
13773 }
13774 }
13775 }
13776 SeqPropKind::Cache => {
13777 if let Some(cache) = cs.cache {
13778 self.write_space();
13779 self.write_keyword("CACHE");
13780 self.write(&format!(" {}", cache));
13781 }
13782 }
13783 SeqPropKind::NoCache => {
13784 self.write_space();
13785 self.write_keyword("NO CACHE");
13786 }
13787 SeqPropKind::NoCacheWord => {
13788 self.write_space();
13789 self.write_keyword("NOCACHE");
13790 }
13791 SeqPropKind::Cycle => {
13792 self.write_space();
13793 self.write_keyword("CYCLE");
13794 }
13795 SeqPropKind::NoCycle => {
13796 self.write_space();
13797 self.write_keyword("NO CYCLE");
13798 }
13799 SeqPropKind::NoCycleWord => {
13800 self.write_space();
13801 self.write_keyword("NOCYCLE");
13802 }
13803 SeqPropKind::OwnedBy => {
13804 if !cs.owned_by_none {
13806 if let Some(owned) = &cs.owned_by {
13807 self.write_space();
13808 self.write_keyword("OWNED BY");
13809 self.write_space();
13810 self.generate_table(owned)?;
13811 }
13812 }
13813 }
13814 SeqPropKind::Order => {
13815 self.write_space();
13816 self.write_keyword("ORDER");
13817 }
13818 SeqPropKind::NoOrder => {
13819 self.write_space();
13820 self.write_keyword("NOORDER");
13821 }
13822 SeqPropKind::Comment => {
13823 }
13825 SeqPropKind::Sharing => {
13826 if let Some(val) = &cs.sharing {
13827 self.write_space();
13828 self.write(&format!("SHARING={}", val));
13829 }
13830 }
13831 SeqPropKind::Keep => {
13832 self.write_space();
13833 self.write_keyword("KEEP");
13834 }
13835 SeqPropKind::NoKeep => {
13836 self.write_space();
13837 self.write_keyword("NOKEEP");
13838 }
13839 SeqPropKind::Scale => {
13840 self.write_space();
13841 self.write_keyword("SCALE");
13842 if let Some(modifier) = &cs.scale_modifier {
13843 if !modifier.is_empty() {
13844 self.write_space();
13845 self.write_keyword(modifier);
13846 }
13847 }
13848 }
13849 SeqPropKind::NoScale => {
13850 self.write_space();
13851 self.write_keyword("NOSCALE");
13852 }
13853 SeqPropKind::Shard => {
13854 self.write_space();
13855 self.write_keyword("SHARD");
13856 if let Some(modifier) = &cs.shard_modifier {
13857 if !modifier.is_empty() {
13858 self.write_space();
13859 self.write_keyword(modifier);
13860 }
13861 }
13862 }
13863 SeqPropKind::NoShard => {
13864 self.write_space();
13865 self.write_keyword("NOSHARD");
13866 }
13867 SeqPropKind::Session => {
13868 self.write_space();
13869 self.write_keyword("SESSION");
13870 }
13871 SeqPropKind::Global => {
13872 self.write_space();
13873 self.write_keyword("GLOBAL");
13874 }
13875 SeqPropKind::NoMinvalueWord => {
13876 self.write_space();
13877 self.write_keyword("NOMINVALUE");
13878 }
13879 SeqPropKind::NoMaxvalueWord => {
13880 self.write_space();
13881 self.write_keyword("NOMAXVALUE");
13882 }
13883 }
13884 }
13885 } else {
13886 if let Some(inc) = cs.increment {
13888 self.write_space();
13889 self.write_keyword("INCREMENT BY");
13890 self.write(&format!(" {}", inc));
13891 }
13892
13893 if let Some(min) = &cs.minvalue {
13894 self.write_space();
13895 match min {
13896 SequenceBound::Value(v) => {
13897 self.write_keyword("MINVALUE");
13898 self.write(&format!(" {}", v));
13899 }
13900 SequenceBound::None => {
13901 self.write_keyword("NO MINVALUE");
13902 }
13903 }
13904 }
13905
13906 if let Some(max) = &cs.maxvalue {
13907 self.write_space();
13908 match max {
13909 SequenceBound::Value(v) => {
13910 self.write_keyword("MAXVALUE");
13911 self.write(&format!(" {}", v));
13912 }
13913 SequenceBound::None => {
13914 self.write_keyword("NO MAXVALUE");
13915 }
13916 }
13917 }
13918
13919 if let Some(start) = cs.start {
13920 self.write_space();
13921 self.write_keyword("START WITH");
13922 self.write(&format!(" {}", start));
13923 }
13924
13925 if let Some(cache) = cs.cache {
13926 self.write_space();
13927 self.write_keyword("CACHE");
13928 self.write(&format!(" {}", cache));
13929 }
13930
13931 if cs.cycle {
13932 self.write_space();
13933 self.write_keyword("CYCLE");
13934 }
13935
13936 if let Some(owned) = &cs.owned_by {
13937 self.write_space();
13938 self.write_keyword("OWNED BY");
13939 self.write_space();
13940 self.generate_table(owned)?;
13941 }
13942 }
13943
13944 Ok(())
13945 }
13946
13947 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
13948 self.write_keyword("DROP SEQUENCE");
13949
13950 if ds.if_exists {
13951 self.write_space();
13952 self.write_keyword("IF EXISTS");
13953 }
13954
13955 self.write_space();
13956 self.generate_table(&ds.name)?;
13957
13958 if ds.cascade {
13959 self.write_space();
13960 self.write_keyword("CASCADE");
13961 }
13962
13963 Ok(())
13964 }
13965
13966 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
13967 self.write_keyword("ALTER SEQUENCE");
13968
13969 if als.if_exists {
13970 self.write_space();
13971 self.write_keyword("IF EXISTS");
13972 }
13973
13974 self.write_space();
13975 self.generate_table(&als.name)?;
13976
13977 if let Some(inc) = als.increment {
13978 self.write_space();
13979 self.write_keyword("INCREMENT BY");
13980 self.write(&format!(" {}", inc));
13981 }
13982
13983 if let Some(min) = &als.minvalue {
13984 self.write_space();
13985 match min {
13986 SequenceBound::Value(v) => {
13987 self.write_keyword("MINVALUE");
13988 self.write(&format!(" {}", v));
13989 }
13990 SequenceBound::None => {
13991 self.write_keyword("NO MINVALUE");
13992 }
13993 }
13994 }
13995
13996 if let Some(max) = &als.maxvalue {
13997 self.write_space();
13998 match max {
13999 SequenceBound::Value(v) => {
14000 self.write_keyword("MAXVALUE");
14001 self.write(&format!(" {}", v));
14002 }
14003 SequenceBound::None => {
14004 self.write_keyword("NO MAXVALUE");
14005 }
14006 }
14007 }
14008
14009 if let Some(start) = als.start {
14010 self.write_space();
14011 self.write_keyword("START WITH");
14012 self.write(&format!(" {}", start));
14013 }
14014
14015 if let Some(restart) = &als.restart {
14016 self.write_space();
14017 self.write_keyword("RESTART");
14018 if let Some(val) = restart {
14019 self.write_keyword(" WITH");
14020 self.write(&format!(" {}", val));
14021 }
14022 }
14023
14024 if let Some(cache) = als.cache {
14025 self.write_space();
14026 self.write_keyword("CACHE");
14027 self.write(&format!(" {}", cache));
14028 }
14029
14030 if let Some(cycle) = als.cycle {
14031 self.write_space();
14032 if cycle {
14033 self.write_keyword("CYCLE");
14034 } else {
14035 self.write_keyword("NO CYCLE");
14036 }
14037 }
14038
14039 if let Some(owned) = &als.owned_by {
14040 self.write_space();
14041 self.write_keyword("OWNED BY");
14042 self.write_space();
14043 if let Some(table) = owned {
14044 self.generate_table(table)?;
14045 } else {
14046 self.write_keyword("NONE");
14047 }
14048 }
14049
14050 Ok(())
14051 }
14052
14053 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
14054 self.write_keyword("CREATE");
14055
14056 if ct.or_alter {
14057 self.write_space();
14058 self.write_keyword("OR ALTER");
14059 } else if ct.or_replace {
14060 self.write_space();
14061 self.write_keyword("OR REPLACE");
14062 }
14063
14064 if ct.constraint {
14065 self.write_space();
14066 self.write_keyword("CONSTRAINT");
14067 }
14068
14069 self.write_space();
14070 self.write_keyword("TRIGGER");
14071 self.write_space();
14072 self.generate_identifier(&ct.name)?;
14073
14074 self.write_space();
14075 match ct.timing {
14076 TriggerTiming::Before => self.write_keyword("BEFORE"),
14077 TriggerTiming::After => self.write_keyword("AFTER"),
14078 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
14079 }
14080
14081 for (i, event) in ct.events.iter().enumerate() {
14083 if i > 0 {
14084 self.write_keyword(" OR");
14085 }
14086 self.write_space();
14087 match event {
14088 TriggerEvent::Insert => self.write_keyword("INSERT"),
14089 TriggerEvent::Update(cols) => {
14090 self.write_keyword("UPDATE");
14091 if let Some(cols) = cols {
14092 self.write_space();
14093 self.write_keyword("OF");
14094 for (j, col) in cols.iter().enumerate() {
14095 if j > 0 {
14096 self.write(",");
14097 }
14098 self.write_space();
14099 self.generate_identifier(col)?;
14100 }
14101 }
14102 }
14103 TriggerEvent::Delete => self.write_keyword("DELETE"),
14104 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
14105 }
14106 }
14107
14108 self.write_space();
14109 self.write_keyword("ON");
14110 self.write_space();
14111 self.generate_table(&ct.table)?;
14112
14113 if let Some(ref_clause) = &ct.referencing {
14115 self.write_space();
14116 self.write_keyword("REFERENCING");
14117 if let Some(old_table) = &ref_clause.old_table {
14118 self.write_space();
14119 self.write_keyword("OLD TABLE AS");
14120 self.write_space();
14121 self.generate_identifier(old_table)?;
14122 }
14123 if let Some(new_table) = &ref_clause.new_table {
14124 self.write_space();
14125 self.write_keyword("NEW TABLE AS");
14126 self.write_space();
14127 self.generate_identifier(new_table)?;
14128 }
14129 if let Some(old_row) = &ref_clause.old_row {
14130 self.write_space();
14131 self.write_keyword("OLD ROW AS");
14132 self.write_space();
14133 self.generate_identifier(old_row)?;
14134 }
14135 if let Some(new_row) = &ref_clause.new_row {
14136 self.write_space();
14137 self.write_keyword("NEW ROW AS");
14138 self.write_space();
14139 self.generate_identifier(new_row)?;
14140 }
14141 }
14142
14143 if let Some(deferrable) = ct.deferrable {
14145 self.write_space();
14146 if deferrable {
14147 self.write_keyword("DEFERRABLE");
14148 } else {
14149 self.write_keyword("NOT DEFERRABLE");
14150 }
14151 }
14152
14153 if let Some(initially) = ct.initially_deferred {
14154 self.write_space();
14155 self.write_keyword("INITIALLY");
14156 self.write_space();
14157 if initially {
14158 self.write_keyword("DEFERRED");
14159 } else {
14160 self.write_keyword("IMMEDIATE");
14161 }
14162 }
14163
14164 if let Some(for_each) = ct.for_each {
14165 self.write_space();
14166 self.write_keyword("FOR EACH");
14167 self.write_space();
14168 match for_each {
14169 TriggerForEach::Row => self.write_keyword("ROW"),
14170 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
14171 }
14172 }
14173
14174 if let Some(when) = &ct.when {
14176 self.write_space();
14177 self.write_keyword("WHEN");
14178 if ct.when_paren {
14179 self.write(" (");
14180 self.generate_expression(when)?;
14181 self.write(")");
14182 } else {
14183 self.write_space();
14184 self.generate_expression(when)?;
14185 }
14186 }
14187
14188 self.write_space();
14190 match &ct.body {
14191 TriggerBody::Execute { function, args } => {
14192 self.write_keyword("EXECUTE FUNCTION");
14193 self.write_space();
14194 self.generate_table(function)?;
14195 self.write("(");
14196 for (i, arg) in args.iter().enumerate() {
14197 if i > 0 {
14198 self.write(", ");
14199 }
14200 self.generate_expression(arg)?;
14201 }
14202 self.write(")");
14203 }
14204 TriggerBody::Block(block) => {
14205 self.write_keyword("BEGIN");
14206 self.write_space();
14207 self.write(block);
14208 self.write_space();
14209 self.write_keyword("END");
14210 }
14211 }
14212
14213 Ok(())
14214 }
14215
14216 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
14217 self.write_keyword("DROP TRIGGER");
14218
14219 if dt.if_exists {
14220 self.write_space();
14221 self.write_keyword("IF EXISTS");
14222 }
14223
14224 self.write_space();
14225 self.generate_identifier(&dt.name)?;
14226
14227 if let Some(table) = &dt.table {
14228 self.write_space();
14229 self.write_keyword("ON");
14230 self.write_space();
14231 self.generate_table(table)?;
14232 }
14233
14234 if dt.cascade {
14235 self.write_space();
14236 self.write_keyword("CASCADE");
14237 }
14238
14239 Ok(())
14240 }
14241
14242 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
14243 self.write_keyword("CREATE TYPE");
14244
14245 if ct.if_not_exists {
14246 self.write_space();
14247 self.write_keyword("IF NOT EXISTS");
14248 }
14249
14250 self.write_space();
14251 self.generate_table(&ct.name)?;
14252
14253 if let TypeDefinition::Base {
14254 input,
14255 output,
14256 internallength,
14257 } = &ct.definition
14258 {
14259 if input.is_empty() && output.is_empty() && internallength.is_none() {
14260 return Ok(());
14261 }
14262 }
14263
14264 self.write_space();
14265 self.write_keyword("AS");
14266 self.write_space();
14267
14268 match &ct.definition {
14269 TypeDefinition::Enum(values) => {
14270 self.write_keyword("ENUM");
14271 self.write(" (");
14272 for (i, val) in values.iter().enumerate() {
14273 if i > 0 {
14274 self.write(", ");
14275 }
14276 self.write(&format!("'{}'", val));
14277 }
14278 self.write(")");
14279 }
14280 TypeDefinition::Composite(attrs) => {
14281 self.write("(");
14282 for (i, attr) in attrs.iter().enumerate() {
14283 if i > 0 {
14284 self.write(", ");
14285 }
14286 self.generate_identifier(&attr.name)?;
14287 self.write_space();
14288 self.generate_data_type(&attr.data_type)?;
14289 if let Some(collate) = &attr.collate {
14290 self.write_space();
14291 self.write_keyword("COLLATE");
14292 self.write_space();
14293 self.generate_identifier(collate)?;
14294 }
14295 }
14296 self.write(")");
14297 }
14298 TypeDefinition::Range {
14299 subtype,
14300 subtype_diff,
14301 canonical,
14302 } => {
14303 self.write_keyword("RANGE");
14304 self.write(" (");
14305 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14306 self.write("subtype");
14307 } else {
14308 self.write_keyword("SUBTYPE");
14309 }
14310 self.write(" = ");
14311 self.generate_data_type(subtype)?;
14312 if let Some(diff) = subtype_diff {
14313 self.write(", ");
14314 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14315 self.write("subtype_diff");
14316 } else {
14317 self.write_keyword("SUBTYPE_DIFF");
14318 }
14319 self.write(" = ");
14320 self.write(diff);
14321 }
14322 if let Some(canon) = canonical {
14323 self.write(", ");
14324 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
14325 self.write("canonical");
14326 } else {
14327 self.write_keyword("CANONICAL");
14328 }
14329 self.write(" = ");
14330 self.write(canon);
14331 }
14332 self.write(")");
14333 }
14334 TypeDefinition::Base {
14335 input,
14336 output,
14337 internallength,
14338 } => {
14339 self.write("(");
14340 self.write_keyword("INPUT");
14341 self.write(" = ");
14342 self.write(input);
14343 self.write(", ");
14344 self.write_keyword("OUTPUT");
14345 self.write(" = ");
14346 self.write(output);
14347 if let Some(len) = internallength {
14348 self.write(", ");
14349 self.write_keyword("INTERNALLENGTH");
14350 self.write(" = ");
14351 self.write(&len.to_string());
14352 }
14353 self.write(")");
14354 }
14355 TypeDefinition::Domain {
14356 base_type,
14357 default,
14358 constraints,
14359 } => {
14360 self.generate_data_type(base_type)?;
14361 if let Some(def) = default {
14362 self.write_space();
14363 self.write_keyword("DEFAULT");
14364 self.write_space();
14365 self.generate_expression(def)?;
14366 }
14367 for constr in constraints {
14368 self.write_space();
14369 if let Some(name) = &constr.name {
14370 self.write_keyword("CONSTRAINT");
14371 self.write_space();
14372 self.generate_identifier(name)?;
14373 self.write_space();
14374 }
14375 self.write_keyword("CHECK");
14376 self.write(" (");
14377 self.generate_expression(&constr.check)?;
14378 self.write(")");
14379 }
14380 }
14381 }
14382
14383 Ok(())
14384 }
14385
14386 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
14387 self.write_keyword("CREATE");
14388 if task.or_replace {
14389 self.write_space();
14390 self.write_keyword("OR REPLACE");
14391 }
14392 self.write_space();
14393 self.write_keyword("TASK");
14394 if task.if_not_exists {
14395 self.write_space();
14396 self.write_keyword("IF NOT EXISTS");
14397 }
14398 self.write_space();
14399 self.write(&task.name);
14400 if !task.properties.is_empty() {
14401 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
14403 self.write_space();
14404 }
14405 self.write(&task.properties);
14406 }
14407 self.write_space();
14408 self.write_keyword("AS");
14409 self.write_space();
14410 self.generate_expression(&task.body)?;
14411 Ok(())
14412 }
14413
14414 fn generate_try_catch(&mut self, try_catch: &TryCatch) -> Result<()> {
14415 self.write_keyword("BEGIN TRY");
14416 self.generate_tsql_block_statements(&try_catch.try_body)?;
14417 self.write_keyword("END TRY");
14418
14419 if let Some(catch_body) = &try_catch.catch_body {
14420 if self.config.pretty {
14421 self.write_newline();
14422 self.write_indent();
14423 } else {
14424 self.write_space();
14425 }
14426 self.write_keyword("BEGIN CATCH");
14427 self.generate_tsql_block_statements(catch_body)?;
14428 self.write_keyword("END CATCH");
14429 }
14430
14431 Ok(())
14432 }
14433
14434 fn generate_tsql_block_statements(&mut self, statements: &[Expression]) -> Result<()> {
14435 if statements.is_empty() {
14436 self.write_space();
14437 return Ok(());
14438 }
14439
14440 if self.config.pretty {
14441 self.indent_level += 1;
14442 for stmt in statements {
14443 self.write_newline();
14444 self.write_indent();
14445 self.generate_expression(stmt)?;
14446 self.write(";");
14447 }
14448 self.indent_level -= 1;
14449 self.write_newline();
14450 self.write_indent();
14451 } else {
14452 self.write_space();
14453 for (i, stmt) in statements.iter().enumerate() {
14454 if i > 0 {
14455 self.write_space();
14456 }
14457 self.generate_expression(stmt)?;
14458 self.write(";");
14459 }
14460 self.write_space();
14461 }
14462
14463 Ok(())
14464 }
14465
14466 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
14467 self.write_keyword("DROP TYPE");
14468
14469 if dt.if_exists {
14470 self.write_space();
14471 self.write_keyword("IF EXISTS");
14472 }
14473
14474 self.write_space();
14475 self.generate_table(&dt.name)?;
14476
14477 if dt.cascade {
14478 self.write_space();
14479 self.write_keyword("CASCADE");
14480 }
14481
14482 Ok(())
14483 }
14484
14485 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
14486 let saved_athena_hive_context = self.athena_hive_context;
14488 if matches!(
14489 self.config.dialect,
14490 Some(crate::dialects::DialectType::Athena)
14491 ) {
14492 self.athena_hive_context = true;
14493 }
14494
14495 for comment in &d.leading_comments {
14497 self.write_formatted_comment(comment);
14498 self.write(" ");
14499 }
14500
14501 self.write_keyword("DESCRIBE");
14502
14503 if d.extended {
14504 self.write_space();
14505 self.write_keyword("EXTENDED");
14506 } else if d.formatted {
14507 self.write_space();
14508 self.write_keyword("FORMATTED");
14509 }
14510
14511 if let Some(ref style) = d.style {
14513 self.write_space();
14514 self.write_keyword(style);
14515 }
14516
14517 let should_output_kind = match self.config.dialect {
14519 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
14521 false
14522 }
14523 Some(DialectType::Snowflake) => true,
14525 _ => d.kind.is_some(),
14526 };
14527 if should_output_kind {
14528 if let Some(ref kind) = d.kind {
14529 self.write_space();
14530 self.write_keyword(kind);
14531 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
14532 self.write_space();
14533 self.write_keyword("TABLE");
14534 }
14535 }
14536
14537 self.write_space();
14538 self.generate_expression(&d.target)?;
14539
14540 if !d.params.is_empty() {
14542 self.write("(");
14543 for (i, param) in d.params.iter().enumerate() {
14544 if i > 0 {
14545 self.write(", ");
14546 }
14547 self.write(param);
14548 }
14549 self.write(")");
14550 }
14551
14552 if let Some(ref partition) = d.partition {
14554 self.write_space();
14555 self.generate_expression(partition)?;
14556 }
14557
14558 if d.as_json {
14560 self.write_space();
14561 self.write_keyword("AS JSON");
14562 }
14563
14564 for (name, value) in &d.properties {
14566 self.write_space();
14567 self.write(name);
14568 self.write("=");
14569 self.write(value);
14570 }
14571
14572 self.athena_hive_context = saved_athena_hive_context;
14574
14575 Ok(())
14576 }
14577
14578 fn generate_show(&mut self, s: &Show) -> Result<()> {
14581 self.write_keyword("SHOW");
14582 self.write_space();
14583
14584 let show_terse = s.terse
14587 && !matches!(
14588 s.this.as_str(),
14589 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
14590 );
14591 if show_terse {
14592 self.write_keyword("TERSE");
14593 self.write_space();
14594 }
14595
14596 self.write_keyword(&s.this);
14598
14599 if let Some(ref target_expr) = s.target {
14601 self.write_space();
14602 self.generate_expression(target_expr)?;
14603 }
14604
14605 if s.history {
14607 self.write_space();
14608 self.write_keyword("HISTORY");
14609 }
14610
14611 if let Some(ref for_target) = s.for_target {
14613 self.write_space();
14614 self.write_keyword("FOR");
14615 self.write_space();
14616 self.generate_expression(for_target)?;
14617 }
14618
14619 use crate::dialects::DialectType;
14623 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
14624 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
14625 let mysql_tables_scope_as_from = is_mysql
14626 && matches!(s.this.as_str(), "TABLES" | "FULL TABLES")
14627 && s.scope_kind.as_deref() == Some("SCHEMA")
14628 && s.scope.is_some()
14629 && s.from.is_none();
14630
14631 if !is_snowflake && s.from.is_some() {
14632 if let Some(ref scope_kind) = s.scope_kind {
14636 self.write_space();
14637 self.write_keyword("IN");
14638 self.write_space();
14639 self.write_keyword(scope_kind);
14640 if let Some(ref scope) = s.scope {
14641 self.write_space();
14642 self.generate_expression(scope)?;
14643 }
14644 } else if let Some(ref scope) = s.scope {
14645 self.write_space();
14646 self.write_keyword("IN");
14647 self.write_space();
14648 self.generate_expression(scope)?;
14649 }
14650
14651 if let Some(ref from) = s.from {
14653 self.write_space();
14654 self.write_keyword("FROM");
14655 self.write_space();
14656 self.generate_expression(from)?;
14657 }
14658
14659 if let Some(ref db) = s.db {
14661 self.write_space();
14662 self.write_keyword("FROM");
14663 self.write_space();
14664 self.generate_expression(db)?;
14665 }
14666
14667 if let Some(ref like) = s.like {
14669 self.write_space();
14670 self.write_keyword("LIKE");
14671 self.write_space();
14672 self.generate_expression(like)?;
14673 }
14674 } else {
14675 if let Some(ref like) = s.like {
14679 self.write_space();
14680 self.write_keyword("LIKE");
14681 self.write_space();
14682 self.generate_expression(like)?;
14683 }
14684
14685 if mysql_tables_scope_as_from {
14687 self.write_space();
14688 self.write_keyword("FROM");
14689 self.write_space();
14690 self.generate_expression(s.scope.as_ref().unwrap())?;
14691 } else if let Some(ref scope_kind) = s.scope_kind {
14692 self.write_space();
14693 self.write_keyword("IN");
14694 self.write_space();
14695 self.write_keyword(scope_kind);
14696 if let Some(ref scope) = s.scope {
14697 self.write_space();
14698 self.generate_expression(scope)?;
14699 }
14700 } else if let Some(ref scope) = s.scope {
14701 self.write_space();
14702 self.write_keyword("IN");
14703 self.write_space();
14704 self.generate_expression(scope)?;
14705 }
14706 }
14707
14708 if let Some(ref starts_with) = s.starts_with {
14710 self.write_space();
14711 self.write_keyword("STARTS WITH");
14712 self.write_space();
14713 self.generate_expression(starts_with)?;
14714 }
14715
14716 if let Some(ref limit) = s.limit {
14718 self.write_space();
14719 self.generate_limit(limit)?;
14720 }
14721
14722 if is_snowflake {
14724 if let Some(ref from) = s.from {
14725 self.write_space();
14726 self.write_keyword("FROM");
14727 self.write_space();
14728 self.generate_expression(from)?;
14729 }
14730 }
14731
14732 if let Some(ref where_clause) = s.where_clause {
14734 self.write_space();
14735 self.write_keyword("WHERE");
14736 self.write_space();
14737 self.generate_expression(where_clause)?;
14738 }
14739
14740 if let Some(is_mutex) = s.mutex {
14742 self.write_space();
14743 if is_mutex {
14744 self.write_keyword("MUTEX");
14745 } else {
14746 self.write_keyword("STATUS");
14747 }
14748 }
14749
14750 if !s.privileges.is_empty() {
14752 self.write_space();
14753 self.write_keyword("WITH PRIVILEGES");
14754 self.write_space();
14755 for (i, priv_name) in s.privileges.iter().enumerate() {
14756 if i > 0 {
14757 self.write(", ");
14758 }
14759 self.write_keyword(priv_name);
14760 }
14761 }
14762
14763 Ok(())
14764 }
14765
14766 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
14769 use crate::dialects::DialectType;
14770 match lit {
14771 Literal::String(s) => {
14772 self.generate_string_literal(s)?;
14773 }
14774 Literal::Number(n) => {
14775 if matches!(self.config.dialect, Some(DialectType::MySQL))
14776 && n.len() > 2
14777 && (n.starts_with("0x") || n.starts_with("0X"))
14778 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
14779 {
14780 return self.generate_identifier(&Identifier {
14781 name: n.clone(),
14782 quoted: true,
14783 trailing_comments: Vec::new(),
14784 span: None,
14785 });
14786 }
14787 let n = if n.contains('_')
14791 && !matches!(
14792 self.config.dialect,
14793 Some(DialectType::ClickHouse)
14794 | Some(DialectType::DuckDB)
14795 | Some(DialectType::PostgreSQL)
14796 | Some(DialectType::Hive)
14797 | Some(DialectType::Spark)
14798 | Some(DialectType::Databricks)
14799 ) {
14800 std::borrow::Cow::Owned(n.replace('_', ""))
14801 } else {
14802 std::borrow::Cow::Borrowed(n.as_str())
14803 };
14804 if n.starts_with('.') {
14807 self.write("0");
14808 self.write(&n);
14809 } else if n.starts_with("-.") {
14810 self.write("-0");
14812 self.write(&n[1..]);
14813 } else {
14814 self.write(&n);
14815 }
14816 }
14817 Literal::HexString(h) => {
14818 match self.config.dialect {
14820 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
14821 self.write("0x");
14822 self.write(h);
14823 return Ok(());
14824 }
14825 Some(DialectType::Spark)
14826 | Some(DialectType::Databricks)
14827 | Some(DialectType::Teradata) => self.write("X'"),
14828 _ => self.write("x'"),
14829 }
14830 self.write(h);
14831 self.write("'");
14832 }
14833 Literal::HexNumber(h) => {
14834 match self.config.dialect {
14838 Some(DialectType::BigQuery)
14839 | Some(DialectType::ClickHouse)
14840 | Some(DialectType::TSQL)
14841 | Some(DialectType::Fabric) => {
14842 self.write("0x");
14843 self.write(h);
14844 }
14845 _ => {
14846 if let Ok(val) = u64::from_str_radix(h, 16) {
14848 self.write(&val.to_string());
14849 } else {
14850 self.write("0x");
14852 self.write(h);
14853 }
14854 }
14855 }
14856 }
14857 Literal::BitString(b) => {
14858 self.write("B'");
14860 self.write(b);
14861 self.write("'");
14862 }
14863 Literal::ByteString(b) => {
14864 self.write("b'");
14866 self.write_escaped_byte_string(b);
14868 self.write("'");
14869 }
14870 Literal::NationalString(s) => {
14871 let keep_n_prefix = matches!(
14874 self.config.dialect,
14875 Some(DialectType::TSQL)
14876 | Some(DialectType::Oracle)
14877 | Some(DialectType::MySQL)
14878 | None
14879 );
14880 if keep_n_prefix {
14881 self.write("N'");
14882 } else {
14883 self.write("'");
14884 }
14885 self.write(s);
14886 self.write("'");
14887 }
14888 Literal::Date(d) => {
14889 self.generate_date_literal(d)?;
14890 }
14891 Literal::Time(t) => {
14892 self.generate_time_literal(t)?;
14893 }
14894 Literal::Timestamp(ts) => {
14895 self.generate_timestamp_literal(ts)?;
14896 }
14897 Literal::Datetime(dt) => {
14898 self.generate_datetime_literal(dt)?;
14899 }
14900 Literal::TripleQuotedString(s, _quote_char) => {
14901 if matches!(
14903 self.config.dialect,
14904 Some(crate::dialects::DialectType::BigQuery)
14905 | Some(crate::dialects::DialectType::DuckDB)
14906 | Some(crate::dialects::DialectType::Snowflake)
14907 | Some(crate::dialects::DialectType::Spark)
14908 | Some(crate::dialects::DialectType::Hive)
14909 | Some(crate::dialects::DialectType::Presto)
14910 | Some(crate::dialects::DialectType::Trino)
14911 | Some(crate::dialects::DialectType::PostgreSQL)
14912 | Some(crate::dialects::DialectType::MySQL)
14913 | Some(crate::dialects::DialectType::Redshift)
14914 | Some(crate::dialects::DialectType::TSQL)
14915 | Some(crate::dialects::DialectType::Oracle)
14916 | Some(crate::dialects::DialectType::ClickHouse)
14917 | Some(crate::dialects::DialectType::Databricks)
14918 | Some(crate::dialects::DialectType::SQLite)
14919 ) {
14920 self.generate_string_literal(s)?;
14921 } else {
14922 let quotes = format!("{0}{0}{0}", _quote_char);
14924 self.write("es);
14925 self.write(s);
14926 self.write("es);
14927 }
14928 }
14929 Literal::EscapeString(s) => {
14930 use crate::dialects::DialectType;
14934 let content = if let Some(c) = s.strip_prefix("e:") {
14935 c
14936 } else if let Some(c) = s.strip_prefix("E:") {
14937 c
14938 } else {
14939 s.as_str()
14940 };
14941
14942 if matches!(
14944 self.config.dialect,
14945 Some(DialectType::MySQL) | Some(DialectType::TiDB)
14946 ) {
14947 self.write("'");
14948 self.write(&content.replace('\'', "''"));
14949 self.write("'");
14950 } else {
14951 let prefix = if matches!(
14953 self.config.dialect,
14954 Some(DialectType::SingleStore)
14955 | Some(DialectType::DuckDB)
14956 | Some(DialectType::PostgreSQL)
14957 | Some(DialectType::CockroachDB)
14958 | Some(DialectType::Materialize)
14959 | Some(DialectType::RisingWave)
14960 ) {
14961 "e'"
14962 } else {
14963 "E'"
14964 };
14965
14966 let normalized = content.replace("\\'", "''");
14968 self.write(prefix);
14969 self.write(&normalized);
14970 self.write("'");
14971 }
14972 }
14973 Literal::DollarString(s) => {
14974 use crate::dialects::DialectType;
14977 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
14979 let escape_backslash = matches!(
14981 self.config.dialect,
14982 Some(DialectType::ClickHouse) | Some(DialectType::Snowflake)
14983 );
14984 let use_backslash_quote =
14988 matches!(self.config.dialect, Some(DialectType::Snowflake));
14989
14990 let mut escaped = String::with_capacity(content.len() + 4);
14991 for ch in content.chars() {
14992 if escape_backslash && ch == '\\' {
14993 escaped.push('\\');
14995 escaped.push('\\');
14996 } else if ch == '\'' {
14997 if use_backslash_quote {
14998 escaped.push('\\');
14999 escaped.push('\'');
15000 } else {
15001 escaped.push('\'');
15002 escaped.push('\'');
15003 }
15004 } else {
15005 escaped.push(ch);
15006 }
15007 }
15008 self.write("'");
15009 self.write(&escaped);
15010 self.write("'");
15011 }
15012 Literal::RawString(s) => {
15013 use crate::dialects::DialectType;
15019
15020 let escape_backslash = matches!(
15022 self.config.dialect,
15023 Some(DialectType::BigQuery)
15024 | Some(DialectType::MySQL)
15025 | Some(DialectType::SingleStore)
15026 | Some(DialectType::TiDB)
15027 | Some(DialectType::Hive)
15028 | Some(DialectType::Spark)
15029 | Some(DialectType::Databricks)
15030 | Some(DialectType::Drill)
15031 | Some(DialectType::Snowflake)
15032 | Some(DialectType::Redshift)
15033 | Some(DialectType::ClickHouse)
15034 );
15035
15036 let backslash_escapes_quote = matches!(
15039 self.config.dialect,
15040 Some(DialectType::BigQuery)
15041 | Some(DialectType::Hive)
15042 | Some(DialectType::Spark)
15043 | Some(DialectType::Databricks)
15044 | Some(DialectType::Drill)
15045 | Some(DialectType::Snowflake)
15046 | Some(DialectType::Redshift)
15047 );
15048
15049 let supports_escape_sequences = escape_backslash;
15052
15053 let mut escaped = String::with_capacity(s.len() + 4);
15054 for ch in s.chars() {
15055 if escape_backslash && ch == '\\' {
15056 escaped.push('\\');
15058 escaped.push('\\');
15059 } else if ch == '\'' {
15060 if backslash_escapes_quote {
15061 escaped.push('\\');
15063 escaped.push('\'');
15064 } else {
15065 escaped.push('\'');
15067 escaped.push('\'');
15068 }
15069 } else if supports_escape_sequences {
15070 match ch {
15073 '\n' => {
15074 escaped.push('\\');
15075 escaped.push('n');
15076 }
15077 '\r' => {
15078 escaped.push('\\');
15079 escaped.push('r');
15080 }
15081 '\t' => {
15082 escaped.push('\\');
15083 escaped.push('t');
15084 }
15085 '\x07' => {
15086 escaped.push('\\');
15087 escaped.push('a');
15088 }
15089 '\x08' => {
15090 escaped.push('\\');
15091 escaped.push('b');
15092 }
15093 '\x0C' => {
15094 escaped.push('\\');
15095 escaped.push('f');
15096 }
15097 '\x0B' => {
15098 escaped.push('\\');
15099 escaped.push('v');
15100 }
15101 _ => escaped.push(ch),
15102 }
15103 } else {
15104 escaped.push(ch);
15105 }
15106 }
15107 self.write("'");
15108 self.write(&escaped);
15109 self.write("'");
15110 }
15111 }
15112 Ok(())
15113 }
15114
15115 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
15117 use crate::dialects::DialectType;
15118
15119 match self.config.dialect {
15120 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
15122 self.write("CAST('");
15123 self.write(d);
15124 self.write("' AS DATE)");
15125 }
15126 Some(DialectType::BigQuery) => {
15129 self.write("CAST('");
15130 self.write(d);
15131 self.write("' AS DATE)");
15132 }
15133 Some(DialectType::Exasol) => {
15136 self.write("CAST('");
15137 self.write(d);
15138 self.write("' AS DATE)");
15139 }
15140 Some(DialectType::Snowflake) => {
15143 self.write("CAST('");
15144 self.write(d);
15145 self.write("' AS DATE)");
15146 }
15147 Some(DialectType::PostgreSQL)
15149 | Some(DialectType::MySQL)
15150 | Some(DialectType::SingleStore)
15151 | Some(DialectType::TiDB)
15152 | Some(DialectType::Redshift) => {
15153 self.write("CAST('");
15154 self.write(d);
15155 self.write("' AS DATE)");
15156 }
15157 Some(DialectType::DuckDB)
15159 | Some(DialectType::Presto)
15160 | Some(DialectType::Trino)
15161 | Some(DialectType::Athena)
15162 | Some(DialectType::Spark)
15163 | Some(DialectType::Databricks)
15164 | Some(DialectType::Hive) => {
15165 self.write("CAST('");
15166 self.write(d);
15167 self.write("' AS DATE)");
15168 }
15169 Some(DialectType::Oracle) => {
15171 self.write("TO_DATE('");
15172 self.write(d);
15173 self.write("', 'YYYY-MM-DD')");
15174 }
15175 _ => {
15177 self.write_keyword("DATE");
15178 self.write(" '");
15179 self.write(d);
15180 self.write("'");
15181 }
15182 }
15183 Ok(())
15184 }
15185
15186 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
15188 use crate::dialects::DialectType;
15189
15190 match self.config.dialect {
15191 Some(DialectType::TSQL) => {
15193 self.write("CAST('");
15194 self.write(t);
15195 self.write("' AS TIME)");
15196 }
15197 _ => {
15199 self.write_keyword("TIME");
15200 self.write(" '");
15201 self.write(t);
15202 self.write("'");
15203 }
15204 }
15205 Ok(())
15206 }
15207
15208 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
15210 use crate::expressions::Literal;
15211
15212 match expr {
15213 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
15214 let Literal::Date(d) = lit.as_ref() else {
15215 unreachable!()
15216 };
15217 self.write("CAST('");
15219 self.write(d);
15220 self.write("' AS DATE)");
15221 }
15222 _ => {
15223 self.generate_expression(expr)?;
15225 }
15226 }
15227 Ok(())
15228 }
15229
15230 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
15232 use crate::dialects::DialectType;
15233
15234 match self.config.dialect {
15235 Some(DialectType::TSQL) => {
15237 self.write("CAST('");
15238 self.write(ts);
15239 self.write("' AS DATETIME2)");
15240 }
15241 Some(DialectType::BigQuery) => {
15244 self.write("CAST('");
15245 self.write(ts);
15246 self.write("' AS TIMESTAMP)");
15247 }
15248 Some(DialectType::Snowflake) => {
15251 self.write("CAST('");
15252 self.write(ts);
15253 self.write("' AS TIMESTAMP)");
15254 }
15255 Some(DialectType::Dremio) => {
15258 self.write("CAST('");
15259 self.write(ts);
15260 self.write("' AS TIMESTAMP)");
15261 }
15262 Some(DialectType::Exasol) => {
15265 self.write("CAST('");
15266 self.write(ts);
15267 self.write("' AS TIMESTAMP)");
15268 }
15269 Some(DialectType::Oracle) => {
15272 self.write("TO_TIMESTAMP('");
15273 self.write(ts);
15274 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
15275 }
15276 Some(DialectType::Presto) | Some(DialectType::Trino) => {
15278 if Self::timestamp_has_timezone(ts) {
15279 self.write("CAST('");
15280 self.write(ts);
15281 self.write("' AS TIMESTAMP WITH TIME ZONE)");
15282 } else {
15283 self.write("CAST('");
15284 self.write(ts);
15285 self.write("' AS TIMESTAMP)");
15286 }
15287 }
15288 Some(DialectType::ClickHouse) => {
15290 self.write("CAST('");
15291 self.write(ts);
15292 self.write("' AS Nullable(DateTime))");
15293 }
15294 Some(DialectType::Spark) => {
15296 self.write("CAST('");
15297 self.write(ts);
15298 self.write("' AS TIMESTAMP)");
15299 }
15300 Some(DialectType::Redshift) => {
15303 if ts == "epoch" {
15304 self.write_keyword("TIMESTAMP");
15305 self.write(" '");
15306 self.write(ts);
15307 self.write("'");
15308 } else {
15309 self.write("CAST('");
15310 self.write(ts);
15311 self.write("' AS TIMESTAMP)");
15312 }
15313 }
15314 Some(DialectType::PostgreSQL)
15316 | Some(DialectType::Hive)
15317 | Some(DialectType::SQLite)
15318 | Some(DialectType::DuckDB)
15319 | Some(DialectType::Athena)
15320 | Some(DialectType::Drill)
15321 | Some(DialectType::Teradata) => {
15322 self.write("CAST('");
15323 self.write(ts);
15324 self.write("' AS TIMESTAMP)");
15325 }
15326 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
15328 self.write("CAST('");
15329 self.write(ts);
15330 self.write("' AS DATETIME)");
15331 }
15332 Some(DialectType::Databricks) => {
15334 self.write("CAST('");
15335 self.write(ts);
15336 self.write("' AS TIMESTAMP_NTZ)");
15337 }
15338 _ => {
15340 self.write_keyword("TIMESTAMP");
15341 self.write(" '");
15342 self.write(ts);
15343 self.write("'");
15344 }
15345 }
15346 Ok(())
15347 }
15348
15349 fn timestamp_has_timezone(ts: &str) -> bool {
15352 let ts_lower = ts.to_ascii_lowercase();
15356
15357 let continent_prefixes = [
15359 "africa/",
15360 "america/",
15361 "antarctica/",
15362 "arctic/",
15363 "asia/",
15364 "atlantic/",
15365 "australia/",
15366 "europe/",
15367 "indian/",
15368 "pacific/",
15369 "etc/",
15370 "brazil/",
15371 "canada/",
15372 "chile/",
15373 "mexico/",
15374 "us/",
15375 ];
15376
15377 for prefix in &continent_prefixes {
15378 if ts_lower.contains(prefix) {
15379 return true;
15380 }
15381 }
15382
15383 let tz_abbrevs = [
15386 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
15387 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
15388 " sgt", " aest", " aedt", " acst", " acdt", " awst",
15389 ];
15390
15391 for abbrev in &tz_abbrevs {
15392 if ts_lower.ends_with(abbrev) {
15393 return true;
15394 }
15395 }
15396
15397 let trimmed = ts.trim();
15401 if let Some(last_space) = trimmed.rfind(' ') {
15402 let suffix = &trimmed[last_space + 1..];
15403 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
15404 let rest = &suffix[1..];
15406 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
15407 return true;
15408 }
15409 }
15410 }
15411
15412 false
15413 }
15414
15415 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
15417 use crate::dialects::DialectType;
15418
15419 match self.config.dialect {
15420 Some(DialectType::BigQuery) => {
15423 self.write("CAST('");
15424 self.write(dt);
15425 self.write("' AS DATETIME)");
15426 }
15427 Some(DialectType::DuckDB) => {
15429 self.write("CAST('");
15430 self.write(dt);
15431 self.write("' AS TIMESTAMP)");
15432 }
15433 _ => {
15436 self.write_keyword("DATETIME");
15437 self.write(" '");
15438 self.write(dt);
15439 self.write("'");
15440 }
15441 }
15442 Ok(())
15443 }
15444
15445 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
15447 use crate::dialects::DialectType;
15448
15449 match self.config.dialect {
15450 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
15454 self.write("'");
15456 for c in s.chars() {
15457 match c {
15458 '\'' => self.write("\\'"),
15459 '\\' => self.write("\\\\"),
15460 '\n' => self.write("\\n"),
15461 '\r' => self.write("\\r"),
15462 '\t' => self.write("\\t"),
15463 '\0' => self.write("\\0"),
15464 _ => self.output.push(c),
15465 }
15466 }
15467 self.write("'");
15468 }
15469 Some(DialectType::Drill) => {
15470 self.write("'");
15473 for c in s.chars() {
15474 match c {
15475 '\'' => self.write("''"),
15476 '\\' => self.write("\\\\"),
15477 '\n' => self.write("\\n"),
15478 '\r' => self.write("\\r"),
15479 '\t' => self.write("\\t"),
15480 '\0' => self.write("\\0"),
15481 _ => self.output.push(c),
15482 }
15483 }
15484 self.write("'");
15485 }
15486 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
15487 self.write("'");
15488 for c in s.chars() {
15489 match c {
15490 '\'' => self.write("''"),
15492 '\\' => self.write("\\\\"),
15493 '\n' => self.write("\\n"),
15494 '\r' => self.write("\\r"),
15495 '\t' => self.write("\\t"),
15496 '\0' => self.output.push('\0'),
15498 _ => self.output.push(c),
15499 }
15500 }
15501 self.write("'");
15502 }
15503 Some(DialectType::BigQuery) => {
15505 self.write("'");
15506 for c in s.chars() {
15507 match c {
15508 '\'' => self.write("\\'"),
15509 '\\' => self.write("\\\\"),
15510 '\n' => self.write("\\n"),
15511 '\r' => self.write("\\r"),
15512 '\t' => self.write("\\t"),
15513 '\0' => self.write("\\0"),
15514 '\x07' => self.write("\\a"),
15515 '\x08' => self.write("\\b"),
15516 '\x0C' => self.write("\\f"),
15517 '\x0B' => self.write("\\v"),
15518 _ => self.output.push(c),
15519 }
15520 }
15521 self.write("'");
15522 }
15523 Some(DialectType::Athena) => {
15527 if self.athena_hive_context {
15528 self.write("'");
15530 for c in s.chars() {
15531 match c {
15532 '\'' => self.write("\\'"),
15533 '\\' => self.write("\\\\"),
15534 '\n' => self.write("\\n"),
15535 '\r' => self.write("\\r"),
15536 '\t' => self.write("\\t"),
15537 '\0' => self.write("\\0"),
15538 _ => self.output.push(c),
15539 }
15540 }
15541 self.write("'");
15542 } else {
15543 self.write("'");
15545 for c in s.chars() {
15546 match c {
15547 '\'' => self.write("''"),
15548 _ => self.output.push(c),
15550 }
15551 }
15552 self.write("'");
15553 }
15554 }
15555 Some(DialectType::Snowflake) => {
15560 self.write("'");
15561 for c in s.chars() {
15562 match c {
15563 '\'' => self.write("\\'"),
15564 '\n' => self.write("\\n"),
15567 '\r' => self.write("\\r"),
15568 '\t' => self.write("\\t"),
15569 _ => self.output.push(c),
15570 }
15571 }
15572 self.write("'");
15573 }
15574 Some(DialectType::PostgreSQL) => {
15576 self.write("'");
15577 for c in s.chars() {
15578 match c {
15579 '\'' => self.write("''"),
15580 _ => self.output.push(c),
15581 }
15582 }
15583 self.write("'");
15584 }
15585 Some(DialectType::Redshift) => {
15587 self.write("'");
15588 for c in s.chars() {
15589 match c {
15590 '\'' => self.write("\\'"),
15591 _ => self.output.push(c),
15592 }
15593 }
15594 self.write("'");
15595 }
15596 Some(DialectType::Oracle) => {
15598 self.write("'");
15599 for ch in s.chars() {
15600 if ch == '\'' {
15601 self.output.push_str("''");
15602 } else {
15603 self.output.push(ch);
15604 }
15605 }
15606 self.write("'");
15607 }
15608 Some(DialectType::ClickHouse) => {
15611 self.write("'");
15612 for c in s.chars() {
15613 match c {
15614 '\'' => self.write("''"),
15615 '\\' => self.write("\\\\"),
15616 '\n' => self.write("\\n"),
15617 '\r' => self.write("\\r"),
15618 '\t' => self.write("\\t"),
15619 '\0' => self.write("\\0"),
15620 '\x07' => self.write("\\a"),
15621 '\x08' => self.write("\\b"),
15622 '\x0C' => self.write("\\f"),
15623 '\x0B' => self.write("\\v"),
15624 c if c.is_control() || (c as u32) < 0x20 => {
15626 let byte = c as u32;
15627 if byte < 256 {
15628 self.write(&format!("\\x{:02X}", byte));
15629 } else {
15630 self.output.push(c);
15631 }
15632 }
15633 _ => self.output.push(c),
15634 }
15635 }
15636 self.write("'");
15637 }
15638 _ => {
15641 self.write("'");
15642 for ch in s.chars() {
15643 if ch == '\'' {
15644 self.output.push_str("''");
15645 } else {
15646 self.output.push(ch);
15647 }
15648 }
15649 self.write("'");
15650 }
15651 }
15652 Ok(())
15653 }
15654
15655 fn write_escaped_byte_string(&mut self, s: &str) {
15658 for c in s.chars() {
15659 match c {
15660 '\'' => self.write("\\'"),
15662 '\\' => self.write("\\\\"),
15664 _ if !c.is_control() => self.output.push(c),
15666 _ => {
15668 let byte = c as u32;
15669 if byte < 256 {
15670 self.write(&format!("\\x{:02x}", byte));
15671 } else {
15672 for b in c.to_string().as_bytes() {
15674 self.write(&format!("\\x{:02x}", b));
15675 }
15676 }
15677 }
15678 }
15679 }
15680 }
15681
15682 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
15683 use crate::dialects::DialectType;
15684
15685 match self.config.dialect {
15687 Some(DialectType::TSQL) => {
15690 self.write(if b.value { "1" } else { "0" });
15691 }
15692 Some(DialectType::Oracle) => {
15694 self.write(if b.value { "1" } else { "0" });
15695 }
15696 Some(DialectType::MySQL) => {
15698 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15699 }
15700 _ => {
15702 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15703 }
15704 }
15705 Ok(())
15706 }
15707
15708 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
15711 let name = &id.name;
15712 let quote_style = &self.config.identifier_quote_style;
15713
15714 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
15718
15719 let output_name = if self.config.normalize_identifiers && !id.quoted {
15721 name.to_ascii_lowercase()
15722 } else {
15723 name.to_string()
15724 };
15725
15726 if needs_quoting {
15727 let quote_style = if matches!(self.config.dialect, Some(DialectType::ClickHouse))
15728 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
15729 && quote_style.start == '"'
15730 && output_name.contains('"')
15731 {
15732 &IdentifierQuoteStyle::BACKTICK
15733 } else {
15734 quote_style
15735 };
15736 let escaped_name = if quote_style.start == quote_style.end {
15738 output_name.replace(
15739 quote_style.end,
15740 &format!("{}{}", quote_style.end, quote_style.end),
15741 )
15742 } else {
15743 output_name.replace(
15744 quote_style.end,
15745 &format!("{}{}", quote_style.end, quote_style.end),
15746 )
15747 };
15748 self.write(&format!(
15749 "{}{}{}",
15750 quote_style.start, escaped_name, quote_style.end
15751 ));
15752 } else {
15753 self.write(&output_name);
15754 }
15755
15756 for comment in &id.trailing_comments {
15758 self.write(" ");
15759 self.write_formatted_comment(comment);
15760 }
15761 Ok(())
15762 }
15763
15764 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
15765 use crate::dialects::DialectType;
15766
15767 let name = &id.name;
15768
15769 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
15771 && self.athena_hive_context
15772 {
15773 &IdentifierQuoteStyle::BACKTICK
15774 } else {
15775 &self.config.identifier_quote_style
15776 };
15777
15778 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
15785 let needs_digit_quoting = starts_with_digit
15786 && !self.config.identifiers_can_start_with_digit
15787 && self.config.dialect.is_some();
15788 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
15789 && name.len() > 2
15790 && (name.starts_with("0x") || name.starts_with("0X"))
15791 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
15792 let clickhouse_unsafe_identifier =
15793 matches!(self.config.dialect, Some(DialectType::ClickHouse))
15794 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
15795 && !name.starts_with('{')
15796 && !name.contains('(')
15797 && !name.contains(')')
15798 && name != "?"
15799 && name
15800 .chars()
15801 .any(|c| !(c.is_ascii_alphanumeric() || c == '_'));
15802 let needs_quoting = id.quoted
15803 || self.is_reserved_keyword(name)
15804 || self.config.always_quote_identifiers
15805 || needs_digit_quoting
15806 || mysql_invalid_hex_identifier
15807 || clickhouse_unsafe_identifier;
15808
15809 let (base_name, suffix) = if needs_quoting {
15812 if let Some(paren_pos) = name.find('(') {
15814 let base = &name[..paren_pos];
15815 let rest = &name[paren_pos..];
15816 if rest.starts_with('(')
15818 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
15819 {
15820 let close_paren = rest.find(')').unwrap_or(rest.len());
15822 let inside = &rest[1..close_paren];
15823 if inside.chars().all(|c| c.is_ascii_digit()) {
15824 (base.to_string(), rest.to_string())
15825 } else {
15826 (name.to_string(), String::new())
15827 }
15828 } else {
15829 (name.to_string(), String::new())
15830 }
15831 } else if name.ends_with(" ASC") {
15832 let base = &name[..name.len() - 4];
15833 (base.to_string(), " ASC".to_string())
15834 } else if name.ends_with(" DESC") {
15835 let base = &name[..name.len() - 5];
15836 (base.to_string(), " DESC".to_string())
15837 } else {
15838 (name.to_string(), String::new())
15839 }
15840 } else {
15841 (name.to_string(), String::new())
15842 };
15843
15844 let output_name = if self.config.normalize_identifiers && !id.quoted {
15848 base_name.to_ascii_lowercase()
15849 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
15850 && !id.quoted
15851 && self.is_reserved_keyword(name)
15852 {
15853 base_name.to_ascii_uppercase()
15856 } else {
15857 base_name
15858 };
15859
15860 if needs_quoting {
15861 let escaped_name = if quote_style.start == quote_style.end {
15863 output_name.replace(
15865 quote_style.end,
15866 &format!("{}{}", quote_style.end, quote_style.end),
15867 )
15868 } else {
15869 output_name.replace(
15871 quote_style.end,
15872 &format!("{}{}", quote_style.end, quote_style.end),
15873 )
15874 };
15875 self.write(&format!(
15876 "{}{}{}{}",
15877 quote_style.start, escaped_name, quote_style.end, suffix
15878 ));
15879 } else {
15880 self.write(&output_name);
15881 }
15882
15883 for comment in &id.trailing_comments {
15885 self.write(" ");
15886 self.write_formatted_comment(comment);
15887 }
15888 Ok(())
15889 }
15890
15891 fn generate_column(&mut self, col: &Column) -> Result<()> {
15892 use crate::dialects::DialectType;
15893
15894 if let Some(table) = &col.table {
15895 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
15899 && !table.quoted
15900 && table.name.eq_ignore_ascii_case("LOCAL");
15901
15902 if is_exasol_local_prefix {
15903 self.write("LOCAL");
15905 } else {
15906 self.generate_identifier(table)?;
15907 }
15908 self.write(".");
15909 }
15910 self.generate_identifier(&col.name)?;
15911 if col.join_mark && self.config.supports_column_join_marks {
15914 self.write(" (+)");
15915 }
15916 for comment in &col.trailing_comments {
15918 self.write_space();
15919 self.write_formatted_comment(comment);
15920 }
15921 Ok(())
15922 }
15923
15924 fn generate_prepare(&mut self, prepare: &PrepareStatement) -> Result<()> {
15925 self.write_keyword("PREPARE");
15926 self.write_space();
15927 self.generate_identifier(&prepare.name)?;
15928
15929 if !prepare.parameter_types.is_empty() {
15930 self.write(" (");
15931 for (i, data_type) in prepare.parameter_types.iter().enumerate() {
15932 if i > 0 {
15933 self.write(", ");
15934 }
15935 self.generate_data_type(data_type)?;
15936 }
15937 self.write(")");
15938 }
15939
15940 self.write_space();
15941 self.write_keyword("AS");
15942 self.write_space();
15943 self.generate_expression(&prepare.statement)
15944 }
15945
15946 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
15949 use crate::dialects::DialectType;
15950 use crate::expressions::PseudocolumnType;
15951
15952 if pc.kind == PseudocolumnType::Sysdate
15954 && !matches!(
15955 self.config.dialect,
15956 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
15957 )
15958 {
15959 self.write_keyword("CURRENT_TIMESTAMP");
15960 if matches!(
15962 self.config.dialect,
15963 Some(DialectType::MySQL)
15964 | Some(DialectType::ClickHouse)
15965 | Some(DialectType::Spark)
15966 | Some(DialectType::Databricks)
15967 | Some(DialectType::Hive)
15968 ) {
15969 self.write("()");
15970 }
15971 } else {
15972 self.write(pc.kind.as_str());
15973 }
15974 Ok(())
15975 }
15976
15977 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
15979 use crate::dialects::DialectType;
15980
15981 let supports_connect_by = matches!(
15984 self.config.dialect,
15985 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
15986 );
15987
15988 if !supports_connect_by && self.config.dialect.is_some() {
15989 if self.config.pretty {
15991 self.write_newline();
15992 } else {
15993 self.write_space();
15994 }
15995 self.write_unsupported_comment(
15996 "CONNECT BY requires manual conversion to recursive CTE",
15997 )?;
15998 }
15999
16000 if let Some(start) = &connect.start {
16002 if self.config.pretty {
16003 self.write_newline();
16004 } else {
16005 self.write_space();
16006 }
16007 self.write_keyword("START WITH");
16008 self.write_space();
16009 self.generate_expression(start)?;
16010 }
16011
16012 if self.config.pretty {
16014 self.write_newline();
16015 } else {
16016 self.write_space();
16017 }
16018 self.write_keyword("CONNECT BY");
16019 if connect.nocycle {
16020 self.write_space();
16021 self.write_keyword("NOCYCLE");
16022 }
16023 self.write_space();
16024 self.generate_expression(&connect.connect)?;
16025
16026 Ok(())
16027 }
16028
16029 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
16031 self.generate_connect(connect)
16032 }
16033
16034 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
16036 self.write_keyword("PRIOR");
16037 self.write_space();
16038 self.generate_expression(&prior.this)?;
16039 Ok(())
16040 }
16041
16042 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
16045 self.write_keyword("CONNECT_BY_ROOT");
16046 self.write_space();
16047 self.generate_expression(&cbr.this)?;
16048 Ok(())
16049 }
16050
16051 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
16053 use crate::dialects::DialectType;
16054
16055 let supports_match_recognize = matches!(
16057 self.config.dialect,
16058 Some(DialectType::Oracle)
16059 | Some(DialectType::Snowflake)
16060 | Some(DialectType::Presto)
16061 | Some(DialectType::Trino)
16062 );
16063
16064 if let Some(source) = &mr.this {
16066 self.generate_expression(source)?;
16067 }
16068
16069 if !supports_match_recognize {
16070 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
16071 return Ok(());
16072 }
16073
16074 if self.config.pretty {
16076 self.write_newline();
16077 } else {
16078 self.write_space();
16079 }
16080
16081 self.write_keyword("MATCH_RECOGNIZE");
16082 self.write(" (");
16083
16084 if self.config.pretty {
16085 self.indent_level += 1;
16086 }
16087
16088 let mut needs_separator = false;
16089
16090 if let Some(partition_by) = &mr.partition_by {
16092 if !partition_by.is_empty() {
16093 if self.config.pretty {
16094 self.write_newline();
16095 self.write_indent();
16096 }
16097 self.write_keyword("PARTITION BY");
16098 self.write_space();
16099 for (i, expr) in partition_by.iter().enumerate() {
16100 if i > 0 {
16101 self.write(", ");
16102 }
16103 self.generate_expression(expr)?;
16104 }
16105 needs_separator = true;
16106 }
16107 }
16108
16109 if let Some(order_by) = &mr.order_by {
16111 if !order_by.is_empty() {
16112 if needs_separator {
16113 if self.config.pretty {
16114 self.write_newline();
16115 self.write_indent();
16116 } else {
16117 self.write_space();
16118 }
16119 } else if self.config.pretty {
16120 self.write_newline();
16121 self.write_indent();
16122 }
16123 self.write_keyword("ORDER BY");
16124 if self.config.pretty {
16126 self.indent_level += 1;
16127 for (i, ordered) in order_by.iter().enumerate() {
16128 if i > 0 {
16129 self.write(",");
16130 }
16131 self.write_newline();
16132 self.write_indent();
16133 self.generate_ordered(ordered)?;
16134 }
16135 self.indent_level -= 1;
16136 } else {
16137 self.write_space();
16138 for (i, ordered) in order_by.iter().enumerate() {
16139 if i > 0 {
16140 self.write(", ");
16141 }
16142 self.generate_ordered(ordered)?;
16143 }
16144 }
16145 needs_separator = true;
16146 }
16147 }
16148
16149 if let Some(measures) = &mr.measures {
16151 if !measures.is_empty() {
16152 if needs_separator {
16153 if self.config.pretty {
16154 self.write_newline();
16155 self.write_indent();
16156 } else {
16157 self.write_space();
16158 }
16159 } else if self.config.pretty {
16160 self.write_newline();
16161 self.write_indent();
16162 }
16163 self.write_keyword("MEASURES");
16164 if self.config.pretty {
16166 self.indent_level += 1;
16167 for (i, measure) in measures.iter().enumerate() {
16168 if i > 0 {
16169 self.write(",");
16170 }
16171 self.write_newline();
16172 self.write_indent();
16173 if let Some(semantics) = &measure.window_frame {
16175 match semantics {
16176 MatchRecognizeSemantics::Running => {
16177 self.write_keyword("RUNNING");
16178 self.write_space();
16179 }
16180 MatchRecognizeSemantics::Final => {
16181 self.write_keyword("FINAL");
16182 self.write_space();
16183 }
16184 }
16185 }
16186 self.generate_expression(&measure.this)?;
16187 }
16188 self.indent_level -= 1;
16189 } else {
16190 self.write_space();
16191 for (i, measure) in measures.iter().enumerate() {
16192 if i > 0 {
16193 self.write(", ");
16194 }
16195 if let Some(semantics) = &measure.window_frame {
16197 match semantics {
16198 MatchRecognizeSemantics::Running => {
16199 self.write_keyword("RUNNING");
16200 self.write_space();
16201 }
16202 MatchRecognizeSemantics::Final => {
16203 self.write_keyword("FINAL");
16204 self.write_space();
16205 }
16206 }
16207 }
16208 self.generate_expression(&measure.this)?;
16209 }
16210 }
16211 needs_separator = true;
16212 }
16213 }
16214
16215 if let Some(rows) = &mr.rows {
16217 if needs_separator {
16218 if self.config.pretty {
16219 self.write_newline();
16220 self.write_indent();
16221 } else {
16222 self.write_space();
16223 }
16224 } else if self.config.pretty {
16225 self.write_newline();
16226 self.write_indent();
16227 }
16228 match rows {
16229 MatchRecognizeRows::OneRowPerMatch => {
16230 self.write_keyword("ONE ROW PER MATCH");
16231 }
16232 MatchRecognizeRows::AllRowsPerMatch => {
16233 self.write_keyword("ALL ROWS PER MATCH");
16234 }
16235 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
16236 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
16237 }
16238 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
16239 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
16240 }
16241 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
16242 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
16243 }
16244 }
16245 needs_separator = true;
16246 }
16247
16248 if let Some(after) = &mr.after {
16250 if needs_separator {
16251 if self.config.pretty {
16252 self.write_newline();
16253 self.write_indent();
16254 } else {
16255 self.write_space();
16256 }
16257 } else if self.config.pretty {
16258 self.write_newline();
16259 self.write_indent();
16260 }
16261 match after {
16262 MatchRecognizeAfter::PastLastRow => {
16263 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
16264 }
16265 MatchRecognizeAfter::ToNextRow => {
16266 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
16267 }
16268 MatchRecognizeAfter::ToFirst(ident) => {
16269 self.write_keyword("AFTER MATCH SKIP TO FIRST");
16270 self.write_space();
16271 self.generate_identifier(ident)?;
16272 }
16273 MatchRecognizeAfter::ToLast(ident) => {
16274 self.write_keyword("AFTER MATCH SKIP TO LAST");
16275 self.write_space();
16276 self.generate_identifier(ident)?;
16277 }
16278 }
16279 needs_separator = true;
16280 }
16281
16282 if let Some(pattern) = &mr.pattern {
16284 if needs_separator {
16285 if self.config.pretty {
16286 self.write_newline();
16287 self.write_indent();
16288 } else {
16289 self.write_space();
16290 }
16291 } else if self.config.pretty {
16292 self.write_newline();
16293 self.write_indent();
16294 }
16295 self.write_keyword("PATTERN");
16296 self.write_space();
16297 self.write("(");
16298 self.write(pattern);
16299 self.write(")");
16300 needs_separator = true;
16301 }
16302
16303 if let Some(define) = &mr.define {
16305 if !define.is_empty() {
16306 if needs_separator {
16307 if self.config.pretty {
16308 self.write_newline();
16309 self.write_indent();
16310 } else {
16311 self.write_space();
16312 }
16313 } else if self.config.pretty {
16314 self.write_newline();
16315 self.write_indent();
16316 }
16317 self.write_keyword("DEFINE");
16318 if self.config.pretty {
16320 self.indent_level += 1;
16321 for (i, (name, expr)) in define.iter().enumerate() {
16322 if i > 0 {
16323 self.write(",");
16324 }
16325 self.write_newline();
16326 self.write_indent();
16327 self.generate_identifier(name)?;
16328 self.write(" AS ");
16329 self.generate_expression(expr)?;
16330 }
16331 self.indent_level -= 1;
16332 } else {
16333 self.write_space();
16334 for (i, (name, expr)) in define.iter().enumerate() {
16335 if i > 0 {
16336 self.write(", ");
16337 }
16338 self.generate_identifier(name)?;
16339 self.write(" AS ");
16340 self.generate_expression(expr)?;
16341 }
16342 }
16343 }
16344 }
16345
16346 if self.config.pretty {
16347 self.indent_level -= 1;
16348 self.write_newline();
16349 }
16350 self.write(")");
16351
16352 if let Some(alias) = &mr.alias {
16354 self.write(" ");
16355 if mr.alias_explicit_as {
16356 self.write_keyword("AS");
16357 self.write(" ");
16358 }
16359 self.generate_identifier(alias)?;
16360 }
16361
16362 Ok(())
16363 }
16364
16365 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
16367 use crate::dialects::DialectType;
16368
16369 let supports_hints = matches!(
16371 self.config.dialect,
16372 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
16374 Some(DialectType::Spark) | Some(DialectType::Hive) |
16375 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
16376 );
16377
16378 if !supports_hints || hint.expressions.is_empty() {
16379 return Ok(());
16380 }
16381
16382 let mut hint_strings: Vec<String> = Vec::new();
16385 for expr in &hint.expressions {
16386 match expr {
16387 HintExpression::Raw(text) => {
16388 let parsed = self.parse_raw_hint_text(text);
16390 hint_strings.extend(parsed);
16391 }
16392 _ => {
16393 hint_strings.push(self.hint_expression_to_string(expr)?);
16394 }
16395 }
16396 }
16397
16398 let use_multiline = self.config.pretty && hint_strings.len() > 1;
16402
16403 if use_multiline {
16404 self.write(" /*+ ");
16406 for (i, hint_str) in hint_strings.iter().enumerate() {
16407 if i > 0 {
16408 self.write_newline();
16409 self.write(" "); }
16411 self.write(hint_str);
16412 }
16413 self.write(" */");
16414 } else {
16415 self.write(" /*+ ");
16417 let sep = match self.config.dialect {
16418 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
16419 _ => " ",
16420 };
16421 for (i, hint_str) in hint_strings.iter().enumerate() {
16422 if i > 0 {
16423 self.write(sep);
16424 }
16425 self.write(hint_str);
16426 }
16427 self.write(" */");
16428 }
16429
16430 Ok(())
16431 }
16432
16433 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
16437 let mut results = Vec::new();
16438 let mut chars = text.chars().peekable();
16439 let mut current = String::new();
16440 let mut paren_depth = 0;
16441 let mut has_unparseable_content = false;
16442 let mut position_after_last_function = 0;
16443 let mut char_position = 0;
16444
16445 while let Some(c) = chars.next() {
16446 char_position += c.len_utf8();
16447 match c {
16448 '(' => {
16449 paren_depth += 1;
16450 current.push(c);
16451 }
16452 ')' => {
16453 paren_depth -= 1;
16454 current.push(c);
16455 if paren_depth == 0 {
16457 let trimmed = current.trim().to_string();
16458 if !trimmed.is_empty() {
16459 let formatted = self.format_hint_function(&trimmed);
16461 results.push(formatted);
16462 }
16463 current.clear();
16464 position_after_last_function = char_position;
16465 }
16466 }
16467 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
16468 }
16470 _ if paren_depth == 0 => {
16471 current.push(c);
16473 }
16474 _ => {
16475 current.push(c);
16476 }
16477 }
16478 }
16479
16480 let remaining_text = text[position_after_last_function..].trim();
16482 if !remaining_text.is_empty() {
16483 let words: Vec<&str> = remaining_text.split_whitespace().collect();
16487 let looks_like_hint_functions = words.iter().all(|word| {
16488 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
16490 });
16491
16492 if !looks_like_hint_functions && words.len() > 1 {
16493 has_unparseable_content = true;
16494 }
16495 }
16496
16497 if has_unparseable_content {
16499 return vec![text.trim().to_string()];
16500 }
16501
16502 if results.is_empty() {
16504 results.push(text.trim().to_string());
16505 }
16506
16507 results
16508 }
16509
16510 fn format_hint_function(&self, hint: &str) -> String {
16513 if !self.config.pretty {
16514 return hint.to_string();
16515 }
16516
16517 if let Some(paren_pos) = hint.find('(') {
16519 if hint.ends_with(')') {
16520 let name = &hint[..paren_pos];
16521 let args_str = &hint[paren_pos + 1..hint.len() - 1];
16522
16523 let args: Vec<&str> = args_str.split_whitespace().collect();
16525
16526 let total_args_width: usize =
16528 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() {
16532 let mut result = format!("{}(\n", name);
16533 for arg in &args {
16534 result.push_str(" "); result.push_str(arg);
16536 result.push('\n');
16537 }
16538 result.push_str(" )"); return result;
16540 }
16541 }
16542 }
16543
16544 hint.to_string()
16545 }
16546
16547 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
16549 match expr {
16550 HintExpression::Function { name, args } => {
16551 let arg_strings: Vec<String> = args
16553 .iter()
16554 .map(|arg| {
16555 let mut gen = Generator::with_arc_config(self.config.clone());
16556 gen.generate_expression(arg)?;
16557 Ok(gen.output)
16558 })
16559 .collect::<Result<Vec<_>>>()?;
16560
16561 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
16563 + arg_strings.len().saturating_sub(1); let args_multiline =
16568 self.config.pretty && total_args_width > self.config.max_text_width;
16569
16570 if args_multiline && !arg_strings.is_empty() {
16571 let mut result = format!("{}(\n", name);
16573 for arg_str in &arg_strings {
16574 result.push_str(" "); result.push_str(arg_str);
16576 result.push('\n');
16577 }
16578 result.push_str(" )"); Ok(result)
16580 } else {
16581 let args_str = arg_strings.join(" ");
16583 Ok(format!("{}({})", name, args_str))
16584 }
16585 }
16586 HintExpression::Identifier(name) => Ok(name.clone()),
16587 HintExpression::Raw(text) => {
16588 if self.config.pretty {
16590 Ok(self.format_hint_function(text))
16591 } else {
16592 Ok(text.clone())
16593 }
16594 }
16595 }
16596 }
16597
16598 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
16599 if table.only {
16601 self.write_keyword("ONLY");
16602 self.write_space();
16603 }
16604
16605 if let Some(ref identifier_func) = table.identifier_func {
16607 self.generate_expression(identifier_func)?;
16608 if !table.name.name.is_empty() {
16610 if let Some(catalog) = &table.catalog {
16611 self.write(".");
16612 self.generate_identifier(catalog)?;
16613 }
16614 if let Some(schema) = &table.schema {
16615 self.write(".");
16616 self.generate_identifier(schema)?;
16617 }
16618 self.write(".");
16619 self.generate_identifier(&table.name)?;
16620 }
16621 } else {
16622 if let Some(catalog) = &table.catalog {
16623 self.generate_identifier(catalog)?;
16624 self.write(".");
16625 }
16626 if let Some(schema) = &table.schema {
16627 self.generate_identifier(schema)?;
16628 self.write(".");
16629 }
16630 self.generate_identifier(&table.name)?;
16631 }
16632
16633 if let Some(changes) = &table.changes {
16635 self.write(" ");
16636 self.generate_changes(changes)?;
16637 }
16638
16639 if !table.partitions.is_empty() {
16641 self.write_space();
16642 self.write_keyword("PARTITION");
16643 self.write("(");
16644 for (i, partition) in table.partitions.iter().enumerate() {
16645 if i > 0 {
16646 self.write(", ");
16647 }
16648 self.generate_identifier(partition)?;
16649 }
16650 self.write(")");
16651 }
16652
16653 if table.changes.is_none() {
16656 if let Some(when) = &table.when {
16657 self.write_space();
16658 self.generate_historical_data(when)?;
16659 }
16660 }
16661
16662 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
16664 if !system_time_post_alias {
16665 if let Some(ref system_time) = table.system_time {
16666 self.write_space();
16667 self.write(system_time);
16668 }
16669 }
16670
16671 if let Some(ref version) = table.version {
16673 self.write_space();
16674 self.generate_version(version)?;
16675 }
16676
16677 let alias_post_tablesample = self.config.alias_post_tablesample;
16681
16682 if alias_post_tablesample {
16683 self.generate_table_sample_clause(table)?;
16685 }
16686
16687 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
16690 && table.hints.iter().any(|h| {
16691 if let Expression::Identifier(id) = h {
16692 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
16693 } else {
16694 false
16695 }
16696 });
16697 if !table.hints.is_empty() && !is_sqlite_hint {
16698 for hint in &table.hints {
16699 self.write_space();
16700 self.generate_expression(hint)?;
16701 }
16702 }
16703
16704 if let Some(alias) = &table.alias {
16705 self.write_space();
16706 let always_use_as = self.config.dialect.is_none()
16709 || matches!(
16710 self.config.dialect,
16711 Some(DialectType::Generic)
16712 | Some(DialectType::PostgreSQL)
16713 | Some(DialectType::Redshift)
16714 | Some(DialectType::Snowflake)
16715 | Some(DialectType::BigQuery)
16716 | Some(DialectType::DuckDB)
16717 | Some(DialectType::Presto)
16718 | Some(DialectType::Trino)
16719 | Some(DialectType::TSQL)
16720 | Some(DialectType::Fabric)
16721 | Some(DialectType::MySQL)
16722 | Some(DialectType::Spark)
16723 | Some(DialectType::Hive)
16724 | Some(DialectType::SQLite)
16725 | Some(DialectType::Drill)
16726 );
16727 let is_stage_ref = table.name.name.starts_with('@');
16728 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16730 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
16731 self.write_keyword("AS");
16732 self.write_space();
16733 }
16734 self.generate_identifier(alias)?;
16735
16736 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
16739 self.write("(");
16740 for (i, col_alias) in table.column_aliases.iter().enumerate() {
16741 if i > 0 {
16742 self.write(", ");
16743 }
16744 self.generate_identifier(col_alias)?;
16745 }
16746 self.write(")");
16747 }
16748 }
16749
16750 if system_time_post_alias {
16752 if let Some(ref system_time) = table.system_time {
16753 self.write_space();
16754 self.write(system_time);
16755 }
16756 }
16757
16758 if !alias_post_tablesample {
16760 self.generate_table_sample_clause(table)?;
16761 }
16762
16763 if is_sqlite_hint {
16765 for hint in &table.hints {
16766 self.write_space();
16767 self.generate_expression(hint)?;
16768 }
16769 }
16770
16771 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16773 self.write_space();
16774 self.write_keyword("FINAL");
16775 }
16776
16777 for comment in &table.trailing_comments {
16779 self.write_space();
16780 self.write_formatted_comment(comment);
16781 }
16782 Ok(())
16786 }
16787
16788 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
16790 if let Some(ref ts) = table.table_sample {
16791 self.write_space();
16792 if ts.is_using_sample {
16793 self.write_keyword("USING SAMPLE");
16794 } else {
16795 self.write_keyword(self.config.tablesample_keywords);
16797 }
16798 self.generate_sample_body(ts)?;
16799 if let Some(ref seed) = ts.seed {
16801 self.write_space();
16802 self.write_keyword(self.config.tablesample_seed_keyword);
16803 self.write(" (");
16804 self.generate_expression(seed)?;
16805 self.write(")");
16806 }
16807 }
16808 Ok(())
16809 }
16810
16811 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
16812 if sr.quoted {
16816 self.write("'");
16817 }
16818
16819 self.write(&sr.name);
16820 if let Some(path) = &sr.path {
16821 self.write(path);
16822 }
16823
16824 if sr.quoted {
16825 self.write("'");
16826 }
16827
16828 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
16830 if has_options {
16831 self.write(" (");
16832 let mut first = true;
16833
16834 if let Some(file_format) = &sr.file_format {
16835 if !first {
16836 self.write(", ");
16837 }
16838 self.write_keyword("FILE_FORMAT");
16839 self.write(" => ");
16840 self.generate_expression(file_format)?;
16841 first = false;
16842 }
16843
16844 if let Some(pattern) = &sr.pattern {
16845 if !first {
16846 self.write(", ");
16847 }
16848 self.write_keyword("PATTERN");
16849 self.write(" => '");
16850 self.write(pattern);
16851 self.write("'");
16852 }
16853
16854 self.write(")");
16855 }
16856 Ok(())
16857 }
16858
16859 fn generate_star(&mut self, star: &Star) -> Result<()> {
16860 use crate::dialects::DialectType;
16861
16862 if let Some(table) = &star.table {
16863 self.generate_identifier(table)?;
16864 self.write(".");
16865 }
16866 self.write("*");
16867
16868 if let Some(except) = &star.except {
16870 if !except.is_empty() {
16871 self.write_space();
16872 match self.config.dialect {
16874 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
16875 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
16876 self.write_keyword("EXCLUDE")
16877 }
16878 _ => self.write_keyword("EXCEPT"), }
16880 self.write(" (");
16881 for (i, col) in except.iter().enumerate() {
16882 if i > 0 {
16883 self.write(", ");
16884 }
16885 self.generate_identifier(col)?;
16886 }
16887 self.write(")");
16888 }
16889 }
16890
16891 if let Some(replace) = &star.replace {
16893 if !replace.is_empty() {
16894 self.write_space();
16895 self.write_keyword("REPLACE");
16896 self.write(" (");
16897 for (i, alias) in replace.iter().enumerate() {
16898 if i > 0 {
16899 self.write(", ");
16900 }
16901 self.generate_expression(&alias.this)?;
16902 self.write_space();
16903 self.write_keyword("AS");
16904 self.write_space();
16905 self.generate_identifier(&alias.alias)?;
16906 }
16907 self.write(")");
16908 }
16909 }
16910
16911 if let Some(rename) = &star.rename {
16913 if !rename.is_empty() {
16914 self.write_space();
16915 self.write_keyword("RENAME");
16916 self.write(" (");
16917 for (i, (old_name, new_name)) in rename.iter().enumerate() {
16918 if i > 0 {
16919 self.write(", ");
16920 }
16921 self.generate_identifier(old_name)?;
16922 self.write_space();
16923 self.write_keyword("AS");
16924 self.write_space();
16925 self.generate_identifier(new_name)?;
16926 }
16927 self.write(")");
16928 }
16929 }
16930
16931 for comment in &star.trailing_comments {
16933 self.write_space();
16934 self.write_formatted_comment(comment);
16935 }
16936
16937 Ok(())
16938 }
16939
16940 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
16942 self.write("{");
16943 match expr {
16944 Expression::Star(star) => {
16945 self.generate_star(star)?;
16947 }
16948 Expression::ILike(ilike) => {
16949 self.generate_expression(&ilike.left)?;
16951 self.write_space();
16952 self.write_keyword("ILIKE");
16953 self.write_space();
16954 self.generate_expression(&ilike.right)?;
16955 }
16956 _ => {
16957 self.generate_expression(expr)?;
16958 }
16959 }
16960 self.write("}");
16961 Ok(())
16962 }
16963
16964 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
16965 match &alias.this {
16969 Expression::Column(col) => {
16970 if let Some(table) = &col.table {
16972 self.generate_identifier(table)?;
16973 self.write(".");
16974 }
16975 self.generate_identifier(&col.name)?;
16976 }
16977 _ => {
16978 self.generate_expression(&alias.this)?;
16979 }
16980 }
16981
16982 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
16986 for comment in &alias.pre_alias_comments {
16987 self.write_space();
16988 self.write_formatted_comment(comment);
16989 }
16990 }
16991
16992 use crate::dialects::DialectType;
16993
16994 let is_table_source = matches!(
17000 &alias.this,
17001 Expression::JSONTable(_)
17002 | Expression::XMLTable(_)
17003 | Expression::TableFromRows(_)
17004 | Expression::Unnest(_)
17005 | Expression::MatchRecognize(_)
17006 | Expression::Select(_)
17007 | Expression::Subquery(_)
17008 | Expression::Paren(_)
17009 );
17010 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
17011 let skip_as = is_table_source && dialect_skips_table_alias_as;
17012
17013 self.write_space();
17014 if !skip_as {
17015 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
17016 if let Some(ref alias_keyword) = alias.alias_keyword {
17017 self.write(alias_keyword);
17018 } else {
17019 self.write_keyword("AS");
17020 }
17021 } else {
17022 self.write_keyword("AS");
17023 }
17024 self.write_space();
17025 }
17026
17027 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
17029
17030 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
17032 self.write("(");
17034 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17035 if i > 0 {
17036 self.write(", ");
17037 }
17038 self.generate_alias_identifier(col_alias)?;
17039 }
17040 self.write(")");
17041 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
17042 self.generate_alias_identifier(&alias.alias)?;
17044 self.write("(");
17045 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
17046 if i > 0 {
17047 self.write(", ");
17048 }
17049 self.generate_alias_identifier(col_alias)?;
17050 }
17051 self.write(")");
17052 } else {
17053 self.generate_alias_identifier(&alias.alias)?;
17055 }
17056
17057 for comment in &alias.trailing_comments {
17059 self.write_space();
17060 self.write_formatted_comment(comment);
17061 }
17062
17063 if alias.trailing_comments.is_empty() {
17068 for comment in &alias.pre_alias_comments {
17069 self.write_space();
17070 self.write_formatted_comment(comment);
17071 }
17072 }
17073
17074 Ok(())
17075 }
17076
17077 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
17078 use crate::dialects::DialectType;
17079
17080 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
17082 self.generate_expression(&cast.this)?;
17083 self.write(" :> ");
17084 self.generate_data_type(&cast.to)?;
17085 return Ok(());
17086 }
17087
17088 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
17090 let is_unknown_type = matches!(cast.to, DataType::Unknown)
17091 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
17092 if is_unknown_type {
17093 if let Some(format) = &cast.format {
17094 self.write_keyword("CAST");
17095 self.write("(");
17096 self.generate_expression(&cast.this)?;
17097 self.write_space();
17098 self.write_keyword("AS");
17099 self.write_space();
17100 self.write_keyword("FORMAT");
17101 self.write_space();
17102 self.generate_expression(format)?;
17103 self.write(")");
17104 return Ok(());
17105 }
17106 }
17107 }
17108
17109 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
17112 if let Some(format) = &cast.format {
17113 let is_date = matches!(cast.to, DataType::Date);
17115 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
17116
17117 if is_date || is_timestamp {
17118 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
17119 self.write_keyword(func_name);
17120 self.write("(");
17121 self.generate_expression(&cast.this)?;
17122 self.write(", ");
17123
17124 if let Expression::Literal(lit) = format.as_ref() {
17127 if let Literal::String(fmt_str) = lit.as_ref() {
17128 let normalized = self.normalize_oracle_format(fmt_str);
17129 self.write("'");
17130 self.write(&normalized);
17131 self.write("'");
17132 }
17133 } else {
17134 self.generate_expression(format)?;
17135 }
17136
17137 self.write(")");
17138 return Ok(());
17139 }
17140 }
17141 }
17142
17143 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
17146 if let Expression::Array(arr) = &cast.this {
17147 self.generate_data_type(&cast.to)?;
17148 self.write("[");
17150 for (i, expr) in arr.expressions.iter().enumerate() {
17151 if i > 0 {
17152 self.write(", ");
17153 }
17154 self.generate_expression(expr)?;
17155 }
17156 self.write("]");
17157 return Ok(());
17158 }
17159 if matches!(&cast.this, Expression::ArrayFunc(_)) {
17160 self.generate_data_type(&cast.to)?;
17161 self.generate_expression(&cast.this)?;
17162 return Ok(());
17163 }
17164 }
17165
17166 if matches!(
17169 self.config.dialect,
17170 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
17171 ) {
17172 if let Expression::Struct(ref s) = cast.this {
17173 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
17174 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
17175 self.write_keyword("CAST");
17176 self.write("(");
17177 self.generate_struct_as_row(s)?;
17178 self.write_space();
17179 self.write_keyword("AS");
17180 self.write_space();
17181 self.generate_data_type(&cast.to)?;
17182 self.write(")");
17183 return Ok(());
17184 }
17185 }
17186 }
17187
17188 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
17191
17192 if use_double_colon {
17193 self.generate_expression(&cast.this)?;
17195 self.write("::");
17196 self.generate_data_type(&cast.to)?;
17197 } else {
17198 self.write_keyword("CAST");
17200 self.write("(");
17201 self.generate_expression(&cast.this)?;
17202 self.write_space();
17203 self.write_keyword("AS");
17204 self.write_space();
17205 if matches!(
17208 self.config.dialect,
17209 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
17210 ) {
17211 match &cast.to {
17212 DataType::Custom { ref name } => {
17213 if name.eq_ignore_ascii_case("LONGTEXT")
17214 || name.eq_ignore_ascii_case("MEDIUMTEXT")
17215 || name.eq_ignore_ascii_case("TINYTEXT")
17216 || name.eq_ignore_ascii_case("LONGBLOB")
17217 || name.eq_ignore_ascii_case("MEDIUMBLOB")
17218 || name.eq_ignore_ascii_case("TINYBLOB")
17219 {
17220 self.write_keyword("CHAR");
17221 } else {
17222 self.generate_data_type(&cast.to)?;
17223 }
17224 }
17225 DataType::VarChar { length, .. } => {
17226 self.write_keyword("CHAR");
17228 if let Some(n) = length {
17229 self.write(&format!("({})", n));
17230 }
17231 }
17232 DataType::Text => {
17233 self.write_keyword("CHAR");
17235 }
17236 DataType::Timestamp {
17237 precision,
17238 timezone: false,
17239 } => {
17240 self.write_keyword("DATETIME");
17242 if let Some(p) = precision {
17243 self.write(&format!("({})", p));
17244 }
17245 }
17246 _ => {
17247 self.generate_data_type(&cast.to)?;
17248 }
17249 }
17250 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
17251 match &cast.to {
17253 DataType::String { length } => {
17254 self.write_keyword("VARCHAR");
17255 if let Some(n) = length {
17256 self.write(&format!("({})", n));
17257 }
17258 }
17259 _ => {
17260 self.generate_data_type(&cast.to)?;
17261 }
17262 }
17263 } else {
17264 self.generate_data_type(&cast.to)?;
17265 }
17266
17267 if let Some(default) = &cast.default {
17269 self.write_space();
17270 self.write_keyword("DEFAULT");
17271 self.write_space();
17272 self.generate_expression(default)?;
17273 self.write_space();
17274 self.write_keyword("ON");
17275 self.write_space();
17276 self.write_keyword("CONVERSION");
17277 self.write_space();
17278 self.write_keyword("ERROR");
17279 }
17280
17281 if let Some(format) = &cast.format {
17284 if matches!(
17286 self.config.dialect,
17287 Some(crate::dialects::DialectType::Oracle)
17288 ) {
17289 self.write(", ");
17290 } else {
17291 self.write_space();
17292 self.write_keyword("FORMAT");
17293 self.write_space();
17294 }
17295 self.generate_expression(format)?;
17296 }
17297
17298 self.write(")");
17299 for comment in &cast.trailing_comments {
17301 self.write_space();
17302 self.write_formatted_comment(comment);
17303 }
17304 }
17305 Ok(())
17306 }
17307
17308 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
17311 self.write_keyword("ROW");
17312 self.write("(");
17313 for (i, (_, expr)) in s.fields.iter().enumerate() {
17314 if i > 0 {
17315 self.write(", ");
17316 }
17317 if let Expression::Struct(ref inner_s) = expr {
17319 self.generate_struct_as_row(inner_s)?;
17320 } else {
17321 self.generate_expression(expr)?;
17322 }
17323 }
17324 self.write(")");
17325 Ok(())
17326 }
17327
17328 fn normalize_oracle_format(&self, format: &str) -> String {
17331 let mut result = String::new();
17334 let chars: Vec<char> = format.chars().collect();
17335 let mut i = 0;
17336
17337 while i < chars.len() {
17338 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
17339 if i + 2 < chars.len() {
17341 let next = chars[i + 2];
17342 if next == '1' || next == '2' {
17343 result.push('H');
17345 result.push('H');
17346 i += 2;
17347 continue;
17348 }
17349 }
17350 result.push_str("HH12");
17352 i += 2;
17353 } else {
17354 result.push(chars[i]);
17355 i += 1;
17356 }
17357 }
17358
17359 result
17360 }
17361
17362 fn dialect_prefers_double_colon(&self) -> bool {
17365 matches!(self.config.dialect, Some(DialectType::ClickHouse))
17366 }
17367
17368 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17370 use crate::dialects::DialectType;
17371
17372 let use_percent_operator = matches!(
17374 self.config.dialect,
17375 Some(DialectType::Snowflake)
17376 | Some(DialectType::MySQL)
17377 | Some(DialectType::Presto)
17378 | Some(DialectType::Trino)
17379 | Some(DialectType::PostgreSQL)
17380 | Some(DialectType::DuckDB)
17381 | Some(DialectType::Hive)
17382 | Some(DialectType::Spark)
17383 | Some(DialectType::Databricks)
17384 | Some(DialectType::Athena)
17385 | Some(DialectType::TSQL)
17386 | Some(DialectType::Fabric)
17387 );
17388
17389 if use_percent_operator {
17390 let needs_paren = |e: &Expression| {
17393 matches!(
17394 e,
17395 Expression::Add(_)
17396 | Expression::Sub(_)
17397 | Expression::Mul(_)
17398 | Expression::Div(_)
17399 | Expression::Mod(_)
17400 | Expression::ModFunc(_)
17401 )
17402 };
17403 if needs_paren(&f.this) {
17404 self.write("(");
17405 self.generate_expression(&f.this)?;
17406 self.write(")");
17407 } else {
17408 self.generate_expression(&f.this)?;
17409 }
17410 self.write(" % ");
17411 if needs_paren(&f.expression) {
17412 self.write("(");
17413 self.generate_expression(&f.expression)?;
17414 self.write(")");
17415 } else {
17416 self.generate_expression(&f.expression)?;
17417 }
17418 Ok(())
17419 } else {
17420 self.generate_binary_func("MOD", &f.this, &f.expression)
17421 }
17422 }
17423
17424 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17426 use crate::dialects::DialectType;
17427
17428 let func_name = match self.config.dialect {
17430 Some(DialectType::Snowflake) => "COALESCE",
17431 _ => "IFNULL",
17432 };
17433
17434 self.generate_binary_func(func_name, &f.this, &f.expression)
17435 }
17436
17437 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17439 if let Some(ref original_name) = f.original_name {
17441 return self.generate_binary_func(original_name, &f.this, &f.expression);
17442 }
17443
17444 use crate::dialects::DialectType;
17446 let func_name = match self.config.dialect {
17447 Some(DialectType::Snowflake)
17448 | Some(DialectType::ClickHouse)
17449 | Some(DialectType::PostgreSQL)
17450 | Some(DialectType::Presto)
17451 | Some(DialectType::Trino)
17452 | Some(DialectType::Athena)
17453 | Some(DialectType::DuckDB)
17454 | Some(DialectType::BigQuery)
17455 | Some(DialectType::Spark)
17456 | Some(DialectType::Databricks)
17457 | Some(DialectType::Hive) => "COALESCE",
17458 Some(DialectType::MySQL)
17459 | Some(DialectType::Doris)
17460 | Some(DialectType::StarRocks)
17461 | Some(DialectType::SingleStore)
17462 | Some(DialectType::TiDB) => "IFNULL",
17463 _ => "NVL",
17464 };
17465
17466 self.generate_binary_func(func_name, &f.this, &f.expression)
17467 }
17468
17469 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
17471 use crate::dialects::DialectType;
17472
17473 let func_name = match self.config.dialect {
17475 Some(DialectType::Snowflake) => "STDDEV",
17476 _ => "STDDEV_SAMP",
17477 };
17478
17479 self.generate_agg_func(func_name, f)
17480 }
17481
17482 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
17483 self.generate_expression(&coll.this)?;
17484 self.write_space();
17485 self.write_keyword("COLLATE");
17486 self.write_space();
17487 if coll.quoted {
17488 self.write("'");
17490 self.write(&coll.collation);
17491 self.write("'");
17492 } else if coll.double_quoted {
17493 self.write("\"");
17495 self.write(&coll.collation);
17496 self.write("\"");
17497 } else {
17498 self.write(&coll.collation);
17500 }
17501 Ok(())
17502 }
17503
17504 fn generate_case(&mut self, case: &Case) -> Result<()> {
17505 let multiline_case = if self.config.pretty {
17507 let mut statements: Vec<String> = Vec::new();
17509 let operand_str = if let Some(operand) = &case.operand {
17510 let s = self.generate_to_string(operand)?;
17511 statements.push(format!("CASE {}", s));
17512 s
17513 } else {
17514 statements.push("CASE".to_string());
17515 String::new()
17516 };
17517 let _ = operand_str;
17518 for (condition, result) in &case.whens {
17519 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
17520 statements.push(format!("THEN {}", self.generate_to_string(result)?));
17521 }
17522 if let Some(else_) = &case.else_ {
17523 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
17524 }
17525 statements.push("END".to_string());
17526 self.too_wide(&statements)
17527 } else {
17528 false
17529 };
17530
17531 self.write_keyword("CASE");
17532 if let Some(operand) = &case.operand {
17533 self.write_space();
17534 self.generate_expression(operand)?;
17535 }
17536 if multiline_case {
17537 self.indent_level += 1;
17538 }
17539 for (condition, result) in &case.whens {
17540 if multiline_case {
17541 self.write_newline();
17542 self.write_indent();
17543 } else {
17544 self.write_space();
17545 }
17546 self.write_keyword("WHEN");
17547 self.write_space();
17548 self.generate_expression(condition)?;
17549 if multiline_case {
17550 self.write_newline();
17551 self.write_indent();
17552 } else {
17553 self.write_space();
17554 }
17555 self.write_keyword("THEN");
17556 self.write_space();
17557 self.generate_expression(result)?;
17558 }
17559 if let Some(else_) = &case.else_ {
17560 if multiline_case {
17561 self.write_newline();
17562 self.write_indent();
17563 } else {
17564 self.write_space();
17565 }
17566 self.write_keyword("ELSE");
17567 self.write_space();
17568 self.generate_expression(else_)?;
17569 }
17570 if multiline_case {
17571 self.indent_level -= 1;
17572 self.write_newline();
17573 self.write_indent();
17574 } else {
17575 self.write_space();
17576 }
17577 self.write_keyword("END");
17578 for comment in &case.comments {
17580 self.write(" ");
17581 self.write_formatted_comment(comment);
17582 }
17583 Ok(())
17584 }
17585
17586 fn generate_function(&mut self, func: &Function) -> Result<()> {
17587 let normalized_name = self.normalize_func_name(&func.name);
17589
17590 if matches!(self.config.dialect, Some(DialectType::DuckDB))
17592 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
17593 {
17594 self.write("LIST_FILTER(");
17595 self.write("[");
17596 for (i, arg) in func.args.iter().enumerate() {
17597 if i > 0 {
17598 self.write(", ");
17599 }
17600 self.generate_expression(arg)?;
17601 }
17602 self.write("], _u -> NOT _u IS NULL)");
17603 return Ok(());
17604 }
17605
17606 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17609 && func.name.eq_ignore_ascii_case("TO_VARIANT")
17610 && func.args.len() == 1
17611 {
17612 let array_expressions = match &func.args[0] {
17613 Expression::ArrayFunc(arr) => Some(&arr.expressions),
17614 Expression::Array(arr) => Some(&arr.expressions),
17615 _ => None,
17616 };
17617 if let Some(expressions) = array_expressions {
17618 self.write_keyword("TO_VARIANT");
17619 self.write("(");
17620 self.write_keyword("ARRAY_CONSTRUCT");
17621 self.write("(");
17622 for (i, arg) in expressions.iter().enumerate() {
17623 if i > 0 {
17624 self.write(", ");
17625 }
17626 self.generate_expression(arg)?;
17627 }
17628 self.write(")");
17629 self.write(")");
17630 return Ok(());
17631 }
17632 }
17633
17634 if func.name.eq_ignore_ascii_case("STRUCT")
17636 && !matches!(
17637 self.config.dialect,
17638 Some(DialectType::BigQuery)
17639 | Some(DialectType::Spark)
17640 | Some(DialectType::Databricks)
17641 | Some(DialectType::Hive)
17642 | None
17643 )
17644 {
17645 return self.generate_struct_function_cross_dialect(func);
17646 }
17647
17648 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
17651 self.generate_expression(&func.args[0])?;
17652 self.write("::?");
17653 if let Expression::Literal(lit) = &func.args[1] {
17655 if let crate::expressions::Literal::String(key) = lit.as_ref() {
17656 self.write(key);
17657 }
17658 } else {
17659 self.generate_expression(&func.args[1])?;
17660 }
17661 return Ok(());
17662 }
17663
17664 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
17666 self.generate_expression(&func.args[0])?;
17667 self.write(" # ");
17668 self.generate_expression(&func.args[1])?;
17669 return Ok(());
17670 }
17671
17672 if matches!(
17674 self.config.dialect,
17675 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
17676 ) && func.name.eq_ignore_ascii_case("TRY")
17677 && func.args.len() == 1
17678 {
17679 self.generate_expression(&func.args[0])?;
17680 return Ok(());
17681 }
17682
17683 if self.config.dialect == Some(DialectType::ClickHouse)
17685 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
17686 && func.args.len() == 1
17687 {
17688 self.write("dateTrunc('DAY', ");
17689 self.generate_expression(&func.args[0])?;
17690 self.write(")");
17691 return Ok(());
17692 }
17693
17694 if self.config.dialect == Some(DialectType::ClickHouse)
17696 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17697 && func.args.len() == 2
17698 {
17699 self.write("dateTrunc(");
17700 self.generate_expression(&func.args[0])?;
17701 self.write(", ");
17702 self.generate_expression(&func.args[1])?;
17703 self.write(")");
17704 return Ok(());
17705 }
17706
17707 if matches!(
17709 self.config.dialect,
17710 Some(DialectType::Presto | DialectType::Trino | DialectType::Athena)
17711 ) && func.name.eq_ignore_ascii_case("SUBSTRING")
17712 {
17713 self.write_keyword("SUBSTR");
17714 self.write("(");
17715 for (i, arg) in func.args.iter().enumerate() {
17716 if i > 0 {
17717 self.write(", ");
17718 }
17719 self.generate_expression(arg)?;
17720 }
17721 self.write(")");
17722 return Ok(());
17723 }
17724
17725 if self.config.dialect == Some(DialectType::Snowflake)
17726 && func.name.eq_ignore_ascii_case("LIST_DISTINCT")
17727 && func.args.len() == 1
17728 {
17729 self.write_keyword("ARRAY_DISTINCT");
17730 self.write("(");
17731 self.write_keyword("ARRAY_COMPACT");
17732 self.write("(");
17733 self.generate_expression(&func.args[0])?;
17734 self.write("))");
17735 return Ok(());
17736 }
17737
17738 if self.config.dialect == Some(DialectType::Snowflake)
17739 && func.name.eq_ignore_ascii_case("LIST")
17740 && func.args.len() == 1
17741 && !matches!(func.args.first(), Some(Expression::Select(_)))
17742 {
17743 self.write_keyword("ARRAY_AGG");
17744 self.write("(");
17745 self.generate_expression(&func.args[0])?;
17746 self.write(")");
17747 return Ok(());
17748 }
17749
17750 if self.config.dialect == Some(DialectType::Redshift)
17752 && func.name.eq_ignore_ascii_case("CONCAT")
17753 && func.args.len() >= 2
17754 {
17755 for (i, arg) in func.args.iter().enumerate() {
17756 if i > 0 {
17757 self.write(" || ");
17758 }
17759 self.generate_expression(arg)?;
17760 }
17761 return Ok(());
17762 }
17763
17764 if self.config.dialect == Some(DialectType::Redshift)
17766 && func.name.eq_ignore_ascii_case("CONCAT_WS")
17767 && func.args.len() >= 2
17768 {
17769 let sep = &func.args[0];
17770 for (i, arg) in func.args.iter().skip(1).enumerate() {
17771 if i > 0 {
17772 self.write(" || ");
17773 self.generate_expression(sep)?;
17774 self.write(" || ");
17775 }
17776 self.generate_expression(arg)?;
17777 }
17778 return Ok(());
17779 }
17780
17781 if self.config.dialect == Some(DialectType::Redshift)
17784 && (func.name.eq_ignore_ascii_case("DATEDIFF")
17785 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
17786 && func.args.len() == 3
17787 {
17788 self.write_keyword("DATEDIFF");
17789 self.write("(");
17790 self.write_redshift_date_part(&func.args[0]);
17792 self.write(", ");
17793 self.generate_expression(&func.args[1])?;
17794 self.write(", ");
17795 self.generate_expression(&func.args[2])?;
17796 self.write(")");
17797 return Ok(());
17798 }
17799
17800 if self.config.dialect == Some(DialectType::Redshift)
17803 && (func.name.eq_ignore_ascii_case("DATEADD")
17804 || func.name.eq_ignore_ascii_case("DATE_ADD"))
17805 && func.args.len() == 3
17806 {
17807 self.write_keyword("DATEADD");
17808 self.write("(");
17809 self.write_redshift_date_part(&func.args[0]);
17811 self.write(", ");
17812 self.generate_expression(&func.args[1])?;
17813 self.write(", ");
17814 self.generate_expression(&func.args[2])?;
17815 self.write(")");
17816 return Ok(());
17817 }
17818
17819 if func.name.eq_ignore_ascii_case("UUID_STRING")
17821 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
17822 {
17823 if matches!(
17824 self.config.dialect,
17825 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
17826 ) {
17827 self.write_keyword("CAST");
17828 self.write("(");
17829 self.write_keyword("UUID");
17830 self.write("() ");
17831 self.write_keyword("AS");
17832 self.write(" ");
17833 self.write_keyword("STRING");
17834 self.write(")");
17835 return Ok(());
17836 }
17837
17838 if matches!(
17839 self.config.dialect,
17840 Some(DialectType::Presto | DialectType::Trino)
17841 ) {
17842 self.write_keyword("CAST");
17843 self.write("(");
17844 self.write_keyword("UUID");
17845 self.write("() ");
17846 self.write_keyword("AS");
17847 self.write(" ");
17848 self.write_keyword("VARCHAR");
17849 self.write(")");
17850 return Ok(());
17851 }
17852
17853 if self.config.dialect == Some(DialectType::DuckDB) && func.args.len() == 2 {
17854 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(");
17855 self.generate_expression(&func.args[0])?;
17856 self.write(", '-', '')) || ENCODE(");
17857 self.generate_expression(&func.args[1])?;
17858 self.write(")), 1, 32) AS h))");
17859 return Ok(());
17860 }
17861
17862 let func_name = match self.config.dialect {
17863 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
17864 Some(DialectType::BigQuery) => "GENERATE_UUID",
17865 _ => "UUID",
17866 };
17867 self.write_keyword(func_name);
17868 self.write("()");
17869 return Ok(());
17870 }
17871
17872 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17876 && func.name.eq_ignore_ascii_case("GENERATOR")
17877 {
17878 let has_positional_args =
17879 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
17880 if has_positional_args {
17881 let param_names = ["ROWCOUNT", "TIMELIMIT"];
17882 self.write_keyword("GENERATOR");
17883 self.write("(");
17884 for (i, arg) in func.args.iter().enumerate() {
17885 if i > 0 {
17886 self.write(", ");
17887 }
17888 if i < param_names.len() {
17889 self.write_keyword(param_names[i]);
17890 self.write(" => ");
17891 self.generate_expression(arg)?;
17892 } else {
17893 self.generate_expression(arg)?;
17894 }
17895 }
17896 self.write(")");
17897 return Ok(());
17898 }
17899 }
17900
17901 if self.config.dialect == Some(DialectType::Redshift)
17904 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17905 && func.args.len() == 2
17906 {
17907 self.write_keyword("DATE_TRUNC");
17908 self.write("(");
17909 self.write_redshift_date_part_quoted(&func.args[0]);
17911 self.write(", ");
17912 self.generate_expression(&func.args[1])?;
17913 self.write(")");
17914 return Ok(());
17915 }
17916
17917 if matches!(
17919 self.config.dialect,
17920 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17921 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17922 || func.name.eq_ignore_ascii_case("DATEPART"))
17923 && func.args.len() == 2
17924 {
17925 self.write_keyword("DATEPART");
17926 self.write("(");
17927 self.generate_expression(&func.args[0])?;
17928 self.write(", ");
17929 self.generate_expression(&func.args[1])?;
17930 self.write(")");
17931 return Ok(());
17932 }
17933
17934 if matches!(
17936 self.config.dialect,
17937 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
17938 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17939 || func.name.eq_ignore_ascii_case("DATEPART"))
17940 && func.args.len() == 2
17941 {
17942 self.write_keyword("EXTRACT");
17943 self.write("(");
17944 match &func.args[0] {
17946 Expression::Literal(lit)
17947 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
17948 {
17949 let crate::expressions::Literal::String(s) = lit.as_ref() else {
17950 unreachable!()
17951 };
17952 self.write(&s.to_ascii_lowercase());
17953 }
17954 _ => self.generate_expression(&func.args[0])?,
17955 }
17956 self.write_space();
17957 self.write_keyword("FROM");
17958 self.write_space();
17959 self.generate_expression(&func.args[1])?;
17960 self.write(")");
17961 return Ok(());
17962 }
17963
17964 if self.config.dialect == Some(DialectType::PostgreSQL)
17966 && matches!(
17967 func.name.to_ascii_uppercase().as_str(),
17968 "DATE_ADD" | "DATE_SUB"
17969 )
17970 && func.args.len() == 2
17971 && matches!(func.args[1], Expression::Interval(_))
17972 {
17973 self.generate_expression(&func.args[0])?;
17974 self.write_space();
17975 if func.name.eq_ignore_ascii_case("DATE_SUB") {
17976 self.write("-");
17977 } else {
17978 self.write("+");
17979 }
17980 self.write_space();
17981 self.generate_expression(&func.args[1])?;
17982 return Ok(());
17983 }
17984
17985 if self.config.dialect == Some(DialectType::Dremio)
17988 && (func.name.eq_ignore_ascii_case("DATE_PART")
17989 || func.name.eq_ignore_ascii_case("DATEPART"))
17990 && func.args.len() == 2
17991 {
17992 self.write_keyword("EXTRACT");
17993 self.write("(");
17994 self.generate_expression(&func.args[0])?;
17995 self.write_space();
17996 self.write_keyword("FROM");
17997 self.write_space();
17998 self.generate_dremio_date_expression(&func.args[1])?;
18000 self.write(")");
18001 return Ok(());
18002 }
18003
18004 if self.config.dialect == Some(DialectType::Dremio)
18006 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
18007 && func.args.is_empty()
18008 {
18009 self.write_keyword("CURRENT_DATE_UTC");
18010 return Ok(());
18011 }
18012
18013 if self.config.dialect == Some(DialectType::Dremio)
18017 && func.name.eq_ignore_ascii_case("DATETYPE")
18018 && func.args.len() == 3
18019 {
18020 fn get_int_literal(expr: &Expression) -> Option<i64> {
18022 if let Expression::Literal(lit) = expr {
18023 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
18024 s.parse::<i64>().ok()
18025 } else {
18026 None
18027 }
18028 } else {
18029 None
18030 }
18031 }
18032
18033 if let (Some(year), Some(month), Some(day)) = (
18035 get_int_literal(&func.args[0]),
18036 get_int_literal(&func.args[1]),
18037 get_int_literal(&func.args[2]),
18038 ) {
18039 self.write_keyword("DATE");
18041 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
18042 return Ok(());
18043 }
18044
18045 self.write_keyword("CAST");
18047 self.write("(");
18048 self.write_keyword("CONCAT");
18049 self.write("(");
18050 self.generate_expression(&func.args[0])?;
18051 self.write(", '-', ");
18052 self.generate_expression(&func.args[1])?;
18053 self.write(", '-', ");
18054 self.generate_expression(&func.args[2])?;
18055 self.write(")");
18056 self.write_space();
18057 self.write_keyword("AS");
18058 self.write_space();
18059 self.write_keyword("DATE");
18060 self.write(")");
18061 return Ok(());
18062 }
18063
18064 let is_presto_like = matches!(
18067 self.config.dialect,
18068 Some(DialectType::Presto) | Some(DialectType::Trino)
18069 );
18070 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
18071 self.write_keyword("DATE_ADD");
18072 self.write("(");
18073 self.generate_expression(&func.args[0])?;
18075 self.write(", ");
18076 let interval = &func.args[1];
18078 let needs_cast = !self.returns_integer_type(interval);
18079 if needs_cast {
18080 self.write_keyword("CAST");
18081 self.write("(");
18082 }
18083 self.generate_expression(interval)?;
18084 if needs_cast {
18085 self.write_space();
18086 self.write_keyword("AS");
18087 self.write_space();
18088 self.write_keyword("BIGINT");
18089 self.write(")");
18090 }
18091 self.write(", ");
18092 self.generate_expression(&func.args[2])?;
18094 self.write(")");
18095 return Ok(());
18096 }
18097
18098 let use_brackets = func.use_bracket_syntax;
18100
18101 let has_ordinality = func.name.len() >= 16
18106 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
18107 let output_name = if has_ordinality {
18108 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
18109 self.normalize_func_name(base_name)
18110 } else {
18111 normalized_name.clone()
18112 };
18113
18114 let quote_source_clickhouse_function =
18117 matches!(self.config.dialect, Some(DialectType::ClickHouse))
18118 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
18119 && func.quoted;
18120
18121 if quote_source_clickhouse_function {
18122 self.generate_identifier(&Identifier {
18123 name: func.name.clone(),
18124 quoted: true,
18125 trailing_comments: Vec::new(),
18126 span: None,
18127 })?;
18128 } else if func.name.contains('.') && !has_ordinality {
18129 if func.quoted {
18132 self.write("`");
18133 self.write(&func.name);
18134 self.write("`");
18135 } else {
18136 self.write(&func.name);
18137 }
18138 } else {
18139 self.write(&output_name);
18140 }
18141
18142 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
18145 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
18146 || func.name.eq_ignore_ascii_case("SESSION_USER")
18147 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
18148 {
18149 matches!(
18150 self.config.dialect,
18151 Some(DialectType::Snowflake)
18152 | Some(DialectType::Spark)
18153 | Some(DialectType::Databricks)
18154 | Some(DialectType::Hive)
18155 )
18156 } else {
18157 false
18158 };
18159 !needs_parens
18160 };
18161 if force_parens {
18162 for comment in &func.trailing_comments {
18164 self.write_space();
18165 self.write_formatted_comment(comment);
18166 }
18167 return Ok(());
18168 }
18169
18170 if func.name.eq_ignore_ascii_case("CUBE")
18172 || func.name.eq_ignore_ascii_case("ROLLUP")
18173 || func.name.eq_ignore_ascii_case("GROUPING SETS")
18174 {
18175 self.write(" (");
18176 } else if use_brackets {
18177 self.write("[");
18178 } else {
18179 self.write("(");
18180 }
18181 if func.distinct {
18182 self.write_keyword("DISTINCT");
18183 self.write_space();
18184 }
18185
18186 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
18188 && (func.name.eq_ignore_ascii_case("TABLE")
18189 || func.name.eq_ignore_ascii_case("FLATTEN"));
18190 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
18192 || func.name.eq_ignore_ascii_case("CUBE")
18193 || func.name.eq_ignore_ascii_case("ROLLUP");
18194 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
18195 if is_grouping_func {
18196 true
18197 } else {
18198 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
18200 for arg in &func.args {
18201 let mut temp_gen = Generator::with_arc_config(self.config.clone());
18202 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
18204 expr_strings.push(temp_gen.output);
18205 }
18206 self.too_wide(&expr_strings)
18207 }
18208 } else {
18209 false
18210 };
18211
18212 if should_split {
18213 self.write_newline();
18215 self.indent_level += 1;
18216 for (i, arg) in func.args.iter().enumerate() {
18217 self.write_indent();
18218 self.generate_expression(arg)?;
18219 if i + 1 < func.args.len() {
18220 self.write(",");
18221 }
18222 self.write_newline();
18223 }
18224 self.indent_level -= 1;
18225 self.write_indent();
18226 } else {
18227 for (i, arg) in func.args.iter().enumerate() {
18229 if i > 0 {
18230 self.write(", ");
18231 }
18232 self.generate_expression(arg)?;
18233 }
18234 }
18235
18236 if use_brackets {
18237 self.write("]");
18238 } else {
18239 self.write(")");
18240 }
18241 if has_ordinality {
18243 self.write_space();
18244 self.write_keyword("WITH ORDINALITY");
18245 }
18246 for comment in &func.trailing_comments {
18248 self.write_space();
18249 self.write_formatted_comment(comment);
18250 }
18251 Ok(())
18252 }
18253
18254 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
18255 self.generate_expression(&fe.this)?;
18256 self.write_keyword(" EMITS ");
18257 self.generate_expression(&fe.emits)?;
18258 Ok(())
18259 }
18260
18261 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
18262 let mut normalized_name = self.normalize_func_name(&func.name);
18264
18265 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
18267 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
18268 match self.config.dialect {
18269 Some(DialectType::ClickHouse) => {
18270 normalized_name = if is_max {
18271 Cow::Borrowed("argMax")
18272 } else {
18273 Cow::Borrowed("argMin")
18274 };
18275 }
18276 Some(DialectType::DuckDB) => {
18277 normalized_name = if is_max {
18278 Cow::Borrowed("ARG_MAX")
18279 } else {
18280 Cow::Borrowed("ARG_MIN")
18281 };
18282 }
18283 _ => {}
18284 }
18285 }
18286 self.write(normalized_name.as_ref());
18287 self.write("(");
18288 if func.distinct {
18289 self.write_keyword("DISTINCT");
18290 self.write_space();
18291 }
18292
18293 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
18297 let needs_multi_arg_transform =
18298 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
18299
18300 if needs_multi_arg_transform {
18301 self.write_keyword("CASE");
18303 for arg in &func.args {
18304 self.write_space();
18305 self.write_keyword("WHEN");
18306 self.write_space();
18307 self.generate_expression(arg)?;
18308 self.write_space();
18309 self.write_keyword("IS NULL THEN NULL");
18310 }
18311 self.write_space();
18312 self.write_keyword("ELSE");
18313 self.write(" (");
18314 for (i, arg) in func.args.iter().enumerate() {
18315 if i > 0 {
18316 self.write(", ");
18317 }
18318 self.generate_expression(arg)?;
18319 }
18320 self.write(")");
18321 self.write_space();
18322 self.write_keyword("END");
18323 } else {
18324 for (i, arg) in func.args.iter().enumerate() {
18325 if i > 0 {
18326 self.write(", ");
18327 }
18328 self.generate_expression(arg)?;
18329 }
18330 }
18331
18332 let clickhouse_ignore_nulls_outside =
18334 matches!(self.config.dialect, Some(DialectType::ClickHouse));
18335 if self.config.ignore_nulls_in_func
18336 && !matches!(
18337 self.config.dialect,
18338 Some(DialectType::DuckDB) | Some(DialectType::ClickHouse)
18339 )
18340 {
18341 if let Some(ignore) = func.ignore_nulls {
18342 self.write_space();
18343 if ignore {
18344 self.write_keyword("IGNORE NULLS");
18345 } else {
18346 self.write_keyword("RESPECT NULLS");
18347 }
18348 }
18349 }
18350
18351 if !func.order_by.is_empty() {
18353 self.write_space();
18354 self.write_keyword("ORDER BY");
18355 self.write_space();
18356 for (i, ord) in func.order_by.iter().enumerate() {
18357 if i > 0 {
18358 self.write(", ");
18359 }
18360 self.generate_ordered(ord)?;
18361 }
18362 }
18363
18364 if let Some(limit) = &func.limit {
18366 self.write_space();
18367 self.write_keyword("LIMIT");
18368 self.write_space();
18369 if let Expression::Tuple(t) = limit.as_ref() {
18371 if t.expressions.len() == 2 {
18372 self.generate_expression(&t.expressions[0])?;
18373 self.write(", ");
18374 self.generate_expression(&t.expressions[1])?;
18375 } else {
18376 self.generate_expression(limit)?;
18377 }
18378 } else {
18379 self.generate_expression(limit)?;
18380 }
18381 }
18382
18383 self.write(")");
18384
18385 if (!self.config.ignore_nulls_in_func || clickhouse_ignore_nulls_outside)
18387 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
18388 {
18389 if let Some(ignore) = func.ignore_nulls {
18390 self.write_space();
18391 if ignore {
18392 self.write_keyword("IGNORE NULLS");
18393 } else {
18394 self.write_keyword("RESPECT NULLS");
18395 }
18396 }
18397 }
18398
18399 if let Some(filter) = &func.filter {
18400 self.write_space();
18401 self.write_keyword("FILTER");
18402 self.write("(");
18403 self.write_keyword("WHERE");
18404 self.write_space();
18405 self.generate_expression(filter)?;
18406 self.write(")");
18407 }
18408
18409 Ok(())
18410 }
18411
18412 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
18413 self.generate_expression(&wf.this)?;
18414
18415 if let Some(keep) = &wf.keep {
18417 self.write_space();
18418 self.write_keyword("KEEP");
18419 self.write(" (");
18420 self.write_keyword("DENSE_RANK");
18421 self.write_space();
18422 if keep.first {
18423 self.write_keyword("FIRST");
18424 } else {
18425 self.write_keyword("LAST");
18426 }
18427 self.write_space();
18428 self.write_keyword("ORDER BY");
18429 self.write_space();
18430 for (i, ord) in keep.order_by.iter().enumerate() {
18431 if i > 0 {
18432 self.write(", ");
18433 }
18434 self.generate_ordered(ord)?;
18435 }
18436 self.write(")");
18437 }
18438
18439 let has_over = !wf.over.partition_by.is_empty()
18441 || !wf.over.order_by.is_empty()
18442 || wf.over.frame.is_some()
18443 || wf.over.window_name.is_some();
18444
18445 if has_over {
18447 self.write_space();
18448 self.write_keyword("OVER");
18449
18450 let has_specs = !wf.over.partition_by.is_empty()
18452 || !wf.over.order_by.is_empty()
18453 || wf.over.frame.is_some();
18454
18455 if wf.over.window_name.is_some() && !has_specs {
18456 self.write_space();
18458 self.write(&wf.over.window_name.as_ref().unwrap().name);
18459 } else {
18460 self.write(" (");
18462 self.generate_over(&wf.over)?;
18463 self.write(")");
18464 }
18465 } else if wf.keep.is_none() {
18466 self.write_space();
18468 self.write_keyword("OVER");
18469 self.write(" ()");
18470 }
18471
18472 Ok(())
18473 }
18474
18475 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
18477 self.generate_expression(&wg.this)?;
18478 self.write_space();
18479 self.write_keyword("WITHIN GROUP");
18480 self.write(" (");
18481 self.write_keyword("ORDER BY");
18482 self.write_space();
18483 for (i, ord) in wg.order_by.iter().enumerate() {
18484 if i > 0 {
18485 self.write(", ");
18486 }
18487 self.generate_ordered(ord)?;
18488 }
18489 self.write(")");
18490 Ok(())
18491 }
18492
18493 fn generate_over(&mut self, over: &Over) -> Result<()> {
18495 let mut has_content = false;
18496
18497 if let Some(name) = &over.window_name {
18499 self.write(&name.name);
18500 has_content = true;
18501 }
18502
18503 if !over.partition_by.is_empty() {
18505 if has_content {
18506 self.write_space();
18507 }
18508 self.write_keyword("PARTITION BY");
18509 self.write_space();
18510 for (i, expr) in over.partition_by.iter().enumerate() {
18511 if i > 0 {
18512 self.write(", ");
18513 }
18514 self.generate_expression(expr)?;
18515 }
18516 has_content = true;
18517 }
18518
18519 if !over.order_by.is_empty() {
18521 if has_content {
18522 self.write_space();
18523 }
18524 self.write_keyword("ORDER BY");
18525 self.write_space();
18526 for (i, ordered) in over.order_by.iter().enumerate() {
18527 if i > 0 {
18528 self.write(", ");
18529 }
18530 self.generate_ordered(ordered)?;
18531 }
18532 has_content = true;
18533 }
18534
18535 if let Some(frame) = &over.frame {
18537 if has_content {
18538 self.write_space();
18539 }
18540 self.generate_window_frame(frame)?;
18541 }
18542
18543 Ok(())
18544 }
18545
18546 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
18547 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18549
18550 if !lowercase_frame {
18552 if let Some(kind_text) = &frame.kind_text {
18553 self.write(kind_text);
18554 } else {
18555 match frame.kind {
18556 WindowFrameKind::Rows => self.write_keyword("ROWS"),
18557 WindowFrameKind::Range => self.write_keyword("RANGE"),
18558 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
18559 }
18560 }
18561 } else {
18562 match frame.kind {
18563 WindowFrameKind::Rows => self.write("rows"),
18564 WindowFrameKind::Range => self.write("range"),
18565 WindowFrameKind::Groups => self.write("groups"),
18566 }
18567 }
18568
18569 self.write_space();
18572 let should_normalize = self.config.normalize_window_frame_between
18573 && frame.end.is_none()
18574 && matches!(
18575 frame.start,
18576 WindowFrameBound::Preceding(_)
18577 | WindowFrameBound::Following(_)
18578 | WindowFrameBound::UnboundedPreceding
18579 | WindowFrameBound::UnboundedFollowing
18580 );
18581
18582 if let Some(end) = &frame.end {
18583 self.write_keyword("BETWEEN");
18585 self.write_space();
18586 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18587 self.write_space();
18588 self.write_keyword("AND");
18589 self.write_space();
18590 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
18591 } else if should_normalize {
18592 self.write_keyword("BETWEEN");
18594 self.write_space();
18595 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18596 self.write_space();
18597 self.write_keyword("AND");
18598 self.write_space();
18599 self.write_keyword("CURRENT ROW");
18600 } else {
18601 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18603 }
18604
18605 if let Some(exclude) = &frame.exclude {
18607 self.write_space();
18608 self.write_keyword("EXCLUDE");
18609 self.write_space();
18610 match exclude {
18611 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
18612 WindowFrameExclude::Group => self.write_keyword("GROUP"),
18613 WindowFrameExclude::Ties => self.write_keyword("TIES"),
18614 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
18615 }
18616 }
18617
18618 Ok(())
18619 }
18620
18621 fn generate_window_frame_bound(
18622 &mut self,
18623 bound: &WindowFrameBound,
18624 side_text: Option<&str>,
18625 ) -> Result<()> {
18626 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18628
18629 match bound {
18630 WindowFrameBound::CurrentRow => {
18631 self.write_keyword("CURRENT ROW");
18632 }
18633 WindowFrameBound::UnboundedPreceding => {
18634 self.write_keyword("UNBOUNDED");
18635 self.write_space();
18636 if lowercase_frame {
18637 self.write("preceding");
18638 } else if let Some(text) = side_text {
18639 self.write(text);
18640 } else {
18641 self.write_keyword("PRECEDING");
18642 }
18643 }
18644 WindowFrameBound::UnboundedFollowing => {
18645 self.write_keyword("UNBOUNDED");
18646 self.write_space();
18647 if lowercase_frame {
18648 self.write("following");
18649 } else if let Some(text) = side_text {
18650 self.write(text);
18651 } else {
18652 self.write_keyword("FOLLOWING");
18653 }
18654 }
18655 WindowFrameBound::Preceding(expr) => {
18656 self.generate_expression(expr)?;
18657 self.write_space();
18658 if lowercase_frame {
18659 self.write("preceding");
18660 } else if let Some(text) = side_text {
18661 self.write(text);
18662 } else {
18663 self.write_keyword("PRECEDING");
18664 }
18665 }
18666 WindowFrameBound::Following(expr) => {
18667 self.generate_expression(expr)?;
18668 self.write_space();
18669 if lowercase_frame {
18670 self.write("following");
18671 } else if let Some(text) = side_text {
18672 self.write(text);
18673 } else {
18674 self.write_keyword("FOLLOWING");
18675 }
18676 }
18677 WindowFrameBound::BarePreceding => {
18678 if lowercase_frame {
18679 self.write("preceding");
18680 } else if let Some(text) = side_text {
18681 self.write(text);
18682 } else {
18683 self.write_keyword("PRECEDING");
18684 }
18685 }
18686 WindowFrameBound::BareFollowing => {
18687 if lowercase_frame {
18688 self.write("following");
18689 } else if let Some(text) = side_text {
18690 self.write(text);
18691 } else {
18692 self.write_keyword("FOLLOWING");
18693 }
18694 }
18695 WindowFrameBound::Value(expr) => {
18696 self.generate_expression(expr)?;
18698 }
18699 }
18700 Ok(())
18701 }
18702
18703 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
18704 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
18707 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
18708 && !matches!(&interval.this, Some(Expression::Literal(_)));
18709
18710 if self.config.single_string_interval {
18713 if let (
18714 Some(Expression::Literal(lit)),
18715 Some(IntervalUnitSpec::Simple {
18716 ref unit,
18717 ref use_plural,
18718 }),
18719 ) = (&interval.this, &interval.unit)
18720 {
18721 if let Literal::String(ref val) = lit.as_ref() {
18722 self.write_keyword("INTERVAL");
18723 self.write_space();
18724 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18725 let unit_str = self.interval_unit_str(unit, effective_plural);
18726 self.write("'");
18727 self.write(val);
18728 self.write(" ");
18729 self.write(&unit_str);
18730 self.write("'");
18731 return Ok(());
18732 }
18733 }
18734 }
18735
18736 if !skip_interval_keyword {
18737 self.write_keyword("INTERVAL");
18738 }
18739
18740 if let Some(ref value) = interval.this {
18742 if !skip_interval_keyword {
18743 self.write_space();
18744 }
18745 let needs_parens = interval.unit.is_some()
18749 && matches!(
18750 value,
18751 Expression::Add(_)
18752 | Expression::Sub(_)
18753 | Expression::Mul(_)
18754 | Expression::Div(_)
18755 | Expression::Mod(_)
18756 | Expression::BitwiseAnd(_)
18757 | Expression::BitwiseOr(_)
18758 | Expression::BitwiseXor(_)
18759 );
18760 if needs_parens {
18761 self.write("(");
18762 }
18763 self.generate_expression(value)?;
18764 if needs_parens {
18765 self.write(")");
18766 }
18767 }
18768
18769 if let Some(ref unit_spec) = interval.unit {
18771 self.write_space();
18772 self.write_interval_unit_spec(unit_spec)?;
18773 }
18774
18775 Ok(())
18776 }
18777
18778 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
18780 match (unit, use_plural) {
18781 (IntervalUnit::Year, false) => "YEAR",
18782 (IntervalUnit::Year, true) => "YEARS",
18783 (IntervalUnit::Quarter, false) => "QUARTER",
18784 (IntervalUnit::Quarter, true) => "QUARTERS",
18785 (IntervalUnit::Month, false) => "MONTH",
18786 (IntervalUnit::Month, true) => "MONTHS",
18787 (IntervalUnit::Week, false) => "WEEK",
18788 (IntervalUnit::Week, true) => "WEEKS",
18789 (IntervalUnit::Day, false) => "DAY",
18790 (IntervalUnit::Day, true) => "DAYS",
18791 (IntervalUnit::Hour, false) => "HOUR",
18792 (IntervalUnit::Hour, true) => "HOURS",
18793 (IntervalUnit::Minute, false) => "MINUTE",
18794 (IntervalUnit::Minute, true) => "MINUTES",
18795 (IntervalUnit::Second, false) => "SECOND",
18796 (IntervalUnit::Second, true) => "SECONDS",
18797 (IntervalUnit::Millisecond, false) => "MILLISECOND",
18798 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
18799 (IntervalUnit::Microsecond, false) => "MICROSECOND",
18800 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
18801 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
18802 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
18803 }
18804 }
18805
18806 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
18807 match unit_spec {
18808 IntervalUnitSpec::Simple { unit, use_plural } => {
18809 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18811 self.write_simple_interval_unit(unit, effective_plural);
18812 }
18813 IntervalUnitSpec::Span(span) => {
18814 self.write_simple_interval_unit(&span.this, false);
18815 self.write_space();
18816 self.write_keyword("TO");
18817 self.write_space();
18818 self.write_simple_interval_unit(&span.expression, false);
18819 }
18820 IntervalUnitSpec::ExprSpan(span) => {
18821 self.generate_expression(&span.this)?;
18823 self.write_space();
18824 self.write_keyword("TO");
18825 self.write_space();
18826 self.generate_expression(&span.expression)?;
18827 }
18828 IntervalUnitSpec::Expr(expr) => {
18829 self.generate_expression(expr)?;
18830 }
18831 }
18832 Ok(())
18833 }
18834
18835 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
18836 match (unit, use_plural) {
18838 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
18839 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
18840 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
18841 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
18842 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
18843 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
18844 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
18845 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
18846 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
18847 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
18848 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
18849 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
18850 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
18851 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
18852 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
18853 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
18854 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
18855 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
18856 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
18857 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
18858 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
18859 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
18860 }
18861 }
18862
18863 fn write_redshift_date_part(&mut self, expr: &Expression) {
18866 let part_str = self.extract_date_part_string(expr);
18867 if let Some(part) = part_str {
18868 let normalized = self.normalize_date_part(&part);
18869 self.write_keyword(&normalized);
18870 } else {
18871 let _ = self.generate_expression(expr);
18873 }
18874 }
18875
18876 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
18879 let part_str = self.extract_date_part_string(expr);
18880 if let Some(part) = part_str {
18881 let normalized = self.normalize_date_part(&part);
18882 self.write("'");
18883 self.write(&normalized);
18884 self.write("'");
18885 } else {
18886 let _ = self.generate_expression(expr);
18888 }
18889 }
18890
18891 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
18893 match expr {
18894 Expression::Literal(lit)
18895 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18896 {
18897 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18898 unreachable!()
18899 };
18900 Some(s.clone())
18901 }
18902 Expression::Identifier(id) => Some(id.name.clone()),
18903 Expression::Var(v) => Some(v.this.clone()),
18904 Expression::Column(col) if col.table.is_none() => {
18905 Some(col.name.name.clone())
18907 }
18908 _ => None,
18909 }
18910 }
18911
18912 fn normalize_date_part(&self, part: &str) -> String {
18915 let mut buf = [0u8; 64];
18916 let lower: &str = if part.len() <= 64 {
18917 for (i, b) in part.bytes().enumerate() {
18918 buf[i] = b.to_ascii_lowercase();
18919 }
18920 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
18921 } else {
18922 return part.to_ascii_uppercase();
18923 };
18924 match lower {
18925 "day" | "days" | "d" => "DAY".to_string(),
18926 "month" | "months" | "mon" | "mons" | "mm" => "MONTH".to_string(),
18927 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
18928 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
18929 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
18930 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
18931 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
18932 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
18933 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
18934 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
18935 _ => part.to_ascii_uppercase(),
18936 }
18937 }
18938
18939 fn write_datetime_field(&mut self, field: &DateTimeField) {
18940 match field {
18941 DateTimeField::Year => self.write_keyword("YEAR"),
18942 DateTimeField::Month => self.write_keyword("MONTH"),
18943 DateTimeField::Day => self.write_keyword("DAY"),
18944 DateTimeField::Hour => self.write_keyword("HOUR"),
18945 DateTimeField::Minute => self.write_keyword("MINUTE"),
18946 DateTimeField::Second => self.write_keyword("SECOND"),
18947 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
18948 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
18949 DateTimeField::DayOfWeek => {
18950 let name = match self.config.dialect {
18951 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
18952 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
18953 _ => "DOW",
18954 };
18955 self.write_keyword(name);
18956 }
18957 DateTimeField::DayOfYear => {
18958 let name = match self.config.dialect {
18959 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
18960 _ => "DOY",
18961 };
18962 self.write_keyword(name);
18963 }
18964 DateTimeField::Week => self.write_keyword("WEEK"),
18965 DateTimeField::WeekWithModifier(modifier) => {
18966 self.write_keyword("WEEK");
18967 self.write("(");
18968 self.write(modifier);
18969 self.write(")");
18970 }
18971 DateTimeField::Quarter => self.write_keyword("QUARTER"),
18972 DateTimeField::Epoch => self.write_keyword("EPOCH"),
18973 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
18974 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
18975 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
18976 DateTimeField::Date => self.write_keyword("DATE"),
18977 DateTimeField::Time => self.write_keyword("TIME"),
18978 DateTimeField::Custom(name) => self.write(name),
18979 }
18980 }
18981
18982 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
18984 match field {
18985 DateTimeField::Year => self.write("year"),
18986 DateTimeField::Month => self.write("month"),
18987 DateTimeField::Day => self.write("day"),
18988 DateTimeField::Hour => self.write("hour"),
18989 DateTimeField::Minute => self.write("minute"),
18990 DateTimeField::Second => self.write("second"),
18991 DateTimeField::Millisecond => self.write("millisecond"),
18992 DateTimeField::Microsecond => self.write("microsecond"),
18993 DateTimeField::DayOfWeek => self.write("dow"),
18994 DateTimeField::DayOfYear => self.write("doy"),
18995 DateTimeField::Week => self.write("week"),
18996 DateTimeField::WeekWithModifier(modifier) => {
18997 self.write("week(");
18998 self.write(modifier);
18999 self.write(")");
19000 }
19001 DateTimeField::Quarter => self.write("quarter"),
19002 DateTimeField::Epoch => self.write("epoch"),
19003 DateTimeField::Timezone => self.write("timezone"),
19004 DateTimeField::TimezoneHour => self.write("timezone_hour"),
19005 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
19006 DateTimeField::Date => self.write("date"),
19007 DateTimeField::Time => self.write("time"),
19008 DateTimeField::Custom(name) => self.write(name),
19009 }
19010 }
19011
19012 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
19015 self.write_keyword(name);
19016 self.write("(");
19017 self.generate_expression(arg)?;
19018 self.write(")");
19019 Ok(())
19020 }
19021
19022 fn generate_unary_func(
19024 &mut self,
19025 default_name: &str,
19026 f: &crate::expressions::UnaryFunc,
19027 ) -> Result<()> {
19028 let name = f.original_name.as_deref().unwrap_or(default_name);
19029 self.write_keyword(name);
19030 self.write("(");
19031 self.generate_expression(&f.this)?;
19032 self.write(")");
19033 Ok(())
19034 }
19035
19036 fn generate_sqrt_cbrt(
19038 &mut self,
19039 f: &crate::expressions::UnaryFunc,
19040 func_name: &str,
19041 _op: &str,
19042 ) -> Result<()> {
19043 self.write_keyword(func_name);
19046 self.write("(");
19047 self.generate_expression(&f.this)?;
19048 self.write(")");
19049 Ok(())
19050 }
19051
19052 fn generate_binary_func(
19053 &mut self,
19054 name: &str,
19055 arg1: &Expression,
19056 arg2: &Expression,
19057 ) -> Result<()> {
19058 self.write_keyword(name);
19059 self.write("(");
19060 self.generate_expression(arg1)?;
19061 self.write(", ");
19062 self.generate_expression(arg2)?;
19063 self.write(")");
19064 Ok(())
19065 }
19066
19067 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
19071 let func_name = f.name.as_deref().unwrap_or("CHAR");
19073 self.write_keyword(func_name);
19074 self.write("(");
19075 for (i, arg) in f.args.iter().enumerate() {
19076 if i > 0 {
19077 self.write(", ");
19078 }
19079 self.generate_expression(arg)?;
19080 }
19081 if let Some(ref charset) = f.charset {
19082 self.write(" ");
19083 self.write_keyword("USING");
19084 self.write(" ");
19085 self.write(charset);
19086 }
19087 self.write(")");
19088 Ok(())
19089 }
19090
19091 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
19092 use crate::dialects::DialectType;
19093
19094 match self.config.dialect {
19095 Some(DialectType::Teradata) => {
19096 self.generate_expression(&f.this)?;
19098 self.write(" ** ");
19099 self.generate_expression(&f.expression)?;
19100 Ok(())
19101 }
19102 _ => {
19103 self.generate_binary_func("POWER", &f.this, &f.expression)
19105 }
19106 }
19107 }
19108
19109 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
19110 self.write_func_name(name);
19111 self.write("(");
19112 for (i, arg) in args.iter().enumerate() {
19113 if i > 0 {
19114 self.write(", ");
19115 }
19116 self.generate_expression(arg)?;
19117 }
19118 self.write(")");
19119 Ok(())
19120 }
19121
19122 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
19125 self.write_keyword("CONCAT_WS");
19126 self.write("(");
19127 self.generate_expression(&f.separator)?;
19128 for expr in &f.expressions {
19129 self.write(", ");
19130 self.generate_expression(expr)?;
19131 }
19132 self.write(")");
19133 Ok(())
19134 }
19135
19136 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
19137 if let Expression::Concat(op) = expr {
19138 Self::collect_concat_operands(&op.left, out);
19139 Self::collect_concat_operands(&op.right, out);
19140 } else {
19141 out.push(expr);
19142 }
19143 }
19144
19145 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
19146 let mut operands = Vec::new();
19147 Self::collect_concat_operands(&op.left, &mut operands);
19148 Self::collect_concat_operands(&op.right, &mut operands);
19149
19150 self.write_keyword("CONCAT");
19151 self.write("(");
19152 for (i, operand) in operands.iter().enumerate() {
19153 if i > 0 {
19154 self.write(", ");
19155 }
19156 self.generate_expression(operand)?;
19157 }
19158 self.write(")");
19159 Ok(())
19160 }
19161
19162 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
19163 if let Expression::DPipe(dpipe) = expr {
19164 Self::collect_dpipe_operands(&dpipe.this, out);
19165 Self::collect_dpipe_operands(&dpipe.expression, out);
19166 } else {
19167 out.push(expr);
19168 }
19169 }
19170
19171 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
19172 let mut operands = Vec::new();
19173 Self::collect_dpipe_operands(&e.this, &mut operands);
19174 Self::collect_dpipe_operands(&e.expression, &mut operands);
19175
19176 self.write_keyword("CONCAT");
19177 self.write("(");
19178 for (i, operand) in operands.iter().enumerate() {
19179 if i > 0 {
19180 self.write(", ");
19181 }
19182 self.generate_expression(operand)?;
19183 }
19184 self.write(")");
19185 Ok(())
19186 }
19187
19188 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
19189 let use_substr = matches!(
19191 self.config.dialect,
19192 Some(
19193 DialectType::Oracle
19194 | DialectType::Presto
19195 | DialectType::Trino
19196 | DialectType::Athena
19197 )
19198 );
19199 if use_substr {
19200 self.write_keyword("SUBSTR");
19201 } else {
19202 self.write_keyword("SUBSTRING");
19203 }
19204 self.write("(");
19205 self.generate_expression(&f.this)?;
19206 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
19208 let use_comma_syntax = matches!(
19210 self.config.dialect,
19211 Some(DialectType::Spark)
19212 | Some(DialectType::Hive)
19213 | Some(DialectType::Databricks)
19214 | Some(DialectType::TSQL)
19215 | Some(DialectType::Fabric)
19216 );
19217 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
19218 self.write_space();
19220 self.write_keyword("FROM");
19221 self.write_space();
19222 self.generate_expression(&f.start)?;
19223 if let Some(length) = &f.length {
19224 self.write_space();
19225 self.write_keyword("FOR");
19226 self.write_space();
19227 self.generate_expression(length)?;
19228 }
19229 } else {
19230 self.write(", ");
19232 self.generate_expression(&f.start)?;
19233 if let Some(length) = &f.length {
19234 self.write(", ");
19235 self.generate_expression(length)?;
19236 }
19237 }
19238 self.write(")");
19239 Ok(())
19240 }
19241
19242 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
19243 self.write_keyword("OVERLAY");
19244 self.write("(");
19245 self.generate_expression(&f.this)?;
19246 self.write_space();
19247 self.write_keyword("PLACING");
19248 self.write_space();
19249 self.generate_expression(&f.replacement)?;
19250 self.write_space();
19251 self.write_keyword("FROM");
19252 self.write_space();
19253 self.generate_expression(&f.from)?;
19254 if let Some(length) = &f.length {
19255 self.write_space();
19256 self.write_keyword("FOR");
19257 self.write_space();
19258 self.generate_expression(length)?;
19259 }
19260 self.write(")");
19261 Ok(())
19262 }
19263
19264 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
19265 if f.position_explicit && f.characters.is_none() {
19268 match f.position {
19269 TrimPosition::Leading => {
19270 self.write_keyword("LTRIM");
19271 self.write("(");
19272 self.generate_expression(&f.this)?;
19273 self.write(")");
19274 return Ok(());
19275 }
19276 TrimPosition::Trailing => {
19277 self.write_keyword("RTRIM");
19278 self.write("(");
19279 self.generate_expression(&f.this)?;
19280 self.write(")");
19281 return Ok(());
19282 }
19283 TrimPosition::Both => {
19284 }
19287 }
19288 }
19289
19290 self.write_keyword("TRIM");
19291 self.write("(");
19292 let force_standard = f.characters.is_some()
19295 && !f.sql_standard_syntax
19296 && matches!(
19297 self.config.dialect,
19298 Some(DialectType::Hive)
19299 | Some(DialectType::Spark)
19300 | Some(DialectType::Databricks)
19301 | Some(DialectType::ClickHouse)
19302 );
19303 let use_standard = (f.sql_standard_syntax || force_standard)
19304 && !(f.position_explicit
19305 && f.characters.is_none()
19306 && matches!(f.position, TrimPosition::Both));
19307 if use_standard {
19308 if f.position_explicit {
19311 match f.position {
19312 TrimPosition::Both => self.write_keyword("BOTH"),
19313 TrimPosition::Leading => self.write_keyword("LEADING"),
19314 TrimPosition::Trailing => self.write_keyword("TRAILING"),
19315 }
19316 self.write_space();
19317 }
19318 if let Some(chars) = &f.characters {
19319 self.generate_expression(chars)?;
19320 self.write_space();
19321 }
19322 self.write_keyword("FROM");
19323 self.write_space();
19324 self.generate_expression(&f.this)?;
19325 } else {
19326 self.generate_expression(&f.this)?;
19328 if let Some(chars) = &f.characters {
19329 self.write(", ");
19330 self.generate_expression(chars)?;
19331 }
19332 }
19333 self.write(")");
19334 Ok(())
19335 }
19336
19337 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
19338 self.write_keyword("REPLACE");
19339 self.write("(");
19340 self.generate_expression(&f.this)?;
19341 self.write(", ");
19342 self.generate_expression(&f.old)?;
19343 self.write(", ");
19344 self.generate_expression(&f.new)?;
19345 self.write(")");
19346 Ok(())
19347 }
19348
19349 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
19350 self.write_keyword(name);
19351 self.write("(");
19352 self.generate_expression(&f.this)?;
19353 self.write(", ");
19354 self.generate_expression(&f.length)?;
19355 self.write(")");
19356 Ok(())
19357 }
19358
19359 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
19360 self.write_keyword("REPEAT");
19361 self.write("(");
19362 self.generate_expression(&f.this)?;
19363 self.write(", ");
19364 self.generate_expression(&f.times)?;
19365 self.write(")");
19366 Ok(())
19367 }
19368
19369 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
19370 self.write_keyword(name);
19371 self.write("(");
19372 self.generate_expression(&f.this)?;
19373 self.write(", ");
19374 self.generate_expression(&f.length)?;
19375 if let Some(fill) = &f.fill {
19376 self.write(", ");
19377 self.generate_expression(fill)?;
19378 }
19379 self.write(")");
19380 Ok(())
19381 }
19382
19383 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
19384 self.write_keyword("SPLIT");
19385 self.write("(");
19386 self.generate_expression(&f.this)?;
19387 self.write(", ");
19388 self.generate_expression(&f.delimiter)?;
19389 self.write(")");
19390 Ok(())
19391 }
19392
19393 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
19394 use crate::dialects::DialectType;
19395 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
19397 self.generate_expression(&f.this)?;
19398 self.write(" ~ ");
19399 self.generate_expression(&f.pattern)?;
19400 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
19401 self.generate_expression(&f.this)?;
19403 self.write_keyword(" REGEXP_LIKE ");
19404 self.generate_expression(&f.pattern)?;
19405 } else if matches!(
19406 self.config.dialect,
19407 Some(DialectType::SingleStore)
19408 | Some(DialectType::Spark)
19409 | Some(DialectType::Hive)
19410 | Some(DialectType::Databricks)
19411 ) && f.flags.is_none()
19412 {
19413 self.generate_expression(&f.this)?;
19415 self.write_keyword(" RLIKE ");
19416 self.generate_expression(&f.pattern)?;
19417 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
19418 self.write_keyword("REGEXP");
19420 self.write("(");
19421 self.generate_expression(&f.this)?;
19422 self.write(", ");
19423 self.generate_expression(&f.pattern)?;
19424 if let Some(flags) = &f.flags {
19425 self.write(", ");
19426 self.generate_expression(flags)?;
19427 }
19428 self.write(")");
19429 } else {
19430 self.write_keyword("REGEXP_LIKE");
19431 self.write("(");
19432 self.generate_expression(&f.this)?;
19433 self.write(", ");
19434 self.generate_expression(&f.pattern)?;
19435 if let Some(flags) = &f.flags {
19436 self.write(", ");
19437 self.generate_expression(flags)?;
19438 }
19439 self.write(")");
19440 }
19441 Ok(())
19442 }
19443
19444 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
19445 self.write_keyword("REGEXP_REPLACE");
19446 self.write("(");
19447 self.generate_expression(&f.this)?;
19448 self.write(", ");
19449 self.generate_expression(&f.pattern)?;
19450 self.write(", ");
19451 self.generate_expression(&f.replacement)?;
19452 if let Some(flags) = &f.flags {
19453 self.write(", ");
19454 self.generate_expression(flags)?;
19455 }
19456 self.write(")");
19457 Ok(())
19458 }
19459
19460 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
19461 self.write_keyword("REGEXP_EXTRACT");
19462 self.write("(");
19463 self.generate_expression(&f.this)?;
19464 self.write(", ");
19465 self.generate_expression(&f.pattern)?;
19466 if let Some(group) = &f.group {
19467 self.write(", ");
19468 self.generate_expression(group)?;
19469 }
19470 self.write(")");
19471 Ok(())
19472 }
19473
19474 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
19477 self.write_keyword("ROUND");
19478 self.write("(");
19479 self.generate_expression(&f.this)?;
19480 if let Some(decimals) = &f.decimals {
19481 self.write(", ");
19482 self.generate_expression(decimals)?;
19483 }
19484 self.write(")");
19485 Ok(())
19486 }
19487
19488 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
19489 self.write_keyword("FLOOR");
19490 self.write("(");
19491 self.generate_expression(&f.this)?;
19492 if let Some(to) = &f.to {
19494 self.write(" ");
19495 self.write_keyword("TO");
19496 self.write(" ");
19497 self.generate_expression(to)?;
19498 } else if let Some(scale) = &f.scale {
19499 self.write(", ");
19500 self.generate_expression(scale)?;
19501 }
19502 self.write(")");
19503 Ok(())
19504 }
19505
19506 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
19507 self.write_keyword("CEIL");
19508 self.write("(");
19509 self.generate_expression(&f.this)?;
19510 if let Some(to) = &f.to {
19512 self.write(" ");
19513 self.write_keyword("TO");
19514 self.write(" ");
19515 self.generate_expression(to)?;
19516 } else if let Some(decimals) = &f.decimals {
19517 self.write(", ");
19518 self.generate_expression(decimals)?;
19519 }
19520 self.write(")");
19521 Ok(())
19522 }
19523
19524 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
19525 use crate::expressions::Literal;
19526
19527 if let Some(base) = &f.base {
19528 if self.is_log_base_none() {
19531 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
19532 {
19533 self.write_func_name("LOG2");
19534 self.write("(");
19535 self.generate_expression(&f.this)?;
19536 self.write(")");
19537 return Ok(());
19538 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
19539 {
19540 self.write_func_name("LOG10");
19541 self.write("(");
19542 self.generate_expression(&f.this)?;
19543 self.write(")");
19544 return Ok(());
19545 }
19546 }
19548
19549 self.write_func_name("LOG");
19550 self.write("(");
19551 if self.is_log_value_first() {
19552 self.generate_expression(&f.this)?;
19554 self.write(", ");
19555 self.generate_expression(base)?;
19556 } else {
19557 self.generate_expression(base)?;
19559 self.write(", ");
19560 self.generate_expression(&f.this)?;
19561 }
19562 self.write(")");
19563 } else {
19564 self.write_func_name("LOG");
19566 self.write("(");
19567 self.generate_expression(&f.this)?;
19568 self.write(")");
19569 }
19570 Ok(())
19571 }
19572
19573 fn is_log_value_first(&self) -> bool {
19576 use crate::dialects::DialectType;
19577 matches!(
19578 self.config.dialect,
19579 Some(DialectType::BigQuery)
19580 | Some(DialectType::TSQL)
19581 | Some(DialectType::Tableau)
19582 | Some(DialectType::Fabric)
19583 )
19584 }
19585
19586 fn is_log_base_none(&self) -> bool {
19589 use crate::dialects::DialectType;
19590 matches!(
19591 self.config.dialect,
19592 Some(DialectType::Presto)
19593 | Some(DialectType::Trino)
19594 | Some(DialectType::ClickHouse)
19595 | Some(DialectType::Athena)
19596 )
19597 }
19598
19599 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
19602 self.write_keyword("CURRENT_TIME");
19603 if let Some(precision) = f.precision {
19604 self.write(&format!("({})", precision));
19605 } else if matches!(
19606 self.config.dialect,
19607 Some(crate::dialects::DialectType::MySQL)
19608 | Some(crate::dialects::DialectType::SingleStore)
19609 | Some(crate::dialects::DialectType::TiDB)
19610 ) {
19611 self.write("()");
19612 }
19613 Ok(())
19614 }
19615
19616 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
19617 use crate::dialects::DialectType;
19618
19619 if f.sysdate {
19621 match self.config.dialect {
19622 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
19623 self.write_keyword("SYSDATE");
19624 return Ok(());
19625 }
19626 Some(DialectType::Snowflake) => {
19627 self.write_keyword("SYSDATE");
19629 self.write("()");
19630 return Ok(());
19631 }
19632 _ => {
19633 }
19635 }
19636 }
19637
19638 self.write_keyword("CURRENT_TIMESTAMP");
19639 if let Some(precision) = f.precision {
19641 self.write(&format!("({})", precision));
19642 } else if matches!(
19643 self.config.dialect,
19644 Some(crate::dialects::DialectType::MySQL)
19645 | Some(crate::dialects::DialectType::SingleStore)
19646 | Some(crate::dialects::DialectType::TiDB)
19647 | Some(crate::dialects::DialectType::Spark)
19648 | Some(crate::dialects::DialectType::Hive)
19649 | Some(crate::dialects::DialectType::Databricks)
19650 | Some(crate::dialects::DialectType::ClickHouse)
19651 | Some(crate::dialects::DialectType::BigQuery)
19652 | Some(crate::dialects::DialectType::Snowflake)
19653 | Some(crate::dialects::DialectType::Exasol)
19654 ) {
19655 self.write("()");
19656 }
19657 Ok(())
19658 }
19659
19660 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
19661 if self.config.dialect == Some(DialectType::Exasol) {
19663 self.write_keyword("CONVERT_TZ");
19664 self.write("(");
19665 self.generate_expression(&f.this)?;
19666 self.write(", 'UTC', ");
19667 self.generate_expression(&f.zone)?;
19668 self.write(")");
19669 return Ok(());
19670 }
19671
19672 self.generate_expression(&f.this)?;
19673 self.write_space();
19674 self.write_keyword("AT TIME ZONE");
19675 self.write_space();
19676 self.generate_expression(&f.zone)?;
19677 Ok(())
19678 }
19679
19680 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
19681 use crate::dialects::DialectType;
19682
19683 let is_presto_like = matches!(
19686 self.config.dialect,
19687 Some(DialectType::Presto) | Some(DialectType::Trino)
19688 );
19689
19690 if is_presto_like {
19691 self.write_keyword(name);
19692 self.write("(");
19693 self.write("'");
19695 self.write_simple_interval_unit(&f.unit, false);
19696 self.write("'");
19697 self.write(", ");
19698 let needs_cast = !self.returns_integer_type(&f.interval);
19700 if needs_cast {
19701 self.write_keyword("CAST");
19702 self.write("(");
19703 }
19704 self.generate_expression(&f.interval)?;
19705 if needs_cast {
19706 self.write_space();
19707 self.write_keyword("AS");
19708 self.write_space();
19709 self.write_keyword("BIGINT");
19710 self.write(")");
19711 }
19712 self.write(", ");
19713 self.generate_expression(&f.this)?;
19714 self.write(")");
19715 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19716 self.generate_expression(&f.this)?;
19717 self.write_space();
19718 if name.eq_ignore_ascii_case("DATE_SUB") {
19719 self.write("-");
19720 } else {
19721 self.write("+");
19722 }
19723 self.write_space();
19724 self.write_keyword("INTERVAL");
19725 self.write_space();
19726 self.write("'");
19727 let mut interval_gen = Generator::with_arc_config(self.config.clone());
19728 let interval_sql = interval_gen.generate(&f.interval)?;
19729 self.write(&interval_sql);
19730 self.write(" ");
19731 self.write_simple_interval_unit(&f.unit, false);
19732 self.write("'");
19733 } else {
19734 self.write_keyword(name);
19735 self.write("(");
19736 self.generate_expression(&f.this)?;
19737 self.write(", ");
19738 self.write_keyword("INTERVAL");
19739 self.write_space();
19740 self.generate_expression(&f.interval)?;
19741 self.write_space();
19742 self.write_simple_interval_unit(&f.unit, false); self.write(")");
19744 }
19745 Ok(())
19746 }
19747
19748 fn returns_integer_type(&self, expr: &Expression) -> bool {
19751 use crate::expressions::{DataType, Literal};
19752 match expr {
19753 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
19755 let Literal::Number(n) = lit.as_ref() else {
19756 unreachable!()
19757 };
19758 !n.contains('.')
19759 }
19760
19761 Expression::Floor(f) => self.returns_integer_type(&f.this),
19763
19764 Expression::Round(f) => {
19766 f.decimals.is_none() && self.returns_integer_type(&f.this)
19768 }
19769
19770 Expression::Sign(f) => self.returns_integer_type(&f.this),
19772
19773 Expression::Abs(f) => self.returns_integer_type(&f.this),
19775
19776 Expression::Mul(op) => {
19778 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19779 }
19780 Expression::Add(op) => {
19781 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19782 }
19783 Expression::Sub(op) => {
19784 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19785 }
19786 Expression::Mod(op) => self.returns_integer_type(&op.left),
19787
19788 Expression::Cast(c) => matches!(
19790 &c.to,
19791 DataType::BigInt { .. }
19792 | DataType::Int { .. }
19793 | DataType::SmallInt { .. }
19794 | DataType::TinyInt { .. }
19795 ),
19796
19797 Expression::Neg(op) => self.returns_integer_type(&op.this),
19799
19800 Expression::Paren(p) => self.returns_integer_type(&p.this),
19802
19803 _ => false,
19806 }
19807 }
19808
19809 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
19810 self.write_keyword("DATEDIFF");
19811 self.write("(");
19812 if let Some(unit) = &f.unit {
19813 self.write_simple_interval_unit(unit, false); self.write(", ");
19815 }
19816 if self.config.dialect == Some(DialectType::Snowflake) {
19817 self.generate_expression(&f.expression)?;
19818 self.write(", ");
19819 self.generate_expression(&f.this)?;
19820 } else {
19821 self.generate_expression(&f.this)?;
19822 self.write(", ");
19823 self.generate_expression(&f.expression)?;
19824 }
19825 self.write(")");
19826 Ok(())
19827 }
19828
19829 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
19830 if self.config.dialect == Some(DialectType::ClickHouse) {
19831 self.write("dateTrunc");
19832 } else {
19833 self.write_keyword("DATE_TRUNC");
19834 }
19835 self.write("('");
19836 self.write_datetime_field(&f.unit);
19837 self.write("', ");
19838 self.generate_expression(&f.this)?;
19839 self.write(")");
19840 Ok(())
19841 }
19842
19843 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
19844 use crate::dialects::DialectType;
19845 use crate::expressions::DateTimeField;
19846
19847 self.write_keyword("LAST_DAY");
19848 self.write("(");
19849 self.generate_expression(&f.this)?;
19850 if let Some(unit) = &f.unit {
19851 self.write(", ");
19852 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
19855 if let DateTimeField::WeekWithModifier(_) = unit {
19856 self.write_keyword("WEEK");
19857 } else {
19858 self.write_datetime_field(unit);
19859 }
19860 } else {
19861 self.write_datetime_field(unit);
19862 }
19863 }
19864 self.write(")");
19865 Ok(())
19866 }
19867
19868 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
19869 if matches!(
19871 self.config.dialect,
19872 Some(DialectType::TSQL) | Some(DialectType::Fabric)
19873 ) {
19874 self.write_keyword("DATEPART");
19875 self.write("(");
19876 self.write_datetime_field(&f.field);
19877 self.write(", ");
19878 self.generate_expression(&f.this)?;
19879 self.write(")");
19880 return Ok(());
19881 }
19882 self.write_keyword("EXTRACT");
19883 self.write("(");
19884 if matches!(
19886 self.config.dialect,
19887 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
19888 ) {
19889 self.write_datetime_field_lower(&f.field);
19890 } else {
19891 self.write_datetime_field(&f.field);
19892 }
19893 self.write_space();
19894 self.write_keyword("FROM");
19895 self.write_space();
19896 self.generate_expression(&f.this)?;
19897 self.write(")");
19898 Ok(())
19899 }
19900
19901 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
19902 self.write_keyword("TO_DATE");
19903 self.write("(");
19904 self.generate_expression(&f.this)?;
19905 if let Some(format) = &f.format {
19906 self.write(", ");
19907 self.generate_expression(format)?;
19908 }
19909 self.write(")");
19910 Ok(())
19911 }
19912
19913 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
19914 self.write_keyword("TO_TIMESTAMP");
19915 self.write("(");
19916 self.generate_expression(&f.this)?;
19917 if let Some(format) = &f.format {
19918 self.write(", ");
19919 self.generate_expression(format)?;
19920 }
19921 self.write(")");
19922 Ok(())
19923 }
19924
19925 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
19928 use crate::dialects::DialectType;
19929
19930 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
19932 self.write_keyword("CASE WHEN");
19933 self.write_space();
19934 self.generate_expression(&f.condition)?;
19935 self.write_space();
19936 self.write_keyword("THEN");
19937 self.write_space();
19938 self.generate_expression(&f.true_value)?;
19939 if let Some(false_val) = &f.false_value {
19940 self.write_space();
19941 self.write_keyword("ELSE");
19942 self.write_space();
19943 self.generate_expression(false_val)?;
19944 }
19945 self.write_space();
19946 self.write_keyword("END");
19947 return Ok(());
19948 }
19949
19950 if self.config.dialect == Some(DialectType::Exasol) {
19952 self.write_keyword("IF");
19953 self.write_space();
19954 self.generate_expression(&f.condition)?;
19955 self.write_space();
19956 self.write_keyword("THEN");
19957 self.write_space();
19958 self.generate_expression(&f.true_value)?;
19959 if let Some(false_val) = &f.false_value {
19960 self.write_space();
19961 self.write_keyword("ELSE");
19962 self.write_space();
19963 self.generate_expression(false_val)?;
19964 }
19965 self.write_space();
19966 self.write_keyword("ENDIF");
19967 return Ok(());
19968 }
19969
19970 let func_name = match self.config.dialect {
19972 Some(DialectType::ClickHouse) => f.original_name.as_deref().unwrap_or("IF"),
19973 Some(DialectType::Snowflake) => "IFF",
19974 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
19975 Some(DialectType::Drill) => "`IF`",
19976 _ => "IF",
19977 };
19978 self.write(func_name);
19979 self.write("(");
19980 self.generate_expression(&f.condition)?;
19981 self.write(", ");
19982 self.generate_expression(&f.true_value)?;
19983 if let Some(false_val) = &f.false_value {
19984 self.write(", ");
19985 self.generate_expression(false_val)?;
19986 }
19987 self.write(")");
19988 Ok(())
19989 }
19990
19991 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
19992 self.write_keyword("NVL2");
19993 self.write("(");
19994 self.generate_expression(&f.this)?;
19995 self.write(", ");
19996 self.generate_expression(&f.true_value)?;
19997 self.write(", ");
19998 self.generate_expression(&f.false_value)?;
19999 self.write(")");
20000 Ok(())
20001 }
20002
20003 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
20006 let count_name = match self.config.normalize_functions {
20008 NormalizeFunctions::Upper => "COUNT".to_string(),
20009 NormalizeFunctions::Lower => "count".to_string(),
20010 NormalizeFunctions::None => f
20011 .original_name
20012 .clone()
20013 .unwrap_or_else(|| "COUNT".to_string()),
20014 };
20015 self.write(&count_name);
20016 self.write("(");
20017 if f.distinct {
20018 self.write_keyword("DISTINCT");
20019 self.write_space();
20020 }
20021 if f.star {
20022 self.write("*");
20023 } else if let Some(ref expr) = f.this {
20024 if let Expression::Tuple(tuple) = expr {
20026 let needs_transform =
20030 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
20031
20032 if needs_transform {
20033 self.write_keyword("CASE");
20035 for e in &tuple.expressions {
20036 self.write_space();
20037 self.write_keyword("WHEN");
20038 self.write_space();
20039 self.generate_expression(e)?;
20040 self.write_space();
20041 self.write_keyword("IS NULL THEN NULL");
20042 }
20043 self.write_space();
20044 self.write_keyword("ELSE");
20045 self.write(" (");
20046 for (i, e) in tuple.expressions.iter().enumerate() {
20047 if i > 0 {
20048 self.write(", ");
20049 }
20050 self.generate_expression(e)?;
20051 }
20052 self.write(")");
20053 self.write_space();
20054 self.write_keyword("END");
20055 } else {
20056 for (i, e) in tuple.expressions.iter().enumerate() {
20057 if i > 0 {
20058 self.write(", ");
20059 }
20060 self.generate_expression(e)?;
20061 }
20062 }
20063 } else {
20064 self.generate_expression(expr)?;
20065 }
20066 }
20067 let clickhouse_ignore_nulls_outside =
20068 matches!(self.config.dialect, Some(DialectType::ClickHouse));
20069 if let Some(ignore) = f.ignore_nulls.filter(|_| !clickhouse_ignore_nulls_outside) {
20070 self.write_space();
20071 if ignore {
20072 self.write_keyword("IGNORE NULLS");
20073 } else {
20074 self.write_keyword("RESPECT NULLS");
20075 }
20076 }
20077 self.write(")");
20078 if let Some(ignore) = f.ignore_nulls.filter(|_| clickhouse_ignore_nulls_outside) {
20079 self.write_space();
20080 if ignore {
20081 self.write_keyword("IGNORE NULLS");
20082 } else {
20083 self.write_keyword("RESPECT NULLS");
20084 }
20085 }
20086 if let Some(ref filter) = f.filter {
20087 self.write_space();
20088 self.write_keyword("FILTER");
20089 self.write("(");
20090 self.write_keyword("WHERE");
20091 self.write_space();
20092 self.generate_expression(filter)?;
20093 self.write(")");
20094 }
20095 Ok(())
20096 }
20097
20098 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
20099 let func_name: Cow<'_, str> = match self.config.normalize_functions {
20101 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
20102 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
20103 NormalizeFunctions::None => {
20104 if let Some(ref original) = f.name {
20107 Cow::Owned(original.clone())
20108 } else {
20109 Cow::Owned(name.to_ascii_lowercase())
20110 }
20111 }
20112 };
20113 self.write(func_name.as_ref());
20114 self.write("(");
20115 if f.distinct {
20116 self.write_keyword("DISTINCT");
20117 self.write_space();
20118 }
20119 let is_zero_arg_mode =
20122 name.eq_ignore_ascii_case("MODE") && matches!(f.this, Expression::Null(_));
20123 if !is_zero_arg_mode {
20124 self.generate_expression(&f.this)?;
20125 }
20126 if self.config.ignore_nulls_in_func
20129 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
20130 {
20131 match f.ignore_nulls {
20132 Some(true) => {
20133 self.write_space();
20134 self.write_keyword("IGNORE NULLS");
20135 }
20136 Some(false) => {
20137 self.write_space();
20138 self.write_keyword("RESPECT NULLS");
20139 }
20140 None => {}
20141 }
20142 }
20143 if let Some((ref expr, is_max)) = f.having_max {
20146 self.write_space();
20147 self.write_keyword("HAVING");
20148 self.write_space();
20149 if is_max {
20150 self.write_keyword("MAX");
20151 } else {
20152 self.write_keyword("MIN");
20153 }
20154 self.write_space();
20155 self.generate_expression(expr)?;
20156 }
20157 if !f.order_by.is_empty() {
20159 self.write_space();
20160 self.write_keyword("ORDER BY");
20161 self.write_space();
20162 for (i, ord) in f.order_by.iter().enumerate() {
20163 if i > 0 {
20164 self.write(", ");
20165 }
20166 self.generate_ordered(ord)?;
20167 }
20168 }
20169 if let Some(ref limit) = f.limit {
20171 self.write_space();
20172 self.write_keyword("LIMIT");
20173 self.write_space();
20174 if let Expression::Tuple(t) = limit.as_ref() {
20176 if t.expressions.len() == 2 {
20177 self.generate_expression(&t.expressions[0])?;
20178 self.write(", ");
20179 self.generate_expression(&t.expressions[1])?;
20180 } else {
20181 self.generate_expression(limit)?;
20182 }
20183 } else {
20184 self.generate_expression(limit)?;
20185 }
20186 }
20187 self.write(")");
20188 if !self.config.ignore_nulls_in_func
20191 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
20192 {
20193 match f.ignore_nulls {
20194 Some(true) => {
20195 self.write_space();
20196 self.write_keyword("IGNORE NULLS");
20197 }
20198 Some(false) => {
20199 self.write_space();
20200 self.write_keyword("RESPECT NULLS");
20201 }
20202 None => {}
20203 }
20204 }
20205 if let Some(ref filter) = f.filter {
20206 self.write_space();
20207 self.write_keyword("FILTER");
20208 self.write("(");
20209 self.write_keyword("WHERE");
20210 self.write_space();
20211 self.generate_expression(filter)?;
20212 self.write(")");
20213 }
20214 Ok(())
20215 }
20216
20217 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
20220 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
20222 let func_name: Cow<'_, str> = match self.config.normalize_functions {
20224 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
20225 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
20226 NormalizeFunctions::None => {
20227 if let Some(ref original) = f.name {
20228 Cow::Owned(original.clone())
20229 } else {
20230 Cow::Owned(name.to_ascii_lowercase())
20231 }
20232 }
20233 };
20234 self.write(func_name.as_ref());
20235 self.write("(");
20236 if f.distinct {
20237 self.write_keyword("DISTINCT");
20238 self.write_space();
20239 }
20240 if !matches!(f.this, Expression::Null(_)) {
20241 self.generate_expression(&f.this)?;
20242 }
20243 self.write(", ");
20244 self.write_keyword("TRUE");
20245 self.write(")");
20246 return Ok(());
20247 }
20248 self.generate_agg_func(name, f)
20249 }
20250
20251 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
20252 self.write_keyword("GROUP_CONCAT");
20253 self.write("(");
20254 if f.distinct {
20255 self.write_keyword("DISTINCT");
20256 self.write_space();
20257 }
20258 self.generate_expression(&f.this)?;
20259 if let Some(ref order_by) = f.order_by {
20260 self.write_space();
20261 self.write_keyword("ORDER BY");
20262 self.write_space();
20263 for (i, ord) in order_by.iter().enumerate() {
20264 if i > 0 {
20265 self.write(", ");
20266 }
20267 self.generate_ordered(ord)?;
20268 }
20269 }
20270 if let Some(ref sep) = f.separator {
20271 if matches!(
20274 self.config.dialect,
20275 Some(crate::dialects::DialectType::SQLite)
20276 ) {
20277 self.write(", ");
20278 self.generate_expression(sep)?;
20279 } else {
20280 self.write_space();
20281 self.write_keyword("SEPARATOR");
20282 self.write_space();
20283 self.generate_expression(sep)?;
20284 }
20285 }
20286 if let Some(ref limit) = f.limit {
20287 self.write_space();
20288 self.write_keyword("LIMIT");
20289 self.write_space();
20290 self.generate_expression(limit)?;
20291 }
20292 self.write(")");
20293 if let Some(ref filter) = f.filter {
20294 self.write_space();
20295 self.write_keyword("FILTER");
20296 self.write("(");
20297 self.write_keyword("WHERE");
20298 self.write_space();
20299 self.generate_expression(filter)?;
20300 self.write(")");
20301 }
20302 Ok(())
20303 }
20304
20305 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
20306 let uses_within_group_order = matches!(
20307 self.config.dialect,
20308 Some(crate::dialects::DialectType::TSQL | crate::dialects::DialectType::Fabric)
20309 );
20310 self.write_keyword("STRING_AGG");
20311 self.write("(");
20312 if f.distinct {
20313 self.write_keyword("DISTINCT");
20314 self.write_space();
20315 }
20316 self.generate_expression(&f.this)?;
20317 if let Some(ref separator) = f.separator {
20318 self.write(", ");
20319 self.generate_expression(separator)?;
20320 }
20321 if !uses_within_group_order {
20323 if let Some(ref order_by) = f.order_by {
20324 self.write_space();
20325 self.write_keyword("ORDER BY");
20326 self.write_space();
20327 for (i, ord) in order_by.iter().enumerate() {
20328 if i > 0 {
20329 self.write(", ");
20330 }
20331 self.generate_ordered(ord)?;
20332 }
20333 }
20334 }
20335 if let Some(ref limit) = f.limit {
20336 self.write_space();
20337 self.write_keyword("LIMIT");
20338 self.write_space();
20339 self.generate_expression(limit)?;
20340 }
20341 self.write(")");
20342 if uses_within_group_order {
20343 if let Some(ref order_by) = f.order_by {
20344 self.write_space();
20345 self.write_keyword("WITHIN GROUP");
20346 self.write(" (");
20347 self.write_keyword("ORDER BY");
20348 self.write_space();
20349 for (i, ord) in order_by.iter().enumerate() {
20350 if i > 0 {
20351 self.write(", ");
20352 }
20353 self.generate_ordered(ord)?;
20354 }
20355 self.write(")");
20356 }
20357 }
20358 if let Some(ref filter) = f.filter {
20359 self.write_space();
20360 self.write_keyword("FILTER");
20361 self.write("(");
20362 self.write_keyword("WHERE");
20363 self.write_space();
20364 self.generate_expression(filter)?;
20365 self.write(")");
20366 }
20367 Ok(())
20368 }
20369
20370 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
20371 use crate::dialects::DialectType;
20372 let order_inside_args = matches!(self.config.dialect, Some(DialectType::DuckDB));
20373 self.write_keyword("LISTAGG");
20374 self.write("(");
20375 if f.distinct {
20376 self.write_keyword("DISTINCT");
20377 self.write_space();
20378 }
20379 self.generate_expression(&f.this)?;
20380 if let Some(ref sep) = f.separator {
20381 self.write(", ");
20382 self.generate_expression(sep)?;
20383 } else if matches!(
20384 self.config.dialect,
20385 Some(DialectType::Trino) | Some(DialectType::Presto)
20386 ) {
20387 self.write(", ','");
20389 }
20390 if let Some(ref overflow) = f.on_overflow {
20391 self.write_space();
20392 self.write_keyword("ON OVERFLOW");
20393 self.write_space();
20394 match overflow {
20395 ListAggOverflow::Error => self.write_keyword("ERROR"),
20396 ListAggOverflow::Truncate { filler, with_count } => {
20397 self.write_keyword("TRUNCATE");
20398 if let Some(ref fill) = filler {
20399 self.write_space();
20400 self.generate_expression(fill)?;
20401 }
20402 if *with_count {
20403 self.write_space();
20404 self.write_keyword("WITH COUNT");
20405 } else {
20406 self.write_space();
20407 self.write_keyword("WITHOUT COUNT");
20408 }
20409 }
20410 }
20411 }
20412 if order_inside_args {
20413 if let Some(ref order_by) = f.order_by {
20414 self.write_space();
20415 self.write_keyword("ORDER BY");
20416 self.write_space();
20417 for (i, ord) in order_by.iter().enumerate() {
20418 if i > 0 {
20419 self.write(", ");
20420 }
20421 self.generate_ordered(ord)?;
20422 }
20423 }
20424 }
20425 self.write(")");
20426 if !order_inside_args {
20427 if let Some(ref order_by) = f.order_by {
20428 self.write_space();
20429 self.write_keyword("WITHIN GROUP");
20430 self.write(" (");
20431 self.write_keyword("ORDER BY");
20432 self.write_space();
20433 for (i, ord) in order_by.iter().enumerate() {
20434 if i > 0 {
20435 self.write(", ");
20436 }
20437 self.generate_ordered(ord)?;
20438 }
20439 self.write(")");
20440 }
20441 }
20442 if let Some(ref filter) = f.filter {
20443 self.write_space();
20444 self.write_keyword("FILTER");
20445 self.write("(");
20446 self.write_keyword("WHERE");
20447 self.write_space();
20448 self.generate_expression(filter)?;
20449 self.write(")");
20450 }
20451 Ok(())
20452 }
20453
20454 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
20455 self.write_keyword("SUM_IF");
20456 self.write("(");
20457 self.generate_expression(&f.this)?;
20458 self.write(", ");
20459 self.generate_expression(&f.condition)?;
20460 self.write(")");
20461 if let Some(ref filter) = f.filter {
20462 self.write_space();
20463 self.write_keyword("FILTER");
20464 self.write("(");
20465 self.write_keyword("WHERE");
20466 self.write_space();
20467 self.generate_expression(filter)?;
20468 self.write(")");
20469 }
20470 Ok(())
20471 }
20472
20473 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
20474 self.write_keyword("APPROX_PERCENTILE");
20475 self.write("(");
20476 self.generate_expression(&f.this)?;
20477 self.write(", ");
20478 self.generate_expression(&f.percentile)?;
20479 if let Some(ref acc) = f.accuracy {
20480 self.write(", ");
20481 self.generate_expression(acc)?;
20482 }
20483 self.write(")");
20484 if let Some(ref filter) = f.filter {
20485 self.write_space();
20486 self.write_keyword("FILTER");
20487 self.write("(");
20488 self.write_keyword("WHERE");
20489 self.write_space();
20490 self.generate_expression(filter)?;
20491 self.write(")");
20492 }
20493 Ok(())
20494 }
20495
20496 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
20497 self.write_keyword(name);
20498 self.write("(");
20499 self.generate_expression(&f.percentile)?;
20500 self.write(")");
20501 if let Some(ref order_by) = f.order_by {
20502 self.write_space();
20503 self.write_keyword("WITHIN GROUP");
20504 self.write(" (");
20505 self.write_keyword("ORDER BY");
20506 self.write_space();
20507 self.generate_expression(&f.this)?;
20508 for ord in order_by.iter() {
20509 if ord.desc {
20510 self.write_space();
20511 self.write_keyword("DESC");
20512 }
20513 }
20514 self.write(")");
20515 }
20516 if let Some(ref filter) = f.filter {
20517 self.write_space();
20518 self.write_keyword("FILTER");
20519 self.write("(");
20520 self.write_keyword("WHERE");
20521 self.write_space();
20522 self.generate_expression(filter)?;
20523 self.write(")");
20524 }
20525 Ok(())
20526 }
20527
20528 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
20531 self.write_keyword("NTILE");
20532 self.write("(");
20533 if let Some(num_buckets) = &f.num_buckets {
20534 self.generate_expression(num_buckets)?;
20535 }
20536 if let Some(order_by) = &f.order_by {
20537 self.write_keyword(" ORDER BY ");
20538 for (i, ob) in order_by.iter().enumerate() {
20539 if i > 0 {
20540 self.write(", ");
20541 }
20542 self.generate_ordered(ob)?;
20543 }
20544 }
20545 self.write(")");
20546 Ok(())
20547 }
20548
20549 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
20550 self.write_keyword(name);
20551 self.write("(");
20552 self.generate_expression(&f.this)?;
20553 if let Some(ref offset) = f.offset {
20554 self.write(", ");
20555 self.generate_expression(offset)?;
20556 if let Some(ref default) = f.default {
20557 self.write(", ");
20558 self.generate_expression(default)?;
20559 }
20560 }
20561 if self.config.ignore_nulls_in_func {
20563 match f.ignore_nulls {
20564 Some(true) => {
20565 self.write_space();
20566 self.write_keyword("IGNORE NULLS");
20567 }
20568 Some(false) => {
20569 self.write_space();
20570 self.write_keyword("RESPECT NULLS");
20571 }
20572 None => {}
20573 }
20574 }
20575 self.write(")");
20576 if !self.config.ignore_nulls_in_func {
20578 match f.ignore_nulls {
20579 Some(true) => {
20580 self.write_space();
20581 self.write_keyword("IGNORE NULLS");
20582 }
20583 Some(false) => {
20584 self.write_space();
20585 self.write_keyword("RESPECT NULLS");
20586 }
20587 None => {}
20588 }
20589 }
20590 Ok(())
20591 }
20592
20593 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
20594 self.write_keyword(name);
20595 self.write("(");
20596 self.generate_expression(&f.this)?;
20597 if !f.order_by.is_empty() {
20599 self.write_space();
20600 self.write_keyword("ORDER BY");
20601 self.write_space();
20602 for (i, ordered) in f.order_by.iter().enumerate() {
20603 if i > 0 {
20604 self.write(", ");
20605 }
20606 self.generate_ordered(ordered)?;
20607 }
20608 }
20609 if self.config.ignore_nulls_in_func {
20611 match f.ignore_nulls {
20612 Some(true) => {
20613 self.write_space();
20614 self.write_keyword("IGNORE NULLS");
20615 }
20616 Some(false) => {
20617 self.write_space();
20618 self.write_keyword("RESPECT NULLS");
20619 }
20620 None => {}
20621 }
20622 }
20623 self.write(")");
20624 if !self.config.ignore_nulls_in_func {
20626 match f.ignore_nulls {
20627 Some(true) => {
20628 self.write_space();
20629 self.write_keyword("IGNORE NULLS");
20630 }
20631 Some(false) => {
20632 self.write_space();
20633 self.write_keyword("RESPECT NULLS");
20634 }
20635 None => {}
20636 }
20637 }
20638 Ok(())
20639 }
20640
20641 fn generate_value_func_with_ignore_nulls_bool(
20644 &mut self,
20645 name: &str,
20646 f: &ValueFunc,
20647 ) -> Result<()> {
20648 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
20649 self.write_keyword(name);
20650 self.write("(");
20651 self.generate_expression(&f.this)?;
20652 self.write(", ");
20653 self.write_keyword("TRUE");
20654 self.write(")");
20655 return Ok(());
20656 }
20657 self.generate_value_func(name, f)
20658 }
20659
20660 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
20661 self.write_keyword("NTH_VALUE");
20662 self.write("(");
20663 self.generate_expression(&f.this)?;
20664 self.write(", ");
20665 self.generate_expression(&f.offset)?;
20666 if self.config.ignore_nulls_in_func {
20668 match f.ignore_nulls {
20669 Some(true) => {
20670 self.write_space();
20671 self.write_keyword("IGNORE NULLS");
20672 }
20673 Some(false) => {
20674 self.write_space();
20675 self.write_keyword("RESPECT NULLS");
20676 }
20677 None => {}
20678 }
20679 }
20680 self.write(")");
20681 if matches!(
20683 self.config.dialect,
20684 Some(crate::dialects::DialectType::Snowflake)
20685 ) {
20686 match f.from_first {
20687 Some(true) => {
20688 self.write_space();
20689 self.write_keyword("FROM FIRST");
20690 }
20691 Some(false) => {
20692 self.write_space();
20693 self.write_keyword("FROM LAST");
20694 }
20695 None => {}
20696 }
20697 }
20698 if !self.config.ignore_nulls_in_func {
20700 match f.ignore_nulls {
20701 Some(true) => {
20702 self.write_space();
20703 self.write_keyword("IGNORE NULLS");
20704 }
20705 Some(false) => {
20706 self.write_space();
20707 self.write_keyword("RESPECT NULLS");
20708 }
20709 None => {}
20710 }
20711 }
20712 Ok(())
20713 }
20714
20715 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
20718 if matches!(
20721 self.config.dialect,
20722 Some(crate::dialects::DialectType::ClickHouse)
20723 ) {
20724 self.write_keyword("POSITION");
20725 self.write("(");
20726 self.generate_expression(&f.string)?;
20727 self.write(", ");
20728 self.generate_expression(&f.substring)?;
20729 if let Some(ref start) = f.start {
20730 self.write(", ");
20731 self.generate_expression(start)?;
20732 }
20733 self.write(")");
20734 return Ok(());
20735 }
20736
20737 self.write_keyword("POSITION");
20738 self.write("(");
20739 self.generate_expression(&f.substring)?;
20740 self.write_space();
20741 self.write_keyword("IN");
20742 self.write_space();
20743 self.generate_expression(&f.string)?;
20744 if let Some(ref start) = f.start {
20745 self.write(", ");
20746 self.generate_expression(start)?;
20747 }
20748 self.write(")");
20749 Ok(())
20750 }
20751
20752 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
20755 if f.lower.is_some() || f.upper.is_some() {
20757 self.write_keyword("RANDOM");
20758 self.write("(");
20759 if let Some(ref lower) = f.lower {
20760 self.generate_expression(lower)?;
20761 }
20762 if let Some(ref upper) = f.upper {
20763 self.write(", ");
20764 self.generate_expression(upper)?;
20765 }
20766 self.write(")");
20767 return Ok(());
20768 }
20769 let func_name = match self.config.dialect {
20771 Some(crate::dialects::DialectType::Snowflake)
20772 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
20773 _ => "RAND",
20774 };
20775 self.write_keyword(func_name);
20776 self.write("(");
20777 if !matches!(
20779 self.config.dialect,
20780 Some(crate::dialects::DialectType::DuckDB)
20781 ) {
20782 if let Some(ref seed) = f.seed {
20783 self.generate_expression(seed)?;
20784 }
20785 }
20786 self.write(")");
20787 Ok(())
20788 }
20789
20790 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
20791 self.write_keyword("TRUNCATE");
20792 self.write("(");
20793 self.generate_expression(&f.this)?;
20794 if let Some(ref decimals) = f.decimals {
20795 self.write(", ");
20796 self.generate_expression(decimals)?;
20797 }
20798 self.write(")");
20799 Ok(())
20800 }
20801
20802 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
20805 self.write_keyword("DECODE");
20806 self.write("(");
20807 self.generate_expression(&f.this)?;
20808 for (search, result) in &f.search_results {
20809 self.write(", ");
20810 self.generate_expression(search)?;
20811 self.write(", ");
20812 self.generate_expression(result)?;
20813 }
20814 if let Some(ref default) = f.default {
20815 self.write(", ");
20816 self.generate_expression(default)?;
20817 }
20818 self.write(")");
20819 Ok(())
20820 }
20821
20822 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
20825 self.write_keyword(name);
20826 self.write("(");
20827 self.generate_expression(&f.this)?;
20828 self.write(", ");
20829 self.generate_expression(&f.format)?;
20830 self.write(")");
20831 Ok(())
20832 }
20833
20834 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
20835 self.write_keyword("FROM_UNIXTIME");
20836 self.write("(");
20837 self.generate_expression(&f.this)?;
20838 if let Some(ref format) = f.format {
20839 self.write(", ");
20840 self.generate_expression(format)?;
20841 }
20842 self.write(")");
20843 Ok(())
20844 }
20845
20846 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
20847 self.write_keyword("UNIX_TIMESTAMP");
20848 self.write("(");
20849 if let Some(ref expr) = f.this {
20850 self.generate_expression(expr)?;
20851 if let Some(ref format) = f.format {
20852 self.write(", ");
20853 self.generate_expression(format)?;
20854 }
20855 } else if matches!(
20856 self.config.dialect,
20857 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
20858 ) {
20859 self.write_keyword("CURRENT_TIMESTAMP");
20861 self.write("()");
20862 }
20863 self.write(")");
20864 Ok(())
20865 }
20866
20867 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
20868 self.write_keyword("MAKE_DATE");
20869 self.write("(");
20870 self.generate_expression(&f.year)?;
20871 self.write(", ");
20872 self.generate_expression(&f.month)?;
20873 self.write(", ");
20874 self.generate_expression(&f.day)?;
20875 self.write(")");
20876 Ok(())
20877 }
20878
20879 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
20880 self.write_keyword("MAKE_TIMESTAMP");
20881 self.write("(");
20882 self.generate_expression(&f.year)?;
20883 self.write(", ");
20884 self.generate_expression(&f.month)?;
20885 self.write(", ");
20886 self.generate_expression(&f.day)?;
20887 self.write(", ");
20888 self.generate_expression(&f.hour)?;
20889 self.write(", ");
20890 self.generate_expression(&f.minute)?;
20891 self.write(", ");
20892 self.generate_expression(&f.second)?;
20893 if let Some(ref tz) = f.timezone {
20894 self.write(", ");
20895 self.generate_expression(tz)?;
20896 }
20897 self.write(")");
20898 Ok(())
20899 }
20900
20901 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
20903 match expr {
20904 Expression::Struct(s) => {
20905 if s.fields.iter().all(|(name, _)| name.is_some()) {
20906 Some(
20907 s.fields
20908 .iter()
20909 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
20910 .collect(),
20911 )
20912 } else {
20913 None
20914 }
20915 }
20916 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20917 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
20919 Some(
20920 f.args
20921 .iter()
20922 .filter_map(|a| {
20923 if let Expression::Alias(alias) = a {
20924 Some(alias.alias.name.clone())
20925 } else {
20926 None
20927 }
20928 })
20929 .collect(),
20930 )
20931 } else {
20932 None
20933 }
20934 }
20935 _ => None,
20936 }
20937 }
20938
20939 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
20941 match expr {
20942 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
20943 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20944 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
20945 }
20946 _ => false,
20947 }
20948 }
20949
20950 fn struct_field_count(expr: &Expression) -> usize {
20952 match expr {
20953 Expression::Struct(s) => s.fields.len(),
20954 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
20955 _ => 0,
20956 }
20957 }
20958
20959 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
20961 match expr {
20962 Expression::Struct(s) => {
20963 let mut new_fields = Vec::with_capacity(s.fields.len());
20964 for (i, (name, value)) in s.fields.iter().enumerate() {
20965 if name.is_none() && i < field_names.len() {
20966 new_fields.push((Some(field_names[i].clone()), value.clone()));
20967 } else {
20968 new_fields.push((name.clone(), value.clone()));
20969 }
20970 }
20971 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
20972 }
20973 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20974 let mut new_args = Vec::with_capacity(f.args.len());
20975 for (i, arg) in f.args.iter().enumerate() {
20976 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
20977 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
20979 this: arg.clone(),
20980 alias: crate::expressions::Identifier::new(field_names[i].clone()),
20981 column_aliases: Vec::new(),
20982 alias_explicit_as: false,
20983 alias_keyword: None,
20984 pre_alias_comments: Vec::new(),
20985 trailing_comments: Vec::new(),
20986 inferred_type: None,
20987 })));
20988 } else {
20989 new_args.push(arg.clone());
20990 }
20991 }
20992 Expression::Function(Box::new(crate::expressions::Function {
20993 name: f.name.clone(),
20994 args: new_args,
20995 distinct: f.distinct,
20996 trailing_comments: f.trailing_comments.clone(),
20997 use_bracket_syntax: f.use_bracket_syntax,
20998 no_parens: f.no_parens,
20999 quoted: f.quoted,
21000 span: None,
21001 inferred_type: None,
21002 }))
21003 }
21004 _ => expr.clone(),
21005 }
21006 }
21007
21008 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
21012 let first = match expressions.first() {
21013 Some(e) => e,
21014 None => return expressions.to_vec(),
21015 };
21016
21017 let field_names = match Self::extract_struct_field_names(first) {
21018 Some(names) if !names.is_empty() => names,
21019 _ => return expressions.to_vec(),
21020 };
21021
21022 let mut result = Vec::with_capacity(expressions.len());
21023 for (idx, expr) in expressions.iter().enumerate() {
21024 if idx == 0 {
21025 result.push(expr.clone());
21026 continue;
21027 }
21028 if Self::struct_field_count(expr) == field_names.len()
21030 && Self::struct_has_unnamed_fields(expr)
21031 {
21032 result.push(Self::apply_struct_field_names(expr, &field_names));
21033 } else {
21034 result.push(expr.clone());
21035 }
21036 }
21037 result
21038 }
21039
21040 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
21043 let needs_inheritance = matches!(
21046 self.config.dialect,
21047 Some(DialectType::DuckDB)
21048 | Some(DialectType::Spark)
21049 | Some(DialectType::Databricks)
21050 | Some(DialectType::Hive)
21051 | Some(DialectType::Snowflake)
21052 | Some(DialectType::Presto)
21053 | Some(DialectType::Trino)
21054 );
21055 let propagated: Vec<Expression>;
21056 let expressions = if needs_inheritance && f.expressions.len() > 1 {
21057 propagated = Self::inherit_struct_field_names(&f.expressions);
21058 &propagated
21059 } else {
21060 &f.expressions
21061 };
21062
21063 let should_split = if self.config.pretty && !expressions.is_empty() {
21065 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
21066 for expr in expressions {
21067 let mut temp_gen = Generator::with_arc_config(self.config.clone());
21068 Arc::make_mut(&mut temp_gen.config).pretty = false;
21069 temp_gen.generate_expression(expr)?;
21070 expr_strings.push(temp_gen.output);
21071 }
21072 self.too_wide(&expr_strings)
21073 } else {
21074 false
21075 };
21076
21077 if f.bracket_notation {
21078 let (open, close) = match self.config.dialect {
21082 None
21083 | Some(DialectType::Generic)
21084 | Some(DialectType::Spark)
21085 | Some(DialectType::Databricks)
21086 | Some(DialectType::Hive) => {
21087 self.write_keyword("ARRAY");
21088 ("(", ")")
21089 }
21090 Some(DialectType::Presto)
21091 | Some(DialectType::Trino)
21092 | Some(DialectType::PostgreSQL)
21093 | Some(DialectType::Redshift)
21094 | Some(DialectType::Materialize)
21095 | Some(DialectType::RisingWave)
21096 | Some(DialectType::CockroachDB) => {
21097 self.write_keyword("ARRAY");
21098 ("[", "]")
21099 }
21100 _ => ("[", "]"),
21101 };
21102 self.write(open);
21103 if should_split {
21104 self.write_newline();
21105 self.indent_level += 1;
21106 for (i, expr) in expressions.iter().enumerate() {
21107 self.write_indent();
21108 self.generate_expression(expr)?;
21109 if i + 1 < expressions.len() {
21110 self.write(",");
21111 }
21112 self.write_newline();
21113 }
21114 self.indent_level -= 1;
21115 self.write_indent();
21116 } else {
21117 for (i, expr) in expressions.iter().enumerate() {
21118 if i > 0 {
21119 self.write(", ");
21120 }
21121 self.generate_expression(expr)?;
21122 }
21123 }
21124 self.write(close);
21125 } else {
21126 if f.use_list_keyword {
21128 self.write_keyword("LIST");
21129 } else {
21130 self.write_keyword("ARRAY");
21131 }
21132 let has_subquery = expressions
21135 .iter()
21136 .any(|e| matches!(e, Expression::Select(_)));
21137 let (open, close) = if matches!(
21138 self.config.dialect,
21139 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
21140 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
21141 && has_subquery)
21142 {
21143 ("(", ")")
21144 } else {
21145 ("[", "]")
21146 };
21147 self.write(open);
21148 if should_split {
21149 self.write_newline();
21150 self.indent_level += 1;
21151 for (i, expr) in expressions.iter().enumerate() {
21152 self.write_indent();
21153 self.generate_expression(expr)?;
21154 if i + 1 < expressions.len() {
21155 self.write(",");
21156 }
21157 self.write_newline();
21158 }
21159 self.indent_level -= 1;
21160 self.write_indent();
21161 } else {
21162 for (i, expr) in expressions.iter().enumerate() {
21163 if i > 0 {
21164 self.write(", ");
21165 }
21166 self.generate_expression(expr)?;
21167 }
21168 }
21169 self.write(close);
21170 }
21171 Ok(())
21172 }
21173
21174 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
21175 self.write_keyword("ARRAY_SORT");
21176 self.write("(");
21177 self.generate_expression(&f.this)?;
21178 if let Some(ref comp) = f.comparator {
21179 self.write(", ");
21180 self.generate_expression(comp)?;
21181 }
21182 self.write(")");
21183 Ok(())
21184 }
21185
21186 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
21187 self.write_keyword(name);
21188 self.write("(");
21189 self.generate_expression(&f.this)?;
21190 self.write(", ");
21191 self.generate_expression(&f.separator)?;
21192 if let Some(ref null_rep) = f.null_replacement {
21193 self.write(", ");
21194 self.generate_expression(null_rep)?;
21195 }
21196 self.write(")");
21197 Ok(())
21198 }
21199
21200 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
21201 self.write_keyword("UNNEST");
21202 self.write("(");
21203 self.generate_expression(&f.this)?;
21204 for extra in &f.expressions {
21205 self.write(", ");
21206 self.generate_expression(extra)?;
21207 }
21208 self.write(")");
21209 if f.with_ordinality {
21210 self.write_space();
21211 if self.config.unnest_with_ordinality {
21212 self.write_keyword("WITH ORDINALITY");
21214 } else if f.offset_alias.is_some() {
21215 if let Some(ref alias) = f.alias {
21218 self.write_keyword("AS");
21219 self.write_space();
21220 self.generate_identifier(alias)?;
21221 self.write_space();
21222 }
21223 self.write_keyword("WITH OFFSET");
21224 if let Some(ref offset_alias) = f.offset_alias {
21225 self.write_space();
21226 self.write_keyword("AS");
21227 self.write_space();
21228 self.generate_identifier(offset_alias)?;
21229 }
21230 } else {
21231 self.write_keyword("WITH OFFSET");
21233 if f.alias.is_none() {
21234 self.write(" AS offset");
21235 }
21236 }
21237 }
21238 if let Some(ref alias) = f.alias {
21239 let should_add_alias = if !f.with_ordinality {
21241 true
21242 } else if self.config.unnest_with_ordinality {
21243 true
21245 } else if f.offset_alias.is_some() {
21246 false
21248 } else {
21249 true
21251 };
21252 if should_add_alias {
21253 self.write_space();
21254 self.write_keyword("AS");
21255 self.write_space();
21256 self.generate_identifier(alias)?;
21257 }
21258 }
21259 Ok(())
21260 }
21261
21262 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
21263 self.write_keyword("FILTER");
21264 self.write("(");
21265 self.generate_expression(&f.this)?;
21266 self.write(", ");
21267 self.generate_expression(&f.filter)?;
21268 self.write(")");
21269 Ok(())
21270 }
21271
21272 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
21273 self.write_keyword("TRANSFORM");
21274 self.write("(");
21275 self.generate_expression(&f.this)?;
21276 self.write(", ");
21277 self.generate_expression(&f.transform)?;
21278 self.write(")");
21279 Ok(())
21280 }
21281
21282 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
21283 self.write_keyword(name);
21284 self.write("(");
21285 self.generate_expression(&f.start)?;
21286 self.write(", ");
21287 self.generate_expression(&f.stop)?;
21288 if let Some(ref step) = f.step {
21289 self.write(", ");
21290 self.generate_expression(step)?;
21291 }
21292 self.write(")");
21293 Ok(())
21294 }
21295
21296 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
21299 self.write_keyword("STRUCT");
21300 self.write("(");
21301 for (i, (name, expr)) in f.fields.iter().enumerate() {
21302 if i > 0 {
21303 self.write(", ");
21304 }
21305 if let Some(ref id) = name {
21306 self.generate_identifier(id)?;
21307 self.write(" ");
21308 self.write_keyword("AS");
21309 self.write(" ");
21310 }
21311 self.generate_expression(expr)?;
21312 }
21313 self.write(")");
21314 Ok(())
21315 }
21316
21317 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
21319 let mut names: Vec<Option<String>> = Vec::new();
21322 let mut values: Vec<&Expression> = Vec::new();
21323 let mut all_named = true;
21324
21325 for arg in &func.args {
21326 match arg {
21327 Expression::Alias(a) => {
21328 names.push(Some(a.alias.name.clone()));
21329 values.push(&a.this);
21330 }
21331 _ => {
21332 names.push(None);
21333 values.push(arg);
21334 all_named = false;
21335 }
21336 }
21337 }
21338
21339 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
21340 self.write("{");
21342 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21343 if i > 0 {
21344 self.write(", ");
21345 }
21346 if let Some(n) = name {
21347 self.write("'");
21348 self.write(n);
21349 self.write("'");
21350 } else {
21351 self.write("'_");
21352 self.write(&i.to_string());
21353 self.write("'");
21354 }
21355 self.write(": ");
21356 self.generate_expression(value)?;
21357 }
21358 self.write("}");
21359 return Ok(());
21360 }
21361
21362 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21363 self.write_keyword("OBJECT_CONSTRUCT");
21365 self.write("(");
21366 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21367 if i > 0 {
21368 self.write(", ");
21369 }
21370 if let Some(n) = name {
21371 self.write("'");
21372 self.write(n);
21373 self.write("'");
21374 } else {
21375 self.write("'_");
21376 self.write(&i.to_string());
21377 self.write("'");
21378 }
21379 self.write(", ");
21380 self.generate_expression(value)?;
21381 }
21382 self.write(")");
21383 return Ok(());
21384 }
21385
21386 if matches!(
21387 self.config.dialect,
21388 Some(DialectType::Presto) | Some(DialectType::Trino)
21389 ) {
21390 if all_named && !names.is_empty() {
21391 self.write_keyword("CAST");
21394 self.write("(");
21395 self.write_keyword("ROW");
21396 self.write("(");
21397 for (i, value) in values.iter().enumerate() {
21398 if i > 0 {
21399 self.write(", ");
21400 }
21401 self.generate_expression(value)?;
21402 }
21403 self.write(")");
21404 self.write(" ");
21405 self.write_keyword("AS");
21406 self.write(" ");
21407 self.write_keyword("ROW");
21408 self.write("(");
21409 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21410 if i > 0 {
21411 self.write(", ");
21412 }
21413 if let Some(n) = name {
21414 self.write(n);
21415 }
21416 self.write(" ");
21417 let type_str = Self::infer_sql_type_for_presto(value);
21418 self.write_keyword(&type_str);
21419 }
21420 self.write(")");
21421 self.write(")");
21422 } else {
21423 self.write_keyword("ROW");
21425 self.write("(");
21426 for (i, value) in values.iter().enumerate() {
21427 if i > 0 {
21428 self.write(", ");
21429 }
21430 self.generate_expression(value)?;
21431 }
21432 self.write(")");
21433 }
21434 return Ok(());
21435 }
21436
21437 self.write_keyword("ROW");
21439 self.write("(");
21440 for (i, value) in values.iter().enumerate() {
21441 if i > 0 {
21442 self.write(", ");
21443 }
21444 self.generate_expression(value)?;
21445 }
21446 self.write(")");
21447 Ok(())
21448 }
21449
21450 fn infer_sql_type_for_presto(expr: &Expression) -> String {
21452 match expr {
21453 Expression::Literal(lit)
21454 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
21455 {
21456 "VARCHAR".to_string()
21457 }
21458 Expression::Literal(lit)
21459 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
21460 {
21461 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
21462 unreachable!()
21463 };
21464 if n.contains('.') {
21465 "DOUBLE".to_string()
21466 } else {
21467 "INTEGER".to_string()
21468 }
21469 }
21470 Expression::Boolean(_) => "BOOLEAN".to_string(),
21471 Expression::Literal(lit)
21472 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
21473 {
21474 "DATE".to_string()
21475 }
21476 Expression::Literal(lit)
21477 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
21478 {
21479 "TIMESTAMP".to_string()
21480 }
21481 Expression::Literal(lit)
21482 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
21483 {
21484 "TIMESTAMP".to_string()
21485 }
21486 Expression::Array(_) | Expression::ArrayFunc(_) => {
21487 "ARRAY(VARCHAR)".to_string()
21489 }
21490 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
21492 Expression::Function(f) => {
21493 if f.name.eq_ignore_ascii_case("STRUCT") {
21494 "ROW".to_string()
21495 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
21496 "DATE".to_string()
21497 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
21498 || f.name.eq_ignore_ascii_case("NOW")
21499 {
21500 "TIMESTAMP".to_string()
21501 } else {
21502 "VARCHAR".to_string()
21503 }
21504 }
21505 _ => "VARCHAR".to_string(),
21506 }
21507 }
21508
21509 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
21510 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
21512 self.write_keyword("STRUCT_EXTRACT");
21513 self.write("(");
21514 self.generate_expression(&f.this)?;
21515 self.write(", ");
21516 self.write("'");
21518 self.write(&f.field.name);
21519 self.write("'");
21520 self.write(")");
21521 return Ok(());
21522 }
21523 self.generate_expression(&f.this)?;
21524 self.write(".");
21525 self.generate_identifier(&f.field)
21526 }
21527
21528 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
21529 if matches!(
21530 self.config.dialect,
21531 Some(DialectType::Spark | DialectType::Databricks)
21532 ) {
21533 self.write_keyword("STRUCT");
21534 self.write("(");
21535 for (i, (name, value)) in f.pairs.iter().enumerate() {
21536 if i > 0 {
21537 self.write(", ");
21538 }
21539 self.generate_expression(value)?;
21540 self.write(" ");
21541 self.write_keyword("AS");
21542 self.write(" ");
21543 if let Expression::Literal(lit) = name {
21544 if let Literal::String(field_name) = lit.as_ref() {
21545 self.generate_identifier(&Identifier::new(field_name))?;
21546 } else {
21547 self.generate_expression(name)?;
21548 }
21549 } else {
21550 self.generate_expression(name)?;
21551 }
21552 }
21553 self.write(")");
21554 return Ok(());
21555 }
21556
21557 self.write_keyword("NAMED_STRUCT");
21558 self.write("(");
21559 for (i, (name, value)) in f.pairs.iter().enumerate() {
21560 if i > 0 {
21561 self.write(", ");
21562 }
21563 self.generate_expression(name)?;
21564 self.write(", ");
21565 self.generate_expression(value)?;
21566 }
21567 self.write(")");
21568 Ok(())
21569 }
21570
21571 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
21574 if f.curly_brace_syntax {
21575 if f.with_map_keyword {
21577 self.write_keyword("MAP");
21578 self.write(" ");
21579 }
21580 self.write("{");
21581 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
21582 if i > 0 {
21583 self.write(", ");
21584 }
21585 self.generate_expression(key)?;
21586 self.write(": ");
21587 self.generate_expression(val)?;
21588 }
21589 self.write("}");
21590 } else {
21591 self.write_keyword("MAP");
21593 self.write("(");
21594 self.write_keyword("ARRAY");
21595 self.write("[");
21596 for (i, key) in f.keys.iter().enumerate() {
21597 if i > 0 {
21598 self.write(", ");
21599 }
21600 self.generate_expression(key)?;
21601 }
21602 self.write("], ");
21603 self.write_keyword("ARRAY");
21604 self.write("[");
21605 for (i, val) in f.values.iter().enumerate() {
21606 if i > 0 {
21607 self.write(", ");
21608 }
21609 self.generate_expression(val)?;
21610 }
21611 self.write("])");
21612 }
21613 Ok(())
21614 }
21615
21616 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
21617 self.write_keyword(name);
21618 self.write("(");
21619 self.generate_expression(&f.this)?;
21620 self.write(", ");
21621 self.generate_expression(&f.transform)?;
21622 self.write(")");
21623 Ok(())
21624 }
21625
21626 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
21629 use crate::dialects::DialectType;
21630
21631 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
21633
21634 if use_arrow {
21635 self.generate_expression(&f.this)?;
21637 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
21638 self.write(" ->> ");
21639 } else {
21640 self.write(" -> ");
21641 }
21642 self.generate_expression(&f.path)?;
21643 return Ok(());
21644 }
21645
21646 if f.hash_arrow_syntax
21648 && matches!(
21649 self.config.dialect,
21650 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21651 )
21652 {
21653 self.generate_expression(&f.this)?;
21654 self.write(" #>> ");
21655 self.generate_expression(&f.path)?;
21656 return Ok(());
21657 }
21658
21659 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21662 match name {
21663 "JSON_EXTRACT_SCALAR"
21664 | "JSON_EXTRACT_PATH_TEXT"
21665 | "JSON_EXTRACT"
21666 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
21667 _ => name,
21668 }
21669 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
21670 match name {
21671 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
21672 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
21673 _ => name,
21674 }
21675 } else {
21676 name
21677 };
21678
21679 self.write_keyword(func_name);
21680 self.write("(");
21681 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21683 if let Expression::Cast(ref cast) = f.this {
21684 if matches!(cast.to, crate::expressions::DataType::Json) {
21685 self.generate_expression(&cast.this)?;
21686 } else {
21687 self.generate_expression(&f.this)?;
21688 }
21689 } else {
21690 self.generate_expression(&f.this)?;
21691 }
21692 } else {
21693 self.generate_expression(&f.this)?;
21694 }
21695 if matches!(
21698 self.config.dialect,
21699 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21700 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
21701 {
21702 if let Expression::Literal(ref lit) = f.path {
21703 if let Literal::String(ref s) = lit.as_ref() {
21704 let parts = Self::decompose_json_path(s);
21705 for part in &parts {
21706 self.write(", '");
21707 self.write(part);
21708 self.write("'");
21709 }
21710 }
21711 } else {
21712 self.write(", ");
21713 self.generate_expression(&f.path)?;
21714 }
21715 } else {
21716 self.write(", ");
21717 self.generate_expression(&f.path)?;
21718 }
21719
21720 if let Some(ref wrapper) = f.wrapper_option {
21723 self.write_space();
21724 self.write_keyword(wrapper);
21725 }
21726 if let Some(ref quotes) = f.quotes_option {
21727 self.write_space();
21728 self.write_keyword(quotes);
21729 if f.on_scalar_string {
21730 self.write_space();
21731 self.write_keyword("ON SCALAR STRING");
21732 }
21733 }
21734 if let Some(ref on_err) = f.on_error {
21735 self.write_space();
21736 self.write_keyword(on_err);
21737 }
21738 if let Some(ref ret_type) = f.returning {
21739 self.write_space();
21740 self.write_keyword("RETURNING");
21741 self.write_space();
21742 self.generate_data_type(ret_type)?;
21743 }
21744
21745 self.write(")");
21746 Ok(())
21747 }
21748
21749 fn dialect_supports_json_arrow(&self) -> bool {
21751 use crate::dialects::DialectType;
21752 match self.config.dialect {
21753 Some(DialectType::PostgreSQL) => true,
21755 Some(DialectType::MySQL) => true,
21756 Some(DialectType::DuckDB) => true,
21757 Some(DialectType::CockroachDB) => true,
21758 Some(DialectType::StarRocks) => true,
21759 Some(DialectType::SQLite) => true,
21760 _ => false,
21762 }
21763 }
21764
21765 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
21766 use crate::dialects::DialectType;
21767
21768 if matches!(
21770 self.config.dialect,
21771 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21772 ) && name == "JSON_EXTRACT_PATH"
21773 {
21774 self.generate_expression(&f.this)?;
21775 self.write(" #> ");
21776 if f.paths.len() == 1 {
21777 self.generate_expression(&f.paths[0])?;
21778 } else {
21779 self.write_keyword("ARRAY");
21781 self.write("[");
21782 for (i, path) in f.paths.iter().enumerate() {
21783 if i > 0 {
21784 self.write(", ");
21785 }
21786 self.generate_expression(path)?;
21787 }
21788 self.write("]");
21789 }
21790 return Ok(());
21791 }
21792
21793 self.write_keyword(name);
21794 self.write("(");
21795 self.generate_expression(&f.this)?;
21796 for path in &f.paths {
21797 self.write(", ");
21798 self.generate_expression(path)?;
21799 }
21800 self.write(")");
21801 Ok(())
21802 }
21803
21804 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
21805 use crate::dialects::DialectType;
21806
21807 self.write_keyword("JSON_OBJECT");
21808 self.write("(");
21809 if f.star {
21810 self.write("*");
21811 } else {
21812 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
21816 || matches!(
21817 self.config.dialect,
21818 Some(DialectType::BigQuery)
21819 | Some(DialectType::MySQL)
21820 | Some(DialectType::SQLite)
21821 );
21822
21823 for (i, (key, value)) in f.pairs.iter().enumerate() {
21824 if i > 0 {
21825 self.write(", ");
21826 }
21827 self.generate_expression(key)?;
21828 if use_comma_syntax {
21829 self.write(", ");
21830 } else {
21831 self.write(": ");
21832 }
21833 self.generate_expression(value)?;
21834 }
21835 }
21836 if let Some(null_handling) = f.null_handling {
21837 self.write_space();
21838 match null_handling {
21839 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21840 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21841 }
21842 }
21843 if f.with_unique_keys {
21844 self.write_space();
21845 self.write_keyword("WITH UNIQUE KEYS");
21846 }
21847 if let Some(ref ret_type) = f.returning_type {
21848 self.write_space();
21849 self.write_keyword("RETURNING");
21850 self.write_space();
21851 self.generate_data_type(ret_type)?;
21852 if f.format_json {
21853 self.write_space();
21854 self.write_keyword("FORMAT JSON");
21855 }
21856 if let Some(ref enc) = f.encoding {
21857 self.write_space();
21858 self.write_keyword("ENCODING");
21859 self.write_space();
21860 self.write(enc);
21861 }
21862 }
21863 self.write(")");
21864 Ok(())
21865 }
21866
21867 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
21868 self.write_keyword(name);
21869 self.write("(");
21870 self.generate_expression(&f.this)?;
21871 for (path, value) in &f.path_values {
21872 self.write(", ");
21873 self.generate_expression(path)?;
21874 self.write(", ");
21875 self.generate_expression(value)?;
21876 }
21877 self.write(")");
21878 Ok(())
21879 }
21880
21881 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
21882 self.write_keyword("JSON_ARRAYAGG");
21883 self.write("(");
21884 self.generate_expression(&f.this)?;
21885 if let Some(ref order_by) = f.order_by {
21886 self.write_space();
21887 self.write_keyword("ORDER BY");
21888 self.write_space();
21889 for (i, ord) in order_by.iter().enumerate() {
21890 if i > 0 {
21891 self.write(", ");
21892 }
21893 self.generate_ordered(ord)?;
21894 }
21895 }
21896 if let Some(null_handling) = f.null_handling {
21897 self.write_space();
21898 match null_handling {
21899 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21900 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21901 }
21902 }
21903 self.write(")");
21904 if let Some(ref filter) = f.filter {
21905 self.write_space();
21906 self.write_keyword("FILTER");
21907 self.write("(");
21908 self.write_keyword("WHERE");
21909 self.write_space();
21910 self.generate_expression(filter)?;
21911 self.write(")");
21912 }
21913 Ok(())
21914 }
21915
21916 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
21917 self.write_keyword("JSON_OBJECTAGG");
21918 self.write("(");
21919 self.generate_expression(&f.key)?;
21920 self.write(": ");
21921 self.generate_expression(&f.value)?;
21922 if let Some(null_handling) = f.null_handling {
21923 self.write_space();
21924 match null_handling {
21925 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21926 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21927 }
21928 }
21929 self.write(")");
21930 if let Some(ref filter) = f.filter {
21931 self.write_space();
21932 self.write_keyword("FILTER");
21933 self.write("(");
21934 self.write_keyword("WHERE");
21935 self.write_space();
21936 self.generate_expression(filter)?;
21937 self.write(")");
21938 }
21939 Ok(())
21940 }
21941
21942 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
21945 use crate::dialects::DialectType;
21946
21947 if self.config.dialect == Some(DialectType::Redshift) {
21949 self.write_keyword("CAST");
21950 self.write("(");
21951 self.generate_expression(&f.this)?;
21952 self.write_space();
21953 self.write_keyword("AS");
21954 self.write_space();
21955 self.generate_data_type(&f.to)?;
21956 self.write(")");
21957 return Ok(());
21958 }
21959
21960 self.write_keyword("CONVERT");
21961 self.write("(");
21962 self.generate_data_type(&f.to)?;
21963 self.write(", ");
21964 self.generate_expression(&f.this)?;
21965 if let Some(ref style) = f.style {
21966 self.write(", ");
21967 self.generate_expression(style)?;
21968 }
21969 self.write(")");
21970 Ok(())
21971 }
21972
21973 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
21976 if f.colon {
21977 self.write_keyword("LAMBDA");
21979 self.write_space();
21980 for (i, param) in f.parameters.iter().enumerate() {
21981 if i > 0 {
21982 self.write(", ");
21983 }
21984 self.generate_identifier(param)?;
21985 }
21986 self.write(" : ");
21987 } else {
21988 if f.parameters.len() == 1 {
21990 self.generate_identifier(&f.parameters[0])?;
21991 } else {
21992 self.write("(");
21993 for (i, param) in f.parameters.iter().enumerate() {
21994 if i > 0 {
21995 self.write(", ");
21996 }
21997 self.generate_identifier(param)?;
21998 }
21999 self.write(")");
22000 }
22001 self.write(" -> ");
22002 }
22003 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22004 if let Expression::Lambda(inner) = &f.body {
22005 self.generate_lambda_with_parenthesized_single_param(inner)?;
22006 return Ok(());
22007 }
22008 }
22009
22010 self.generate_expression(&f.body)
22011 }
22012
22013 fn generate_lambda_with_parenthesized_single_param(&mut self, f: &LambdaExpr) -> Result<()> {
22014 if f.colon {
22015 return self.generate_lambda(f);
22016 }
22017
22018 self.write("(");
22019 for (i, param) in f.parameters.iter().enumerate() {
22020 if i > 0 {
22021 self.write(", ");
22022 }
22023 self.generate_identifier(param)?;
22024 }
22025 self.write(") -> ");
22026 self.generate_expression(&f.body)
22027 }
22028
22029 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
22030 self.generate_identifier(&f.name)?;
22031 match f.separator {
22032 NamedArgSeparator::DArrow => self.write(" => "),
22033 NamedArgSeparator::ColonEq => self.write(" := "),
22034 NamedArgSeparator::Eq => self.write(" = "),
22035 }
22036 self.generate_expression(&f.value)
22037 }
22038
22039 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
22040 self.write_keyword(&f.prefix);
22041 self.write(" ");
22042 self.generate_expression(&f.this)
22043 }
22044
22045 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
22046 match f.style {
22047 ParameterStyle::Question => self.write("?"),
22048 ParameterStyle::Dollar => {
22049 self.write("$");
22050 if let Some(idx) = f.index {
22051 self.write(&idx.to_string());
22052 } else if let Some(ref name) = f.name {
22053 self.write(name);
22055 }
22056 }
22057 ParameterStyle::DollarBrace => {
22058 self.write("${");
22060 if let Some(ref name) = f.name {
22061 self.write(name);
22062 }
22063 if let Some(ref expr) = f.expression {
22064 self.write(":");
22065 self.write(expr);
22066 }
22067 self.write("}");
22068 }
22069 ParameterStyle::Colon => {
22070 self.write(":");
22071 if let Some(idx) = f.index {
22072 self.write(&idx.to_string());
22073 } else if let Some(ref name) = f.name {
22074 self.write(name);
22075 }
22076 }
22077 ParameterStyle::At => {
22078 self.write("@");
22079 if let Some(ref name) = f.name {
22080 if f.string_quoted {
22081 self.write("'");
22082 self.write(name);
22083 self.write("'");
22084 } else if f.quoted {
22085 self.write("\"");
22086 self.write(name);
22087 self.write("\"");
22088 } else {
22089 self.write(name);
22090 }
22091 }
22092 }
22093 ParameterStyle::DoubleAt => {
22094 self.write("@@");
22095 if let Some(ref name) = f.name {
22096 self.write(name);
22097 }
22098 }
22099 ParameterStyle::DoubleDollar => {
22100 self.write("$$");
22101 if let Some(ref name) = f.name {
22102 self.write(name);
22103 }
22104 }
22105 ParameterStyle::Percent => {
22106 if let Some(ref name) = f.name {
22107 self.write("%(");
22109 self.write(name);
22110 self.write(")s");
22111 } else {
22112 self.write("%s");
22114 }
22115 }
22116 ParameterStyle::Brace => {
22117 self.write("{");
22120 if let Some(ref name) = f.name {
22121 self.write(name);
22122 }
22123 if let Some(ref expr) = f.expression {
22124 self.write(": ");
22125 self.write(expr);
22126 }
22127 self.write("}");
22128 }
22129 }
22130 Ok(())
22131 }
22132
22133 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
22134 self.write("?");
22135 if let Some(idx) = f.index {
22136 self.write(&idx.to_string());
22137 }
22138 Ok(())
22139 }
22140
22141 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
22142 if f.is_block {
22143 self.write("/*");
22144 self.write(&f.text);
22145 self.write("*/");
22146 } else {
22147 self.write("--");
22148 self.write(&f.text);
22149 }
22150 Ok(())
22151 }
22152
22153 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
22156 self.generate_expression(&f.this)?;
22157 if f.not {
22158 self.write_space();
22159 self.write_keyword("NOT");
22160 }
22161 self.write_space();
22162 self.write_keyword("SIMILAR TO");
22163 self.write_space();
22164 self.generate_expression(&f.pattern)?;
22165 if let Some(ref escape) = f.escape {
22166 self.write_space();
22167 self.write_keyword("ESCAPE");
22168 self.write_space();
22169 self.generate_expression(escape)?;
22170 }
22171 Ok(())
22172 }
22173
22174 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
22175 self.generate_expression(&f.this)?;
22176 self.write_space();
22177 if let Some(op) = &f.op {
22179 match op {
22180 QuantifiedOp::Eq => self.write("="),
22181 QuantifiedOp::Neq => self.write("<>"),
22182 QuantifiedOp::Lt => self.write("<"),
22183 QuantifiedOp::Lte => self.write("<="),
22184 QuantifiedOp::Gt => self.write(">"),
22185 QuantifiedOp::Gte => self.write(">="),
22186 }
22187 self.write_space();
22188 }
22189 self.write_keyword(name);
22190
22191 if matches!(&f.subquery, Expression::Subquery(_)) {
22193 self.write_space();
22194 self.generate_expression(&f.subquery)?;
22195 } else {
22196 let is_statement = matches!(
22197 &f.subquery,
22198 Expression::Select(_)
22199 | Expression::Union(_)
22200 | Expression::Intersect(_)
22201 | Expression::Except(_)
22202 );
22203 if is_statement
22204 && !self.config.quantified_no_paren_space
22205 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
22206 {
22207 self.write_space();
22208 }
22209 self.write("(");
22210
22211 if self.config.pretty && is_statement {
22212 self.write_newline();
22213 self.indent_level += 1;
22214 self.write_indent();
22215 }
22216 self.generate_expression(&f.subquery)?;
22217 if self.config.pretty && is_statement {
22218 self.write_newline();
22219 self.indent_level -= 1;
22220 self.write_indent();
22221 }
22222 self.write(")");
22223 }
22224 Ok(())
22225 }
22226
22227 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
22228 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
22230 self.generate_expression(this)?;
22231 self.write_space();
22232 self.write_keyword("OVERLAPS");
22233 self.write_space();
22234 self.generate_expression(expr)?;
22235 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
22236 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
22237 {
22238 self.write("(");
22240 self.generate_expression(ls)?;
22241 self.write(", ");
22242 self.generate_expression(le)?;
22243 self.write(")");
22244 self.write_space();
22245 self.write_keyword("OVERLAPS");
22246 self.write_space();
22247 self.write("(");
22248 self.generate_expression(rs)?;
22249 self.write(", ");
22250 self.generate_expression(re)?;
22251 self.write(")");
22252 }
22253 Ok(())
22254 }
22255
22256 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
22259 use crate::dialects::DialectType;
22260
22261 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22263 self.generate_expression(&cast.this)?;
22264 self.write(" !:> ");
22265 self.generate_data_type(&cast.to)?;
22266 return Ok(());
22267 }
22268
22269 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
22271 self.write_keyword("TRYCAST");
22272 self.write("(");
22273 self.generate_expression(&cast.this)?;
22274 self.write_space();
22275 self.write_keyword("AS");
22276 self.write_space();
22277 self.generate_data_type(&cast.to)?;
22278 self.write(")");
22279 return Ok(());
22280 }
22281
22282 let keyword = if matches!(
22284 self.config.dialect,
22285 Some(DialectType::Hive)
22286 | Some(DialectType::MySQL)
22287 | Some(DialectType::SQLite)
22288 | Some(DialectType::Oracle)
22289 | Some(DialectType::ClickHouse)
22290 | Some(DialectType::Redshift)
22291 | Some(DialectType::PostgreSQL)
22292 | Some(DialectType::StarRocks)
22293 | Some(DialectType::Doris)
22294 ) {
22295 "CAST"
22296 } else {
22297 "TRY_CAST"
22298 };
22299
22300 self.write_keyword(keyword);
22301 self.write("(");
22302 self.generate_expression(&cast.this)?;
22303 self.write_space();
22304 self.write_keyword("AS");
22305 self.write_space();
22306 self.generate_data_type(&cast.to)?;
22307
22308 if let Some(format) = &cast.format {
22310 self.write_space();
22311 self.write_keyword("FORMAT");
22312 self.write_space();
22313 self.generate_expression(format)?;
22314 }
22315
22316 self.write(")");
22317 Ok(())
22318 }
22319
22320 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
22321 self.write_keyword("SAFE_CAST");
22322 self.write("(");
22323 self.generate_expression(&cast.this)?;
22324 self.write_space();
22325 self.write_keyword("AS");
22326 self.write_space();
22327 self.generate_data_type(&cast.to)?;
22328
22329 if let Some(format) = &cast.format {
22331 self.write_space();
22332 self.write_keyword("FORMAT");
22333 self.write_space();
22334 self.generate_expression(format)?;
22335 }
22336
22337 self.write(")");
22338 Ok(())
22339 }
22340
22341 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
22344 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
22348 if needs_parens {
22349 self.write("(");
22350 }
22351 self.generate_expression(&s.this)?;
22352 if needs_parens {
22353 self.write(")");
22354 }
22355 self.write("[");
22356 self.generate_expression(&s.index)?;
22357 self.write("]");
22358 Ok(())
22359 }
22360
22361 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
22362 self.generate_expression(&d.this)?;
22363 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
22366 && matches!(
22367 &d.this,
22368 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
22369 );
22370 if use_colon {
22371 self.write(":");
22372 } else {
22373 self.write(".");
22374 }
22375 self.generate_identifier(&d.field)
22376 }
22377
22378 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
22379 self.generate_expression(&m.this)?;
22380 self.write(".");
22381 if m.method.quoted {
22384 let q = self.config.identifier_quote;
22385 self.write(&format!("{}{}{}", q, m.method.name, q));
22386 } else {
22387 self.write(&m.method.name);
22388 }
22389 self.write("(");
22390 for (i, arg) in m.args.iter().enumerate() {
22391 if i > 0 {
22392 self.write(", ");
22393 }
22394 self.generate_expression(arg)?;
22395 }
22396 self.write(")");
22397 Ok(())
22398 }
22399
22400 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
22401 let needs_parens = matches!(
22404 &s.this,
22405 Expression::JsonExtract(f) if f.arrow_syntax
22406 ) || matches!(
22407 &s.this,
22408 Expression::JsonExtractScalar(f) if f.arrow_syntax
22409 );
22410
22411 if needs_parens {
22412 self.write("(");
22413 }
22414 self.generate_expression(&s.this)?;
22415 if needs_parens {
22416 self.write(")");
22417 }
22418 self.write("[");
22419 if let Some(start) = &s.start {
22420 self.generate_expression(start)?;
22421 }
22422 self.write(":");
22423 if let Some(end) = &s.end {
22424 self.generate_expression(end)?;
22425 }
22426 self.write("]");
22427 Ok(())
22428 }
22429
22430 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22431 match &op.left {
22435 Expression::Column(col) => {
22436 if let Some(table) = &col.table {
22439 self.generate_identifier(table)?;
22440 self.write(".");
22441 }
22442 self.generate_identifier(&col.name)?;
22443 if col.join_mark && self.config.supports_column_join_marks {
22445 self.write(" (+)");
22446 }
22447 if op.left_comments.is_empty() {
22449 for comment in &col.trailing_comments {
22450 self.write_space();
22451 self.write_formatted_comment(comment);
22452 }
22453 }
22454 }
22455 Expression::Add(inner_op)
22456 | Expression::Sub(inner_op)
22457 | Expression::Mul(inner_op)
22458 | Expression::Div(inner_op)
22459 | Expression::Concat(inner_op) => {
22460 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22462 Expression::Add(_) => "+",
22463 Expression::Sub(_) => "-",
22464 Expression::Mul(_) => "*",
22465 Expression::Div(_) => "/",
22466 Expression::Concat(_) => "||",
22467 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22468 })?;
22469 }
22470 _ => {
22471 self.generate_expression(&op.left)?;
22472 }
22473 }
22474 for comment in &op.left_comments {
22476 self.write_space();
22477 self.write_formatted_comment(comment);
22478 }
22479 if self.config.pretty
22480 && matches!(self.config.dialect, Some(DialectType::Snowflake))
22481 && (operator == "AND" || operator == "OR")
22482 {
22483 self.write_newline();
22484 self.write_indent();
22485 self.write_keyword(operator);
22486 } else {
22487 self.write_space();
22488 if operator.chars().all(|c| c.is_alphabetic()) {
22489 self.write_keyword(operator);
22490 } else {
22491 self.write(operator);
22492 }
22493 }
22494 for comment in &op.operator_comments {
22496 self.write_space();
22497 self.write_formatted_comment(comment);
22498 }
22499 self.write_space();
22500 self.generate_expression(&op.right)?;
22501 for comment in &op.trailing_comments {
22503 self.write_space();
22504 self.write_formatted_comment(comment);
22505 }
22506 Ok(())
22507 }
22508
22509 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
22510 let keyword = connector.keyword();
22511 let Some(terms) = self.flatten_connector_terms(op, connector) else {
22512 return self.generate_binary_op(op, keyword);
22513 };
22514
22515 let wrap_clickhouse_or_term = |generator: &mut Self, term: &Expression| -> Result<()> {
22516 let should_wrap = matches!(connector, ConnectorOperator::Or)
22517 && matches!(generator.config.dialect, Some(DialectType::ClickHouse))
22518 && matches!(
22519 generator.config.source_dialect,
22520 Some(DialectType::ClickHouse)
22521 )
22522 && matches!(term, Expression::And(_));
22523 if should_wrap {
22524 generator.write("(");
22525 generator.generate_expression(term)?;
22526 generator.write(")");
22527 } else {
22528 generator.generate_expression(term)?;
22529 }
22530 Ok(())
22531 };
22532
22533 wrap_clickhouse_or_term(self, terms[0])?;
22534 for term in terms.iter().skip(1) {
22535 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
22536 self.write_newline();
22537 self.write_indent();
22538 self.write_keyword(keyword);
22539 } else {
22540 self.write_space();
22541 self.write_keyword(keyword);
22542 }
22543 self.write_space();
22544 wrap_clickhouse_or_term(self, term)?;
22545 }
22546
22547 Ok(())
22548 }
22549
22550 fn flatten_connector_terms<'a>(
22551 &self,
22552 root: &'a BinaryOp,
22553 connector: ConnectorOperator,
22554 ) -> Option<Vec<&'a Expression>> {
22555 if !root.left_comments.is_empty()
22556 || !root.operator_comments.is_empty()
22557 || !root.trailing_comments.is_empty()
22558 {
22559 return None;
22560 }
22561
22562 let mut terms = Vec::new();
22563 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
22564
22565 while let Some(expr) = stack.pop() {
22566 match (connector, expr) {
22567 (ConnectorOperator::And, Expression::And(inner))
22568 if inner.left_comments.is_empty()
22569 && inner.operator_comments.is_empty()
22570 && inner.trailing_comments.is_empty() =>
22571 {
22572 stack.push(&inner.right);
22573 stack.push(&inner.left);
22574 }
22575 (ConnectorOperator::Or, Expression::Or(inner))
22576 if inner.left_comments.is_empty()
22577 && inner.operator_comments.is_empty()
22578 && inner.trailing_comments.is_empty() =>
22579 {
22580 stack.push(&inner.right);
22581 stack.push(&inner.left);
22582 }
22583 _ => terms.push(expr),
22584 }
22585 }
22586
22587 if terms.len() > 1 {
22588 Some(terms)
22589 } else {
22590 None
22591 }
22592 }
22593
22594 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22596 self.generate_like_op_inner(op, operator, false)
22597 }
22598
22599 fn generate_like_op_negated(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22600 self.generate_like_op_inner(op, operator, true)
22601 }
22602
22603 fn generate_like_op_inner(&mut self, op: &LikeOp, operator: &str, negated: bool) -> Result<()> {
22604 if negated
22605 && matches!(
22606 self.config.dialect,
22607 Some(DialectType::ClickHouse)
22608 | Some(DialectType::DataFusion)
22609 | Some(DialectType::TSQL)
22610 | Some(DialectType::Fabric)
22611 )
22612 {
22613 self.write_keyword("NOT");
22614 self.write_space();
22615 return self.generate_like_op_inner(op, operator, false);
22616 }
22617
22618 self.generate_expression(&op.left)?;
22619 self.write_space();
22620 if negated {
22621 self.write_keyword("NOT");
22622 self.write_space();
22623 }
22624 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
22626 self.write("`ILIKE`");
22627 } else {
22628 self.write_keyword(operator);
22629 }
22630 if let Some(quantifier) = &op.quantifier {
22631 self.write_space();
22632 self.write_keyword(quantifier);
22633 let is_any =
22638 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
22639 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
22640 self.write_space();
22641 }
22642 } else {
22643 self.write_space();
22644 }
22645 self.generate_expression(&op.right)?;
22646 if let Some(escape) = &op.escape {
22647 self.write_space();
22648 self.write_keyword("ESCAPE");
22649 self.write_space();
22650 self.generate_expression(escape)?;
22651 }
22652 Ok(())
22653 }
22654
22655 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
22658 use crate::dialects::DialectType;
22659 self.generate_expression(&op.left)?;
22660 self.write_space();
22661 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
22662 self.write("<=>");
22663 } else {
22664 self.write_keyword("IS NOT DISTINCT FROM");
22665 }
22666 self.write_space();
22667 self.generate_expression(&op.right)?;
22668 Ok(())
22669 }
22670
22671 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
22673 self.generate_expression(&op.left)?;
22674 self.write_space();
22675 self.write_keyword("IS DISTINCT FROM");
22676 self.write_space();
22677 self.generate_expression(&op.right)?;
22678 Ok(())
22679 }
22680
22681 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22683 match &op.left {
22685 Expression::Column(col) => {
22686 if let Some(table) = &col.table {
22687 self.generate_identifier(table)?;
22688 self.write(".");
22689 }
22690 self.generate_identifier(&col.name)?;
22691 if col.join_mark && self.config.supports_column_join_marks {
22693 self.write(" (+)");
22694 }
22695 }
22696 Expression::Add(inner_op)
22697 | Expression::Sub(inner_op)
22698 | Expression::Mul(inner_op)
22699 | Expression::Div(inner_op)
22700 | Expression::Concat(inner_op) => {
22701 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22702 Expression::Add(_) => "+",
22703 Expression::Sub(_) => "-",
22704 Expression::Mul(_) => "*",
22705 Expression::Div(_) => "/",
22706 Expression::Concat(_) => "||",
22707 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22708 })?;
22709 }
22710 _ => {
22711 self.generate_expression(&op.left)?;
22712 }
22713 }
22714 for comment in &op.left_comments {
22716 self.write_space();
22717 self.write_formatted_comment(comment);
22718 }
22719 self.write_space();
22720 if operator.chars().all(|c| c.is_alphabetic()) {
22721 self.write_keyword(operator);
22722 } else {
22723 self.write(operator);
22724 }
22725 for comment in &op.operator_comments {
22727 self.write_space();
22728 self.write_formatted_comment(comment);
22729 }
22730 self.write_space();
22731 match &op.right {
22734 Expression::Column(col) => {
22735 if let Some(table) = &col.table {
22736 self.generate_identifier(table)?;
22737 self.write(".");
22738 }
22739 self.generate_identifier(&col.name)?;
22740 if col.join_mark && self.config.supports_column_join_marks {
22742 self.write(" (+)");
22743 }
22744 }
22745 _ => {
22746 self.generate_expression(&op.right)?;
22747 }
22748 }
22749 Ok(())
22751 }
22752
22753 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
22754 if operator.chars().all(|c| c.is_alphabetic()) {
22755 self.write_keyword(operator);
22756 self.write_space();
22757 } else {
22758 self.write(operator);
22759 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
22761 self.write_space();
22762 }
22763 }
22764 self.generate_expression(&op.this)
22765 }
22766
22767 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
22768 let is_generic =
22772 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22773 let use_prefix_not =
22774 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
22775 if use_prefix_not {
22776 self.write_keyword("NOT");
22777 self.write_space();
22778 }
22779 self.generate_expression(&in_expr.this)?;
22780 if in_expr.global {
22781 self.write_space();
22782 self.write_keyword("GLOBAL");
22783 }
22784 if in_expr.not && !use_prefix_not {
22785 self.write_space();
22786 self.write_keyword("NOT");
22787 }
22788 self.write_space();
22789 self.write_keyword("IN");
22790
22791 if let Some(unnest_expr) = &in_expr.unnest {
22793 self.write_space();
22794 self.write_keyword("UNNEST");
22795 self.write("(");
22796 self.generate_expression(unnest_expr)?;
22797 self.write(")");
22798 return Ok(());
22799 }
22800
22801 if let Some(query) = &in_expr.query {
22802 let is_bare = in_expr.expressions.is_empty()
22805 && !matches!(
22806 query,
22807 Expression::Select(_)
22808 | Expression::Union(_)
22809 | Expression::Intersect(_)
22810 | Expression::Except(_)
22811 | Expression::Subquery(_)
22812 );
22813 if is_bare {
22814 self.write_space();
22816 self.generate_expression(query)?;
22817 } else {
22818 self.write(" (");
22820 let is_statement = matches!(
22821 query,
22822 Expression::Select(_)
22823 | Expression::Union(_)
22824 | Expression::Intersect(_)
22825 | Expression::Except(_)
22826 | Expression::Subquery(_)
22827 );
22828 if self.config.pretty && is_statement {
22829 self.write_newline();
22830 self.indent_level += 1;
22831 self.write_indent();
22832 }
22833 self.generate_expression(query)?;
22834 if self.config.pretty && is_statement {
22835 self.write_newline();
22836 self.indent_level -= 1;
22837 self.write_indent();
22838 }
22839 self.write(")");
22840 }
22841 } else {
22842 let is_duckdb = matches!(
22846 self.config.dialect,
22847 Some(crate::dialects::DialectType::DuckDB)
22848 );
22849 let is_clickhouse = matches!(
22850 self.config.dialect,
22851 Some(crate::dialects::DialectType::ClickHouse)
22852 );
22853 let single_expr = in_expr.expressions.len() == 1;
22854 if is_clickhouse && single_expr {
22855 if let Expression::Array(arr) = &in_expr.expressions[0] {
22856 self.write(" (");
22858 for (i, expr) in arr.expressions.iter().enumerate() {
22859 if i > 0 {
22860 self.write(", ");
22861 }
22862 self.generate_expression(expr)?;
22863 }
22864 self.write(")");
22865 } else if in_expr.is_field {
22866 self.write_space();
22867 self.generate_expression(&in_expr.expressions[0])?;
22868 } else {
22869 self.write(" (");
22870 self.generate_expression(&in_expr.expressions[0])?;
22871 self.write(")");
22872 }
22873 } else {
22874 let is_bare_ref = single_expr
22875 && matches!(
22876 &in_expr.expressions[0],
22877 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
22878 );
22879 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
22880 self.write_space();
22883 self.generate_expression(&in_expr.expressions[0])?;
22884 } else {
22885 self.write(" (");
22887 for (i, expr) in in_expr.expressions.iter().enumerate() {
22888 if i > 0 {
22889 self.write(", ");
22890 }
22891 self.generate_expression(expr)?;
22892 }
22893 self.write(")");
22894 }
22895 }
22896 }
22897
22898 Ok(())
22899 }
22900
22901 fn generate_between(&mut self, between: &Between) -> Result<()> {
22902 let use_prefix_not = between.not
22904 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
22905 if use_prefix_not {
22906 self.write_keyword("NOT");
22907 self.write_space();
22908 }
22909 self.generate_expression(&between.this)?;
22910 if between.not && !use_prefix_not {
22911 self.write_space();
22912 self.write_keyword("NOT");
22913 }
22914 self.write_space();
22915 self.write_keyword("BETWEEN");
22916 if let Some(sym) = between.symmetric {
22918 if sym {
22919 self.write(" SYMMETRIC");
22920 } else {
22921 self.write(" ASYMMETRIC");
22922 }
22923 }
22924 self.write_space();
22925 self.generate_expression(&between.low)?;
22926 self.write_space();
22927 self.write_keyword("AND");
22928 self.write_space();
22929 self.generate_expression(&between.high)
22930 }
22931
22932 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
22933 let use_prefix_not = is_null.not
22935 && (self.config.dialect.is_none()
22936 || self.config.dialect == Some(DialectType::Generic)
22937 || is_null.postfix_form);
22938 if use_prefix_not {
22939 self.write_keyword("NOT");
22941 self.write_space();
22942 self.generate_expression(&is_null.this)?;
22943 self.write_space();
22944 self.write_keyword("IS");
22945 self.write_space();
22946 self.write_keyword("NULL");
22947 } else {
22948 self.generate_expression(&is_null.this)?;
22949 self.write_space();
22950 self.write_keyword("IS");
22951 if is_null.not {
22952 self.write_space();
22953 self.write_keyword("NOT");
22954 }
22955 self.write_space();
22956 self.write_keyword("NULL");
22957 }
22958 Ok(())
22959 }
22960
22961 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
22962 self.generate_expression(&is_true.this)?;
22963 self.write_space();
22964 self.write_keyword("IS");
22965 if is_true.not {
22966 self.write_space();
22967 self.write_keyword("NOT");
22968 }
22969 self.write_space();
22970 self.write_keyword("TRUE");
22971 Ok(())
22972 }
22973
22974 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
22975 self.generate_expression(&is_false.this)?;
22976 self.write_space();
22977 self.write_keyword("IS");
22978 if is_false.not {
22979 self.write_space();
22980 self.write_keyword("NOT");
22981 }
22982 self.write_space();
22983 self.write_keyword("FALSE");
22984 Ok(())
22985 }
22986
22987 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
22988 self.generate_expression(&is_json.this)?;
22989 self.write_space();
22990 self.write_keyword("IS");
22991 if is_json.negated {
22992 self.write_space();
22993 self.write_keyword("NOT");
22994 }
22995 self.write_space();
22996 self.write_keyword("JSON");
22997
22998 if let Some(ref json_type) = is_json.json_type {
23000 self.write_space();
23001 self.write_keyword(json_type);
23002 }
23003
23004 match &is_json.unique_keys {
23006 Some(JsonUniqueKeys::With) => {
23007 self.write_space();
23008 self.write_keyword("WITH UNIQUE KEYS");
23009 }
23010 Some(JsonUniqueKeys::Without) => {
23011 self.write_space();
23012 self.write_keyword("WITHOUT UNIQUE KEYS");
23013 }
23014 Some(JsonUniqueKeys::Shorthand) => {
23015 self.write_space();
23016 self.write_keyword("UNIQUE KEYS");
23017 }
23018 None => {}
23019 }
23020
23021 Ok(())
23022 }
23023
23024 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
23025 self.generate_expression(&is_expr.left)?;
23026 self.write_space();
23027 self.write_keyword("IS");
23028 self.write_space();
23029 self.generate_expression(&is_expr.right)
23030 }
23031
23032 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
23033 if exists.not {
23034 self.write_keyword("NOT");
23035 self.write_space();
23036 }
23037 self.write_keyword("EXISTS");
23038 self.write("(");
23039 let is_statement = matches!(
23040 &exists.this,
23041 Expression::Select(_)
23042 | Expression::Union(_)
23043 | Expression::Intersect(_)
23044 | Expression::Except(_)
23045 );
23046 if self.config.pretty && is_statement {
23047 self.write_newline();
23048 self.indent_level += 1;
23049 self.write_indent();
23050 self.generate_expression(&exists.this)?;
23051 self.write_newline();
23052 self.indent_level -= 1;
23053 self.write_indent();
23054 self.write(")");
23055 } else {
23056 self.generate_expression(&exists.this)?;
23057 self.write(")");
23058 }
23059 Ok(())
23060 }
23061
23062 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
23063 self.generate_expression(&op.left)?;
23064 self.write_space();
23065 self.write_keyword("MEMBER OF");
23066 self.write("(");
23067 self.generate_expression(&op.right)?;
23068 self.write(")");
23069 Ok(())
23070 }
23071
23072 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
23073 if subquery.lateral {
23074 self.write_keyword("LATERAL");
23075 self.write_space();
23076 }
23077
23078 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
23082 matches!(
23083 &p.this,
23084 Expression::Select(_)
23085 | Expression::Union(_)
23086 | Expression::Intersect(_)
23087 | Expression::Except(_)
23088 | Expression::Subquery(_)
23089 )
23090 } else {
23091 false
23092 };
23093
23094 let is_statement = matches!(
23096 &subquery.this,
23097 Expression::Select(_)
23098 | Expression::Union(_)
23099 | Expression::Intersect(_)
23100 | Expression::Except(_)
23101 | Expression::Merge(_)
23102 );
23103
23104 if !skip_outer_parens {
23105 self.write("(");
23106 if self.config.pretty && is_statement {
23107 self.write_newline();
23108 self.indent_level += 1;
23109 self.write_indent();
23110 }
23111 }
23112 self.generate_expression(&subquery.this)?;
23113
23114 if subquery.modifiers_inside {
23116 if let Some(order_by) = &subquery.order_by {
23118 self.write_space();
23119 self.write_keyword("ORDER BY");
23120 self.write_space();
23121 for (i, ord) in order_by.expressions.iter().enumerate() {
23122 if i > 0 {
23123 self.write(", ");
23124 }
23125 self.generate_ordered(ord)?;
23126 }
23127 }
23128
23129 if let Some(limit) = &subquery.limit {
23130 self.write_space();
23131 self.write_keyword("LIMIT");
23132 self.write_space();
23133 self.generate_expression(&limit.this)?;
23134 if limit.percent {
23135 self.write_space();
23136 self.write_keyword("PERCENT");
23137 }
23138 }
23139
23140 if let Some(offset) = &subquery.offset {
23141 self.write_space();
23142 self.write_keyword("OFFSET");
23143 self.write_space();
23144 self.generate_expression(&offset.this)?;
23145 }
23146 }
23147
23148 if !skip_outer_parens {
23149 if self.config.pretty && is_statement {
23150 self.write_newline();
23151 self.indent_level -= 1;
23152 self.write_indent();
23153 }
23154 self.write(")");
23155 }
23156
23157 if !subquery.modifiers_inside {
23159 if let Some(order_by) = &subquery.order_by {
23160 self.write_space();
23161 self.write_keyword("ORDER BY");
23162 self.write_space();
23163 for (i, ord) in order_by.expressions.iter().enumerate() {
23164 if i > 0 {
23165 self.write(", ");
23166 }
23167 self.generate_ordered(ord)?;
23168 }
23169 }
23170
23171 if let Some(limit) = &subquery.limit {
23172 self.write_space();
23173 self.write_keyword("LIMIT");
23174 self.write_space();
23175 self.generate_expression(&limit.this)?;
23176 if limit.percent {
23177 self.write_space();
23178 self.write_keyword("PERCENT");
23179 }
23180 }
23181
23182 if let Some(offset) = &subquery.offset {
23183 self.write_space();
23184 self.write_keyword("OFFSET");
23185 self.write_space();
23186 self.generate_expression(&offset.this)?;
23187 }
23188
23189 if let Some(distribute_by) = &subquery.distribute_by {
23191 self.write_space();
23192 self.write_keyword("DISTRIBUTE BY");
23193 self.write_space();
23194 for (i, expr) in distribute_by.expressions.iter().enumerate() {
23195 if i > 0 {
23196 self.write(", ");
23197 }
23198 self.generate_expression(expr)?;
23199 }
23200 }
23201
23202 if let Some(sort_by) = &subquery.sort_by {
23204 self.write_space();
23205 self.write_keyword("SORT BY");
23206 self.write_space();
23207 for (i, ord) in sort_by.expressions.iter().enumerate() {
23208 if i > 0 {
23209 self.write(", ");
23210 }
23211 self.generate_ordered(ord)?;
23212 }
23213 }
23214
23215 if let Some(cluster_by) = &subquery.cluster_by {
23217 self.write_space();
23218 self.write_keyword("CLUSTER BY");
23219 self.write_space();
23220 for (i, ord) in cluster_by.expressions.iter().enumerate() {
23221 if i > 0 {
23222 self.write(", ");
23223 }
23224 self.generate_ordered(ord)?;
23225 }
23226 }
23227 }
23228
23229 if let Some(alias) = &subquery.alias {
23230 self.write_space();
23231 let skip_as = matches!(self.config.dialect, Some(DialectType::Oracle))
23232 || (matches!(self.config.dialect, Some(DialectType::ClickHouse))
23233 && !subquery.alias_explicit_as);
23234 if !skip_as {
23235 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23236 self.write(subquery.alias_keyword.as_deref().unwrap_or("AS"));
23237 } else {
23238 self.write_keyword("AS");
23239 }
23240 self.write_space();
23241 }
23242 self.generate_identifier(alias)?;
23243 if !subquery.column_aliases.is_empty() {
23244 self.write("(");
23245 for (i, col) in subquery.column_aliases.iter().enumerate() {
23246 if i > 0 {
23247 self.write(", ");
23248 }
23249 self.generate_identifier(col)?;
23250 }
23251 self.write(")");
23252 }
23253 }
23254 for comment in &subquery.trailing_comments {
23256 self.write(" ");
23257 self.write_formatted_comment(comment);
23258 }
23259 Ok(())
23260 }
23261
23262 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
23263 if let Some(ref with) = pivot.with {
23265 self.generate_with(with)?;
23266 self.write_space();
23267 }
23268
23269 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
23270
23271 let is_redshift_unpivot = pivot.unpivot
23275 && pivot.expressions.is_empty()
23276 && pivot.fields.is_empty()
23277 && pivot.using.is_empty()
23278 && pivot.into.is_none()
23279 && !matches!(&pivot.this, Expression::Null(_));
23280
23281 if is_redshift_unpivot {
23282 self.write_keyword("UNPIVOT");
23284 self.write_space();
23285 self.generate_expression(&pivot.this)?;
23286 if let Some(alias) = &pivot.alias {
23288 self.write_space();
23289 self.write_keyword("AS");
23290 self.write_space();
23291 self.write(&alias.name);
23293 }
23294 return Ok(());
23295 }
23296
23297 let is_simplified = !pivot.using.is_empty()
23299 || pivot.into.is_some()
23300 || (pivot.fields.is_empty()
23301 && !pivot.expressions.is_empty()
23302 && !matches!(&pivot.this, Expression::Null(_)));
23303
23304 if is_simplified {
23305 self.write_keyword(direction);
23309 self.write_space();
23310 self.generate_expression(&pivot.this)?;
23311
23312 if !pivot.expressions.is_empty() {
23313 self.write_space();
23314 self.write_keyword("ON");
23315 self.write_space();
23316 for (i, expr) in pivot.expressions.iter().enumerate() {
23317 if i > 0 {
23318 self.write(", ");
23319 }
23320 self.generate_expression(expr)?;
23321 }
23322 }
23323
23324 if let Some(into) = &pivot.into {
23326 self.write_space();
23327 self.write_keyword("INTO");
23328 self.write_space();
23329 self.generate_expression(into)?;
23330 }
23331
23332 if !pivot.using.is_empty() {
23334 self.write_space();
23335 self.write_keyword("USING");
23336 self.write_space();
23337 for (i, expr) in pivot.using.iter().enumerate() {
23338 if i > 0 {
23339 self.write(", ");
23340 }
23341 self.generate_expression(expr)?;
23342 }
23343 }
23344
23345 if let Some(group) = &pivot.group {
23347 self.write_space();
23348 self.generate_expression(group)?;
23349 }
23350 } else {
23351 if !matches!(&pivot.this, Expression::Null(_)) {
23356 self.generate_expression(&pivot.this)?;
23357 self.write_space();
23358 }
23359 self.write_keyword(direction);
23360 self.write("(");
23361
23362 for (i, expr) in pivot.expressions.iter().enumerate() {
23364 if i > 0 {
23365 self.write(", ");
23366 }
23367 self.generate_expression(expr)?;
23368 }
23369
23370 if !pivot.fields.is_empty() {
23372 if !pivot.expressions.is_empty() {
23373 self.write_space();
23374 }
23375 self.write_keyword("FOR");
23376 self.write_space();
23377 for (i, field) in pivot.fields.iter().enumerate() {
23378 if i > 0 {
23379 self.write_space();
23380 }
23381 self.generate_expression(field)?;
23383 }
23384 }
23385
23386 if let Some(default_val) = &pivot.default_on_null {
23388 self.write_space();
23389 self.write_keyword("DEFAULT ON NULL");
23390 self.write(" (");
23391 self.generate_expression(default_val)?;
23392 self.write(")");
23393 }
23394
23395 if let Some(group) = &pivot.group {
23397 self.write_space();
23398 self.generate_expression(group)?;
23399 }
23400
23401 self.write(")");
23402 }
23403
23404 if let Some(alias) = &pivot.alias {
23406 self.write_space();
23407 self.write_keyword("AS");
23408 self.write_space();
23409 self.generate_identifier(alias)?;
23410 self.generate_alias_column_list(&pivot.alias_columns)?;
23411 }
23412
23413 Ok(())
23414 }
23415
23416 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
23417 self.generate_expression(&unpivot.this)?;
23418 self.write_space();
23419 self.write_keyword("UNPIVOT");
23420 if let Some(include) = unpivot.include_nulls {
23422 self.write_space();
23423 if include {
23424 self.write_keyword("INCLUDE NULLS");
23425 } else {
23426 self.write_keyword("EXCLUDE NULLS");
23427 }
23428 self.write_space();
23429 }
23430 self.write("(");
23431 if unpivot.value_column_parenthesized {
23432 self.write("(");
23433 }
23434 self.generate_identifier(&unpivot.value_column)?;
23435 for extra_col in &unpivot.extra_value_columns {
23437 self.write(", ");
23438 self.generate_identifier(extra_col)?;
23439 }
23440 if unpivot.value_column_parenthesized {
23441 self.write(")");
23442 }
23443 self.write_space();
23444 self.write_keyword("FOR");
23445 self.write_space();
23446 self.generate_identifier(&unpivot.name_column)?;
23447 self.write_space();
23448 self.write_keyword("IN");
23449 self.write(" (");
23450 for (i, col) in unpivot.columns.iter().enumerate() {
23451 if i > 0 {
23452 self.write(", ");
23453 }
23454 self.generate_expression(col)?;
23455 }
23456 self.write("))");
23457 if let Some(alias) = &unpivot.alias {
23458 self.write_space();
23459 self.write_keyword("AS");
23460 self.write_space();
23461 self.generate_identifier(alias)?;
23462 self.generate_alias_column_list(&unpivot.alias_columns)?;
23463 }
23464 Ok(())
23465 }
23466
23467 fn generate_alias_column_list(&mut self, columns: &[Identifier]) -> Result<()> {
23468 if columns.is_empty() {
23469 return Ok(());
23470 }
23471
23472 self.write("(");
23473 for (i, column) in columns.iter().enumerate() {
23474 if i > 0 {
23475 self.write(", ");
23476 }
23477 self.generate_identifier(column)?;
23478 }
23479 self.write(")");
23480 Ok(())
23481 }
23482
23483 fn generate_values(&mut self, values: &Values) -> Result<()> {
23484 self.write_keyword("VALUES");
23485 for (i, row) in values.expressions.iter().enumerate() {
23486 if i > 0 {
23487 self.write(",");
23488 }
23489 self.write(" (");
23490 for (j, expr) in row.expressions.iter().enumerate() {
23491 if j > 0 {
23492 self.write(", ");
23493 }
23494 self.generate_expression(expr)?;
23495 }
23496 self.write(")");
23497 }
23498 if let Some(alias) = &values.alias {
23499 self.write_space();
23500 self.write_keyword("AS");
23501 self.write_space();
23502 self.generate_identifier(alias)?;
23503 if !values.column_aliases.is_empty() {
23504 self.write("(");
23505 for (i, col) in values.column_aliases.iter().enumerate() {
23506 if i > 0 {
23507 self.write(", ");
23508 }
23509 self.generate_identifier(col)?;
23510 }
23511 self.write(")");
23512 }
23513 }
23514 Ok(())
23515 }
23516
23517 fn generate_array(&mut self, arr: &Array) -> Result<()> {
23518 let needs_inheritance = matches!(
23520 self.config.dialect,
23521 Some(DialectType::DuckDB)
23522 | Some(DialectType::Spark)
23523 | Some(DialectType::Databricks)
23524 | Some(DialectType::Hive)
23525 | Some(DialectType::Snowflake)
23526 | Some(DialectType::Presto)
23527 | Some(DialectType::Trino)
23528 );
23529 let propagated: Vec<Expression>;
23530 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
23531 propagated = Self::inherit_struct_field_names(&arr.expressions);
23532 &propagated
23533 } else {
23534 &arr.expressions
23535 };
23536
23537 let use_parens =
23540 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
23541 if !self.config.array_bracket_only {
23542 self.write_keyword("ARRAY");
23543 }
23544 if use_parens {
23545 self.write("(");
23546 } else {
23547 self.write("[");
23548 }
23549 for (i, expr) in expressions.iter().enumerate() {
23550 if i > 0 {
23551 self.write(", ");
23552 }
23553 self.generate_expression(expr)?;
23554 }
23555 if use_parens {
23556 self.write(")");
23557 } else {
23558 self.write("]");
23559 }
23560 Ok(())
23561 }
23562
23563 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
23564 if tuple.expressions.len() == 2 {
23567 if let Expression::TableAlias(_) = &tuple.expressions[1] {
23568 self.generate_expression(&tuple.expressions[0])?;
23570 self.write_space();
23571 self.write_keyword("AS");
23572 self.write_space();
23573 self.generate_expression(&tuple.expressions[1])?;
23574 return Ok(());
23575 }
23576 }
23577
23578 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
23581 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
23582 for expr in &tuple.expressions {
23583 expr_strings.push(self.generate_to_string(expr)?);
23584 }
23585 self.too_wide(&expr_strings)
23586 } else {
23587 false
23588 };
23589
23590 if expand_tuple {
23591 self.write("(");
23592 self.write_newline();
23593 self.indent_level += 1;
23594 for (i, expr) in tuple.expressions.iter().enumerate() {
23595 if i > 0 {
23596 self.write(",");
23597 self.write_newline();
23598 }
23599 self.write_indent();
23600 self.generate_expression(expr)?;
23601 }
23602 self.indent_level -= 1;
23603 self.write_newline();
23604 self.write_indent();
23605 self.write(")");
23606 } else {
23607 self.write("(");
23608 for (i, expr) in tuple.expressions.iter().enumerate() {
23609 if i > 0 {
23610 self.write(", ");
23611 }
23612 self.generate_expression(expr)?;
23613 }
23614 self.write(")");
23615 }
23616 Ok(())
23617 }
23618
23619 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
23620 self.generate_expression(&pipe.this)?;
23621 self.write(" |> ");
23622 self.generate_expression(&pipe.expression)?;
23623 Ok(())
23624 }
23625
23626 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
23627 let unsupported_tsql_null_ordering = ordered.nulls_first.is_some()
23628 && !self.config.null_ordering_supported
23629 && matches!(
23630 self.config.dialect,
23631 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23632 );
23633 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
23634 let emulate_tsql_null_ordering = if let Some(nulls_first) = ordered.nulls_first {
23635 let target_default_nulls_first = !ordered.desc;
23636
23637 unsupported_tsql_null_ordering
23638 && nulls_first != target_default_nulls_first
23639 && !random_ordering
23640 } else {
23641 false
23642 };
23643
23644 if emulate_tsql_null_ordering {
23645 self.write_keyword("CASE WHEN");
23646 self.write_space();
23647 self.generate_expression(&ordered.this)?;
23648 self.write_space();
23649 self.write_keyword("IS NULL THEN 1 ELSE 0 END");
23650 if ordered.nulls_first == Some(true) {
23651 self.write_space();
23652 self.write_keyword("DESC");
23653 }
23654 self.write(", ");
23655 }
23656
23657 self.generate_expression(&ordered.this)?;
23658 if ordered.desc {
23659 self.write_space();
23660 self.write_keyword("DESC");
23661 } else if ordered.explicit_asc {
23662 self.write_space();
23663 self.write_keyword("ASC");
23664 }
23665 if let Some(nulls_first) = ordered.nulls_first {
23666 if !unsupported_tsql_null_ordering
23667 && (self.config.null_ordering_supported
23668 || !matches!(self.config.dialect, Some(DialectType::Fabric)))
23669 {
23670 let is_asc = !ordered.desc;
23684 let is_nulls_are_large = matches!(
23685 self.config.dialect,
23686 Some(DialectType::Oracle)
23687 | Some(DialectType::PostgreSQL)
23688 | Some(DialectType::Redshift)
23689 | Some(DialectType::Snowflake)
23690 );
23691 let is_nulls_are_last = matches!(
23692 self.config.dialect,
23693 Some(DialectType::Dremio)
23694 | Some(DialectType::DuckDB)
23695 | Some(DialectType::Presto)
23696 | Some(DialectType::Trino)
23697 | Some(DialectType::Athena)
23698 | Some(DialectType::ClickHouse)
23699 | Some(DialectType::Drill)
23700 | Some(DialectType::Exasol)
23701 );
23702
23703 let is_default_nulls = if is_nulls_are_large {
23705 (is_asc && !nulls_first) || (!is_asc && nulls_first)
23707 } else if is_nulls_are_last {
23708 !nulls_first
23710 } else {
23711 false
23712 };
23713
23714 if !is_default_nulls {
23715 self.write_space();
23716 self.write_keyword("NULLS");
23717 self.write_space();
23718 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
23719 }
23720 }
23721 }
23722 if let Some(ref with_fill) = ordered.with_fill {
23724 self.write_space();
23725 self.generate_with_fill(with_fill)?;
23726 }
23727 Ok(())
23728 }
23729
23730 fn write_clickhouse_type(&mut self, type_str: &str) {
23732 if self.clickhouse_nullable_depth < 0 {
23733 self.write(type_str);
23735 } else {
23736 self.write(&format!("Nullable({})", type_str));
23737 }
23738 }
23739
23740 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
23741 use crate::dialects::DialectType;
23742
23743 match dt {
23744 DataType::Boolean => {
23745 match self.config.dialect {
23747 Some(DialectType::TSQL) => self.write_keyword("BIT"),
23748 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
23750 self.write_keyword("NUMBER(1)")
23752 }
23753 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
23755 }
23756 }
23757 DataType::TinyInt { length } => {
23758 match self.config.dialect {
23762 Some(DialectType::PostgreSQL)
23763 | Some(DialectType::Redshift)
23764 | Some(DialectType::Oracle)
23765 | Some(DialectType::Exasol) => {
23766 self.write_keyword("SMALLINT");
23767 }
23768 Some(DialectType::Teradata) => {
23769 self.write_keyword("BYTEINT");
23771 }
23772 Some(DialectType::Dremio) => {
23773 self.write_keyword("INT");
23775 }
23776 Some(DialectType::ClickHouse) => {
23777 self.write_clickhouse_type("Int8");
23778 }
23779 _ => {
23780 self.write_keyword("TINYINT");
23781 }
23782 }
23783 if let Some(n) = length {
23784 if !matches!(
23785 self.config.dialect,
23786 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
23787 ) {
23788 self.write(&format!("({})", n));
23789 }
23790 }
23791 }
23792 DataType::SmallInt { length } => {
23793 match self.config.dialect {
23795 Some(DialectType::Dremio) => {
23796 self.write_keyword("INT");
23797 }
23798 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
23799 self.write_keyword("INTEGER");
23800 }
23801 Some(DialectType::BigQuery) => {
23802 self.write_keyword("INT64");
23803 }
23804 Some(DialectType::ClickHouse) => {
23805 self.write_clickhouse_type("Int16");
23806 }
23807 _ => {
23808 self.write_keyword("SMALLINT");
23809 if let Some(n) = length {
23810 self.write(&format!("({})", n));
23811 }
23812 }
23813 }
23814 }
23815 DataType::Int {
23816 length,
23817 integer_spelling: _,
23818 } => {
23819 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
23821 self.write_keyword("INT64");
23822 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23823 self.write_clickhouse_type("Int32");
23824 } else {
23825 let use_integer = match self.config.dialect {
23827 Some(DialectType::TSQL)
23828 | Some(DialectType::Fabric)
23829 | Some(DialectType::Presto)
23830 | Some(DialectType::Trino)
23831 | Some(DialectType::SQLite)
23832 | Some(DialectType::Redshift) => true,
23833 _ => false,
23834 };
23835 if use_integer {
23836 self.write_keyword("INTEGER");
23837 } else {
23838 self.write_keyword("INT");
23839 }
23840 if let Some(n) = length {
23841 self.write(&format!("({})", n));
23842 }
23843 }
23844 }
23845 DataType::BigInt { length } => {
23846 match self.config.dialect {
23848 Some(DialectType::Oracle) => {
23849 self.write_keyword("INT");
23851 }
23852 Some(DialectType::ClickHouse) => {
23853 self.write_clickhouse_type("Int64");
23854 }
23855 _ => {
23856 self.write_keyword("BIGINT");
23857 if let Some(n) = length {
23858 self.write(&format!("({})", n));
23859 }
23860 }
23861 }
23862 }
23863 DataType::Float {
23864 precision,
23865 scale,
23866 real_spelling,
23867 } => {
23868 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23872 self.write_clickhouse_type("Float32");
23873 } else if *real_spelling
23874 && !matches!(
23875 self.config.dialect,
23876 Some(DialectType::Spark)
23877 | Some(DialectType::Databricks)
23878 | Some(DialectType::Hive)
23879 | Some(DialectType::Snowflake)
23880 | Some(DialectType::MySQL)
23881 | Some(DialectType::BigQuery)
23882 )
23883 {
23884 self.write_keyword("REAL")
23885 } else {
23886 match self.config.dialect {
23887 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
23888 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23889 _ => self.write_keyword("FLOAT"),
23890 }
23891 }
23892 if !matches!(
23895 self.config.dialect,
23896 Some(DialectType::Spark)
23897 | Some(DialectType::Databricks)
23898 | Some(DialectType::Hive)
23899 | Some(DialectType::Presto)
23900 | Some(DialectType::Trino)
23901 ) {
23902 if let Some(p) = precision {
23903 self.write(&format!("({}", p));
23904 if let Some(s) = scale {
23905 self.write(&format!(", {})", s));
23906 } else {
23907 self.write(")");
23908 }
23909 }
23910 }
23911 }
23912 DataType::Double { precision, scale } => {
23913 match self.config.dialect {
23915 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23916 self.write_keyword("FLOAT")
23917 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
23919 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
23920 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23921 Some(DialectType::SQLite) => self.write_keyword("REAL"),
23922 Some(DialectType::PostgreSQL)
23923 | Some(DialectType::Redshift)
23924 | Some(DialectType::Teradata)
23925 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
23926 _ => self.write_keyword("DOUBLE"),
23927 }
23928 if let Some(p) = precision {
23930 self.write(&format!("({}", p));
23931 if let Some(s) = scale {
23932 self.write(&format!(", {})", s));
23933 } else {
23934 self.write(")");
23935 }
23936 }
23937 }
23938 DataType::Decimal { precision, scale } => {
23939 match self.config.dialect {
23941 Some(DialectType::ClickHouse) => {
23942 self.write("Decimal");
23943 if let Some(p) = precision {
23944 self.write(&format!("({}", p));
23945 if let Some(s) = scale {
23946 self.write(&format!(", {}", s));
23947 }
23948 self.write(")");
23949 }
23950 }
23951 Some(DialectType::Oracle) => {
23952 self.write_keyword("NUMBER");
23954 if let Some(p) = precision {
23955 self.write(&format!("({}", p));
23956 if let Some(s) = scale {
23957 self.write(&format!(", {}", s));
23958 }
23959 self.write(")");
23960 }
23961 }
23962 Some(DialectType::BigQuery) => {
23963 self.write_keyword("NUMERIC");
23965 if let Some(p) = precision {
23966 self.write(&format!("({}", p));
23967 if let Some(s) = scale {
23968 self.write(&format!(", {}", s));
23969 }
23970 self.write(")");
23971 }
23972 }
23973 _ => {
23974 self.write_keyword("DECIMAL");
23975 if let Some(p) = precision {
23976 self.write(&format!("({}", p));
23977 if let Some(s) = scale {
23978 self.write(&format!(", {}", s));
23979 }
23980 self.write(")");
23981 }
23982 }
23983 }
23984 }
23985 DataType::Char { length } => {
23986 match self.config.dialect {
23988 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23989 self.write_keyword("TEXT");
23991 }
23992 Some(DialectType::Hive)
23993 | Some(DialectType::Spark)
23994 | Some(DialectType::Databricks) => {
23995 if length.is_some()
23998 && !matches!(self.config.dialect, Some(DialectType::Hive))
23999 {
24000 self.write_keyword("CHAR");
24001 if let Some(n) = length {
24002 self.write(&format!("({})", n));
24003 }
24004 } else {
24005 self.write_keyword("STRING");
24006 }
24007 }
24008 Some(DialectType::Dremio) => {
24009 self.write_keyword("VARCHAR");
24011 if let Some(n) = length {
24012 self.write(&format!("({})", n));
24013 }
24014 }
24015 _ => {
24016 self.write_keyword("CHAR");
24017 if let Some(n) = length {
24018 self.write(&format!("({})", n));
24019 }
24020 }
24021 }
24022 }
24023 DataType::VarChar {
24024 length,
24025 parenthesized_length,
24026 } => {
24027 match self.config.dialect {
24029 Some(DialectType::Oracle) => {
24030 self.write_keyword("VARCHAR2");
24031 if let Some(n) = length {
24032 self.write(&format!("({})", n));
24033 }
24034 }
24035 Some(DialectType::DuckDB) => {
24036 self.write_keyword("TEXT");
24038 if let Some(n) = length {
24039 self.write(&format!("({})", n));
24040 }
24041 }
24042 Some(DialectType::SQLite) => {
24043 self.write_keyword("TEXT");
24045 if let Some(n) = length {
24046 self.write(&format!("({})", n));
24047 }
24048 }
24049 Some(DialectType::MySQL) if length.is_none() => {
24050 self.write_keyword("TEXT");
24052 }
24053 Some(DialectType::Hive)
24054 | Some(DialectType::Spark)
24055 | Some(DialectType::Databricks)
24056 if length.is_none() =>
24057 {
24058 self.write_keyword("STRING");
24060 }
24061 _ => {
24062 self.write_keyword("VARCHAR");
24063 if let Some(n) = length {
24064 if *parenthesized_length {
24066 self.write(&format!("(({}))", n));
24067 } else {
24068 self.write(&format!("({})", n));
24069 }
24070 }
24071 }
24072 }
24073 }
24074 DataType::Text => {
24075 match self.config.dialect {
24077 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
24078 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24079 self.write_keyword("VARCHAR(MAX)")
24080 }
24081 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24082 Some(DialectType::Snowflake)
24083 | Some(DialectType::Dremio)
24084 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
24085 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
24086 Some(DialectType::Presto)
24087 | Some(DialectType::Trino)
24088 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24089 Some(DialectType::Spark)
24090 | Some(DialectType::Databricks)
24091 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24092 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
24093 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
24094 self.write_keyword("STRING")
24095 }
24096 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
24097 _ => self.write_keyword("TEXT"),
24098 }
24099 }
24100 DataType::TextWithLength { length } => {
24101 match self.config.dialect {
24103 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
24104 Some(DialectType::Hive)
24105 | Some(DialectType::Spark)
24106 | Some(DialectType::Databricks) => {
24107 self.write(&format!("VARCHAR({})", length));
24108 }
24109 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
24110 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
24111 Some(DialectType::Snowflake)
24112 | Some(DialectType::Presto)
24113 | Some(DialectType::Trino)
24114 | Some(DialectType::Athena)
24115 | Some(DialectType::Drill)
24116 | Some(DialectType::Dremio) => {
24117 self.write(&format!("VARCHAR({})", length));
24118 }
24119 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24120 self.write(&format!("VARCHAR({})", length))
24121 }
24122 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
24123 self.write(&format!("STRING({})", length))
24124 }
24125 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
24126 _ => self.write(&format!("TEXT({})", length)),
24127 }
24128 }
24129 DataType::String { length } => {
24130 match self.config.dialect {
24132 Some(DialectType::ClickHouse) => {
24133 self.write("String");
24135 if let Some(n) = length {
24136 self.write(&format!("({})", n));
24137 }
24138 }
24139 Some(DialectType::BigQuery)
24140 | Some(DialectType::Hive)
24141 | Some(DialectType::Spark)
24142 | Some(DialectType::Databricks)
24143 | Some(DialectType::StarRocks)
24144 | Some(DialectType::Doris) => {
24145 self.write_keyword("STRING");
24146 if let Some(n) = length {
24147 self.write(&format!("({})", n));
24148 }
24149 }
24150 Some(DialectType::PostgreSQL) => {
24151 if let Some(n) = length {
24153 self.write_keyword("VARCHAR");
24154 self.write(&format!("({})", n));
24155 } else {
24156 self.write_keyword("TEXT");
24157 }
24158 }
24159 Some(DialectType::Redshift) => {
24160 if let Some(n) = length {
24162 self.write_keyword("VARCHAR");
24163 self.write(&format!("({})", n));
24164 } else {
24165 self.write_keyword("VARCHAR(MAX)");
24166 }
24167 }
24168 Some(DialectType::MySQL) => {
24169 if let Some(n) = length {
24171 self.write_keyword("VARCHAR");
24172 self.write(&format!("({})", n));
24173 } else {
24174 self.write_keyword("TEXT");
24175 }
24176 }
24177 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24178 if let Some(n) = length {
24180 self.write_keyword("VARCHAR");
24181 self.write(&format!("({})", n));
24182 } else {
24183 self.write_keyword("VARCHAR(MAX)");
24184 }
24185 }
24186 Some(DialectType::Oracle) => {
24187 self.write_keyword("CLOB");
24189 }
24190 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
24191 self.write_keyword("TEXT");
24193 if let Some(n) = length {
24194 self.write(&format!("({})", n));
24195 }
24196 }
24197 Some(DialectType::Presto)
24198 | Some(DialectType::Trino)
24199 | Some(DialectType::Drill)
24200 | Some(DialectType::Dremio) => {
24201 self.write_keyword("VARCHAR");
24203 if let Some(n) = length {
24204 self.write(&format!("({})", n));
24205 }
24206 }
24207 Some(DialectType::Snowflake) => {
24208 self.write_keyword("STRING");
24211 if let Some(n) = length {
24212 self.write(&format!("({})", n));
24213 }
24214 }
24215 _ => {
24216 self.write_keyword("STRING");
24218 if let Some(n) = length {
24219 self.write(&format!("({})", n));
24220 }
24221 }
24222 }
24223 }
24224 DataType::Binary { length } => {
24225 match self.config.dialect {
24227 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
24228 self.write_keyword("BYTEA");
24229 if let Some(n) = length {
24230 self.write(&format!("({})", n));
24231 }
24232 }
24233 Some(DialectType::Redshift) => {
24234 self.write_keyword("VARBYTE");
24235 if let Some(n) = length {
24236 self.write(&format!("({})", n));
24237 }
24238 }
24239 Some(DialectType::DuckDB)
24240 | Some(DialectType::SQLite)
24241 | Some(DialectType::Oracle) => {
24242 self.write_keyword("BLOB");
24244 if let Some(n) = length {
24245 self.write(&format!("({})", n));
24246 }
24247 }
24248 Some(DialectType::Presto)
24249 | Some(DialectType::Trino)
24250 | Some(DialectType::Athena)
24251 | Some(DialectType::Drill)
24252 | Some(DialectType::Dremio) => {
24253 self.write_keyword("VARBINARY");
24255 if let Some(n) = length {
24256 self.write(&format!("({})", n));
24257 }
24258 }
24259 Some(DialectType::ClickHouse) => {
24260 if self.clickhouse_nullable_depth < 0 {
24262 self.write("BINARY");
24263 } else {
24264 self.write("Nullable(BINARY");
24265 }
24266 if let Some(n) = length {
24267 self.write(&format!("({})", n));
24268 }
24269 if self.clickhouse_nullable_depth >= 0 {
24270 self.write(")");
24271 }
24272 }
24273 _ => {
24274 self.write_keyword("BINARY");
24275 if let Some(n) = length {
24276 self.write(&format!("({})", n));
24277 }
24278 }
24279 }
24280 }
24281 DataType::VarBinary { length } => {
24282 match self.config.dialect {
24284 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
24285 self.write_keyword("BYTEA");
24286 if let Some(n) = length {
24287 self.write(&format!("({})", n));
24288 }
24289 }
24290 Some(DialectType::Redshift) => {
24291 self.write_keyword("VARBYTE");
24292 if let Some(n) = length {
24293 self.write(&format!("({})", n));
24294 }
24295 }
24296 Some(DialectType::DuckDB)
24297 | Some(DialectType::SQLite)
24298 | Some(DialectType::Oracle) => {
24299 self.write_keyword("BLOB");
24301 if let Some(n) = length {
24302 self.write(&format!("({})", n));
24303 }
24304 }
24305 Some(DialectType::Exasol) => {
24306 self.write_keyword("VARCHAR");
24308 }
24309 Some(DialectType::Spark)
24310 | Some(DialectType::Hive)
24311 | Some(DialectType::Databricks) => {
24312 self.write_keyword("BINARY");
24314 if let Some(n) = length {
24315 self.write(&format!("({})", n));
24316 }
24317 }
24318 Some(DialectType::ClickHouse) => {
24319 self.write_clickhouse_type("String");
24321 }
24322 _ => {
24323 self.write_keyword("VARBINARY");
24324 if let Some(n) = length {
24325 self.write(&format!("({})", n));
24326 }
24327 }
24328 }
24329 }
24330 DataType::Blob => {
24331 match self.config.dialect {
24333 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
24334 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
24335 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24336 self.write_keyword("VARBINARY")
24337 }
24338 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24339 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
24340 Some(DialectType::Presto)
24341 | Some(DialectType::Trino)
24342 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24343 Some(DialectType::DuckDB) => {
24344 self.write_keyword("VARBINARY");
24347 }
24348 Some(DialectType::Spark)
24349 | Some(DialectType::Databricks)
24350 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
24351 Some(DialectType::ClickHouse) => {
24352 self.write("Nullable(String)");
24356 }
24357 _ => self.write_keyword("BLOB"),
24358 }
24359 }
24360 DataType::Bit { length } => {
24361 match self.config.dialect {
24363 Some(DialectType::Dremio)
24364 | Some(DialectType::Spark)
24365 | Some(DialectType::Databricks)
24366 | Some(DialectType::Hive)
24367 | Some(DialectType::Snowflake)
24368 | Some(DialectType::BigQuery)
24369 | Some(DialectType::Presto)
24370 | Some(DialectType::Trino)
24371 | Some(DialectType::ClickHouse)
24372 | Some(DialectType::Redshift) => {
24373 self.write_keyword("BOOLEAN");
24375 }
24376 _ => {
24377 self.write_keyword("BIT");
24378 if let Some(n) = length {
24379 self.write(&format!("({})", n));
24380 }
24381 }
24382 }
24383 }
24384 DataType::VarBit { length } => {
24385 self.write_keyword("VARBIT");
24386 if let Some(n) = length {
24387 self.write(&format!("({})", n));
24388 }
24389 }
24390 DataType::Date => self.write_keyword("DATE"),
24391 DataType::Time {
24392 precision,
24393 timezone,
24394 } => {
24395 if *timezone {
24396 match self.config.dialect {
24398 Some(DialectType::DuckDB) => {
24399 self.write_keyword("TIMETZ");
24401 }
24402 Some(DialectType::PostgreSQL) => {
24403 self.write_keyword("TIMETZ");
24405 if let Some(p) = precision {
24406 self.write(&format!("({})", p));
24407 }
24408 }
24409 _ => {
24410 self.write_keyword("TIME");
24412 if let Some(p) = precision {
24413 self.write(&format!("({})", p));
24414 }
24415 self.write_keyword(" WITH TIME ZONE");
24416 }
24417 }
24418 } else {
24419 if matches!(
24421 self.config.dialect,
24422 Some(DialectType::Spark)
24423 | Some(DialectType::Databricks)
24424 | Some(DialectType::Hive)
24425 ) {
24426 self.write_keyword("TIMESTAMP");
24427 } else {
24428 self.write_keyword("TIME");
24429 if let Some(p) = precision {
24430 self.write(&format!("({})", p));
24431 }
24432 }
24433 }
24434 }
24435 DataType::Timestamp {
24436 precision,
24437 timezone,
24438 } => {
24439 match self.config.dialect {
24441 Some(DialectType::Snowflake) if *timezone => {
24442 self.write_keyword("TIMESTAMPTZ");
24443 if let Some(p) = precision {
24444 self.write(&format!("({})", p));
24445 }
24446 }
24447 Some(DialectType::ClickHouse) => {
24448 self.write("DateTime");
24449 if let Some(p) = precision {
24450 self.write(&format!("({})", p));
24451 }
24452 }
24453 Some(DialectType::TSQL) => {
24454 if *timezone {
24455 self.write_keyword("DATETIMEOFFSET");
24456 } else {
24457 self.write_keyword("DATETIME2");
24458 }
24459 if let Some(p) = precision {
24460 self.write(&format!("({})", p));
24461 }
24462 }
24463 Some(DialectType::MySQL) => {
24464 self.write_keyword("TIMESTAMP");
24466 if let Some(p) = precision {
24467 self.write(&format!("({})", p));
24468 }
24469 }
24470 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
24471 self.write_keyword("DATETIME");
24473 if let Some(p) = precision {
24474 self.write(&format!("({})", p));
24475 }
24476 }
24477 Some(DialectType::BigQuery) => {
24478 if *timezone {
24480 self.write_keyword("TIMESTAMP");
24481 } else {
24482 self.write_keyword("DATETIME");
24483 }
24484 }
24485 Some(DialectType::DuckDB) => {
24486 if *timezone {
24488 self.write_keyword("TIMESTAMPTZ");
24489 } else {
24490 self.write_keyword("TIMESTAMP");
24491 if let Some(p) = precision {
24492 self.write(&format!("({})", p));
24493 }
24494 }
24495 }
24496 _ => {
24497 if *timezone && !self.config.tz_to_with_time_zone {
24498 self.write_keyword("TIMESTAMPTZ");
24500 if let Some(p) = precision {
24501 self.write(&format!("({})", p));
24502 }
24503 } else {
24504 self.write_keyword("TIMESTAMP");
24505 if let Some(p) = precision {
24506 self.write(&format!("({})", p));
24507 }
24508 if *timezone {
24509 self.write_space();
24510 self.write_keyword("WITH TIME ZONE");
24511 }
24512 }
24513 }
24514 }
24515 }
24516 DataType::Interval { unit, to } => {
24517 self.write_keyword("INTERVAL");
24518 if let Some(u) = unit {
24519 self.write_space();
24520 self.write_keyword(u);
24521 }
24522 if let Some(t) = to {
24524 self.write_space();
24525 self.write_keyword("TO");
24526 self.write_space();
24527 self.write_keyword(t);
24528 }
24529 }
24530 DataType::Json => {
24531 match self.config.dialect {
24533 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
24536 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24537 _ => self.write_keyword("JSON"),
24538 }
24539 }
24540 DataType::JsonB => {
24541 match self.config.dialect {
24543 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
24544 Some(DialectType::Doris) => self.write_keyword("JSONB"),
24545 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24546 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24547 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
24550 }
24551 DataType::Uuid => {
24552 match self.config.dialect {
24554 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
24555 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
24556 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
24557 Some(DialectType::BigQuery)
24558 | Some(DialectType::Spark)
24559 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
24560 _ => self.write_keyword("UUID"),
24561 }
24562 }
24563 DataType::Array {
24564 element_type,
24565 dimension,
24566 } => {
24567 match self.config.dialect {
24569 Some(DialectType::PostgreSQL)
24570 | Some(DialectType::Redshift)
24571 | Some(DialectType::DuckDB) => {
24572 self.generate_data_type(element_type)?;
24574 if let Some(dim) = dimension {
24575 self.write(&format!("[{}]", dim));
24576 } else {
24577 self.write("[]");
24578 }
24579 }
24580 Some(DialectType::BigQuery) => {
24581 self.write_keyword("ARRAY<");
24582 self.generate_data_type(element_type)?;
24583 self.write(">");
24584 }
24585 Some(DialectType::Snowflake)
24586 | Some(DialectType::Presto)
24587 | Some(DialectType::Trino)
24588 | Some(DialectType::ClickHouse) => {
24589 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24591 self.write("Array(");
24592 } else {
24593 self.write_keyword("ARRAY(");
24594 }
24595 self.generate_data_type(element_type)?;
24596 self.write(")");
24597 }
24598 Some(DialectType::TSQL)
24599 | Some(DialectType::MySQL)
24600 | Some(DialectType::Oracle) => {
24601 match self.config.dialect {
24604 Some(DialectType::MySQL) => self.write_keyword("JSON"),
24605 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24606 _ => self.write_keyword("JSON"),
24607 }
24608 }
24609 _ => {
24610 self.write_keyword("ARRAY<");
24612 self.generate_data_type(element_type)?;
24613 self.write(">");
24614 }
24615 }
24616 }
24617 DataType::List { element_type } => {
24618 self.generate_data_type(element_type)?;
24620 self.write_keyword(" LIST");
24621 }
24622 DataType::Map {
24623 key_type,
24624 value_type,
24625 } => {
24626 match self.config.dialect {
24628 Some(DialectType::Materialize) => {
24629 self.write_keyword("MAP[");
24631 self.generate_data_type(key_type)?;
24632 self.write(" => ");
24633 self.generate_data_type(value_type)?;
24634 self.write("]");
24635 }
24636 Some(DialectType::Snowflake)
24637 | Some(DialectType::RisingWave)
24638 | Some(DialectType::DuckDB)
24639 | Some(DialectType::Presto)
24640 | Some(DialectType::Trino)
24641 | Some(DialectType::Athena) => {
24642 self.write_keyword("MAP(");
24643 self.generate_data_type(key_type)?;
24644 self.write(", ");
24645 self.generate_data_type(value_type)?;
24646 self.write(")");
24647 }
24648 Some(DialectType::ClickHouse) => {
24649 self.write("Map(");
24652 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
24654 self.clickhouse_nullable_depth = 0;
24655 self.write(", ");
24656 self.generate_data_type(value_type)?;
24657 self.write(")");
24658 }
24659 _ => {
24660 self.write_keyword("MAP<");
24661 self.generate_data_type(key_type)?;
24662 self.write(", ");
24663 self.generate_data_type(value_type)?;
24664 self.write(">");
24665 }
24666 }
24667 }
24668 DataType::Vector {
24669 element_type,
24670 dimension,
24671 } => {
24672 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
24673 self.write_keyword("VECTOR(");
24675 if let Some(dim) = dimension {
24676 self.write(&dim.to_string());
24677 }
24678 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
24680 DataType::TinyInt { .. } => Some("I8"),
24681 DataType::SmallInt { .. } => Some("I16"),
24682 DataType::Int { .. } => Some("I32"),
24683 DataType::BigInt { .. } => Some("I64"),
24684 DataType::Float { .. } => Some("F32"),
24685 DataType::Double { .. } => Some("F64"),
24686 _ => None,
24687 });
24688 if let Some(alias) = type_alias {
24689 if dimension.is_some() {
24690 self.write(", ");
24691 }
24692 self.write(alias);
24693 }
24694 self.write(")");
24695 } else {
24696 self.write_keyword("VECTOR(");
24698 if let Some(ref et) = element_type {
24699 self.generate_data_type(et)?;
24700 if dimension.is_some() {
24701 self.write(", ");
24702 }
24703 }
24704 if let Some(dim) = dimension {
24705 self.write(&dim.to_string());
24706 }
24707 self.write(")");
24708 }
24709 }
24710 DataType::Object { fields, modifier } => {
24711 self.write_keyword("OBJECT(");
24712 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
24713 if i > 0 {
24714 self.write(", ");
24715 }
24716 self.write(name);
24717 self.write(" ");
24718 self.generate_data_type(dt)?;
24719 if *not_null {
24720 self.write_keyword(" NOT NULL");
24721 }
24722 }
24723 self.write(")");
24724 if let Some(mod_str) = modifier {
24725 self.write(" ");
24726 self.write_keyword(mod_str);
24727 }
24728 }
24729 DataType::Struct { fields, nested } => {
24730 match self.config.dialect {
24732 Some(DialectType::Snowflake) => {
24733 self.write_keyword("OBJECT(");
24735 for (i, field) in fields.iter().enumerate() {
24736 if i > 0 {
24737 self.write(", ");
24738 }
24739 if !field.name.is_empty() {
24740 self.write(&field.name);
24741 self.write(" ");
24742 }
24743 self.generate_data_type(&field.data_type)?;
24744 }
24745 self.write(")");
24746 }
24747 Some(DialectType::Presto) | Some(DialectType::Trino) => {
24748 self.write_keyword("ROW(");
24750 for (i, field) in fields.iter().enumerate() {
24751 if i > 0 {
24752 self.write(", ");
24753 }
24754 if !field.name.is_empty() {
24755 self.write(&field.name);
24756 self.write(" ");
24757 }
24758 self.generate_data_type(&field.data_type)?;
24759 }
24760 self.write(")");
24761 }
24762 Some(DialectType::DuckDB) => {
24763 self.write_keyword("STRUCT(");
24765 for (i, field) in fields.iter().enumerate() {
24766 if i > 0 {
24767 self.write(", ");
24768 }
24769 if !field.name.is_empty() {
24770 self.write(&field.name);
24771 self.write(" ");
24772 }
24773 self.generate_data_type(&field.data_type)?;
24774 }
24775 self.write(")");
24776 }
24777 Some(DialectType::ClickHouse) => {
24778 self.write("Tuple(");
24780 for (i, field) in fields.iter().enumerate() {
24781 if i > 0 {
24782 self.write(", ");
24783 }
24784 if !field.name.is_empty() {
24785 self.write(&field.name);
24786 self.write(" ");
24787 }
24788 self.generate_data_type(&field.data_type)?;
24789 }
24790 self.write(")");
24791 }
24792 Some(DialectType::SingleStore) => {
24793 self.write_keyword("RECORD(");
24795 for (i, field) in fields.iter().enumerate() {
24796 if i > 0 {
24797 self.write(", ");
24798 }
24799 if !field.name.is_empty() {
24800 self.write(&field.name);
24801 self.write(" ");
24802 }
24803 self.generate_data_type(&field.data_type)?;
24804 }
24805 self.write(")");
24806 }
24807 _ => {
24808 let force_angle_brackets = matches!(
24810 self.config.dialect,
24811 Some(DialectType::Hive)
24812 | Some(DialectType::Spark)
24813 | Some(DialectType::Databricks)
24814 );
24815 if *nested && !force_angle_brackets {
24816 self.write_keyword("STRUCT(");
24817 for (i, field) in fields.iter().enumerate() {
24818 if i > 0 {
24819 self.write(", ");
24820 }
24821 if !field.name.is_empty() {
24822 self.write(&field.name);
24823 self.write(" ");
24824 }
24825 self.generate_data_type(&field.data_type)?;
24826 }
24827 self.write(")");
24828 } else {
24829 self.write_keyword("STRUCT<");
24830 for (i, field) in fields.iter().enumerate() {
24831 if i > 0 {
24832 self.write(", ");
24833 }
24834 if !field.name.is_empty() {
24835 self.write(&field.name);
24837 self.write(self.config.struct_field_sep);
24838 }
24839 self.generate_data_type(&field.data_type)?;
24841 if let Some(comment) = &field.comment {
24843 self.write(" COMMENT '");
24844 self.write(comment);
24845 self.write("'");
24846 }
24847 if !field.options.is_empty() {
24849 self.write(" ");
24850 self.generate_options_clause(&field.options)?;
24851 }
24852 }
24853 self.write(">");
24854 }
24855 }
24856 }
24857 }
24858 DataType::Enum {
24859 values,
24860 assignments,
24861 } => {
24862 if self.config.dialect == Some(DialectType::ClickHouse) {
24865 self.write("Enum(");
24866 } else {
24867 self.write_keyword("ENUM(");
24868 }
24869 for (i, val) in values.iter().enumerate() {
24870 if i > 0 {
24871 self.write(", ");
24872 }
24873 self.write("'");
24874 self.write(val);
24875 self.write("'");
24876 if let Some(Some(assignment)) = assignments.get(i) {
24877 self.write(" = ");
24878 self.write(assignment);
24879 }
24880 }
24881 self.write(")");
24882 }
24883 DataType::Set { values } => {
24884 self.write_keyword("SET(");
24886 for (i, val) in values.iter().enumerate() {
24887 if i > 0 {
24888 self.write(", ");
24889 }
24890 self.write("'");
24891 self.write(val);
24892 self.write("'");
24893 }
24894 self.write(")");
24895 }
24896 DataType::Union { fields } => {
24897 self.write_keyword("UNION(");
24899 for (i, (name, dt)) in fields.iter().enumerate() {
24900 if i > 0 {
24901 self.write(", ");
24902 }
24903 if !name.is_empty() {
24904 self.write(name);
24905 self.write(" ");
24906 }
24907 self.generate_data_type(dt)?;
24908 }
24909 self.write(")");
24910 }
24911 DataType::Nullable { inner } => {
24912 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24914 self.write("Nullable(");
24915 let saved_depth = self.clickhouse_nullable_depth;
24917 self.clickhouse_nullable_depth = -1;
24918 self.generate_data_type(inner)?;
24919 self.clickhouse_nullable_depth = saved_depth;
24920 self.write(")");
24921 } else {
24922 match inner.as_ref() {
24924 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
24925 self.generate_data_type(&DataType::Timestamp {
24926 precision: None,
24927 timezone: false,
24928 })?;
24929 }
24930 _ => {
24931 self.generate_data_type(inner)?;
24932 }
24933 }
24934 }
24935 }
24936 DataType::Custom { name } => {
24937 let name_upper = name.to_ascii_uppercase();
24939 match self.config.dialect {
24940 Some(DialectType::ClickHouse) => {
24941 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
24942 (name_upper[..idx].to_string(), &name[idx..])
24943 } else {
24944 (name_upper.clone(), "")
24945 };
24946 let mapped = match base_upper.as_str() {
24947 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
24948 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
24949 "DATETIME64" => "DateTime64",
24950 "DATE32" => "Date32",
24951 "INT" => "Int32",
24952 "MEDIUMINT" => "Int32",
24953 "INT8" => "Int8",
24954 "INT16" => "Int16",
24955 "INT32" => "Int32",
24956 "INT64" => "Int64",
24957 "INT128" => "Int128",
24958 "INT256" => "Int256",
24959 "UINT8" => "UInt8",
24960 "UINT16" => "UInt16",
24961 "UINT32" => "UInt32",
24962 "UINT64" => "UInt64",
24963 "UINT128" => "UInt128",
24964 "UINT256" => "UInt256",
24965 "FLOAT32" => "Float32",
24966 "FLOAT64" => "Float64",
24967 "DECIMAL32" => "Decimal32",
24968 "DECIMAL64" => "Decimal64",
24969 "DECIMAL128" => "Decimal128",
24970 "DECIMAL256" => "Decimal256",
24971 "ENUM" => "Enum",
24972 "ENUM8" => "Enum8",
24973 "ENUM16" => "Enum16",
24974 "FIXEDSTRING" => "FixedString",
24975 "NESTED" => "Nested",
24976 "LOWCARDINALITY" => "LowCardinality",
24977 "NULLABLE" => "Nullable",
24978 "IPV4" => "IPv4",
24979 "IPV6" => "IPv6",
24980 "POINT" => "Point",
24981 "RING" => "Ring",
24982 "LINESTRING" => "LineString",
24983 "MULTILINESTRING" => "MultiLineString",
24984 "POLYGON" => "Polygon",
24985 "MULTIPOLYGON" => "MultiPolygon",
24986 "AGGREGATEFUNCTION" => "AggregateFunction",
24987 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
24988 "DYNAMIC" => "Dynamic",
24989 _ => "",
24990 };
24991 if mapped.is_empty() {
24992 self.write(name);
24993 } else {
24994 self.write(mapped);
24995 if matches!(base_upper.as_str(), "ENUM8" | "ENUM16")
24996 && !suffix.is_empty()
24997 {
24998 let escaped_suffix = suffix
24999 .replace('\\', "\\\\")
25000 .replace('\t', "\\t")
25001 .replace('\n', "\\n")
25002 .replace('\r', "\\r");
25003 self.write(&escaped_suffix);
25004 } else {
25005 self.write(suffix);
25006 }
25007 }
25008 }
25009 Some(DialectType::MySQL)
25010 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
25011 {
25012 self.write_keyword("TIMESTAMP");
25014 }
25015 Some(DialectType::Snowflake) => {
25016 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
25017 (name_upper[..idx].to_string(), &name[idx..])
25018 } else {
25019 (name_upper.clone(), "")
25020 };
25021
25022 match base_upper.as_str() {
25023 "TIMESTAMPNTZ" | "TIMESTAMP_NTZ" => {
25024 self.write_keyword("TIMESTAMPNTZ");
25025 self.write(suffix);
25026 }
25027 "TIMESTAMPLTZ" | "TIMESTAMP_LTZ" => {
25028 self.write_keyword("TIMESTAMPLTZ");
25029 self.write(suffix);
25030 }
25031 "TIMESTAMPTZ" | "TIMESTAMP_TZ" => {
25032 self.write_keyword("TIMESTAMPTZ");
25033 self.write(suffix);
25034 }
25035 _ => self.write(name),
25036 }
25037 }
25038 Some(DialectType::Fabric) => {
25039 let (base_upper, args_str) = if let Some(idx) = name.find('(') {
25040 (name_upper[..idx].to_string(), Some(&name[idx..]))
25041 } else {
25042 (name_upper.clone(), None)
25043 };
25044
25045 match base_upper.as_str() {
25046 "NVARCHAR" => {
25047 self.write_keyword("VARCHAR");
25048 if let Some(args) = args_str {
25049 self.write(args);
25050 }
25051 }
25052 "NCHAR" => {
25053 self.write_keyword("CHAR");
25054 if let Some(args) = args_str {
25055 self.write(args);
25056 }
25057 }
25058 _ => self.write(name),
25059 }
25060 }
25061 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
25062 self.write_keyword("SQL_VARIANT");
25063 }
25064 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
25065 self.write_keyword("DECIMAL(38, 5)");
25066 }
25067 Some(DialectType::Exasol) => {
25068 match name_upper.as_str() {
25070 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
25072 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
25074 "MEDIUMINT" => self.write_keyword("INT"),
25076 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
25078 self.write_keyword("DECIMAL")
25079 }
25080 "DATETIME" => self.write_keyword("TIMESTAMP"),
25082 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
25083 _ => self.write(name),
25084 }
25085 }
25086 Some(DialectType::Dremio) => {
25087 match name_upper.as_str() {
25089 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
25090 "ARRAY" => self.write_keyword("LIST"),
25091 "NCHAR" => self.write_keyword("VARCHAR"),
25092 _ => self.write(name),
25093 }
25094 }
25095 _ => {
25097 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
25099 (name_upper[..idx].to_string(), Some(&name[idx..]))
25100 } else {
25101 (name_upper.clone(), None)
25102 };
25103
25104 match base_upper.as_str() {
25105 "INT64"
25106 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25107 {
25108 self.write_keyword("BIGINT");
25109 }
25110 "FLOAT64"
25111 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25112 {
25113 self.write_keyword("DOUBLE");
25114 }
25115 "BOOL"
25116 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25117 {
25118 self.write_keyword("BOOLEAN");
25119 }
25120 "BYTES"
25121 if matches!(
25122 self.config.dialect,
25123 Some(DialectType::Spark)
25124 | Some(DialectType::Hive)
25125 | Some(DialectType::Databricks)
25126 ) =>
25127 {
25128 self.write_keyword("BINARY");
25129 }
25130 "BYTES"
25131 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25132 {
25133 self.write_keyword("VARBINARY");
25134 }
25135 "DATETIME2" | "SMALLDATETIME"
25137 if !matches!(
25138 self.config.dialect,
25139 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25140 ) =>
25141 {
25142 if matches!(
25144 self.config.dialect,
25145 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25146 ) {
25147 self.write_keyword("TIMESTAMP");
25148 if let Some(args) = _args_str {
25149 self.write(args);
25150 }
25151 } else {
25152 self.write_keyword("TIMESTAMP");
25153 }
25154 }
25155 "DATETIMEOFFSET"
25157 if !matches!(
25158 self.config.dialect,
25159 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25160 ) =>
25161 {
25162 if matches!(
25163 self.config.dialect,
25164 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25165 ) {
25166 self.write_keyword("TIMESTAMPTZ");
25167 if let Some(args) = _args_str {
25168 self.write(args);
25169 }
25170 } else {
25171 self.write_keyword("TIMESTAMPTZ");
25172 }
25173 }
25174 "UNIQUEIDENTIFIER"
25176 if !matches!(
25177 self.config.dialect,
25178 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25179 ) =>
25180 {
25181 match self.config.dialect {
25182 Some(DialectType::Spark)
25183 | Some(DialectType::Databricks)
25184 | Some(DialectType::Hive) => self.write_keyword("STRING"),
25185 _ => self.write_keyword("UUID"),
25186 }
25187 }
25188 "BIT"
25190 if !matches!(
25191 self.config.dialect,
25192 Some(DialectType::TSQL)
25193 | Some(DialectType::Fabric)
25194 | Some(DialectType::PostgreSQL)
25195 | Some(DialectType::MySQL)
25196 | Some(DialectType::DuckDB)
25197 ) =>
25198 {
25199 self.write_keyword("BOOLEAN");
25200 }
25201 "NVARCHAR"
25203 if !matches!(
25204 self.config.dialect,
25205 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25206 ) =>
25207 {
25208 match self.config.dialect {
25209 Some(DialectType::Oracle) => {
25210 self.write_keyword("NVARCHAR2");
25212 if let Some(args) = _args_str {
25213 self.write(args);
25214 }
25215 }
25216 Some(DialectType::BigQuery) => {
25217 self.write_keyword("STRING");
25219 }
25220 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
25221 self.write_keyword("TEXT");
25222 if let Some(args) = _args_str {
25223 self.write(args);
25224 }
25225 }
25226 Some(DialectType::Hive) => {
25227 self.write_keyword("STRING");
25229 }
25230 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
25231 if _args_str.is_some() {
25232 self.write_keyword("VARCHAR");
25233 self.write(_args_str.unwrap());
25234 } else {
25235 self.write_keyword("STRING");
25236 }
25237 }
25238 _ => {
25239 self.write_keyword("VARCHAR");
25240 if let Some(args) = _args_str {
25241 self.write(args);
25242 }
25243 }
25244 }
25245 }
25246 "NCHAR"
25248 if !matches!(
25249 self.config.dialect,
25250 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25251 ) =>
25252 {
25253 match self.config.dialect {
25254 Some(DialectType::Oracle) => {
25255 self.write_keyword("NCHAR");
25257 if let Some(args) = _args_str {
25258 self.write(args);
25259 }
25260 }
25261 Some(DialectType::BigQuery) => {
25262 self.write_keyword("STRING");
25264 }
25265 Some(DialectType::Hive) => {
25266 self.write_keyword("STRING");
25268 }
25269 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
25270 self.write_keyword("TEXT");
25271 if let Some(args) = _args_str {
25272 self.write(args);
25273 }
25274 }
25275 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
25276 if _args_str.is_some() {
25277 self.write_keyword("CHAR");
25278 self.write(_args_str.unwrap());
25279 } else {
25280 self.write_keyword("STRING");
25281 }
25282 }
25283 _ => {
25284 self.write_keyword("CHAR");
25285 if let Some(args) = _args_str {
25286 self.write(args);
25287 }
25288 }
25289 }
25290 }
25291 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
25294 Some(DialectType::MySQL)
25295 | Some(DialectType::SingleStore)
25296 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
25297 Some(DialectType::Spark)
25298 | Some(DialectType::Databricks)
25299 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
25300 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
25301 Some(DialectType::Presto)
25302 | Some(DialectType::Trino)
25303 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
25304 Some(DialectType::Snowflake)
25305 | Some(DialectType::Redshift)
25306 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
25307 _ => self.write_keyword("TEXT"),
25308 },
25309 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
25312 Some(DialectType::MySQL)
25313 | Some(DialectType::SingleStore)
25314 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
25315 Some(DialectType::Spark)
25316 | Some(DialectType::Databricks)
25317 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
25318 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
25319 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
25320 Some(DialectType::Presto)
25321 | Some(DialectType::Trino)
25322 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
25323 Some(DialectType::Snowflake)
25324 | Some(DialectType::Redshift)
25325 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
25326 _ => self.write_keyword("BLOB"),
25327 },
25328 "LONGVARCHAR" => match self.config.dialect {
25330 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
25331 _ => self.write_keyword("VARCHAR"),
25332 },
25333 "DATETIME" => {
25335 match self.config.dialect {
25336 Some(DialectType::MySQL)
25337 | Some(DialectType::Doris)
25338 | Some(DialectType::StarRocks)
25339 | Some(DialectType::TSQL)
25340 | Some(DialectType::Fabric)
25341 | Some(DialectType::BigQuery)
25342 | Some(DialectType::SQLite)
25343 | Some(DialectType::Snowflake) => {
25344 self.write_keyword("DATETIME");
25345 if let Some(args) = _args_str {
25346 self.write(args);
25347 }
25348 }
25349 Some(_) => {
25350 self.write_keyword("TIMESTAMP");
25352 if let Some(args) = _args_str {
25353 self.write(args);
25354 }
25355 }
25356 None => {
25357 self.write(name);
25359 }
25360 }
25361 }
25362 "VARCHAR2"
25364 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
25365 {
25366 match self.config.dialect {
25367 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25368 self.write_keyword("TEXT");
25369 }
25370 Some(DialectType::Hive)
25371 | Some(DialectType::Spark)
25372 | Some(DialectType::Databricks)
25373 | Some(DialectType::BigQuery)
25374 | Some(DialectType::ClickHouse)
25375 | Some(DialectType::StarRocks)
25376 | Some(DialectType::Doris) => {
25377 self.write_keyword("STRING");
25378 }
25379 _ => {
25380 self.write_keyword("VARCHAR");
25381 if let Some(args) = _args_str {
25382 self.write(args);
25383 }
25384 }
25385 }
25386 }
25387 "NVARCHAR2"
25388 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
25389 {
25390 match self.config.dialect {
25391 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25392 self.write_keyword("TEXT");
25393 }
25394 Some(DialectType::Hive)
25395 | Some(DialectType::Spark)
25396 | Some(DialectType::Databricks)
25397 | Some(DialectType::BigQuery)
25398 | Some(DialectType::ClickHouse)
25399 | Some(DialectType::StarRocks)
25400 | Some(DialectType::Doris) => {
25401 self.write_keyword("STRING");
25402 }
25403 _ => {
25404 self.write_keyword("VARCHAR");
25405 if let Some(args) = _args_str {
25406 self.write(args);
25407 }
25408 }
25409 }
25410 }
25411 _ => self.write(name),
25412 }
25413 }
25414 }
25415 }
25416 DataType::Geometry { subtype, srid } => {
25417 match self.config.dialect {
25419 Some(DialectType::MySQL) => {
25420 if let Some(sub) = subtype {
25422 self.write_keyword(sub);
25423 if let Some(s) = srid {
25424 self.write(" SRID ");
25425 self.write(&s.to_string());
25426 }
25427 } else {
25428 self.write_keyword("GEOMETRY");
25429 }
25430 }
25431 Some(DialectType::BigQuery) => {
25432 self.write_keyword("GEOGRAPHY");
25434 }
25435 Some(DialectType::Teradata) => {
25436 self.write_keyword("ST_GEOMETRY");
25438 if subtype.is_some() || srid.is_some() {
25439 self.write("(");
25440 if let Some(sub) = subtype {
25441 self.write_keyword(sub);
25442 }
25443 if let Some(s) = srid {
25444 if subtype.is_some() {
25445 self.write(", ");
25446 }
25447 self.write(&s.to_string());
25448 }
25449 self.write(")");
25450 }
25451 }
25452 _ => {
25453 self.write_keyword("GEOMETRY");
25455 if subtype.is_some() || srid.is_some() {
25456 self.write("(");
25457 if let Some(sub) = subtype {
25458 self.write_keyword(sub);
25459 }
25460 if let Some(s) = srid {
25461 if subtype.is_some() {
25462 self.write(", ");
25463 }
25464 self.write(&s.to_string());
25465 }
25466 self.write(")");
25467 }
25468 }
25469 }
25470 }
25471 DataType::Geography { subtype, srid } => {
25472 match self.config.dialect {
25474 Some(DialectType::MySQL) => {
25475 if let Some(sub) = subtype {
25477 self.write_keyword(sub);
25478 } else {
25479 self.write_keyword("GEOMETRY");
25480 }
25481 let effective_srid = srid.unwrap_or(4326);
25483 self.write(" SRID ");
25484 self.write(&effective_srid.to_string());
25485 }
25486 Some(DialectType::BigQuery) => {
25487 self.write_keyword("GEOGRAPHY");
25489 }
25490 Some(DialectType::Snowflake) => {
25491 self.write_keyword("GEOGRAPHY");
25493 }
25494 _ => {
25495 self.write_keyword("GEOGRAPHY");
25497 if subtype.is_some() || srid.is_some() {
25498 self.write("(");
25499 if let Some(sub) = subtype {
25500 self.write_keyword(sub);
25501 }
25502 if let Some(s) = srid {
25503 if subtype.is_some() {
25504 self.write(", ");
25505 }
25506 self.write(&s.to_string());
25507 }
25508 self.write(")");
25509 }
25510 }
25511 }
25512 }
25513 DataType::CharacterSet { name } => {
25514 self.write_keyword("CHAR CHARACTER SET ");
25516 self.write(name);
25517 }
25518 _ => self.write("UNKNOWN"),
25519 }
25520 Ok(())
25521 }
25522
25523 #[inline]
25526 fn write(&mut self, s: &str) {
25527 self.output.push_str(s);
25528 }
25529
25530 #[inline]
25531 fn write_space(&mut self) {
25532 self.output.push(' ');
25533 }
25534
25535 #[inline]
25536 fn write_keyword(&mut self, keyword: &str) {
25537 if self.config.uppercase_keywords {
25538 self.output.push_str(keyword);
25539 } else {
25540 for b in keyword.bytes() {
25541 self.output.push(b.to_ascii_lowercase() as char);
25542 }
25543 }
25544 }
25545
25546 fn write_func_name(&mut self, name: &str) {
25548 let normalized = self.normalize_func_name(name);
25549 self.output.push_str(normalized.as_ref());
25550 }
25551
25552 fn convert_strptime_to_exasol_format(format: &str) -> String {
25556 let mut result = String::new();
25557 let chars: Vec<char> = format.chars().collect();
25558 let mut i = 0;
25559 while i < chars.len() {
25560 if chars[i] == '%' && i + 1 < chars.len() {
25561 let spec = chars[i + 1];
25562 let exasol_spec = match spec {
25563 'Y' => "YYYY",
25564 'y' => "YY",
25565 'm' => "MM",
25566 'd' => "DD",
25567 'H' => "HH",
25568 'M' => "MI",
25569 'S' => "SS",
25570 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
25582 result.push('%');
25584 result.push(spec);
25585 i += 2;
25586 continue;
25587 }
25588 };
25589 result.push_str(exasol_spec);
25590 i += 2;
25591 } else {
25592 result.push(chars[i]);
25593 i += 1;
25594 }
25595 }
25596 result
25597 }
25598
25599 fn convert_strptime_to_postgres_format(format: &str) -> String {
25603 let mut result = String::new();
25604 let chars: Vec<char> = format.chars().collect();
25605 let mut i = 0;
25606 while i < chars.len() {
25607 if chars[i] == '%' && i + 1 < chars.len() {
25608 if chars[i + 1] == '-' && i + 2 < chars.len() {
25610 let spec = chars[i + 2];
25611 let pg_spec = match spec {
25612 'd' => "FMDD",
25613 'm' => "FMMM",
25614 'H' => "FMHH24",
25615 'M' => "FMMI",
25616 'S' => "FMSS",
25617 _ => {
25618 result.push('%');
25619 result.push('-');
25620 result.push(spec);
25621 i += 3;
25622 continue;
25623 }
25624 };
25625 result.push_str(pg_spec);
25626 i += 3;
25627 continue;
25628 }
25629 let spec = chars[i + 1];
25630 let pg_spec = match spec {
25631 'Y' => "YYYY",
25632 'y' => "YY",
25633 'm' => "MM",
25634 'd' => "DD",
25635 'H' => "HH24",
25636 'I' => "HH12",
25637 'M' => "MI",
25638 'S' => "SS",
25639 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
25650 result.push('%');
25652 result.push(spec);
25653 i += 2;
25654 continue;
25655 }
25656 };
25657 result.push_str(pg_spec);
25658 i += 2;
25659 } else {
25660 result.push(chars[i]);
25661 i += 1;
25662 }
25663 }
25664 result
25665 }
25666
25667 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
25669 if self.config.limit_only_literals {
25670 if let Some(value) = Self::try_evaluate_constant(expr) {
25671 self.write(&value.to_string());
25672 return Ok(());
25673 }
25674 }
25675 self.generate_expression(expr)
25676 }
25677
25678 fn write_formatted_comment(&mut self, comment: &str) {
25682 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
25685 &comment[2..comment.len() - 2]
25688 } else if comment.starts_with("--") {
25689 &comment[2..]
25692 } else {
25693 comment
25695 };
25696 if content.trim().is_empty() {
25698 return;
25699 }
25700 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
25703 let content = &sanitized;
25704 self.output.push_str("/*");
25706 if !content.starts_with(' ') {
25707 self.output.push(' ');
25708 }
25709 self.output.push_str(content);
25710 if !content.ends_with(' ') {
25711 self.output.push(' ');
25712 }
25713 self.output.push_str("*/");
25714 }
25715
25716 fn escape_block_for_single_quote(&self, block: &str) -> String {
25719 let escape_backslash = matches!(
25720 self.config.dialect,
25721 Some(crate::dialects::DialectType::Snowflake)
25722 );
25723 let mut escaped = String::with_capacity(block.len() + 4);
25724 for ch in block.chars() {
25725 if ch == '\'' {
25726 escaped.push('\\');
25727 escaped.push('\'');
25728 } else if escape_backslash && ch == '\\' {
25729 escaped.push('\\');
25730 escaped.push('\\');
25731 } else {
25732 escaped.push(ch);
25733 }
25734 }
25735 escaped
25736 }
25737
25738 fn write_newline(&mut self) {
25739 self.output.push('\n');
25740 }
25741
25742 fn write_indent(&mut self) {
25743 for _ in 0..self.indent_level {
25744 self.output.push_str(self.config.indent);
25745 }
25746 }
25747
25748 fn too_wide(&self, args: &[String]) -> bool {
25754 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
25755 }
25756
25757 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
25760 let config = GeneratorConfig {
25761 pretty: false,
25762 dialect: self.config.dialect,
25763 ..Default::default()
25764 };
25765 let mut gen = Generator::with_config(config);
25766 gen.generate_expression(expr)?;
25767 Ok(gen.output)
25768 }
25769
25770 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
25773 if self.config.pretty {
25774 self.write_newline();
25775 self.write_indent();
25776 self.write_keyword(keyword);
25777 self.write_newline();
25778 self.indent_level += 1;
25779 self.write_indent();
25780 self.generate_expression(condition)?;
25781 self.indent_level -= 1;
25782 } else {
25783 self.write_space();
25784 self.write_keyword(keyword);
25785 self.write_space();
25786 self.generate_expression(condition)?;
25787 }
25788 Ok(())
25789 }
25790
25791 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
25794 if exprs.is_empty() {
25795 return Ok(());
25796 }
25797
25798 if self.config.pretty {
25799 self.write_newline();
25800 self.write_indent();
25801 self.write_keyword(keyword);
25802 self.write_newline();
25803 self.indent_level += 1;
25804 for (i, expr) in exprs.iter().enumerate() {
25805 if i > 0 {
25806 self.write(",");
25807 self.write_newline();
25808 }
25809 self.write_indent();
25810 self.generate_expression(expr)?;
25811 }
25812 self.indent_level -= 1;
25813 } else {
25814 self.write_space();
25815 self.write_keyword(keyword);
25816 self.write_space();
25817 for (i, expr) in exprs.iter().enumerate() {
25818 if i > 0 {
25819 self.write(", ");
25820 }
25821 self.generate_expression(expr)?;
25822 }
25823 }
25824 Ok(())
25825 }
25826
25827 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
25829 if orderings.is_empty() {
25830 return Ok(());
25831 }
25832
25833 if self.config.pretty {
25834 self.write_newline();
25835 self.write_indent();
25836 self.write_keyword(keyword);
25837 self.write_newline();
25838 self.indent_level += 1;
25839 for (i, ordered) in orderings.iter().enumerate() {
25840 if i > 0 {
25841 self.write(",");
25842 self.write_newline();
25843 }
25844 self.write_indent();
25845 self.generate_ordered(ordered)?;
25846 }
25847 self.indent_level -= 1;
25848 } else {
25849 self.write_space();
25850 self.write_keyword(keyword);
25851 self.write_space();
25852 for (i, ordered) in orderings.iter().enumerate() {
25853 if i > 0 {
25854 self.write(", ");
25855 }
25856 self.generate_ordered(ordered)?;
25857 }
25858 }
25859 Ok(())
25860 }
25861
25862 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
25864 if windows.is_empty() {
25865 return Ok(());
25866 }
25867
25868 if self.config.pretty {
25869 self.write_newline();
25870 self.write_indent();
25871 self.write_keyword("WINDOW");
25872 self.write_newline();
25873 self.indent_level += 1;
25874 for (i, named_window) in windows.iter().enumerate() {
25875 if i > 0 {
25876 self.write(",");
25877 self.write_newline();
25878 }
25879 self.write_indent();
25880 self.generate_identifier(&named_window.name)?;
25881 self.write_space();
25882 self.write_keyword("AS");
25883 self.write(" (");
25884 self.generate_over(&named_window.spec)?;
25885 self.write(")");
25886 }
25887 self.indent_level -= 1;
25888 } else {
25889 self.write_space();
25890 self.write_keyword("WINDOW");
25891 self.write_space();
25892 for (i, named_window) in windows.iter().enumerate() {
25893 if i > 0 {
25894 self.write(", ");
25895 }
25896 self.generate_identifier(&named_window.name)?;
25897 self.write_space();
25898 self.write_keyword("AS");
25899 self.write(" (");
25900 self.generate_over(&named_window.spec)?;
25901 self.write(")");
25902 }
25903 }
25904 Ok(())
25905 }
25906
25907 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
25909 self.write_keyword("AI_AGG");
25911 self.write("(");
25912 self.generate_expression(&e.this)?;
25913 self.write(", ");
25914 self.generate_expression(&e.expression)?;
25915 self.write(")");
25916 Ok(())
25917 }
25918
25919 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
25920 self.write_keyword("AI_CLASSIFY");
25922 self.write("(");
25923 self.generate_expression(&e.this)?;
25924 if let Some(categories) = &e.categories {
25925 self.write(", ");
25926 self.generate_expression(categories)?;
25927 }
25928 if let Some(config) = &e.config {
25929 self.write(", ");
25930 self.generate_expression(config)?;
25931 }
25932 self.write(")");
25933 Ok(())
25934 }
25935
25936 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
25937 self.write_keyword("ADD");
25939 self.write_space();
25940 if e.exists {
25941 self.write_keyword("IF NOT EXISTS");
25942 self.write_space();
25943 }
25944 self.generate_expression(&e.this)?;
25945 if let Some(location) = &e.location {
25946 self.write_space();
25947 self.generate_expression(location)?;
25948 }
25949 Ok(())
25950 }
25951
25952 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
25953 self.write_keyword("ALGORITHM");
25955 self.write("=");
25956 self.generate_expression(&e.this)?;
25957 Ok(())
25958 }
25959
25960 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
25961 self.generate_expression(&e.this)?;
25963 self.write_space();
25964 self.write_keyword("AS");
25965 self.write(" (");
25966 for (i, expr) in e.expressions.iter().enumerate() {
25967 if i > 0 {
25968 self.write(", ");
25969 }
25970 self.generate_expression(expr)?;
25971 }
25972 self.write(")");
25973 Ok(())
25974 }
25975
25976 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
25977 self.write_keyword("ALLOWED_VALUES");
25979 self.write_space();
25980 for (i, expr) in e.expressions.iter().enumerate() {
25981 if i > 0 {
25982 self.write(", ");
25983 }
25984 self.generate_expression(expr)?;
25985 }
25986 Ok(())
25987 }
25988
25989 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
25990 self.write_keyword("ALTER COLUMN");
25992 self.write_space();
25993 self.generate_expression(&e.this)?;
25994
25995 if let Some(dtype) = &e.dtype {
25996 self.write_space();
25997 self.write_keyword("SET DATA TYPE");
25998 self.write_space();
25999 self.generate_expression(dtype)?;
26000 if let Some(collate) = &e.collate {
26001 self.write_space();
26002 self.write_keyword("COLLATE");
26003 self.write_space();
26004 self.generate_expression(collate)?;
26005 }
26006 if let Some(using) = &e.using {
26007 self.write_space();
26008 self.write_keyword("USING");
26009 self.write_space();
26010 self.generate_expression(using)?;
26011 }
26012 } else if let Some(default) = &e.default {
26013 self.write_space();
26014 self.write_keyword("SET DEFAULT");
26015 self.write_space();
26016 self.generate_expression(default)?;
26017 } else if let Some(comment) = &e.comment {
26018 self.write_space();
26019 self.write_keyword("COMMENT");
26020 self.write_space();
26021 self.generate_expression(comment)?;
26022 } else if let Some(drop) = &e.drop {
26023 self.write_space();
26024 self.write_keyword("DROP");
26025 self.write_space();
26026 self.generate_expression(drop)?;
26027 } else if let Some(visible) = &e.visible {
26028 self.write_space();
26029 self.generate_expression(visible)?;
26030 } else if let Some(rename_to) = &e.rename_to {
26031 self.write_space();
26032 self.write_keyword("RENAME TO");
26033 self.write_space();
26034 self.generate_expression(rename_to)?;
26035 } else if let Some(allow_null) = &e.allow_null {
26036 self.write_space();
26037 self.generate_expression(allow_null)?;
26038 }
26039 Ok(())
26040 }
26041
26042 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
26043 self.write_keyword("ALTER SESSION");
26045 self.write_space();
26046 if e.unset.is_some() {
26047 self.write_keyword("UNSET");
26048 } else {
26049 self.write_keyword("SET");
26050 }
26051 self.write_space();
26052 for (i, expr) in e.expressions.iter().enumerate() {
26053 if i > 0 {
26054 self.write(", ");
26055 }
26056 self.generate_expression(expr)?;
26057 }
26058 Ok(())
26059 }
26060
26061 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
26062 self.write_keyword("SET");
26064
26065 if let Some(opt) = &e.option {
26067 self.write_space();
26068 self.generate_expression(opt)?;
26069 }
26070
26071 if !e.expressions.is_empty() {
26074 let is_properties = e
26076 .expressions
26077 .iter()
26078 .any(|expr| matches!(expr, Expression::Eq(_)));
26079 if is_properties && e.option.is_none() {
26080 self.write_space();
26081 self.write_keyword("PROPERTIES");
26082 }
26083 self.write_space();
26084 for (i, expr) in e.expressions.iter().enumerate() {
26085 if i > 0 {
26086 self.write(", ");
26087 }
26088 self.generate_expression(expr)?;
26089 }
26090 }
26091
26092 if let Some(file_format) = &e.file_format {
26094 self.write(" ");
26095 self.write_keyword("STAGE_FILE_FORMAT");
26096 self.write(" = (");
26097 self.generate_space_separated_properties(file_format)?;
26098 self.write(")");
26099 }
26100
26101 if let Some(copy_options) = &e.copy_options {
26103 self.write(" ");
26104 self.write_keyword("STAGE_COPY_OPTIONS");
26105 self.write(" = (");
26106 self.generate_space_separated_properties(copy_options)?;
26107 self.write(")");
26108 }
26109
26110 if let Some(tag) = &e.tag {
26112 self.write(" ");
26113 self.write_keyword("TAG");
26114 self.write(" ");
26115 self.generate_expression(tag)?;
26116 }
26117
26118 Ok(())
26119 }
26120
26121 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
26123 match expr {
26124 Expression::Tuple(t) => {
26125 for (i, prop) in t.expressions.iter().enumerate() {
26126 if i > 0 {
26127 self.write(" ");
26128 }
26129 self.generate_expression(prop)?;
26130 }
26131 }
26132 _ => {
26133 self.generate_expression(expr)?;
26134 }
26135 }
26136 Ok(())
26137 }
26138
26139 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
26140 self.write_keyword("ALTER");
26142 if e.compound.is_some() {
26143 self.write_space();
26144 self.write_keyword("COMPOUND");
26145 }
26146 self.write_space();
26147 self.write_keyword("SORTKEY");
26148 self.write_space();
26149 if let Some(this) = &e.this {
26150 self.generate_expression(this)?;
26151 } else if !e.expressions.is_empty() {
26152 self.write("(");
26153 for (i, expr) in e.expressions.iter().enumerate() {
26154 if i > 0 {
26155 self.write(", ");
26156 }
26157 self.generate_expression(expr)?;
26158 }
26159 self.write(")");
26160 }
26161 Ok(())
26162 }
26163
26164 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
26165 self.write_keyword("ANALYZE");
26167 if !e.options.is_empty() {
26168 self.write_space();
26169 for (i, opt) in e.options.iter().enumerate() {
26170 if i > 0 {
26171 self.write_space();
26172 }
26173 if let Expression::Identifier(id) = opt {
26175 self.write_keyword(&id.name);
26176 } else {
26177 self.generate_expression(opt)?;
26178 }
26179 }
26180 }
26181 if let Some(kind) = &e.kind {
26182 self.write_space();
26183 self.write_keyword(kind);
26184 }
26185 if let Some(this) = &e.this {
26186 self.write_space();
26187 self.generate_expression(this)?;
26188 }
26189 if !e.columns.is_empty() {
26191 self.write("(");
26192 for (i, col) in e.columns.iter().enumerate() {
26193 if i > 0 {
26194 self.write(", ");
26195 }
26196 self.write(col);
26197 }
26198 self.write(")");
26199 }
26200 if let Some(partition) = &e.partition {
26201 self.write_space();
26202 self.generate_expression(partition)?;
26203 }
26204 if let Some(mode) = &e.mode {
26205 self.write_space();
26206 self.generate_expression(mode)?;
26207 }
26208 if let Some(expression) = &e.expression {
26209 self.write_space();
26210 self.generate_expression(expression)?;
26211 }
26212 if !e.properties.is_empty() {
26213 self.write_space();
26214 self.write_keyword(self.config.with_properties_prefix);
26215 self.write(" (");
26216 for (i, prop) in e.properties.iter().enumerate() {
26217 if i > 0 {
26218 self.write(", ");
26219 }
26220 self.generate_expression(prop)?;
26221 }
26222 self.write(")");
26223 }
26224 Ok(())
26225 }
26226
26227 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
26228 self.write_keyword("DELETE");
26230 if let Some(kind) = &e.kind {
26231 self.write_space();
26232 self.write_keyword(kind);
26233 }
26234 self.write_space();
26235 self.write_keyword("STATISTICS");
26236 Ok(())
26237 }
26238
26239 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
26240 if let Expression::Identifier(id) = e.this.as_ref() {
26243 self.write_keyword(&id.name);
26244 } else {
26245 self.generate_expression(&e.this)?;
26246 }
26247 self.write_space();
26248 self.write_keyword("HISTOGRAM ON");
26249 self.write_space();
26250 for (i, expr) in e.expressions.iter().enumerate() {
26251 if i > 0 {
26252 self.write(", ");
26253 }
26254 self.generate_expression(expr)?;
26255 }
26256 if let Some(expression) = &e.expression {
26257 self.write_space();
26258 self.generate_expression(expression)?;
26259 }
26260 if let Some(update_options) = &e.update_options {
26261 self.write_space();
26262 self.generate_expression(update_options)?;
26263 self.write_space();
26264 self.write_keyword("UPDATE");
26265 }
26266 Ok(())
26267 }
26268
26269 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
26270 self.write_keyword("LIST CHAINED ROWS");
26272 if let Some(expression) = &e.expression {
26273 self.write_space();
26274 self.write_keyword("INTO");
26275 self.write_space();
26276 self.generate_expression(expression)?;
26277 }
26278 Ok(())
26279 }
26280
26281 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
26282 self.write_keyword("SAMPLE");
26284 self.write_space();
26285 if let Some(sample) = &e.sample {
26286 self.generate_expression(sample)?;
26287 self.write_space();
26288 }
26289 self.write_keyword(&e.kind);
26290 Ok(())
26291 }
26292
26293 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
26294 self.write_keyword(&e.kind);
26296 if let Some(option) = &e.option {
26297 self.write_space();
26298 self.generate_expression(option)?;
26299 }
26300 self.write_space();
26301 self.write_keyword("STATISTICS");
26302 if let Some(this) = &e.this {
26303 self.write_space();
26304 self.generate_expression(this)?;
26305 }
26306 if !e.expressions.is_empty() {
26307 self.write_space();
26308 for (i, expr) in e.expressions.iter().enumerate() {
26309 if i > 0 {
26310 self.write(", ");
26311 }
26312 self.generate_expression(expr)?;
26313 }
26314 }
26315 Ok(())
26316 }
26317
26318 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
26319 self.write_keyword("VALIDATE");
26321 self.write_space();
26322 self.write_keyword(&e.kind);
26323 if let Some(this) = &e.this {
26324 self.write_space();
26325 if let Expression::Identifier(id) = this.as_ref() {
26327 self.write_keyword(&id.name);
26328 } else {
26329 self.generate_expression(this)?;
26330 }
26331 }
26332 if let Some(expression) = &e.expression {
26333 self.write_space();
26334 self.write_keyword("INTO");
26335 self.write_space();
26336 self.generate_expression(expression)?;
26337 }
26338 Ok(())
26339 }
26340
26341 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
26342 self.write_keyword("WITH");
26344 self.write_space();
26345 for (i, expr) in e.expressions.iter().enumerate() {
26346 if i > 0 {
26347 self.write(", ");
26348 }
26349 self.generate_expression(expr)?;
26350 }
26351 Ok(())
26352 }
26353
26354 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
26355 self.generate_expression(&e.this)?;
26358 self.write("(");
26359 for (i, arg) in e.expressions.iter().enumerate() {
26360 if i > 0 {
26361 self.write(", ");
26362 }
26363 self.generate_expression(arg)?;
26364 }
26365 self.write(")");
26366 Ok(())
26367 }
26368
26369 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
26370 self.generate_expression(&e.this)?;
26372 self.write("(");
26373 for (i, arg) in e.expressions.iter().enumerate() {
26374 if i > 0 {
26375 self.write(", ");
26376 }
26377 self.generate_expression(arg)?;
26378 }
26379 self.write(")");
26380 Ok(())
26381 }
26382
26383 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
26384 self.generate_expression(&e.this)?;
26386 self.write_space();
26387 self.write_keyword("APPLY");
26388 self.write("(");
26389 self.generate_expression(&e.expression)?;
26390 self.write(")");
26391 Ok(())
26392 }
26393
26394 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
26395 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
26397 self.write("(");
26398 self.generate_expression(&e.this)?;
26399 if let Some(percentile) = &e.percentile {
26400 self.write(", ");
26401 self.generate_expression(percentile)?;
26402 }
26403 self.write(")");
26404 Ok(())
26405 }
26406
26407 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
26408 self.write_keyword("APPROX_QUANTILE");
26410 self.write("(");
26411 self.generate_expression(&e.this)?;
26412 if let Some(quantile) = &e.quantile {
26413 self.write(", ");
26414 self.generate_expression(quantile)?;
26415 }
26416 if let Some(accuracy) = &e.accuracy {
26417 self.write(", ");
26418 self.generate_expression(accuracy)?;
26419 }
26420 if let Some(weight) = &e.weight {
26421 self.write(", ");
26422 self.generate_expression(weight)?;
26423 }
26424 self.write(")");
26425 Ok(())
26426 }
26427
26428 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
26429 self.write_keyword("APPROX_QUANTILES");
26431 self.write("(");
26432 self.generate_expression(&e.this)?;
26433 if let Some(expression) = &e.expression {
26434 self.write(", ");
26435 self.generate_expression(expression)?;
26436 }
26437 self.write(")");
26438 Ok(())
26439 }
26440
26441 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
26442 self.write_keyword("APPROX_TOP_K");
26444 self.write("(");
26445 self.generate_expression(&e.this)?;
26446 if let Some(expression) = &e.expression {
26447 self.write(", ");
26448 self.generate_expression(expression)?;
26449 }
26450 if let Some(counters) = &e.counters {
26451 self.write(", ");
26452 self.generate_expression(counters)?;
26453 }
26454 self.write(")");
26455 Ok(())
26456 }
26457
26458 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
26459 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
26461 self.write("(");
26462 self.generate_expression(&e.this)?;
26463 if let Some(expression) = &e.expression {
26464 self.write(", ");
26465 self.generate_expression(expression)?;
26466 }
26467 self.write(")");
26468 Ok(())
26469 }
26470
26471 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
26472 self.write_keyword("APPROX_TOP_K_COMBINE");
26474 self.write("(");
26475 self.generate_expression(&e.this)?;
26476 if let Some(expression) = &e.expression {
26477 self.write(", ");
26478 self.generate_expression(expression)?;
26479 }
26480 self.write(")");
26481 Ok(())
26482 }
26483
26484 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
26485 self.write_keyword("APPROX_TOP_K_ESTIMATE");
26487 self.write("(");
26488 self.generate_expression(&e.this)?;
26489 if let Some(expression) = &e.expression {
26490 self.write(", ");
26491 self.generate_expression(expression)?;
26492 }
26493 self.write(")");
26494 Ok(())
26495 }
26496
26497 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
26498 self.write_keyword("APPROX_TOP_SUM");
26500 self.write("(");
26501 self.generate_expression(&e.this)?;
26502 self.write(", ");
26503 self.generate_expression(&e.expression)?;
26504 if let Some(count) = &e.count {
26505 self.write(", ");
26506 self.generate_expression(count)?;
26507 }
26508 self.write(")");
26509 Ok(())
26510 }
26511
26512 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
26513 self.write_keyword("ARG_MAX");
26515 self.write("(");
26516 self.generate_expression(&e.this)?;
26517 self.write(", ");
26518 self.generate_expression(&e.expression)?;
26519 if let Some(count) = &e.count {
26520 self.write(", ");
26521 self.generate_expression(count)?;
26522 }
26523 self.write(")");
26524 Ok(())
26525 }
26526
26527 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
26528 self.write_keyword("ARG_MIN");
26530 self.write("(");
26531 self.generate_expression(&e.this)?;
26532 self.write(", ");
26533 self.generate_expression(&e.expression)?;
26534 if let Some(count) = &e.count {
26535 self.write(", ");
26536 self.generate_expression(count)?;
26537 }
26538 self.write(")");
26539 Ok(())
26540 }
26541
26542 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
26543 self.write_keyword("ARRAY_ALL");
26545 self.write("(");
26546 self.generate_expression(&e.this)?;
26547 self.write(", ");
26548 self.generate_expression(&e.expression)?;
26549 self.write(")");
26550 Ok(())
26551 }
26552
26553 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
26554 self.write_keyword("ARRAY_ANY");
26556 self.write("(");
26557 self.generate_expression(&e.this)?;
26558 self.write(", ");
26559 self.generate_expression(&e.expression)?;
26560 self.write(")");
26561 Ok(())
26562 }
26563
26564 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
26565 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
26567 self.write("(");
26568 for (i, expr) in e.expressions.iter().enumerate() {
26569 if i > 0 {
26570 self.write(", ");
26571 }
26572 self.generate_expression(expr)?;
26573 }
26574 self.write(")");
26575 Ok(())
26576 }
26577
26578 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
26579 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26581 self.write("arraySum");
26582 } else {
26583 self.write_keyword("ARRAY_SUM");
26584 }
26585 self.write("(");
26586 self.generate_expression(&e.this)?;
26587 if let Some(expression) = &e.expression {
26588 self.write(", ");
26589 self.generate_expression(expression)?;
26590 }
26591 self.write(")");
26592 Ok(())
26593 }
26594
26595 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
26596 self.generate_expression(&e.this)?;
26598 self.write_space();
26599 self.write_keyword("AT");
26600 self.write_space();
26601 self.generate_expression(&e.expression)?;
26602 Ok(())
26603 }
26604
26605 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
26606 self.write_keyword("ATTACH");
26608 if e.exists {
26609 self.write_space();
26610 self.write_keyword("IF NOT EXISTS");
26611 }
26612 self.write_space();
26613 self.generate_expression(&e.this)?;
26614 if !e.expressions.is_empty() {
26615 self.write(" (");
26616 for (i, expr) in e.expressions.iter().enumerate() {
26617 if i > 0 {
26618 self.write(", ");
26619 }
26620 self.generate_expression(expr)?;
26621 }
26622 self.write(")");
26623 }
26624 Ok(())
26625 }
26626
26627 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
26628 self.generate_expression(&e.this)?;
26631 if let Some(expression) = &e.expression {
26632 self.write_space();
26633 self.generate_expression(expression)?;
26634 }
26635 Ok(())
26636 }
26637
26638 fn generate_auto_increment_keyword(
26642 &mut self,
26643 col: &crate::expressions::ColumnDef,
26644 ) -> Result<()> {
26645 use crate::dialects::DialectType;
26646 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
26647 self.write_keyword("IDENTITY");
26648 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26649 self.write("(");
26650 if let Some(ref start) = col.auto_increment_start {
26651 self.generate_expression(start)?;
26652 } else {
26653 self.write("0");
26654 }
26655 self.write(", ");
26656 if let Some(ref inc) = col.auto_increment_increment {
26657 self.generate_expression(inc)?;
26658 } else {
26659 self.write("1");
26660 }
26661 self.write(")");
26662 }
26663 } else if matches!(
26664 self.config.dialect,
26665 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
26666 ) {
26667 self.write_keyword("AUTOINCREMENT");
26668 if let Some(ref start) = col.auto_increment_start {
26669 self.write_space();
26670 self.write_keyword("START");
26671 self.write_space();
26672 self.generate_expression(start)?;
26673 }
26674 if let Some(ref inc) = col.auto_increment_increment {
26675 self.write_space();
26676 self.write_keyword("INCREMENT");
26677 self.write_space();
26678 self.generate_expression(inc)?;
26679 }
26680 if let Some(order) = col.auto_increment_order {
26681 self.write_space();
26682 if order {
26683 self.write_keyword("ORDER");
26684 } else {
26685 self.write_keyword("NOORDER");
26686 }
26687 }
26688 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
26689 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26690 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26691 self.write(" (");
26692 let mut first = true;
26693 if let Some(ref start) = col.auto_increment_start {
26694 self.write_keyword("START WITH");
26695 self.write_space();
26696 self.generate_expression(start)?;
26697 first = false;
26698 }
26699 if let Some(ref inc) = col.auto_increment_increment {
26700 if !first {
26701 self.write_space();
26702 }
26703 self.write_keyword("INCREMENT BY");
26704 self.write_space();
26705 self.generate_expression(inc)?;
26706 }
26707 self.write(")");
26708 }
26709 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
26710 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26713 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26714 } else {
26715 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
26716 }
26717 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26718 self.write(" (");
26719 let mut first = true;
26720 if let Some(ref start) = col.auto_increment_start {
26721 self.write_keyword("START WITH");
26722 self.write_space();
26723 self.generate_expression(start)?;
26724 first = false;
26725 }
26726 if let Some(ref inc) = col.auto_increment_increment {
26727 if !first {
26728 self.write_space();
26729 }
26730 self.write_keyword("INCREMENT BY");
26731 self.write_space();
26732 self.generate_expression(inc)?;
26733 }
26734 self.write(")");
26735 }
26736 } else if matches!(
26737 self.config.dialect,
26738 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26739 ) {
26740 self.write_keyword("IDENTITY");
26741 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26742 self.write("(");
26743 if let Some(ref start) = col.auto_increment_start {
26744 self.generate_expression(start)?;
26745 } else {
26746 self.write("0");
26747 }
26748 self.write(", ");
26749 if let Some(ref inc) = col.auto_increment_increment {
26750 self.generate_expression(inc)?;
26751 } else {
26752 self.write("1");
26753 }
26754 self.write(")");
26755 }
26756 } else {
26757 self.write_keyword("AUTO_INCREMENT");
26758 if let Some(ref start) = col.auto_increment_start {
26759 self.write_space();
26760 self.write_keyword("START");
26761 self.write_space();
26762 self.generate_expression(start)?;
26763 }
26764 if let Some(ref inc) = col.auto_increment_increment {
26765 self.write_space();
26766 self.write_keyword("INCREMENT");
26767 self.write_space();
26768 self.generate_expression(inc)?;
26769 }
26770 if let Some(order) = col.auto_increment_order {
26771 self.write_space();
26772 if order {
26773 self.write_keyword("ORDER");
26774 } else {
26775 self.write_keyword("NOORDER");
26776 }
26777 }
26778 }
26779 Ok(())
26780 }
26781
26782 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
26783 self.write_keyword("AUTO_INCREMENT");
26785 self.write("=");
26786 self.generate_expression(&e.this)?;
26787 Ok(())
26788 }
26789
26790 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
26791 self.write_keyword("AUTO_REFRESH");
26793 self.write("=");
26794 self.generate_expression(&e.this)?;
26795 Ok(())
26796 }
26797
26798 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
26799 self.write_keyword("BACKUP");
26801 self.write_space();
26802 self.generate_expression(&e.this)?;
26803 Ok(())
26804 }
26805
26806 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
26807 self.write_keyword("BASE64_DECODE_BINARY");
26809 self.write("(");
26810 self.generate_expression(&e.this)?;
26811 if let Some(alphabet) = &e.alphabet {
26812 self.write(", ");
26813 self.generate_expression(alphabet)?;
26814 }
26815 self.write(")");
26816 Ok(())
26817 }
26818
26819 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
26820 self.write_keyword("BASE64_DECODE_STRING");
26822 self.write("(");
26823 self.generate_expression(&e.this)?;
26824 if let Some(alphabet) = &e.alphabet {
26825 self.write(", ");
26826 self.generate_expression(alphabet)?;
26827 }
26828 self.write(")");
26829 Ok(())
26830 }
26831
26832 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
26833 self.write_keyword("BASE64_ENCODE");
26835 self.write("(");
26836 self.generate_expression(&e.this)?;
26837 if let Some(max_line_length) = &e.max_line_length {
26838 self.write(", ");
26839 self.generate_expression(max_line_length)?;
26840 }
26841 if let Some(alphabet) = &e.alphabet {
26842 self.write(", ");
26843 self.generate_expression(alphabet)?;
26844 }
26845 self.write(")");
26846 Ok(())
26847 }
26848
26849 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
26850 self.write_keyword("BLOCKCOMPRESSION");
26852 self.write("=");
26853 if let Some(autotemp) = &e.autotemp {
26854 self.write_keyword("AUTOTEMP");
26855 self.write("(");
26856 self.generate_expression(autotemp)?;
26857 self.write(")");
26858 }
26859 if let Some(always) = &e.always {
26860 self.generate_expression(always)?;
26861 }
26862 if let Some(default) = &e.default {
26863 self.generate_expression(default)?;
26864 }
26865 if let Some(manual) = &e.manual {
26866 self.generate_expression(manual)?;
26867 }
26868 if let Some(never) = &e.never {
26869 self.generate_expression(never)?;
26870 }
26871 Ok(())
26872 }
26873
26874 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
26875 self.write("((");
26877 self.generate_expression(&e.this)?;
26878 self.write(") ");
26879 self.write_keyword("AND");
26880 self.write(" (");
26881 self.generate_expression(&e.expression)?;
26882 self.write("))");
26883 Ok(())
26884 }
26885
26886 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
26887 self.write("((");
26889 self.generate_expression(&e.this)?;
26890 self.write(") ");
26891 self.write_keyword("OR");
26892 self.write(" (");
26893 self.generate_expression(&e.expression)?;
26894 self.write("))");
26895 Ok(())
26896 }
26897
26898 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
26899 self.write_keyword("BUILD");
26901 self.write_space();
26902 self.generate_expression(&e.this)?;
26903 Ok(())
26904 }
26905
26906 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
26907 self.generate_expression(&e.this)?;
26909 Ok(())
26910 }
26911
26912 fn generate_case_specific_column_constraint(
26913 &mut self,
26914 e: &CaseSpecificColumnConstraint,
26915 ) -> Result<()> {
26916 if e.not_.is_some() {
26918 self.write_keyword("NOT");
26919 self.write_space();
26920 }
26921 self.write_keyword("CASESPECIFIC");
26922 Ok(())
26923 }
26924
26925 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
26926 self.write_keyword("CAST");
26928 self.write("(");
26929 self.generate_expression(&e.this)?;
26930 if self.config.dialect == Some(DialectType::ClickHouse) {
26931 self.write(", ");
26933 } else {
26934 self.write_space();
26935 self.write_keyword("AS");
26936 self.write_space();
26937 }
26938 if let Some(to) = &e.to {
26939 self.generate_expression(to)?;
26940 }
26941 self.write(")");
26942 Ok(())
26943 }
26944
26945 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
26946 self.write_keyword("CHANGES");
26949 self.write(" (");
26950 if let Some(information) = &e.information {
26951 self.write_keyword("INFORMATION");
26952 self.write(" => ");
26953 self.generate_expression(information)?;
26954 }
26955 self.write(")");
26956 if let Some(at_before) = &e.at_before {
26958 self.write(" ");
26959 self.generate_expression(at_before)?;
26960 }
26961 if let Some(end) = &e.end {
26962 self.write(" ");
26963 self.generate_expression(end)?;
26964 }
26965 Ok(())
26966 }
26967
26968 fn generate_character_set_column_constraint(
26969 &mut self,
26970 e: &CharacterSetColumnConstraint,
26971 ) -> Result<()> {
26972 self.write_keyword("CHARACTER SET");
26974 self.write_space();
26975 self.generate_expression(&e.this)?;
26976 Ok(())
26977 }
26978
26979 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
26980 if e.default.is_some() {
26982 self.write_keyword("DEFAULT");
26983 self.write_space();
26984 }
26985 self.write_keyword("CHARACTER SET");
26986 self.write("=");
26987 self.generate_expression(&e.this)?;
26988 Ok(())
26989 }
26990
26991 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
26992 self.write_keyword("CHECK");
26994 self.write(" (");
26995 self.generate_expression(&e.this)?;
26996 self.write(")");
26997 if e.enforced.is_some() {
26998 self.write_space();
26999 self.write_keyword("ENFORCED");
27000 }
27001 Ok(())
27002 }
27003
27004 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
27005 self.write_keyword("ASSUME");
27007 self.write(" (");
27008 self.generate_expression(&e.this)?;
27009 self.write(")");
27010 Ok(())
27011 }
27012
27013 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
27014 self.write_keyword("CHECK_JSON");
27016 self.write("(");
27017 self.generate_expression(&e.this)?;
27018 self.write(")");
27019 Ok(())
27020 }
27021
27022 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
27023 self.write_keyword("CHECK_XML");
27025 self.write("(");
27026 self.generate_expression(&e.this)?;
27027 self.write(")");
27028 Ok(())
27029 }
27030
27031 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
27032 self.write_keyword("CHECKSUM");
27034 self.write("=");
27035 if e.on.is_some() {
27036 self.write_keyword("ON");
27037 } else if e.default.is_some() {
27038 self.write_keyword("DEFAULT");
27039 } else {
27040 self.write_keyword("OFF");
27041 }
27042 Ok(())
27043 }
27044
27045 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
27046 if e.shallow.is_some() {
27048 self.write_keyword("SHALLOW");
27049 self.write_space();
27050 }
27051 if e.copy.is_some() {
27052 self.write_keyword("COPY");
27053 } else {
27054 self.write_keyword("CLONE");
27055 }
27056 self.write_space();
27057 self.generate_expression(&e.this)?;
27058 Ok(())
27059 }
27060
27061 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
27062 self.write_keyword("CLUSTER BY");
27064 self.write(" (");
27065 for (i, ord) in e.expressions.iter().enumerate() {
27066 if i > 0 {
27067 self.write(", ");
27068 }
27069 self.generate_ordered(ord)?;
27070 }
27071 self.write(")");
27072 Ok(())
27073 }
27074
27075 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
27076 self.write_keyword("CLUSTER BY");
27078 self.write_space();
27079 for (i, col) in e.columns.iter().enumerate() {
27080 if i > 0 {
27081 self.write(", ");
27082 }
27083 self.generate_identifier(col)?;
27084 }
27085 Ok(())
27086 }
27087
27088 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
27089 self.write_keyword("CLUSTERED BY");
27091 self.write(" (");
27092 for (i, expr) in e.expressions.iter().enumerate() {
27093 if i > 0 {
27094 self.write(", ");
27095 }
27096 self.generate_expression(expr)?;
27097 }
27098 self.write(")");
27099 if let Some(sorted_by) = &e.sorted_by {
27100 self.write_space();
27101 self.write_keyword("SORTED BY");
27102 self.write(" (");
27103 if let Expression::Tuple(t) = sorted_by.as_ref() {
27105 for (i, expr) in t.expressions.iter().enumerate() {
27106 if i > 0 {
27107 self.write(", ");
27108 }
27109 self.generate_expression(expr)?;
27110 }
27111 } else {
27112 self.generate_expression(sorted_by)?;
27113 }
27114 self.write(")");
27115 }
27116 if let Some(buckets) = &e.buckets {
27117 self.write_space();
27118 self.write_keyword("INTO");
27119 self.write_space();
27120 self.generate_expression(buckets)?;
27121 self.write_space();
27122 self.write_keyword("BUCKETS");
27123 }
27124 Ok(())
27125 }
27126
27127 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
27128 if e.default.is_some() {
27132 self.write_keyword("DEFAULT");
27133 self.write_space();
27134 }
27135 self.write_keyword("COLLATE");
27136 match self.config.dialect {
27138 Some(DialectType::BigQuery) => self.write_space(),
27139 _ => self.write("="),
27140 }
27141 self.generate_expression(&e.this)?;
27142 Ok(())
27143 }
27144
27145 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
27146 match e {
27148 ColumnConstraint::NotNull => {
27149 self.write_keyword("NOT NULL");
27150 }
27151 ColumnConstraint::Null => {
27152 self.write_keyword("NULL");
27153 }
27154 ColumnConstraint::Unique => {
27155 self.write_keyword("UNIQUE");
27156 }
27157 ColumnConstraint::PrimaryKey => {
27158 self.write_keyword("PRIMARY KEY");
27159 }
27160 ColumnConstraint::Default(expr) => {
27161 self.write_keyword("DEFAULT");
27162 self.write_space();
27163 self.generate_expression(expr)?;
27164 }
27165 ColumnConstraint::Check(expr) => {
27166 self.write_keyword("CHECK");
27167 self.write(" (");
27168 self.generate_expression(expr)?;
27169 self.write(")");
27170 }
27171 ColumnConstraint::References(fk_ref) => {
27172 if fk_ref.has_foreign_key_keywords {
27173 self.write_keyword("FOREIGN KEY");
27174 self.write_space();
27175 }
27176 self.write_keyword("REFERENCES");
27177 self.write_space();
27178 self.generate_table(&fk_ref.table)?;
27179 if !fk_ref.columns.is_empty() {
27180 self.write(" (");
27181 for (i, col) in fk_ref.columns.iter().enumerate() {
27182 if i > 0 {
27183 self.write(", ");
27184 }
27185 self.generate_identifier(col)?;
27186 }
27187 self.write(")");
27188 }
27189 }
27190 ColumnConstraint::GeneratedAsIdentity(gen) => {
27191 self.write_keyword("GENERATED");
27192 self.write_space();
27193 if gen.always {
27194 self.write_keyword("ALWAYS");
27195 } else {
27196 self.write_keyword("BY DEFAULT");
27197 if gen.on_null {
27198 self.write_space();
27199 self.write_keyword("ON NULL");
27200 }
27201 }
27202 self.write_space();
27203 self.write_keyword("AS IDENTITY");
27204 }
27205 ColumnConstraint::Collate(collation) => {
27206 self.write_keyword("COLLATE");
27207 self.write_space();
27208 self.generate_identifier(collation)?;
27209 }
27210 ColumnConstraint::Comment(comment) => {
27211 self.write_keyword("COMMENT");
27212 self.write(" '");
27213 self.write(comment);
27214 self.write("'");
27215 }
27216 ColumnConstraint::ComputedColumn(cc) => {
27217 self.generate_computed_column_inline(cc)?;
27218 }
27219 ColumnConstraint::GeneratedAsRow(gar) => {
27220 self.generate_generated_as_row_inline(gar)?;
27221 }
27222 ColumnConstraint::Tags(tags) => {
27223 self.write_keyword("TAG");
27224 self.write(" (");
27225 for (i, expr) in tags.expressions.iter().enumerate() {
27226 if i > 0 {
27227 self.write(", ");
27228 }
27229 self.generate_expression(expr)?;
27230 }
27231 self.write(")");
27232 }
27233 ColumnConstraint::Path(path_expr) => {
27234 self.write_keyword("PATH");
27235 self.write_space();
27236 self.generate_expression(path_expr)?;
27237 }
27238 }
27239 Ok(())
27240 }
27241
27242 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
27243 match e {
27245 ColumnPosition::First => {
27246 self.write_keyword("FIRST");
27247 }
27248 ColumnPosition::After(ident) => {
27249 self.write_keyword("AFTER");
27250 self.write_space();
27251 self.generate_identifier(ident)?;
27252 }
27253 }
27254 Ok(())
27255 }
27256
27257 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
27258 self.generate_expression(&e.this)?;
27260 self.write("(");
27261 self.generate_expression(&e.expression)?;
27262 self.write(")");
27263 Ok(())
27264 }
27265
27266 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
27267 if let Some(ref unpack) = e.unpack {
27270 if let Expression::Boolean(b) = unpack.as_ref() {
27271 if b.value {
27272 self.write("*");
27273 }
27274 }
27275 }
27276 self.write_keyword("COLUMNS");
27277 self.write("(");
27278 self.generate_expression(&e.this)?;
27279 self.write(")");
27280 Ok(())
27281 }
27282
27283 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
27284 self.generate_expression(&e.this)?;
27286 self.write("(");
27287 for (i, expr) in e.expressions.iter().enumerate() {
27288 if i > 0 {
27289 self.write(", ");
27290 }
27291 self.generate_expression(expr)?;
27292 }
27293 self.write(")");
27294 Ok(())
27295 }
27296
27297 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
27298 self.generate_expression(&e.this)?;
27300 self.write("(");
27301 for (i, param) in e.params.iter().enumerate() {
27302 if i > 0 {
27303 self.write(", ");
27304 }
27305 self.generate_expression(param)?;
27306 }
27307 self.write(")(");
27308 for (i, expr) in e.expressions.iter().enumerate() {
27309 if i > 0 {
27310 self.write(", ");
27311 }
27312 self.generate_expression(expr)?;
27313 }
27314 self.write(")");
27315 Ok(())
27316 }
27317
27318 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
27319 self.write_keyword("COMMIT");
27321
27322 if e.this.is_none()
27324 && matches!(
27325 self.config.dialect,
27326 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27327 )
27328 {
27329 self.write_space();
27330 self.write_keyword("TRANSACTION");
27331 }
27332
27333 if let Some(this) = &e.this {
27335 let is_transaction_marker = matches!(
27337 this.as_ref(),
27338 Expression::Identifier(id) if id.name == "TRANSACTION"
27339 );
27340
27341 self.write_space();
27342 self.write_keyword("TRANSACTION");
27343
27344 if !is_transaction_marker {
27346 self.write_space();
27347 self.generate_expression(this)?;
27348 }
27349 }
27350
27351 if let Some(durability) = &e.durability {
27353 self.write_space();
27354 self.write_keyword("WITH");
27355 self.write(" (");
27356 self.write_keyword("DELAYED_DURABILITY");
27357 self.write(" = ");
27358 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
27359 self.write_keyword("ON");
27360 } else {
27361 self.write_keyword("OFF");
27362 }
27363 self.write(")");
27364 }
27365
27366 if let Some(chain) = &e.chain {
27368 self.write_space();
27369 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
27370 self.write_keyword("AND NO CHAIN");
27371 } else {
27372 self.write_keyword("AND CHAIN");
27373 }
27374 }
27375 Ok(())
27376 }
27377
27378 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
27379 self.write("[");
27381 self.generate_expression(&e.this)?;
27382 self.write_space();
27383 self.write_keyword("FOR");
27384 self.write_space();
27385 self.generate_expression(&e.expression)?;
27386 if let Some(pos) = &e.position {
27388 self.write(", ");
27389 self.generate_expression(pos)?;
27390 }
27391 if let Some(iterator) = &e.iterator {
27392 self.write_space();
27393 self.write_keyword("IN");
27394 self.write_space();
27395 self.generate_expression(iterator)?;
27396 }
27397 if let Some(condition) = &e.condition {
27398 self.write_space();
27399 self.write_keyword("IF");
27400 self.write_space();
27401 self.generate_expression(condition)?;
27402 }
27403 self.write("]");
27404 Ok(())
27405 }
27406
27407 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
27408 self.write_keyword("COMPRESS");
27410 self.write("(");
27411 self.generate_expression(&e.this)?;
27412 if let Some(method) = &e.method {
27413 self.write(", '");
27414 self.write(method);
27415 self.write("'");
27416 }
27417 self.write(")");
27418 Ok(())
27419 }
27420
27421 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
27422 self.write_keyword("COMPRESS");
27424 if let Some(this) = &e.this {
27425 self.write_space();
27426 self.generate_expression(this)?;
27427 }
27428 Ok(())
27429 }
27430
27431 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
27432 self.write_keyword("AS");
27434 self.write_space();
27435 self.generate_expression(&e.this)?;
27436 if e.not_null.is_some() {
27437 self.write_space();
27438 self.write_keyword("PERSISTED NOT NULL");
27439 } else if e.persisted.is_some() {
27440 self.write_space();
27441 self.write_keyword("PERSISTED");
27442 }
27443 Ok(())
27444 }
27445
27446 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
27450 let computed_expr = if matches!(
27451 self.config.dialect,
27452 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27453 ) {
27454 match &*cc.expression {
27455 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27456 {
27457 let wrapped = Expression::Cast(Box::new(Cast {
27458 this: y.this.clone(),
27459 to: DataType::Date,
27460 trailing_comments: Vec::new(),
27461 double_colon_syntax: false,
27462 format: None,
27463 default: None,
27464 inferred_type: None,
27465 }));
27466 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
27467 }
27468 Expression::Function(f)
27469 if f.name.eq_ignore_ascii_case("YEAR")
27470 && f.args.len() == 1
27471 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27472 {
27473 let wrapped = Expression::Cast(Box::new(Cast {
27474 this: f.args[0].clone(),
27475 to: DataType::Date,
27476 trailing_comments: Vec::new(),
27477 double_colon_syntax: false,
27478 format: None,
27479 default: None,
27480 inferred_type: None,
27481 }));
27482 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
27483 }
27484 _ => *cc.expression.clone(),
27485 }
27486 } else {
27487 *cc.expression.clone()
27488 };
27489
27490 match cc.persistence_kind.as_deref() {
27491 Some("STORED") | Some("VIRTUAL") => {
27492 self.write_keyword("GENERATED ALWAYS AS");
27494 self.write(" (");
27495 self.generate_expression(&computed_expr)?;
27496 self.write(")");
27497 self.write_space();
27498 if cc.persisted {
27499 self.write_keyword("STORED");
27500 } else {
27501 self.write_keyword("VIRTUAL");
27502 }
27503 }
27504 Some("PERSISTED") => {
27505 self.write_keyword("AS");
27507 self.write(" (");
27508 self.generate_expression(&computed_expr)?;
27509 self.write(")");
27510 self.write_space();
27511 self.write_keyword("PERSISTED");
27512 if let Some(ref dt) = cc.data_type {
27514 self.write_space();
27515 self.generate_data_type(dt)?;
27516 }
27517 if cc.not_null {
27518 self.write_space();
27519 self.write_keyword("NOT NULL");
27520 }
27521 }
27522 _ => {
27523 if matches!(
27526 self.config.dialect,
27527 Some(DialectType::Spark)
27528 | Some(DialectType::Databricks)
27529 | Some(DialectType::Hive)
27530 ) {
27531 self.write_keyword("GENERATED ALWAYS AS");
27532 self.write(" (");
27533 self.generate_expression(&computed_expr)?;
27534 self.write(")");
27535 } else if matches!(
27536 self.config.dialect,
27537 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27538 ) {
27539 self.write_keyword("AS");
27540 let omit_parens = matches!(computed_expr, Expression::Year(_))
27541 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
27542 if omit_parens {
27543 self.write_space();
27544 self.generate_expression(&computed_expr)?;
27545 } else {
27546 self.write(" (");
27547 self.generate_expression(&computed_expr)?;
27548 self.write(")");
27549 }
27550 } else {
27551 self.write_keyword("AS");
27552 self.write(" (");
27553 self.generate_expression(&computed_expr)?;
27554 self.write(")");
27555 }
27556 }
27557 }
27558 Ok(())
27559 }
27560
27561 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
27564 self.write_keyword("GENERATED ALWAYS AS ROW ");
27565 if gar.start {
27566 self.write_keyword("START");
27567 } else {
27568 self.write_keyword("END");
27569 }
27570 if gar.hidden {
27571 self.write_space();
27572 self.write_keyword("HIDDEN");
27573 }
27574 Ok(())
27575 }
27576
27577 fn generate_system_versioning_content(
27579 &mut self,
27580 e: &WithSystemVersioningProperty,
27581 ) -> Result<()> {
27582 let mut parts = Vec::new();
27583
27584 if let Some(this) = &e.this {
27585 let mut s = String::from("HISTORY_TABLE=");
27586 let mut gen = Generator::with_arc_config(self.config.clone());
27587 gen.generate_expression(this)?;
27588 s.push_str(&gen.output);
27589 parts.push(s);
27590 }
27591
27592 if let Some(data_consistency) = &e.data_consistency {
27593 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
27594 let mut gen = Generator::with_arc_config(self.config.clone());
27595 gen.generate_expression(data_consistency)?;
27596 s.push_str(&gen.output);
27597 parts.push(s);
27598 }
27599
27600 if let Some(retention_period) = &e.retention_period {
27601 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
27602 let mut gen = Generator::with_arc_config(self.config.clone());
27603 gen.generate_expression(retention_period)?;
27604 s.push_str(&gen.output);
27605 parts.push(s);
27606 }
27607
27608 self.write_keyword("SYSTEM_VERSIONING");
27609 self.write("=");
27610
27611 if !parts.is_empty() {
27612 self.write_keyword("ON");
27613 self.write("(");
27614 self.write(&parts.join(", "));
27615 self.write(")");
27616 } else if e.on.is_some() {
27617 self.write_keyword("ON");
27618 } else {
27619 self.write_keyword("OFF");
27620 }
27621
27622 Ok(())
27623 }
27624
27625 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
27626 if e.else_.is_some() {
27629 self.write_keyword("ELSE");
27630 self.write_space();
27631 } else if let Some(expression) = &e.expression {
27632 self.write_keyword("WHEN");
27633 self.write_space();
27634 self.generate_expression(expression)?;
27635 self.write_space();
27636 self.write_keyword("THEN");
27637 self.write_space();
27638 }
27639
27640 if let Expression::Insert(insert) = e.this.as_ref() {
27643 self.write_keyword("INTO");
27644 self.write_space();
27645 self.generate_table(&insert.table)?;
27646
27647 if !insert.columns.is_empty() {
27649 self.write(" (");
27650 for (i, col) in insert.columns.iter().enumerate() {
27651 if i > 0 {
27652 self.write(", ");
27653 }
27654 self.generate_identifier(col)?;
27655 }
27656 self.write(")");
27657 }
27658
27659 if !insert.values.is_empty() {
27661 self.write_space();
27662 self.write_keyword("VALUES");
27663 for (row_idx, row) in insert.values.iter().enumerate() {
27664 if row_idx > 0 {
27665 self.write(", ");
27666 }
27667 self.write(" (");
27668 for (i, val) in row.iter().enumerate() {
27669 if i > 0 {
27670 self.write(", ");
27671 }
27672 self.generate_expression(val)?;
27673 }
27674 self.write(")");
27675 }
27676 }
27677 } else {
27678 self.generate_expression(&e.this)?;
27680 }
27681 Ok(())
27682 }
27683
27684 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
27685 self.write_keyword("CONSTRAINT");
27687 self.write_space();
27688 self.generate_expression(&e.this)?;
27689 if !e.expressions.is_empty() {
27690 self.write_space();
27691 for (i, expr) in e.expressions.iter().enumerate() {
27692 if i > 0 {
27693 self.write_space();
27694 }
27695 self.generate_expression(expr)?;
27696 }
27697 }
27698 Ok(())
27699 }
27700
27701 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
27702 self.write_keyword("CONVERT_TIMEZONE");
27704 self.write("(");
27705 let mut first = true;
27706 if let Some(source_tz) = &e.source_tz {
27707 self.generate_expression(source_tz)?;
27708 first = false;
27709 }
27710 if let Some(target_tz) = &e.target_tz {
27711 if !first {
27712 self.write(", ");
27713 }
27714 self.generate_expression(target_tz)?;
27715 first = false;
27716 }
27717 if let Some(timestamp) = &e.timestamp {
27718 if !first {
27719 self.write(", ");
27720 }
27721 self.generate_expression(timestamp)?;
27722 }
27723 self.write(")");
27724 Ok(())
27725 }
27726
27727 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
27728 self.write_keyword("CONVERT");
27730 self.write("(");
27731 self.generate_expression(&e.this)?;
27732 if let Some(dest) = &e.dest {
27733 self.write_space();
27734 self.write_keyword("USING");
27735 self.write_space();
27736 self.generate_expression(dest)?;
27737 }
27738 self.write(")");
27739 Ok(())
27740 }
27741
27742 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
27743 self.write_keyword("COPY");
27744 if e.is_into {
27745 self.write_space();
27746 self.write_keyword("INTO");
27747 }
27748 self.write_space();
27749
27750 if let Expression::Literal(lit) = &e.this {
27752 if let Literal::String(s) = lit.as_ref() {
27753 if s.starts_with('@') {
27754 self.write(s);
27755 } else {
27756 self.generate_expression(&e.this)?;
27757 }
27758 }
27759 } else {
27760 self.generate_expression(&e.this)?;
27761 }
27762
27763 if e.kind {
27765 if self.config.pretty {
27767 self.write_newline();
27768 } else {
27769 self.write_space();
27770 }
27771 self.write_keyword("FROM");
27772 self.write_space();
27773 } else if !e.files.is_empty() {
27774 if self.config.pretty {
27776 self.write_newline();
27777 } else {
27778 self.write_space();
27779 }
27780 self.write_keyword("TO");
27781 self.write_space();
27782 }
27783
27784 for (i, file) in e.files.iter().enumerate() {
27786 if i > 0 {
27787 self.write_space();
27788 }
27789 if let Expression::Literal(lit) = file {
27791 if let Literal::String(s) = lit.as_ref() {
27792 if s.starts_with('@') {
27793 self.write(s);
27794 } else {
27795 self.generate_expression(file)?;
27796 }
27797 }
27798 } else if let Expression::Identifier(id) = file {
27799 if id.quoted {
27801 self.write("`");
27802 self.write(&id.name);
27803 self.write("`");
27804 } else {
27805 self.generate_expression(file)?;
27806 }
27807 } else {
27808 self.generate_expression(file)?;
27809 }
27810 }
27811
27812 if !e.with_wrapped {
27814 if let Some(ref creds) = e.credentials {
27815 if let Some(ref storage) = creds.storage {
27816 if self.config.pretty {
27817 self.write_newline();
27818 } else {
27819 self.write_space();
27820 }
27821 self.write_keyword("STORAGE_INTEGRATION");
27822 self.write(" = ");
27823 self.write(storage);
27824 }
27825 if creds.credentials.is_empty() {
27826 if self.config.pretty {
27828 self.write_newline();
27829 } else {
27830 self.write_space();
27831 }
27832 self.write_keyword("CREDENTIALS");
27833 self.write(" = ()");
27834 } else {
27835 if self.config.pretty {
27836 self.write_newline();
27837 } else {
27838 self.write_space();
27839 }
27840 self.write_keyword("CREDENTIALS");
27841 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
27844 self.write(" '");
27846 self.write(&creds.credentials[0].1);
27847 self.write("'");
27848 } else {
27849 self.write(" = (");
27851 for (i, (k, v)) in creds.credentials.iter().enumerate() {
27852 if i > 0 {
27853 self.write_space();
27854 }
27855 self.write(k);
27856 self.write("='");
27857 self.write(v);
27858 self.write("'");
27859 }
27860 self.write(")");
27861 }
27862 }
27863 if let Some(ref encryption) = creds.encryption {
27864 self.write_space();
27865 self.write_keyword("ENCRYPTION");
27866 self.write(" = ");
27867 self.write(encryption);
27868 }
27869 }
27870 }
27871
27872 if !e.params.is_empty() {
27874 if e.with_wrapped {
27875 self.write_space();
27877 self.write_keyword("WITH");
27878 self.write(" (");
27879 for (i, param) in e.params.iter().enumerate() {
27880 if i > 0 {
27881 self.write(", ");
27882 }
27883 self.generate_copy_param_with_format(param)?;
27884 }
27885 self.write(")");
27886 } else {
27887 for param in &e.params {
27891 if self.config.pretty {
27892 self.write_newline();
27893 } else {
27894 self.write_space();
27895 }
27896 self.write(¶m.name);
27898 if let Some(ref value) = param.value {
27899 if param.eq {
27901 self.write(" = ");
27902 } else {
27903 self.write(" ");
27904 }
27905 if !param.values.is_empty() {
27906 self.write("(");
27907 for (i, v) in param.values.iter().enumerate() {
27908 if i > 0 {
27909 self.write_space();
27910 }
27911 self.generate_copy_nested_param(v)?;
27912 }
27913 self.write(")");
27914 } else {
27915 self.generate_copy_param_value(value)?;
27917 }
27918 } else if !param.values.is_empty() {
27919 if param.eq {
27921 self.write(" = (");
27922 } else {
27923 self.write(" (");
27924 }
27925 let is_key_value_pairs = param
27930 .values
27931 .first()
27932 .map_or(false, |v| matches!(v, Expression::Eq(_)));
27933 let sep = if is_key_value_pairs && param.eq {
27934 " "
27935 } else {
27936 ", "
27937 };
27938 for (i, v) in param.values.iter().enumerate() {
27939 if i > 0 {
27940 self.write(sep);
27941 }
27942 self.generate_copy_nested_param(v)?;
27943 }
27944 self.write(")");
27945 }
27946 }
27947 }
27948 }
27949
27950 Ok(())
27951 }
27952
27953 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
27956 self.write_keyword(¶m.name);
27957 if !param.values.is_empty() {
27958 self.write(" = (");
27960 for (i, v) in param.values.iter().enumerate() {
27961 if i > 0 {
27962 self.write(", ");
27963 }
27964 self.generate_copy_nested_param(v)?;
27965 }
27966 self.write(")");
27967 } else if let Some(ref value) = param.value {
27968 if param.eq {
27969 self.write(" = ");
27970 } else {
27971 self.write(" ");
27972 }
27973 self.generate_expression(value)?;
27974 }
27975 Ok(())
27976 }
27977
27978 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
27980 match expr {
27981 Expression::Eq(eq) => {
27982 match &eq.left {
27984 Expression::Column(c) => self.write(&c.name.name),
27985 _ => self.generate_expression(&eq.left)?,
27986 }
27987 self.write("=");
27988 match &eq.right {
27990 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27991 let Literal::String(s) = lit.as_ref() else {
27992 unreachable!()
27993 };
27994 self.write("'");
27995 self.write(s);
27996 self.write("'");
27997 }
27998 Expression::Tuple(t) => {
27999 self.write("(");
28001 if self.config.pretty {
28002 self.write_newline();
28003 self.indent_level += 1;
28004 for (i, item) in t.expressions.iter().enumerate() {
28005 if i > 0 {
28006 self.write(", ");
28007 }
28008 self.write_indent();
28009 self.generate_expression(item)?;
28010 }
28011 self.write_newline();
28012 self.indent_level -= 1;
28013 } else {
28014 for (i, item) in t.expressions.iter().enumerate() {
28015 if i > 0 {
28016 self.write(", ");
28017 }
28018 self.generate_expression(item)?;
28019 }
28020 }
28021 self.write(")");
28022 }
28023 _ => self.generate_expression(&eq.right)?,
28024 }
28025 Ok(())
28026 }
28027 Expression::Column(c) => {
28028 self.write(&c.name.name);
28030 Ok(())
28031 }
28032 _ => self.generate_expression(expr),
28033 }
28034 }
28035
28036 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
28039 match expr {
28040 Expression::Column(c) => {
28041 if c.name.quoted {
28043 self.write("\"");
28044 self.write(&c.name.name);
28045 self.write("\"");
28046 } else {
28047 self.write(&c.name.name);
28048 }
28049 Ok(())
28050 }
28051 Expression::Identifier(id) => {
28052 if id.quoted {
28054 self.write("\"");
28055 self.write(&id.name);
28056 self.write("\"");
28057 } else {
28058 self.write(&id.name);
28059 }
28060 Ok(())
28061 }
28062 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28063 let Literal::String(s) = lit.as_ref() else {
28064 unreachable!()
28065 };
28066 self.write("'");
28068 self.write(s);
28069 self.write("'");
28070 Ok(())
28071 }
28072 _ => self.generate_expression(expr),
28073 }
28074 }
28075
28076 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
28077 self.write_keyword(&e.name);
28078 if let Some(ref value) = e.value {
28079 if e.eq {
28080 self.write(" = ");
28081 } else {
28082 self.write(" ");
28083 }
28084 self.generate_expression(value)?;
28085 }
28086 if !e.values.is_empty() {
28087 if e.eq {
28088 self.write(" = ");
28089 } else {
28090 self.write(" ");
28091 }
28092 self.write("(");
28093 for (i, v) in e.values.iter().enumerate() {
28094 if i > 0 {
28095 self.write(", ");
28096 }
28097 self.generate_expression(v)?;
28098 }
28099 self.write(")");
28100 }
28101 Ok(())
28102 }
28103
28104 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
28105 self.write_keyword("CORR");
28107 self.write("(");
28108 self.generate_expression(&e.this)?;
28109 self.write(", ");
28110 self.generate_expression(&e.expression)?;
28111 self.write(")");
28112 Ok(())
28113 }
28114
28115 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
28116 self.write_keyword("COSINE_DISTANCE");
28118 self.write("(");
28119 self.generate_expression(&e.this)?;
28120 self.write(", ");
28121 self.generate_expression(&e.expression)?;
28122 self.write(")");
28123 Ok(())
28124 }
28125
28126 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
28127 self.write_keyword("COVAR_POP");
28129 self.write("(");
28130 self.generate_expression(&e.this)?;
28131 self.write(", ");
28132 self.generate_expression(&e.expression)?;
28133 self.write(")");
28134 Ok(())
28135 }
28136
28137 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
28138 self.write_keyword("COVAR_SAMP");
28140 self.write("(");
28141 self.generate_expression(&e.this)?;
28142 self.write(", ");
28143 self.generate_expression(&e.expression)?;
28144 self.write(")");
28145 Ok(())
28146 }
28147
28148 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
28149 self.write_keyword("CREDENTIALS");
28151 self.write(" (");
28152 for (i, (key, value)) in e.credentials.iter().enumerate() {
28153 if i > 0 {
28154 self.write(", ");
28155 }
28156 self.write(key);
28157 self.write("='");
28158 self.write(value);
28159 self.write("'");
28160 }
28161 self.write(")");
28162 Ok(())
28163 }
28164
28165 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
28166 self.write_keyword("CREDENTIALS");
28168 self.write("=(");
28169 for (i, expr) in e.expressions.iter().enumerate() {
28170 if i > 0 {
28171 self.write(", ");
28172 }
28173 self.generate_expression(expr)?;
28174 }
28175 self.write(")");
28176 Ok(())
28177 }
28178
28179 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
28180 use crate::dialects::DialectType;
28181
28182 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
28185 self.generate_expression(&e.this)?;
28186 self.write_space();
28187 self.write_keyword("AS");
28188 self.write_space();
28189 self.generate_identifier(&e.alias)?;
28190 return Ok(());
28191 }
28192 self.write(&e.alias.name);
28193
28194 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
28196
28197 if !e.columns.is_empty() && !skip_cte_columns {
28198 self.write("(");
28199 for (i, col) in e.columns.iter().enumerate() {
28200 if i > 0 {
28201 self.write(", ");
28202 }
28203 self.write(&col.name);
28204 }
28205 self.write(")");
28206 }
28207 if !e.key_expressions.is_empty() {
28209 self.write_space();
28210 self.write_keyword("USING KEY");
28211 self.write(" (");
28212 for (i, key) in e.key_expressions.iter().enumerate() {
28213 if i > 0 {
28214 self.write(", ");
28215 }
28216 self.write(&key.name);
28217 }
28218 self.write(")");
28219 }
28220 self.write_space();
28221 self.write_keyword("AS");
28222 self.write_space();
28223 if let Some(materialized) = e.materialized {
28224 if materialized {
28225 self.write_keyword("MATERIALIZED");
28226 } else {
28227 self.write_keyword("NOT MATERIALIZED");
28228 }
28229 self.write_space();
28230 }
28231 self.write("(");
28232 self.generate_expression(&e.this)?;
28233 self.write(")");
28234 Ok(())
28235 }
28236
28237 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
28238 if e.expressions.is_empty() {
28240 self.write_keyword("WITH CUBE");
28241 } else {
28242 self.write_keyword("CUBE");
28243 self.write("(");
28244 for (i, expr) in e.expressions.iter().enumerate() {
28245 if i > 0 {
28246 self.write(", ");
28247 }
28248 self.generate_expression(expr)?;
28249 }
28250 self.write(")");
28251 }
28252 Ok(())
28253 }
28254
28255 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
28256 self.write_keyword("CURRENT_DATETIME");
28258 if let Some(this) = &e.this {
28259 self.write("(");
28260 self.generate_expression(this)?;
28261 self.write(")");
28262 }
28263 Ok(())
28264 }
28265
28266 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
28267 self.write_keyword("CURRENT_SCHEMA");
28269 Ok(())
28270 }
28271
28272 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
28273 self.write_keyword("CURRENT_SCHEMAS");
28275 self.write("(");
28276 if !matches!(
28278 self.config.dialect,
28279 Some(crate::dialects::DialectType::Snowflake)
28280 ) {
28281 if let Some(this) = &e.this {
28282 self.generate_expression(this)?;
28283 }
28284 }
28285 self.write(")");
28286 Ok(())
28287 }
28288
28289 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
28290 self.write_keyword("CURRENT_USER");
28292 let needs_parens = e.this.is_some()
28294 || matches!(
28295 self.config.dialect,
28296 Some(DialectType::Snowflake)
28297 | Some(DialectType::Spark)
28298 | Some(DialectType::Hive)
28299 | Some(DialectType::DuckDB)
28300 | Some(DialectType::BigQuery)
28301 | Some(DialectType::MySQL)
28302 | Some(DialectType::Databricks)
28303 );
28304 if needs_parens {
28305 self.write("()");
28306 }
28307 Ok(())
28308 }
28309
28310 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
28311 if self.config.dialect == Some(DialectType::Solr) {
28313 self.generate_expression(&e.this)?;
28314 self.write(" ");
28315 self.write_keyword("OR");
28316 self.write(" ");
28317 self.generate_expression(&e.expression)?;
28318 } else if self.config.dialect == Some(DialectType::MySQL) {
28319 self.generate_mysql_concat_from_dpipe(e)?;
28320 } else {
28321 self.generate_expression(&e.this)?;
28323 self.write(" || ");
28324 self.generate_expression(&e.expression)?;
28325 }
28326 Ok(())
28327 }
28328
28329 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
28330 self.write_keyword("DATABLOCKSIZE");
28332 self.write("=");
28333 if let Some(size) = e.size {
28334 self.write(&size.to_string());
28335 if let Some(units) = &e.units {
28336 self.write_space();
28337 self.generate_expression(units)?;
28338 }
28339 } else if e.minimum.is_some() {
28340 self.write_keyword("MINIMUM");
28341 } else if e.maximum.is_some() {
28342 self.write_keyword("MAXIMUM");
28343 } else if e.default.is_some() {
28344 self.write_keyword("DEFAULT");
28345 }
28346 Ok(())
28347 }
28348
28349 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
28350 self.write_keyword("DATA_DELETION");
28352 self.write("=");
28353
28354 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
28355 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
28356
28357 if is_on {
28358 self.write_keyword("ON");
28359 if has_options {
28360 self.write("(");
28361 let mut first = true;
28362 if let Some(filter_column) = &e.filter_column {
28363 self.write_keyword("FILTER_COLUMN");
28364 self.write("=");
28365 self.generate_expression(filter_column)?;
28366 first = false;
28367 }
28368 if let Some(retention_period) = &e.retention_period {
28369 if !first {
28370 self.write(", ");
28371 }
28372 self.write_keyword("RETENTION_PERIOD");
28373 self.write("=");
28374 self.generate_expression(retention_period)?;
28375 }
28376 self.write(")");
28377 }
28378 } else {
28379 self.write_keyword("OFF");
28380 }
28381 Ok(())
28382 }
28383
28384 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
28388 use crate::dialects::DialectType;
28389 use crate::expressions::Literal;
28390
28391 match self.config.dialect {
28392 Some(DialectType::Exasol) => {
28394 self.write_keyword("TO_DATE");
28395 self.write("(");
28396 match &e.this {
28398 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28399 let Literal::String(s) = lit.as_ref() else {
28400 unreachable!()
28401 };
28402 self.write("'");
28403 self.write(s);
28404 self.write("'");
28405 }
28406 _ => {
28407 self.generate_expression(&e.this)?;
28408 }
28409 }
28410 self.write(")");
28411 }
28412 _ => {
28414 self.write_keyword("DATE");
28415 self.write("(");
28416 self.generate_expression(&e.this)?;
28417 self.write(")");
28418 }
28419 }
28420 Ok(())
28421 }
28422
28423 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
28424 self.write_keyword("DATE_BIN");
28426 self.write("(");
28427 self.generate_expression(&e.this)?;
28428 self.write(", ");
28429 self.generate_expression(&e.expression)?;
28430 if let Some(origin) = &e.origin {
28431 self.write(", ");
28432 self.generate_expression(origin)?;
28433 }
28434 self.write(")");
28435 Ok(())
28436 }
28437
28438 fn generate_date_format_column_constraint(
28439 &mut self,
28440 e: &DateFormatColumnConstraint,
28441 ) -> Result<()> {
28442 self.write_keyword("FORMAT");
28444 self.write_space();
28445 self.generate_expression(&e.this)?;
28446 Ok(())
28447 }
28448
28449 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
28450 self.write_keyword("DATE_FROM_PARTS");
28452 self.write("(");
28453 let mut first = true;
28454 if let Some(year) = &e.year {
28455 self.generate_expression(year)?;
28456 first = false;
28457 }
28458 if let Some(month) = &e.month {
28459 if !first {
28460 self.write(", ");
28461 }
28462 self.generate_expression(month)?;
28463 first = false;
28464 }
28465 if let Some(day) = &e.day {
28466 if !first {
28467 self.write(", ");
28468 }
28469 self.generate_expression(day)?;
28470 }
28471 self.write(")");
28472 Ok(())
28473 }
28474
28475 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
28476 self.write_keyword("DATETIME");
28478 self.write("(");
28479 self.generate_expression(&e.this)?;
28480 if let Some(expr) = &e.expression {
28481 self.write(", ");
28482 self.generate_expression(expr)?;
28483 }
28484 self.write(")");
28485 Ok(())
28486 }
28487
28488 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
28489 self.write_keyword("DATETIME_ADD");
28491 self.write("(");
28492 self.generate_expression(&e.this)?;
28493 self.write(", ");
28494 self.generate_expression(&e.expression)?;
28495 if let Some(unit) = &e.unit {
28496 self.write(", ");
28497 self.write_keyword(unit);
28498 }
28499 self.write(")");
28500 Ok(())
28501 }
28502
28503 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
28504 self.write_keyword("DATETIME_DIFF");
28506 self.write("(");
28507 self.generate_expression(&e.this)?;
28508 self.write(", ");
28509 self.generate_expression(&e.expression)?;
28510 if let Some(unit) = &e.unit {
28511 self.write(", ");
28512 self.write_keyword(unit);
28513 }
28514 self.write(")");
28515 Ok(())
28516 }
28517
28518 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
28519 self.write_keyword("DATETIME_SUB");
28521 self.write("(");
28522 self.generate_expression(&e.this)?;
28523 self.write(", ");
28524 self.generate_expression(&e.expression)?;
28525 if let Some(unit) = &e.unit {
28526 self.write(", ");
28527 self.write_keyword(unit);
28528 }
28529 self.write(")");
28530 Ok(())
28531 }
28532
28533 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
28534 self.write_keyword("DATETIME_TRUNC");
28536 self.write("(");
28537 self.generate_expression(&e.this)?;
28538 self.write(", ");
28539 self.write_keyword(&e.unit);
28540 if let Some(zone) = &e.zone {
28541 self.write(", ");
28542 self.generate_expression(zone)?;
28543 }
28544 self.write(")");
28545 Ok(())
28546 }
28547
28548 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
28549 self.write_keyword("DAYNAME");
28551 self.write("(");
28552 self.generate_expression(&e.this)?;
28553 self.write(")");
28554 Ok(())
28555 }
28556
28557 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
28558 self.write_keyword("DECLARE");
28560 self.write_space();
28561 if e.replace {
28562 self.write_keyword("OR");
28563 self.write_space();
28564 self.write_keyword("REPLACE");
28565 self.write_space();
28566 }
28567 for (i, expr) in e.expressions.iter().enumerate() {
28568 if i > 0 {
28569 self.write(", ");
28570 }
28571 self.generate_expression(expr)?;
28572 }
28573 Ok(())
28574 }
28575
28576 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
28577 use crate::dialects::DialectType;
28578
28579 self.generate_expression(&e.this)?;
28581 for name in &e.additional_names {
28583 self.write(", ");
28584 self.generate_expression(name)?;
28585 }
28586 if let Some(kind) = &e.kind {
28587 self.write_space();
28588 match self.config.dialect {
28592 Some(DialectType::BigQuery) => {
28593 self.write(kind);
28594 }
28595 Some(DialectType::TSQL) => {
28596 let is_complex_table = kind.starts_with("TABLE")
28600 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
28601 if is_complex_table {
28602 self.write(kind);
28603 } else if kind == "INT" {
28604 self.write("INTEGER");
28605 } else if kind.starts_with("TABLE") {
28606 let normalized = kind
28608 .replace(" INT ", " INTEGER ")
28609 .replace(" INT,", " INTEGER,")
28610 .replace(" INT)", " INTEGER)")
28611 .replace("(INT ", "(INTEGER ");
28612 self.write(&normalized);
28613 } else {
28614 self.write(kind);
28615 }
28616 }
28617 _ => {
28618 if e.has_as {
28619 self.write_keyword("AS");
28620 self.write_space();
28621 }
28622 self.write(kind);
28623 }
28624 }
28625 }
28626 if let Some(default) = &e.default {
28627 match self.config.dialect {
28629 Some(DialectType::BigQuery) => {
28630 self.write_space();
28631 self.write_keyword("DEFAULT");
28632 self.write_space();
28633 }
28634 _ => {
28635 self.write(" = ");
28636 }
28637 }
28638 self.generate_expression(default)?;
28639 }
28640 Ok(())
28641 }
28642
28643 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
28644 self.write_keyword("DECODE");
28646 self.write("(");
28647 for (i, expr) in e.expressions.iter().enumerate() {
28648 if i > 0 {
28649 self.write(", ");
28650 }
28651 self.generate_expression(expr)?;
28652 }
28653 self.write(")");
28654 Ok(())
28655 }
28656
28657 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
28658 self.write_keyword("DECOMPRESS");
28660 self.write("(");
28661 self.generate_expression(&e.this)?;
28662 self.write(", '");
28663 self.write(&e.method);
28664 self.write("')");
28665 Ok(())
28666 }
28667
28668 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
28669 self.write_keyword("DECOMPRESS");
28671 self.write("(");
28672 self.generate_expression(&e.this)?;
28673 self.write(", '");
28674 self.write(&e.method);
28675 self.write("')");
28676 Ok(())
28677 }
28678
28679 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
28680 self.write_keyword("DECRYPT");
28682 self.write("(");
28683 self.generate_expression(&e.this)?;
28684 if let Some(passphrase) = &e.passphrase {
28685 self.write(", ");
28686 self.generate_expression(passphrase)?;
28687 }
28688 if let Some(aad) = &e.aad {
28689 self.write(", ");
28690 self.generate_expression(aad)?;
28691 }
28692 if let Some(method) = &e.encryption_method {
28693 self.write(", ");
28694 self.generate_expression(method)?;
28695 }
28696 self.write(")");
28697 Ok(())
28698 }
28699
28700 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
28701 self.write_keyword("DECRYPT_RAW");
28703 self.write("(");
28704 self.generate_expression(&e.this)?;
28705 if let Some(key) = &e.key {
28706 self.write(", ");
28707 self.generate_expression(key)?;
28708 }
28709 if let Some(iv) = &e.iv {
28710 self.write(", ");
28711 self.generate_expression(iv)?;
28712 }
28713 if let Some(aad) = &e.aad {
28714 self.write(", ");
28715 self.generate_expression(aad)?;
28716 }
28717 if let Some(method) = &e.encryption_method {
28718 self.write(", ");
28719 self.generate_expression(method)?;
28720 }
28721 self.write(")");
28722 Ok(())
28723 }
28724
28725 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
28726 self.write_keyword("DEFINER");
28728 self.write(" = ");
28729 self.generate_expression(&e.this)?;
28730 Ok(())
28731 }
28732
28733 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
28734 self.write_keyword("DETACH");
28736 if e.exists {
28737 self.write_keyword(" DATABASE IF EXISTS");
28738 }
28739 self.write_space();
28740 self.generate_expression(&e.this)?;
28741 Ok(())
28742 }
28743
28744 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
28745 let property_name = match e.this.as_ref() {
28746 Expression::Identifier(id) => id.name.as_str(),
28747 Expression::Var(v) => v.this.as_str(),
28748 _ => "DICTIONARY",
28749 };
28750 self.write_keyword(property_name);
28751 self.write("(");
28752 self.write(&e.kind);
28753 if let Some(settings) = &e.settings {
28754 self.write("(");
28755 if let Expression::Tuple(t) = settings.as_ref() {
28756 if self.config.pretty && !t.expressions.is_empty() {
28757 self.write_newline();
28758 self.indent_level += 1;
28759 for (i, pair) in t.expressions.iter().enumerate() {
28760 if i > 0 {
28761 self.write(",");
28762 self.write_newline();
28763 }
28764 self.write_indent();
28765 if let Expression::Tuple(pair_tuple) = pair {
28766 if let Some(k) = pair_tuple.expressions.first() {
28767 self.generate_expression(k)?;
28768 }
28769 if let Some(v) = pair_tuple.expressions.get(1) {
28770 self.write(" ");
28771 self.generate_expression(v)?;
28772 }
28773 } else {
28774 self.generate_expression(pair)?;
28775 }
28776 }
28777 self.indent_level -= 1;
28778 self.write_newline();
28779 self.write_indent();
28780 } else {
28781 for (i, pair) in t.expressions.iter().enumerate() {
28782 if i > 0 {
28783 self.write(" ");
28785 }
28786 if let Expression::Tuple(pair_tuple) = pair {
28787 if let Some(k) = pair_tuple.expressions.first() {
28788 self.generate_expression(k)?;
28789 }
28790 if let Some(v) = pair_tuple.expressions.get(1) {
28791 self.write(" ");
28792 self.generate_expression(v)?;
28793 }
28794 } else {
28795 self.generate_expression(pair)?;
28796 }
28797 }
28798 }
28799 } else {
28800 self.generate_expression(settings)?;
28801 }
28802 self.write(")");
28803 } else {
28804 self.write("()");
28806 }
28807 self.write(")");
28808 Ok(())
28809 }
28810
28811 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
28812 let property_name = match e.this.as_ref() {
28813 Expression::Identifier(id) => id.name.as_str(),
28814 Expression::Var(v) => v.this.as_str(),
28815 _ => "RANGE",
28816 };
28817 self.write_keyword(property_name);
28818 self.write("(");
28819 if let Some(min) = &e.min {
28820 self.write_keyword("MIN");
28821 self.write_space();
28822 self.generate_expression(min)?;
28823 }
28824 if let Some(max) = &e.max {
28825 self.write_space();
28826 self.write_keyword("MAX");
28827 self.write_space();
28828 self.generate_expression(max)?;
28829 }
28830 self.write(")");
28831 Ok(())
28832 }
28833
28834 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
28835 if e.local.is_some() {
28837 self.write_keyword("LOCAL ");
28838 }
28839 self.write_keyword("DIRECTORY");
28840 self.write_space();
28841 self.generate_expression(&e.this)?;
28842 if let Some(row_format) = &e.row_format {
28843 self.write_space();
28844 self.generate_expression(row_format)?;
28845 }
28846 Ok(())
28847 }
28848
28849 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
28850 self.write_keyword("DISTKEY");
28852 self.write("(");
28853 self.generate_expression(&e.this)?;
28854 self.write(")");
28855 Ok(())
28856 }
28857
28858 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
28859 self.write_keyword("DISTSTYLE");
28861 self.write_space();
28862 self.generate_expression(&e.this)?;
28863 Ok(())
28864 }
28865
28866 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
28867 self.write_keyword("DISTRIBUTE BY");
28869 self.write_space();
28870 for (i, expr) in e.expressions.iter().enumerate() {
28871 if i > 0 {
28872 self.write(", ");
28873 }
28874 self.generate_expression(expr)?;
28875 }
28876 Ok(())
28877 }
28878
28879 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
28880 self.write_keyword("DISTRIBUTED BY");
28882 self.write_space();
28883 self.write(&e.kind);
28884 if !e.expressions.is_empty() {
28885 self.write(" (");
28886 for (i, expr) in e.expressions.iter().enumerate() {
28887 if i > 0 {
28888 self.write(", ");
28889 }
28890 self.generate_expression(expr)?;
28891 }
28892 self.write(")");
28893 }
28894 if let Some(buckets) = &e.buckets {
28895 self.write_space();
28896 self.write_keyword("BUCKETS");
28897 self.write_space();
28898 self.generate_expression(buckets)?;
28899 }
28900 if let Some(order) = &e.order {
28901 self.write_space();
28902 self.generate_expression(order)?;
28903 }
28904 Ok(())
28905 }
28906
28907 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
28908 self.write_keyword("DOT_PRODUCT");
28910 self.write("(");
28911 self.generate_expression(&e.this)?;
28912 self.write(", ");
28913 self.generate_expression(&e.expression)?;
28914 self.write(")");
28915 Ok(())
28916 }
28917
28918 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
28919 self.write_keyword("DROP");
28921 if e.exists {
28922 self.write_keyword(" IF EXISTS ");
28923 } else {
28924 self.write_space();
28925 }
28926 for (i, expr) in e.expressions.iter().enumerate() {
28927 if i > 0 {
28928 self.write(", ");
28929 }
28930 self.generate_expression(expr)?;
28931 }
28932 Ok(())
28933 }
28934
28935 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
28936 self.write_keyword("DUPLICATE KEY");
28938 self.write(" (");
28939 for (i, expr) in e.expressions.iter().enumerate() {
28940 if i > 0 {
28941 self.write(", ");
28942 }
28943 self.generate_expression(expr)?;
28944 }
28945 self.write(")");
28946 Ok(())
28947 }
28948
28949 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
28950 self.write_keyword("ELT");
28952 self.write("(");
28953 self.generate_expression(&e.this)?;
28954 for expr in &e.expressions {
28955 self.write(", ");
28956 self.generate_expression(expr)?;
28957 }
28958 self.write(")");
28959 Ok(())
28960 }
28961
28962 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
28963 self.write_keyword("ENCODE");
28965 self.write("(");
28966 self.generate_expression(&e.this)?;
28967 if let Some(charset) = &e.charset {
28968 self.write(", ");
28969 self.generate_expression(charset)?;
28970 }
28971 self.write(")");
28972 Ok(())
28973 }
28974
28975 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
28976 if e.key.is_some() {
28978 self.write_keyword("KEY ");
28979 }
28980 self.write_keyword("ENCODE");
28981 self.write_space();
28982 self.generate_expression(&e.this)?;
28983 if !e.properties.is_empty() {
28984 self.write(" (");
28985 for (i, prop) in e.properties.iter().enumerate() {
28986 if i > 0 {
28987 self.write(", ");
28988 }
28989 self.generate_expression(prop)?;
28990 }
28991 self.write(")");
28992 }
28993 Ok(())
28994 }
28995
28996 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
28997 self.write_keyword("ENCRYPT");
28999 self.write("(");
29000 self.generate_expression(&e.this)?;
29001 if let Some(passphrase) = &e.passphrase {
29002 self.write(", ");
29003 self.generate_expression(passphrase)?;
29004 }
29005 if let Some(aad) = &e.aad {
29006 self.write(", ");
29007 self.generate_expression(aad)?;
29008 }
29009 if let Some(method) = &e.encryption_method {
29010 self.write(", ");
29011 self.generate_expression(method)?;
29012 }
29013 self.write(")");
29014 Ok(())
29015 }
29016
29017 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
29018 self.write_keyword("ENCRYPT_RAW");
29020 self.write("(");
29021 self.generate_expression(&e.this)?;
29022 if let Some(key) = &e.key {
29023 self.write(", ");
29024 self.generate_expression(key)?;
29025 }
29026 if let Some(iv) = &e.iv {
29027 self.write(", ");
29028 self.generate_expression(iv)?;
29029 }
29030 if let Some(aad) = &e.aad {
29031 self.write(", ");
29032 self.generate_expression(aad)?;
29033 }
29034 if let Some(method) = &e.encryption_method {
29035 self.write(", ");
29036 self.generate_expression(method)?;
29037 }
29038 self.write(")");
29039 Ok(())
29040 }
29041
29042 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
29043 self.write_keyword("ENGINE");
29045 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
29046 self.write("=");
29047 } else {
29048 self.write(" = ");
29049 }
29050 self.generate_expression(&e.this)?;
29051 Ok(())
29052 }
29053
29054 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
29055 self.write_keyword("ENVIRONMENT");
29057 self.write(" (");
29058 for (i, expr) in e.expressions.iter().enumerate() {
29059 if i > 0 {
29060 self.write(", ");
29061 }
29062 self.generate_expression(expr)?;
29063 }
29064 self.write(")");
29065 Ok(())
29066 }
29067
29068 fn generate_ephemeral_column_constraint(
29069 &mut self,
29070 e: &EphemeralColumnConstraint,
29071 ) -> Result<()> {
29072 self.write_keyword("EPHEMERAL");
29074 if let Some(this) = &e.this {
29075 self.write_space();
29076 self.generate_expression(this)?;
29077 }
29078 Ok(())
29079 }
29080
29081 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
29082 self.write_keyword("EQUAL_NULL");
29084 self.write("(");
29085 self.generate_expression(&e.this)?;
29086 self.write(", ");
29087 self.generate_expression(&e.expression)?;
29088 self.write(")");
29089 Ok(())
29090 }
29091
29092 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
29093 use crate::dialects::DialectType;
29094
29095 match self.config.dialect {
29097 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
29098 self.generate_expression(&e.this)?;
29099 self.write(" <-> ");
29100 self.generate_expression(&e.expression)?;
29101 }
29102 _ => {
29103 self.write_keyword("EUCLIDEAN_DISTANCE");
29105 self.write("(");
29106 self.generate_expression(&e.this)?;
29107 self.write(", ");
29108 self.generate_expression(&e.expression)?;
29109 self.write(")");
29110 }
29111 }
29112 Ok(())
29113 }
29114
29115 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
29116 self.write_keyword("EXECUTE AS");
29118 self.write_space();
29119 self.generate_expression(&e.this)?;
29120 Ok(())
29121 }
29122
29123 fn generate_export(&mut self, e: &Export) -> Result<()> {
29124 self.write_keyword("EXPORT DATA");
29126 if let Some(connection) = &e.connection {
29127 self.write_space();
29128 self.write_keyword("WITH CONNECTION");
29129 self.write_space();
29130 self.generate_expression(connection)?;
29131 }
29132 if !e.options.is_empty() {
29133 self.write_space();
29134 self.generate_options_clause(&e.options)?;
29135 }
29136 self.write_space();
29137 self.write_keyword("AS");
29138 self.write_space();
29139 self.generate_expression(&e.this)?;
29140 Ok(())
29141 }
29142
29143 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
29144 self.write_keyword("EXTERNAL");
29146 if let Some(this) = &e.this {
29147 self.write_space();
29148 self.generate_expression(this)?;
29149 }
29150 Ok(())
29151 }
29152
29153 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
29154 if e.no.is_some() {
29156 self.write_keyword("NO ");
29157 }
29158 self.write_keyword("FALLBACK");
29159 if e.protection.is_some() {
29160 self.write_keyword(" PROTECTION");
29161 }
29162 Ok(())
29163 }
29164
29165 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
29166 self.write_keyword("FARM_FINGERPRINT");
29168 self.write("(");
29169 for (i, expr) in e.expressions.iter().enumerate() {
29170 if i > 0 {
29171 self.write(", ");
29172 }
29173 self.generate_expression(expr)?;
29174 }
29175 self.write(")");
29176 Ok(())
29177 }
29178
29179 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
29180 self.write_keyword("FEATURES_AT_TIME");
29182 self.write("(");
29183 self.generate_expression(&e.this)?;
29184 if let Some(time) = &e.time {
29185 self.write(", ");
29186 self.generate_expression(time)?;
29187 }
29188 if let Some(num_rows) = &e.num_rows {
29189 self.write(", ");
29190 self.generate_expression(num_rows)?;
29191 }
29192 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
29193 self.write(", ");
29194 self.generate_expression(ignore_nulls)?;
29195 }
29196 self.write(")");
29197 Ok(())
29198 }
29199
29200 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
29201 let use_limit = !e.percent
29203 && !e.with_ties
29204 && e.count.is_some()
29205 && matches!(
29206 self.config.dialect,
29207 Some(DialectType::Spark)
29208 | Some(DialectType::Hive)
29209 | Some(DialectType::DuckDB)
29210 | Some(DialectType::SQLite)
29211 | Some(DialectType::MySQL)
29212 | Some(DialectType::BigQuery)
29213 | Some(DialectType::Databricks)
29214 | Some(DialectType::StarRocks)
29215 | Some(DialectType::Doris)
29216 | Some(DialectType::Athena)
29217 | Some(DialectType::ClickHouse)
29218 );
29219
29220 if use_limit {
29221 self.write_keyword("LIMIT");
29222 self.write_space();
29223 self.generate_expression(e.count.as_ref().unwrap())?;
29224 return Ok(());
29225 }
29226
29227 self.write_keyword("FETCH");
29229 if !e.direction.is_empty() {
29230 self.write_space();
29231 self.write_keyword(&e.direction);
29232 }
29233 if let Some(count) = &e.count {
29234 self.write_space();
29235 self.generate_expression(count)?;
29236 }
29237 if e.percent {
29239 self.write_keyword(" PERCENT");
29240 }
29241 if e.rows {
29242 self.write_keyword(" ROWS");
29243 }
29244 if e.with_ties {
29245 self.write_keyword(" WITH TIES");
29246 } else if e.rows {
29247 self.write_keyword(" ONLY");
29248 } else {
29249 self.write_keyword(" ROWS ONLY");
29250 }
29251 Ok(())
29252 }
29253
29254 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
29255 if e.hive_format.is_some() {
29259 self.write_keyword("STORED AS");
29261 self.write_space();
29262 if let Some(this) = &e.this {
29263 if let Expression::Identifier(id) = this.as_ref() {
29265 self.write_keyword(&id.name.to_ascii_uppercase());
29266 } else {
29267 self.generate_expression(this)?;
29268 }
29269 }
29270 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
29271 self.write_keyword("STORED AS");
29273 self.write_space();
29274 if let Some(this) = &e.this {
29275 if let Expression::Identifier(id) = this.as_ref() {
29276 self.write_keyword(&id.name.to_ascii_uppercase());
29277 } else {
29278 self.generate_expression(this)?;
29279 }
29280 }
29281 } else if matches!(
29282 self.config.dialect,
29283 Some(DialectType::Spark) | Some(DialectType::Databricks)
29284 ) {
29285 self.write_keyword("USING");
29287 self.write_space();
29288 if let Some(this) = &e.this {
29289 self.generate_expression(this)?;
29290 }
29291 } else {
29292 self.write_keyword("FILE_FORMAT");
29294 self.write(" = ");
29295 if let Some(this) = &e.this {
29296 self.generate_expression(this)?;
29297 } else if !e.expressions.is_empty() {
29298 self.write("(");
29299 for (i, expr) in e.expressions.iter().enumerate() {
29300 if i > 0 {
29301 self.write(", ");
29302 }
29303 self.generate_expression(expr)?;
29304 }
29305 self.write(")");
29306 }
29307 }
29308 Ok(())
29309 }
29310
29311 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
29312 self.generate_expression(&e.this)?;
29314 self.write_space();
29315 self.write_keyword("FILTER");
29316 self.write("(");
29317 self.write_keyword("WHERE");
29318 self.write_space();
29319 self.generate_expression(&e.expression)?;
29320 self.write(")");
29321 Ok(())
29322 }
29323
29324 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
29325 self.write_keyword("FLOAT64");
29327 self.write("(");
29328 self.generate_expression(&e.this)?;
29329 if let Some(expr) = &e.expression {
29330 self.write(", ");
29331 self.generate_expression(expr)?;
29332 }
29333 self.write(")");
29334 Ok(())
29335 }
29336
29337 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
29338 self.write_keyword("FOR");
29340 self.write_space();
29341 self.generate_expression(&e.this)?;
29342 self.write_space();
29343 self.write_keyword("DO");
29344 self.write_space();
29345 self.generate_expression(&e.expression)?;
29346 Ok(())
29347 }
29348
29349 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
29350 self.write_keyword("FOREIGN KEY");
29352 if !e.expressions.is_empty() {
29353 self.write(" (");
29354 for (i, expr) in e.expressions.iter().enumerate() {
29355 if i > 0 {
29356 self.write(", ");
29357 }
29358 self.generate_expression(expr)?;
29359 }
29360 self.write(")");
29361 }
29362 if let Some(reference) = &e.reference {
29363 self.write_space();
29364 self.generate_expression(reference)?;
29365 }
29366 if let Some(delete) = &e.delete {
29367 self.write_space();
29368 self.write_keyword("ON DELETE");
29369 self.write_space();
29370 self.generate_expression(delete)?;
29371 }
29372 if let Some(update) = &e.update {
29373 self.write_space();
29374 self.write_keyword("ON UPDATE");
29375 self.write_space();
29376 self.generate_expression(update)?;
29377 }
29378 if !e.options.is_empty() {
29379 self.write_space();
29380 for (i, opt) in e.options.iter().enumerate() {
29381 if i > 0 {
29382 self.write_space();
29383 }
29384 self.generate_expression(opt)?;
29385 }
29386 }
29387 Ok(())
29388 }
29389
29390 fn generate_format(&mut self, e: &Format) -> Result<()> {
29391 self.write_keyword("FORMAT");
29393 self.write("(");
29394 self.generate_expression(&e.this)?;
29395 for expr in &e.expressions {
29396 self.write(", ");
29397 self.generate_expression(expr)?;
29398 }
29399 self.write(")");
29400 Ok(())
29401 }
29402
29403 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
29404 self.generate_expression(&e.this)?;
29406 self.write(" (");
29407 self.write_keyword("FORMAT");
29408 self.write(" '");
29409 self.write(&e.format);
29410 self.write("')");
29411 Ok(())
29412 }
29413
29414 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
29415 self.write_keyword("FREESPACE");
29417 self.write("=");
29418 self.generate_expression(&e.this)?;
29419 if e.percent.is_some() {
29420 self.write_keyword(" PERCENT");
29421 }
29422 Ok(())
29423 }
29424
29425 fn generate_from(&mut self, e: &From) -> Result<()> {
29426 self.write_keyword("FROM");
29428 self.write_space();
29429
29430 use crate::dialects::DialectType;
29434 let has_tablesample = e
29435 .expressions
29436 .iter()
29437 .any(|expr| matches!(expr, Expression::TableSample(_)));
29438 let is_cross_join_dialect = matches!(
29439 self.config.dialect,
29440 Some(DialectType::BigQuery)
29441 | Some(DialectType::Hive)
29442 | Some(DialectType::Spark)
29443 | Some(DialectType::Databricks)
29444 | Some(DialectType::SQLite)
29445 | Some(DialectType::ClickHouse)
29446 );
29447 let source_is_same_as_target2 = self.config.source_dialect.is_some()
29448 && self.config.source_dialect == self.config.dialect;
29449 let source_is_cross_join_dialect2 = matches!(
29450 self.config.source_dialect,
29451 Some(DialectType::BigQuery)
29452 | Some(DialectType::Hive)
29453 | Some(DialectType::Spark)
29454 | Some(DialectType::Databricks)
29455 | Some(DialectType::SQLite)
29456 | Some(DialectType::ClickHouse)
29457 );
29458 let use_cross_join = !has_tablesample
29459 && is_cross_join_dialect
29460 && (source_is_same_as_target2
29461 || source_is_cross_join_dialect2
29462 || self.config.source_dialect.is_none());
29463
29464 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
29466
29467 for (i, expr) in e.expressions.iter().enumerate() {
29468 if i > 0 {
29469 if use_cross_join {
29470 self.write(" CROSS JOIN ");
29471 } else {
29472 self.write(", ");
29473 }
29474 }
29475 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
29476 self.write("(");
29477 self.generate_expression(expr)?;
29478 self.write(")");
29479 } else {
29480 self.generate_expression(expr)?;
29481 }
29482 let leading = Self::extract_table_leading_comments(expr);
29485 for comment in &leading {
29486 self.write_space();
29487 self.write_formatted_comment(comment);
29488 }
29489 }
29490 Ok(())
29491 }
29492
29493 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
29495 match expr {
29496 Expression::Table(t) => t.leading_comments.clone(),
29497 Expression::Pivot(p) => {
29498 if let Expression::Table(t) = &p.this {
29499 t.leading_comments.clone()
29500 } else {
29501 Vec::new()
29502 }
29503 }
29504 _ => Vec::new(),
29505 }
29506 }
29507
29508 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
29509 self.write_keyword("FROM_BASE");
29511 self.write("(");
29512 self.generate_expression(&e.this)?;
29513 self.write(", ");
29514 self.generate_expression(&e.expression)?;
29515 self.write(")");
29516 Ok(())
29517 }
29518
29519 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
29520 self.generate_expression(&e.this)?;
29522 if let Some(zone) = &e.zone {
29523 self.write_space();
29524 self.write_keyword("AT TIME ZONE");
29525 self.write_space();
29526 self.generate_expression(zone)?;
29527 self.write_space();
29528 self.write_keyword("AT TIME ZONE");
29529 self.write(" 'UTC'");
29530 }
29531 Ok(())
29532 }
29533
29534 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
29535 self.write_keyword("GAP_FILL");
29537 self.write("(");
29538 self.generate_expression(&e.this)?;
29539 if let Some(ts_column) = &e.ts_column {
29540 self.write(", ");
29541 self.generate_expression(ts_column)?;
29542 }
29543 if let Some(bucket_width) = &e.bucket_width {
29544 self.write(", ");
29545 self.generate_expression(bucket_width)?;
29546 }
29547 if let Some(partitioning_columns) = &e.partitioning_columns {
29548 self.write(", ");
29549 self.generate_expression(partitioning_columns)?;
29550 }
29551 if let Some(value_columns) = &e.value_columns {
29552 self.write(", ");
29553 self.generate_expression(value_columns)?;
29554 }
29555 self.write(")");
29556 Ok(())
29557 }
29558
29559 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
29560 self.write_keyword("GENERATE_DATE_ARRAY");
29562 self.write("(");
29563 let mut first = true;
29564 if let Some(start) = &e.start {
29565 self.generate_expression(start)?;
29566 first = false;
29567 }
29568 if let Some(end) = &e.end {
29569 if !first {
29570 self.write(", ");
29571 }
29572 self.generate_expression(end)?;
29573 first = false;
29574 }
29575 if let Some(step) = &e.step {
29576 if !first {
29577 self.write(", ");
29578 }
29579 self.generate_expression(step)?;
29580 }
29581 self.write(")");
29582 Ok(())
29583 }
29584
29585 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
29586 self.write_keyword("ML.GENERATE_EMBEDDING");
29588 self.write("(");
29589 self.generate_expression(&e.this)?;
29590 self.write(", ");
29591 self.generate_expression(&e.expression)?;
29592 if let Some(params) = &e.params_struct {
29593 self.write(", ");
29594 self.generate_expression(params)?;
29595 }
29596 self.write(")");
29597 Ok(())
29598 }
29599
29600 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
29601 let fn_name = match self.config.dialect {
29603 Some(DialectType::Presto)
29604 | Some(DialectType::Trino)
29605 | Some(DialectType::Athena)
29606 | Some(DialectType::Spark)
29607 | Some(DialectType::Databricks)
29608 | Some(DialectType::Hive) => "SEQUENCE",
29609 _ => "GENERATE_SERIES",
29610 };
29611 self.write_keyword(fn_name);
29612 self.write("(");
29613 let mut first = true;
29614 if let Some(start) = &e.start {
29615 self.generate_expression(start)?;
29616 first = false;
29617 }
29618 if let Some(end) = &e.end {
29619 if !first {
29620 self.write(", ");
29621 }
29622 self.generate_expression(end)?;
29623 first = false;
29624 }
29625 if let Some(step) = &e.step {
29626 if !first {
29627 self.write(", ");
29628 }
29629 if matches!(
29632 self.config.dialect,
29633 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
29634 ) {
29635 if let Some(converted) = self.convert_week_interval_to_day(step) {
29636 self.generate_expression(&converted)?;
29637 } else {
29638 self.generate_expression(step)?;
29639 }
29640 } else {
29641 self.generate_expression(step)?;
29642 }
29643 }
29644 self.write(")");
29645 Ok(())
29646 }
29647
29648 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
29651 use crate::expressions::*;
29652 if let Expression::Interval(ref iv) = expr {
29653 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
29655 unit: IntervalUnit::Week,
29656 ..
29657 }) = &iv.unit
29658 {
29659 let count = match &iv.this {
29661 Some(Expression::Literal(lit)) => match lit.as_ref() {
29662 Literal::String(s) | Literal::Number(s) => s.clone(),
29663 _ => return None,
29664 },
29665 _ => return None,
29666 };
29667 (true, count)
29668 } else if iv.unit.is_none() {
29669 if let Some(Expression::Literal(lit)) = &iv.this {
29671 if let Literal::String(s) = lit.as_ref() {
29672 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
29673 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
29674 (true, parts[0].to_string())
29675 } else {
29676 (false, String::new())
29677 }
29678 } else {
29679 (false, String::new())
29680 }
29681 } else {
29682 (false, String::new())
29683 }
29684 } else {
29685 (false, String::new())
29686 };
29687
29688 if is_week {
29689 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
29691 let day_interval = Expression::Interval(Box::new(Interval {
29692 this: Some(Expression::Literal(Box::new(Literal::String(
29693 "7".to_string(),
29694 )))),
29695 unit: Some(IntervalUnitSpec::Simple {
29696 unit: IntervalUnit::Day,
29697 use_plural: false,
29698 }),
29699 }));
29700 let mul = Expression::Mul(Box::new(BinaryOp {
29701 left: count_expr,
29702 right: day_interval,
29703 left_comments: vec![],
29704 operator_comments: vec![],
29705 trailing_comments: vec![],
29706 inferred_type: None,
29707 }));
29708 return Some(Expression::Paren(Box::new(Paren {
29709 this: mul,
29710 trailing_comments: vec![],
29711 })));
29712 }
29713 }
29714 None
29715 }
29716
29717 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
29718 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
29720 self.write("(");
29721 let mut first = true;
29722 if let Some(start) = &e.start {
29723 self.generate_expression(start)?;
29724 first = false;
29725 }
29726 if let Some(end) = &e.end {
29727 if !first {
29728 self.write(", ");
29729 }
29730 self.generate_expression(end)?;
29731 first = false;
29732 }
29733 if let Some(step) = &e.step {
29734 if !first {
29735 self.write(", ");
29736 }
29737 self.generate_expression(step)?;
29738 }
29739 self.write(")");
29740 Ok(())
29741 }
29742
29743 fn generate_generated_as_identity_column_constraint(
29744 &mut self,
29745 e: &GeneratedAsIdentityColumnConstraint,
29746 ) -> Result<()> {
29747 use crate::dialects::DialectType;
29748
29749 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29751 self.write_keyword("AUTOINCREMENT");
29752 if let Some(start) = &e.start {
29753 self.write_keyword(" START ");
29754 self.generate_expression(start)?;
29755 }
29756 if let Some(increment) = &e.increment {
29757 self.write_keyword(" INCREMENT ");
29758 self.generate_expression(increment)?;
29759 }
29760 return Ok(());
29761 }
29762
29763 self.write_keyword("GENERATED");
29765 if let Some(this) = &e.this {
29766 if let Expression::Boolean(b) = this.as_ref() {
29768 if b.value {
29769 self.write_keyword(" ALWAYS");
29770 } else {
29771 self.write_keyword(" BY DEFAULT");
29772 if e.on_null.is_some() {
29773 self.write_keyword(" ON NULL");
29774 }
29775 }
29776 } else {
29777 self.write_keyword(" ALWAYS");
29778 }
29779 }
29780 self.write_keyword(" AS IDENTITY");
29781 let has_options = e.start.is_some()
29783 || e.increment.is_some()
29784 || e.minvalue.is_some()
29785 || e.maxvalue.is_some();
29786 if has_options {
29787 self.write(" (");
29788 let mut first = true;
29789 if let Some(start) = &e.start {
29790 self.write_keyword("START WITH ");
29791 self.generate_expression(start)?;
29792 first = false;
29793 }
29794 if let Some(increment) = &e.increment {
29795 if !first {
29796 self.write(" ");
29797 }
29798 self.write_keyword("INCREMENT BY ");
29799 self.generate_expression(increment)?;
29800 first = false;
29801 }
29802 if let Some(minvalue) = &e.minvalue {
29803 if !first {
29804 self.write(" ");
29805 }
29806 self.write_keyword("MINVALUE ");
29807 self.generate_expression(minvalue)?;
29808 first = false;
29809 }
29810 if let Some(maxvalue) = &e.maxvalue {
29811 if !first {
29812 self.write(" ");
29813 }
29814 self.write_keyword("MAXVALUE ");
29815 self.generate_expression(maxvalue)?;
29816 }
29817 self.write(")");
29818 }
29819 Ok(())
29820 }
29821
29822 fn generate_generated_as_row_column_constraint(
29823 &mut self,
29824 e: &GeneratedAsRowColumnConstraint,
29825 ) -> Result<()> {
29826 self.write_keyword("GENERATED ALWAYS AS ROW ");
29828 if e.start.is_some() {
29829 self.write_keyword("START");
29830 } else {
29831 self.write_keyword("END");
29832 }
29833 if e.hidden.is_some() {
29834 self.write_keyword(" HIDDEN");
29835 }
29836 Ok(())
29837 }
29838
29839 fn generate_get(&mut self, e: &Get) -> Result<()> {
29840 self.write_keyword("GET");
29842 self.write_space();
29843 self.generate_expression(&e.this)?;
29844 if let Some(target) = &e.target {
29845 self.write_space();
29846 self.generate_expression(target)?;
29847 }
29848 for prop in &e.properties {
29849 self.write_space();
29850 self.generate_expression(prop)?;
29851 }
29852 Ok(())
29853 }
29854
29855 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
29856 self.generate_expression(&e.this)?;
29858 self.write("[");
29859 self.generate_expression(&e.expression)?;
29860 self.write("]");
29861 Ok(())
29862 }
29863
29864 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
29865 self.write_keyword("GETBIT");
29867 self.write("(");
29868 self.generate_expression(&e.this)?;
29869 self.write(", ");
29870 self.generate_expression(&e.expression)?;
29871 self.write(")");
29872 Ok(())
29873 }
29874
29875 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
29876 if e.is_role {
29878 self.write_keyword("ROLE");
29879 self.write_space();
29880 } else if e.is_group {
29881 self.write_keyword("GROUP");
29882 self.write_space();
29883 } else if e.is_share {
29884 self.write_keyword("SHARE");
29885 self.write_space();
29886 }
29887 self.write(&e.name.name);
29888 Ok(())
29889 }
29890
29891 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
29892 self.generate_expression(&e.this)?;
29894 if !e.expressions.is_empty() {
29895 self.write("(");
29896 for (i, expr) in e.expressions.iter().enumerate() {
29897 if i > 0 {
29898 self.write(", ");
29899 }
29900 self.generate_expression(expr)?;
29901 }
29902 self.write(")");
29903 }
29904 Ok(())
29905 }
29906
29907 fn generate_group(&mut self, e: &Group) -> Result<()> {
29908 self.write_keyword("GROUP BY");
29910 match e.all {
29912 Some(true) => {
29913 self.write_space();
29914 self.write_keyword("ALL");
29915 }
29916 Some(false) => {
29917 self.write_space();
29918 self.write_keyword("DISTINCT");
29919 }
29920 None => {}
29921 }
29922 if !e.expressions.is_empty() {
29923 self.write_space();
29924 for (i, expr) in e.expressions.iter().enumerate() {
29925 if i > 0 {
29926 self.write(", ");
29927 }
29928 self.generate_expression(expr)?;
29929 }
29930 }
29931 if let Some(cube) = &e.cube {
29933 if !e.expressions.is_empty() {
29934 self.write(", ");
29935 } else {
29936 self.write_space();
29937 }
29938 self.generate_expression(cube)?;
29939 }
29940 if let Some(rollup) = &e.rollup {
29941 if !e.expressions.is_empty() || e.cube.is_some() {
29942 self.write(", ");
29943 } else {
29944 self.write_space();
29945 }
29946 self.generate_expression(rollup)?;
29947 }
29948 if let Some(grouping_sets) = &e.grouping_sets {
29949 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
29950 self.write(", ");
29951 } else {
29952 self.write_space();
29953 }
29954 self.generate_expression(grouping_sets)?;
29955 }
29956 if let Some(totals) = &e.totals {
29957 self.write_space();
29958 self.write_keyword("WITH TOTALS");
29959 self.generate_expression(totals)?;
29960 }
29961 Ok(())
29962 }
29963
29964 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
29965 self.write_keyword("GROUP BY");
29967 match e.all {
29969 Some(true) => {
29970 self.write_space();
29971 self.write_keyword("ALL");
29972 }
29973 Some(false) => {
29974 self.write_space();
29975 self.write_keyword("DISTINCT");
29976 }
29977 None => {}
29978 }
29979
29980 let mut trailing_cube = false;
29983 let mut trailing_rollup = false;
29984 let mut regular_expressions: Vec<&Expression> = Vec::new();
29985
29986 for expr in &e.expressions {
29987 match expr {
29988 Expression::Cube(c) if c.expressions.is_empty() => {
29989 trailing_cube = true;
29990 }
29991 Expression::Rollup(r) if r.expressions.is_empty() => {
29992 trailing_rollup = true;
29993 }
29994 _ => {
29995 regular_expressions.push(expr);
29996 }
29997 }
29998 }
29999
30000 if self.config.pretty {
30002 self.write_newline();
30003 self.indent_level += 1;
30004 for (i, expr) in regular_expressions.iter().enumerate() {
30005 if i > 0 {
30006 self.write(",");
30007 self.write_newline();
30008 }
30009 self.write_indent();
30010 self.generate_expression(expr)?;
30011 }
30012 self.indent_level -= 1;
30013 } else {
30014 self.write_space();
30015 for (i, expr) in regular_expressions.iter().enumerate() {
30016 if i > 0 {
30017 self.write(", ");
30018 }
30019 self.generate_expression(expr)?;
30020 }
30021 }
30022
30023 if trailing_cube {
30025 self.write_space();
30026 self.write_keyword("WITH CUBE");
30027 } else if trailing_rollup {
30028 self.write_space();
30029 self.write_keyword("WITH ROLLUP");
30030 }
30031
30032 if e.totals {
30034 self.write_space();
30035 self.write_keyword("WITH TOTALS");
30036 }
30037
30038 Ok(())
30039 }
30040
30041 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
30042 self.write_keyword("GROUPING");
30044 self.write("(");
30045 for (i, expr) in e.expressions.iter().enumerate() {
30046 if i > 0 {
30047 self.write(", ");
30048 }
30049 self.generate_expression(expr)?;
30050 }
30051 self.write(")");
30052 Ok(())
30053 }
30054
30055 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
30056 self.write_keyword("GROUPING_ID");
30058 self.write("(");
30059 for (i, expr) in e.expressions.iter().enumerate() {
30060 if i > 0 {
30061 self.write(", ");
30062 }
30063 self.generate_expression(expr)?;
30064 }
30065 self.write(")");
30066 Ok(())
30067 }
30068
30069 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
30070 self.write_keyword("GROUPING SETS");
30072 self.write(" (");
30073 for (i, expr) in e.expressions.iter().enumerate() {
30074 if i > 0 {
30075 self.write(", ");
30076 }
30077 self.generate_expression(expr)?;
30078 }
30079 self.write(")");
30080 Ok(())
30081 }
30082
30083 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
30084 self.write_keyword("HASH_AGG");
30086 self.write("(");
30087 self.generate_expression(&e.this)?;
30088 for expr in &e.expressions {
30089 self.write(", ");
30090 self.generate_expression(expr)?;
30091 }
30092 self.write(")");
30093 Ok(())
30094 }
30095
30096 fn generate_having(&mut self, e: &Having) -> Result<()> {
30097 self.write_keyword("HAVING");
30099 self.write_space();
30100 self.generate_expression(&e.this)?;
30101 Ok(())
30102 }
30103
30104 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
30105 self.generate_expression(&e.this)?;
30107 self.write_space();
30108 self.write_keyword("HAVING");
30109 self.write_space();
30110 if e.max.is_some() {
30111 self.write_keyword("MAX");
30112 } else {
30113 self.write_keyword("MIN");
30114 }
30115 self.write_space();
30116 self.generate_expression(&e.expression)?;
30117 Ok(())
30118 }
30119
30120 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
30121 use crate::dialects::DialectType;
30122 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
30124 if let Expression::Literal(ref lit) = *e.this {
30126 if let Literal::String(ref s) = lit.as_ref() {
30127 return self.generate_string_literal(s);
30128 }
30129 }
30130 }
30131 if matches!(
30133 self.config.dialect,
30134 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
30135 ) {
30136 self.write("$");
30137 if let Some(tag) = &e.tag {
30138 self.generate_expression(tag)?;
30139 }
30140 self.write("$");
30141 self.generate_expression(&e.this)?;
30142 self.write("$");
30143 if let Some(tag) = &e.tag {
30144 self.generate_expression(tag)?;
30145 }
30146 self.write("$");
30147 return Ok(());
30148 }
30149 self.write("$");
30151 if let Some(tag) = &e.tag {
30152 self.generate_expression(tag)?;
30153 }
30154 self.write("$");
30155 self.generate_expression(&e.this)?;
30156 self.write("$");
30157 if let Some(tag) = &e.tag {
30158 self.generate_expression(tag)?;
30159 }
30160 self.write("$");
30161 Ok(())
30162 }
30163
30164 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
30165 self.write_keyword("HEX_ENCODE");
30167 self.write("(");
30168 self.generate_expression(&e.this)?;
30169 self.write(")");
30170 Ok(())
30171 }
30172
30173 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
30174 match e.this.as_ref() {
30177 Expression::Identifier(id) => self.write(&id.name),
30178 other => self.generate_expression(other)?,
30179 }
30180 self.write(" (");
30181 self.write(&e.kind);
30182 self.write(" => ");
30183 self.generate_expression(&e.expression)?;
30184 self.write(")");
30185 Ok(())
30186 }
30187
30188 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
30189 self.write_keyword("HLL");
30191 self.write("(");
30192 self.generate_expression(&e.this)?;
30193 for expr in &e.expressions {
30194 self.write(", ");
30195 self.generate_expression(expr)?;
30196 }
30197 self.write(")");
30198 Ok(())
30199 }
30200
30201 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
30202 if e.input_.is_some() && e.output.is_some() {
30204 self.write_keyword("IN OUT");
30205 } else if e.input_.is_some() {
30206 self.write_keyword("IN");
30207 } else if e.output.is_some() {
30208 self.write_keyword("OUT");
30209 }
30210 Ok(())
30211 }
30212
30213 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
30214 self.write_keyword("INCLUDE");
30216 self.write_space();
30217 self.generate_expression(&e.this)?;
30218 if let Some(column_def) = &e.column_def {
30219 self.write_space();
30220 self.generate_expression(column_def)?;
30221 }
30222 if let Some(alias) = &e.alias {
30223 self.write_space();
30224 self.write_keyword("AS");
30225 self.write_space();
30226 self.write(alias);
30227 }
30228 Ok(())
30229 }
30230
30231 fn generate_index(&mut self, e: &Index) -> Result<()> {
30232 if e.unique {
30234 self.write_keyword("UNIQUE");
30235 self.write_space();
30236 }
30237 if e.primary.is_some() {
30238 self.write_keyword("PRIMARY");
30239 self.write_space();
30240 }
30241 if e.amp.is_some() {
30242 self.write_keyword("AMP");
30243 self.write_space();
30244 }
30245 if e.table.is_none() {
30246 self.write_keyword("INDEX");
30247 self.write_space();
30248 }
30249 if let Some(name) = &e.this {
30250 self.generate_expression(name)?;
30251 self.write_space();
30252 }
30253 if let Some(table) = &e.table {
30254 self.write_keyword("ON");
30255 self.write_space();
30256 self.generate_expression(table)?;
30257 }
30258 if !e.params.is_empty() {
30259 self.write("(");
30260 for (i, param) in e.params.iter().enumerate() {
30261 if i > 0 {
30262 self.write(", ");
30263 }
30264 self.generate_expression(param)?;
30265 }
30266 self.write(")");
30267 }
30268 Ok(())
30269 }
30270
30271 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
30272 if let Some(kind) = &e.kind {
30274 self.write(kind);
30275 self.write_space();
30276 }
30277 self.write_keyword("INDEX");
30278 if let Some(this) = &e.this {
30279 self.write_space();
30280 self.generate_expression(this)?;
30281 }
30282 if let Some(index_type) = &e.index_type {
30283 self.write_space();
30284 self.write_keyword("USING");
30285 self.write_space();
30286 self.generate_expression(index_type)?;
30287 }
30288 if !e.expressions.is_empty() {
30289 self.write(" (");
30290 for (i, expr) in e.expressions.iter().enumerate() {
30291 if i > 0 {
30292 self.write(", ");
30293 }
30294 self.generate_expression(expr)?;
30295 }
30296 self.write(")");
30297 }
30298 for opt in &e.options {
30299 self.write_space();
30300 self.generate_expression(opt)?;
30301 }
30302 Ok(())
30303 }
30304
30305 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
30306 if let Some(key_block_size) = &e.key_block_size {
30308 self.write_keyword("KEY_BLOCK_SIZE");
30309 self.write(" = ");
30310 self.generate_expression(key_block_size)?;
30311 } else if let Some(using) = &e.using {
30312 self.write_keyword("USING");
30313 self.write_space();
30314 self.generate_expression(using)?;
30315 } else if let Some(parser) = &e.parser {
30316 self.write_keyword("WITH PARSER");
30317 self.write_space();
30318 self.generate_expression(parser)?;
30319 } else if let Some(comment) = &e.comment {
30320 self.write_keyword("COMMENT");
30321 self.write_space();
30322 self.generate_expression(comment)?;
30323 } else if let Some(visible) = &e.visible {
30324 self.generate_expression(visible)?;
30325 } else if let Some(engine_attr) = &e.engine_attr {
30326 self.write_keyword("ENGINE_ATTRIBUTE");
30327 self.write(" = ");
30328 self.generate_expression(engine_attr)?;
30329 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
30330 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
30331 self.write(" = ");
30332 self.generate_expression(secondary_engine_attr)?;
30333 }
30334 Ok(())
30335 }
30336
30337 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
30338 if let Some(using) = &e.using {
30340 self.write_keyword("USING");
30341 self.write_space();
30342 self.generate_expression(using)?;
30343 }
30344 if !e.columns.is_empty() {
30345 self.write("(");
30346 for (i, col) in e.columns.iter().enumerate() {
30347 if i > 0 {
30348 self.write(", ");
30349 }
30350 self.generate_expression(col)?;
30351 }
30352 self.write(")");
30353 }
30354 if let Some(partition_by) = &e.partition_by {
30355 self.write_space();
30356 self.write_keyword("PARTITION BY");
30357 self.write_space();
30358 self.generate_expression(partition_by)?;
30359 }
30360 if let Some(where_) = &e.where_ {
30361 self.write_space();
30362 self.generate_expression(where_)?;
30363 }
30364 if let Some(include) = &e.include {
30365 self.write_space();
30366 self.write_keyword("INCLUDE");
30367 self.write(" (");
30368 self.generate_expression(include)?;
30369 self.write(")");
30370 }
30371 if let Some(with_storage) = &e.with_storage {
30372 self.write_space();
30373 self.write_keyword("WITH");
30374 self.write(" (");
30375 self.generate_expression(with_storage)?;
30376 self.write(")");
30377 }
30378 if let Some(tablespace) = &e.tablespace {
30379 self.write_space();
30380 self.write_keyword("USING INDEX TABLESPACE");
30381 self.write_space();
30382 self.generate_expression(tablespace)?;
30383 }
30384 Ok(())
30385 }
30386
30387 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
30388 if let Expression::Identifier(id) = &*e.this {
30392 self.write_keyword(&id.name);
30393 } else {
30394 self.generate_expression(&e.this)?;
30395 }
30396 self.write_space();
30397 self.write_keyword("INDEX");
30398 if let Some(target) = &e.target {
30399 self.write_space();
30400 self.write_keyword("FOR");
30401 self.write_space();
30402 if let Expression::Identifier(id) = &**target {
30403 self.write_keyword(&id.name);
30404 } else {
30405 self.generate_expression(target)?;
30406 }
30407 }
30408 self.write(" (");
30410 for (i, expr) in e.expressions.iter().enumerate() {
30411 if i > 0 {
30412 self.write(", ");
30413 }
30414 self.generate_expression(expr)?;
30415 }
30416 self.write(")");
30417 Ok(())
30418 }
30419
30420 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
30421 self.write_keyword("INHERITS");
30423 self.write(" (");
30424 for (i, expr) in e.expressions.iter().enumerate() {
30425 if i > 0 {
30426 self.write(", ");
30427 }
30428 self.generate_expression(expr)?;
30429 }
30430 self.write(")");
30431 Ok(())
30432 }
30433
30434 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
30435 self.write_keyword("INPUT");
30437 self.write("(");
30438 self.generate_expression(&e.this)?;
30439 self.write(")");
30440 Ok(())
30441 }
30442
30443 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
30444 if let Some(input_format) = &e.input_format {
30446 self.write_keyword("INPUTFORMAT");
30447 self.write_space();
30448 self.generate_expression(input_format)?;
30449 }
30450 if let Some(output_format) = &e.output_format {
30451 if e.input_format.is_some() {
30452 self.write(" ");
30453 }
30454 self.write_keyword("OUTPUTFORMAT");
30455 self.write_space();
30456 self.generate_expression(output_format)?;
30457 }
30458 Ok(())
30459 }
30460
30461 fn generate_install(&mut self, e: &Install) -> Result<()> {
30462 if e.force.is_some() {
30464 self.write_keyword("FORCE");
30465 self.write_space();
30466 }
30467 self.write_keyword("INSTALL");
30468 self.write_space();
30469 self.generate_expression(&e.this)?;
30470 if let Some(from) = &e.from_ {
30471 self.write_space();
30472 self.write_keyword("FROM");
30473 self.write_space();
30474 self.generate_expression(from)?;
30475 }
30476 Ok(())
30477 }
30478
30479 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
30480 self.write_keyword("INTERVAL");
30482 self.write_space();
30483 self.generate_expression(&e.expression)?;
30485 if let Some(unit) = &e.unit {
30486 self.write_space();
30487 self.write(unit);
30488 }
30489 Ok(())
30490 }
30491
30492 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
30493 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
30495 self.write_space();
30496 self.write_keyword("TO");
30497 self.write_space();
30498 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
30499 Ok(())
30500 }
30501
30502 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
30503 self.write_keyword("INTO");
30505 if e.temporary {
30506 self.write_keyword(" TEMPORARY");
30507 }
30508 if e.unlogged.is_some() {
30509 self.write_keyword(" UNLOGGED");
30510 }
30511 if let Some(this) = &e.this {
30512 self.write_space();
30513 self.generate_expression(this)?;
30514 }
30515 if !e.expressions.is_empty() {
30516 self.write(" (");
30517 for (i, expr) in e.expressions.iter().enumerate() {
30518 if i > 0 {
30519 self.write(", ");
30520 }
30521 self.generate_expression(expr)?;
30522 }
30523 self.write(")");
30524 }
30525 Ok(())
30526 }
30527
30528 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
30529 self.generate_expression(&e.this)?;
30531 self.write_space();
30532 self.generate_expression(&e.expression)?;
30533 Ok(())
30534 }
30535
30536 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
30537 self.write_keyword("WITH");
30539 if e.no.is_some() {
30540 self.write_keyword(" NO");
30541 }
30542 if e.concurrent.is_some() {
30543 self.write_keyword(" CONCURRENT");
30544 }
30545 self.write_keyword(" ISOLATED LOADING");
30546 if let Some(target) = &e.target {
30547 self.write_space();
30548 self.generate_expression(target)?;
30549 }
30550 Ok(())
30551 }
30552
30553 fn generate_json(&mut self, e: &JSON) -> Result<()> {
30554 self.write_keyword("JSON");
30556 if let Some(this) = &e.this {
30557 self.write_space();
30558 self.generate_expression(this)?;
30559 }
30560 if let Some(with_) = &e.with_ {
30561 if let Expression::Boolean(b) = with_.as_ref() {
30563 if b.value {
30564 self.write_keyword(" WITH");
30565 } else {
30566 self.write_keyword(" WITHOUT");
30567 }
30568 }
30569 }
30570 if e.unique {
30571 self.write_keyword(" UNIQUE KEYS");
30572 }
30573 Ok(())
30574 }
30575
30576 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
30577 self.write_keyword("JSON_ARRAY");
30579 self.write("(");
30580 for (i, expr) in e.expressions.iter().enumerate() {
30581 if i > 0 {
30582 self.write(", ");
30583 }
30584 self.generate_expression(expr)?;
30585 }
30586 if let Some(null_handling) = &e.null_handling {
30587 self.write_space();
30588 self.generate_expression(null_handling)?;
30589 }
30590 if let Some(return_type) = &e.return_type {
30591 self.write_space();
30592 self.write_keyword("RETURNING");
30593 self.write_space();
30594 self.generate_expression(return_type)?;
30595 }
30596 if e.strict.is_some() {
30597 self.write_space();
30598 self.write_keyword("STRICT");
30599 }
30600 self.write(")");
30601 Ok(())
30602 }
30603
30604 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
30605 self.write_keyword("JSON_ARRAYAGG");
30607 self.write("(");
30608 self.generate_expression(&e.this)?;
30609 if let Some(order) = &e.order {
30610 self.write_space();
30611 if let Expression::OrderBy(ob) = order.as_ref() {
30613 self.write_keyword("ORDER BY");
30614 self.write_space();
30615 for (i, ord) in ob.expressions.iter().enumerate() {
30616 if i > 0 {
30617 self.write(", ");
30618 }
30619 self.generate_ordered(ord)?;
30620 }
30621 } else {
30622 self.generate_expression(order)?;
30624 }
30625 }
30626 if let Some(null_handling) = &e.null_handling {
30627 self.write_space();
30628 self.generate_expression(null_handling)?;
30629 }
30630 if let Some(return_type) = &e.return_type {
30631 self.write_space();
30632 self.write_keyword("RETURNING");
30633 self.write_space();
30634 self.generate_expression(return_type)?;
30635 }
30636 if e.strict.is_some() {
30637 self.write_space();
30638 self.write_keyword("STRICT");
30639 }
30640 self.write(")");
30641 Ok(())
30642 }
30643
30644 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
30645 self.write_keyword("JSON_OBJECTAGG");
30647 self.write("(");
30648 for (i, expr) in e.expressions.iter().enumerate() {
30649 if i > 0 {
30650 self.write(", ");
30651 }
30652 self.generate_expression(expr)?;
30653 }
30654 if let Some(null_handling) = &e.null_handling {
30655 self.write_space();
30656 self.generate_expression(null_handling)?;
30657 }
30658 if let Some(unique_keys) = &e.unique_keys {
30659 self.write_space();
30660 if let Expression::Boolean(b) = unique_keys.as_ref() {
30661 if b.value {
30662 self.write_keyword("WITH UNIQUE KEYS");
30663 } else {
30664 self.write_keyword("WITHOUT UNIQUE KEYS");
30665 }
30666 }
30667 }
30668 if let Some(return_type) = &e.return_type {
30669 self.write_space();
30670 self.write_keyword("RETURNING");
30671 self.write_space();
30672 self.generate_expression(return_type)?;
30673 }
30674 self.write(")");
30675 Ok(())
30676 }
30677
30678 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
30679 self.write_keyword("JSON_ARRAY_APPEND");
30681 self.write("(");
30682 self.generate_expression(&e.this)?;
30683 for expr in &e.expressions {
30684 self.write(", ");
30685 self.generate_expression(expr)?;
30686 }
30687 self.write(")");
30688 Ok(())
30689 }
30690
30691 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
30692 self.write_keyword("JSON_ARRAY_CONTAINS");
30694 self.write("(");
30695 self.generate_expression(&e.this)?;
30696 self.write(", ");
30697 self.generate_expression(&e.expression)?;
30698 self.write(")");
30699 Ok(())
30700 }
30701
30702 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
30703 self.write_keyword("JSON_ARRAY_INSERT");
30705 self.write("(");
30706 self.generate_expression(&e.this)?;
30707 for expr in &e.expressions {
30708 self.write(", ");
30709 self.generate_expression(expr)?;
30710 }
30711 self.write(")");
30712 Ok(())
30713 }
30714
30715 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
30716 self.write_keyword("JSONB_EXISTS");
30718 self.write("(");
30719 self.generate_expression(&e.this)?;
30720 if let Some(path) = &e.path {
30721 self.write(", ");
30722 self.generate_expression(path)?;
30723 }
30724 self.write(")");
30725 Ok(())
30726 }
30727
30728 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
30729 self.write_keyword("JSONB_EXTRACT_SCALAR");
30731 self.write("(");
30732 self.generate_expression(&e.this)?;
30733 self.write(", ");
30734 self.generate_expression(&e.expression)?;
30735 self.write(")");
30736 Ok(())
30737 }
30738
30739 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
30740 self.write_keyword("JSONB_OBJECT_AGG");
30742 self.write("(");
30743 self.generate_expression(&e.this)?;
30744 self.write(", ");
30745 self.generate_expression(&e.expression)?;
30746 self.write(")");
30747 Ok(())
30748 }
30749
30750 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
30751 if let Some(nested_schema) = &e.nested_schema {
30753 self.write_keyword("NESTED");
30754 if let Some(path) = &e.path {
30755 self.write_space();
30756 self.write_keyword("PATH");
30757 self.write_space();
30758 self.generate_expression(path)?;
30759 }
30760 self.write_space();
30761 self.generate_expression(nested_schema)?;
30762 } else {
30763 if let Some(this) = &e.this {
30764 self.generate_expression(this)?;
30765 }
30766 if let Some(kind) = &e.kind {
30767 self.write_space();
30768 self.write(kind);
30769 }
30770 if e.format_json {
30771 self.write_space();
30772 self.write_keyword("FORMAT JSON");
30773 }
30774 if let Some(path) = &e.path {
30775 self.write_space();
30776 self.write_keyword("PATH");
30777 self.write_space();
30778 self.generate_expression(path)?;
30779 }
30780 if e.ordinality.is_some() {
30781 self.write_keyword(" FOR ORDINALITY");
30782 }
30783 }
30784 Ok(())
30785 }
30786
30787 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
30788 self.write_keyword("JSON_EXISTS");
30790 self.write("(");
30791 self.generate_expression(&e.this)?;
30792 if let Some(path) = &e.path {
30793 self.write(", ");
30794 self.generate_expression(path)?;
30795 }
30796 if let Some(passing) = &e.passing {
30797 self.write_space();
30798 self.write_keyword("PASSING");
30799 self.write_space();
30800 self.generate_expression(passing)?;
30801 }
30802 if let Some(on_condition) = &e.on_condition {
30803 self.write_space();
30804 self.generate_expression(on_condition)?;
30805 }
30806 self.write(")");
30807 Ok(())
30808 }
30809
30810 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
30811 self.generate_expression(&e.this)?;
30812 self.write(".:");
30813 if Self::data_type_has_nested_expressions(&e.to) {
30817 let saved = std::mem::take(&mut self.output);
30819 self.generate_data_type(&e.to)?;
30820 let type_sql = std::mem::replace(&mut self.output, saved);
30821 self.write("\"");
30822 self.write(&type_sql);
30823 self.write("\"");
30824 } else {
30825 self.generate_data_type(&e.to)?;
30826 }
30827 Ok(())
30828 }
30829
30830 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
30833 matches!(
30834 dt,
30835 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
30836 )
30837 }
30838
30839 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
30840 self.write_keyword("JSON_EXTRACT_ARRAY");
30842 self.write("(");
30843 self.generate_expression(&e.this)?;
30844 if let Some(expr) = &e.expression {
30845 self.write(", ");
30846 self.generate_expression(expr)?;
30847 }
30848 self.write(")");
30849 Ok(())
30850 }
30851
30852 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
30853 if let Some(option) = &e.option {
30855 self.generate_expression(option)?;
30856 self.write_space();
30857 }
30858 self.write_keyword("QUOTES");
30859 if e.scalar.is_some() {
30860 self.write_keyword(" SCALAR_ONLY");
30861 }
30862 Ok(())
30863 }
30864
30865 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
30866 self.write_keyword("JSON_EXTRACT_SCALAR");
30868 self.write("(");
30869 self.generate_expression(&e.this)?;
30870 self.write(", ");
30871 self.generate_expression(&e.expression)?;
30872 self.write(")");
30873 Ok(())
30874 }
30875
30876 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
30877 if e.variant_extract.is_some() {
30881 use crate::dialects::DialectType;
30882 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
30883 self.generate_expression(&e.this)?;
30887 self.write(":");
30888 match e.expression.as_ref() {
30889 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
30890 let Literal::String(s) = lit.as_ref() else {
30891 unreachable!()
30892 };
30893 self.write_databricks_json_path(s);
30894 }
30895 _ => {
30896 self.generate_expression(&e.expression)?;
30898 }
30899 }
30900 } else {
30901 self.write_keyword("GET_PATH");
30903 self.write("(");
30904 self.generate_expression(&e.this)?;
30905 self.write(", ");
30906 self.generate_expression(&e.expression)?;
30907 self.write(")");
30908 }
30909 } else {
30910 self.write_keyword("JSON_EXTRACT");
30911 self.write("(");
30912 self.generate_expression(&e.this)?;
30913 self.write(", ");
30914 self.generate_expression(&e.expression)?;
30915 for expr in &e.expressions {
30916 self.write(", ");
30917 self.generate_expression(expr)?;
30918 }
30919 self.write(")");
30920 }
30921 Ok(())
30922 }
30923
30924 fn write_databricks_json_path(&mut self, path: &str) {
30928 if path.starts_with("[\"") || path.starts_with("['") {
30931 self.write(path);
30932 return;
30933 }
30934 let mut first = true;
30938 for segment in path.split('.') {
30939 if !first {
30940 self.write(".");
30941 }
30942 first = false;
30943 if let Some(bracket_pos) = segment.find('[') {
30945 let key = &segment[..bracket_pos];
30946 let subscript = &segment[bracket_pos..];
30947 if key.is_empty() {
30948 self.write(segment);
30950 } else if Self::is_safe_json_path_key(key) {
30951 self.write(key);
30952 self.write(subscript);
30953 } else {
30954 self.write("[\"");
30955 self.write(key);
30956 self.write("\"]");
30957 self.write(subscript);
30958 }
30959 } else if Self::is_safe_json_path_key(segment) {
30960 self.write(segment);
30961 } else {
30962 self.write("[\"");
30963 self.write(segment);
30964 self.write("\"]");
30965 }
30966 }
30967 }
30968
30969 fn is_safe_json_path_key(key: &str) -> bool {
30972 if key.is_empty() {
30973 return false;
30974 }
30975 let mut chars = key.chars();
30976 let first = chars.next().unwrap();
30977 if first != '_' && !first.is_ascii_alphabetic() {
30978 return false;
30979 }
30980 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
30981 }
30982
30983 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
30984 if let Some(this) = &e.this {
30987 self.generate_expression(this)?;
30988 self.write_space();
30989 }
30990 self.write_keyword("FORMAT JSON");
30991 Ok(())
30992 }
30993
30994 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
30995 self.generate_expression(&e.this)?;
30997 self.write(": ");
30998 self.generate_expression(&e.expression)?;
30999 Ok(())
31000 }
31001
31002 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
31003 self.write_keyword("JSON_KEYS");
31005 self.write("(");
31006 self.generate_expression(&e.this)?;
31007 if let Some(expr) = &e.expression {
31008 self.write(", ");
31009 self.generate_expression(expr)?;
31010 }
31011 for expr in &e.expressions {
31012 self.write(", ");
31013 self.generate_expression(expr)?;
31014 }
31015 self.write(")");
31016 Ok(())
31017 }
31018
31019 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
31020 self.write_keyword("JSON_KEYS");
31022 self.write("(");
31023 self.generate_expression(&e.this)?;
31024 if let Some(expr) = &e.expression {
31025 self.write(", ");
31026 self.generate_expression(expr)?;
31027 }
31028 self.write(")");
31029 Ok(())
31030 }
31031
31032 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
31033 let mut path_str = String::new();
31036 for expr in &e.expressions {
31037 match expr {
31038 Expression::JSONPathRoot(_) => {
31039 path_str.push('$');
31040 }
31041 Expression::JSONPathKey(k) => {
31042 if let Expression::Literal(lit) = k.this.as_ref() {
31044 if let crate::expressions::Literal::String(s) = lit.as_ref() {
31045 path_str.push('.');
31046 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
31048 if needs_quoting {
31049 path_str.push('"');
31050 path_str.push_str(s);
31051 path_str.push('"');
31052 } else {
31053 path_str.push_str(s);
31054 }
31055 }
31056 }
31057 }
31058 Expression::JSONPathSubscript(s) => {
31059 if let Expression::Literal(lit) = s.this.as_ref() {
31061 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
31062 path_str.push('[');
31063 path_str.push_str(n);
31064 path_str.push(']');
31065 }
31066 }
31067 }
31068 _ => {
31069 let mut temp_gen = Self::with_arc_config(self.config.clone());
31071 temp_gen.generate_expression(expr)?;
31072 path_str.push_str(&temp_gen.output);
31073 }
31074 }
31075 }
31076 self.write("'");
31078 self.write(&path_str);
31079 self.write("'");
31080 Ok(())
31081 }
31082
31083 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
31084 self.write("?(");
31086 self.generate_expression(&e.this)?;
31087 self.write(")");
31088 Ok(())
31089 }
31090
31091 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
31092 self.write(".");
31094 self.generate_expression(&e.this)?;
31095 Ok(())
31096 }
31097
31098 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
31099 self.write("..");
31101 if let Some(this) = &e.this {
31102 self.generate_expression(this)?;
31103 }
31104 Ok(())
31105 }
31106
31107 fn generate_json_path_root(&mut self) -> Result<()> {
31108 self.write("$");
31110 Ok(())
31111 }
31112
31113 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
31114 self.write("(");
31116 self.generate_expression(&e.this)?;
31117 self.write(")");
31118 Ok(())
31119 }
31120
31121 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
31122 self.generate_expression(&e.this)?;
31124 Ok(())
31125 }
31126
31127 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
31128 self.write("[");
31130 if let Some(start) = &e.start {
31131 self.generate_expression(start)?;
31132 }
31133 self.write(":");
31134 if let Some(end) = &e.end {
31135 self.generate_expression(end)?;
31136 }
31137 if let Some(step) = &e.step {
31138 self.write(":");
31139 self.generate_expression(step)?;
31140 }
31141 self.write("]");
31142 Ok(())
31143 }
31144
31145 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
31146 self.write("[");
31148 self.generate_expression(&e.this)?;
31149 self.write("]");
31150 Ok(())
31151 }
31152
31153 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
31154 self.write("[");
31156 for (i, expr) in e.expressions.iter().enumerate() {
31157 if i > 0 {
31158 self.write(", ");
31159 }
31160 self.generate_expression(expr)?;
31161 }
31162 self.write("]");
31163 Ok(())
31164 }
31165
31166 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
31167 self.write_keyword("JSON_REMOVE");
31169 self.write("(");
31170 self.generate_expression(&e.this)?;
31171 for expr in &e.expressions {
31172 self.write(", ");
31173 self.generate_expression(expr)?;
31174 }
31175 self.write(")");
31176 Ok(())
31177 }
31178
31179 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
31180 self.write_keyword("COLUMNS");
31183 self.write("(");
31184
31185 if self.config.pretty && !e.expressions.is_empty() {
31186 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
31188 for expr in &e.expressions {
31189 let mut temp_gen = Generator::with_arc_config(self.config.clone());
31190 temp_gen.generate_expression(expr)?;
31191 expr_strings.push(temp_gen.output);
31192 }
31193
31194 if self.too_wide(&expr_strings) {
31196 self.write_newline();
31198 self.indent_level += 1;
31199 for (i, expr_str) in expr_strings.iter().enumerate() {
31200 if i > 0 {
31201 self.write(",");
31202 self.write_newline();
31203 }
31204 self.write_indent();
31205 self.write(expr_str);
31206 }
31207 self.write_newline();
31208 self.indent_level -= 1;
31209 self.write_indent();
31210 } else {
31211 for (i, expr_str) in expr_strings.iter().enumerate() {
31213 if i > 0 {
31214 self.write(", ");
31215 }
31216 self.write(expr_str);
31217 }
31218 }
31219 } else {
31220 for (i, expr) in e.expressions.iter().enumerate() {
31222 if i > 0 {
31223 self.write(", ");
31224 }
31225 self.generate_expression(expr)?;
31226 }
31227 }
31228 self.write(")");
31229 Ok(())
31230 }
31231
31232 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
31233 self.write_keyword("JSON_SET");
31235 self.write("(");
31236 self.generate_expression(&e.this)?;
31237 for expr in &e.expressions {
31238 self.write(", ");
31239 self.generate_expression(expr)?;
31240 }
31241 self.write(")");
31242 Ok(())
31243 }
31244
31245 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
31246 self.write_keyword("JSON_STRIP_NULLS");
31248 self.write("(");
31249 self.generate_expression(&e.this)?;
31250 if let Some(expr) = &e.expression {
31251 self.write(", ");
31252 self.generate_expression(expr)?;
31253 }
31254 self.write(")");
31255 Ok(())
31256 }
31257
31258 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
31259 self.write_keyword("JSON_TABLE");
31261 self.write("(");
31262 self.generate_expression(&e.this)?;
31263 if let Some(path) = &e.path {
31264 self.write(", ");
31265 self.generate_expression(path)?;
31266 }
31267 if let Some(error_handling) = &e.error_handling {
31268 self.write_space();
31269 self.generate_expression(error_handling)?;
31270 }
31271 if let Some(empty_handling) = &e.empty_handling {
31272 self.write_space();
31273 self.generate_expression(empty_handling)?;
31274 }
31275 if let Some(schema) = &e.schema {
31276 self.write_space();
31277 self.generate_expression(schema)?;
31278 }
31279 self.write(")");
31280 Ok(())
31281 }
31282
31283 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
31284 self.write_keyword("JSON_TYPE");
31286 self.write("(");
31287 self.generate_expression(&e.this)?;
31288 self.write(")");
31289 Ok(())
31290 }
31291
31292 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
31293 self.write_keyword("JSON_VALUE");
31295 self.write("(");
31296 self.generate_expression(&e.this)?;
31297 if let Some(path) = &e.path {
31298 self.write(", ");
31299 self.generate_expression(path)?;
31300 }
31301 if let Some(returning) = &e.returning {
31302 self.write_space();
31303 self.write_keyword("RETURNING");
31304 self.write_space();
31305 self.generate_expression(returning)?;
31306 }
31307 if let Some(on_condition) = &e.on_condition {
31308 self.write_space();
31309 self.generate_expression(on_condition)?;
31310 }
31311 self.write(")");
31312 Ok(())
31313 }
31314
31315 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
31316 self.write_keyword("JSON_VALUE_ARRAY");
31318 self.write("(");
31319 self.generate_expression(&e.this)?;
31320 self.write(")");
31321 Ok(())
31322 }
31323
31324 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
31325 self.write_keyword("JAROWINKLER_SIMILARITY");
31327 self.write("(");
31328 self.generate_expression(&e.this)?;
31329 self.write(", ");
31330 self.generate_expression(&e.expression)?;
31331 self.write(")");
31332 Ok(())
31333 }
31334
31335 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
31336 self.generate_expression(&e.this)?;
31338 self.write("(");
31339 for (i, expr) in e.expressions.iter().enumerate() {
31340 if i > 0 {
31341 self.write(", ");
31342 }
31343 self.generate_expression(expr)?;
31344 }
31345 self.write(")");
31346 Ok(())
31347 }
31348
31349 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
31350 if e.no.is_some() {
31352 self.write_keyword("NO ");
31353 }
31354 if let Some(local) = &e.local {
31355 self.generate_expression(local)?;
31356 self.write_space();
31357 }
31358 if e.dual.is_some() {
31359 self.write_keyword("DUAL ");
31360 }
31361 if e.before.is_some() {
31362 self.write_keyword("BEFORE ");
31363 }
31364 if e.after.is_some() {
31365 self.write_keyword("AFTER ");
31366 }
31367 self.write_keyword("JOURNAL");
31368 Ok(())
31369 }
31370
31371 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
31372 self.write_keyword("LANGUAGE");
31374 self.write_space();
31375 self.generate_expression(&e.this)?;
31376 Ok(())
31377 }
31378
31379 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
31380 if e.view.is_some() {
31382 self.write_keyword("LATERAL VIEW");
31384 if e.outer.is_some() {
31385 self.write_space();
31386 self.write_keyword("OUTER");
31387 }
31388 self.write_space();
31389 self.generate_expression(&e.this)?;
31390 if let Some(alias) = &e.alias {
31391 self.write_space();
31392 self.write(alias);
31393 }
31394 } else {
31395 self.write_keyword("LATERAL");
31397 self.write_space();
31398 self.generate_expression(&e.this)?;
31399 if e.ordinality.is_some() {
31400 self.write_space();
31401 self.write_keyword("WITH ORDINALITY");
31402 }
31403 if let Some(alias) = &e.alias {
31404 self.write_space();
31405 self.write_keyword("AS");
31406 self.write_space();
31407 self.write(alias);
31408 if !e.column_aliases.is_empty() {
31409 self.write("(");
31410 for (i, col) in e.column_aliases.iter().enumerate() {
31411 if i > 0 {
31412 self.write(", ");
31413 }
31414 self.write(col);
31415 }
31416 self.write(")");
31417 }
31418 }
31419 }
31420 Ok(())
31421 }
31422
31423 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
31424 self.write_keyword("LIKE");
31426 self.write_space();
31427 self.generate_expression(&e.this)?;
31428 for expr in &e.expressions {
31429 self.write_space();
31430 self.generate_expression(expr)?;
31431 }
31432 Ok(())
31433 }
31434
31435 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
31436 self.write_keyword("LIMIT");
31437 self.write_space();
31438 self.write_limit_expr(&e.this)?;
31439 if e.percent {
31440 self.write_space();
31441 self.write_keyword("PERCENT");
31442 }
31443 for comment in &e.comments {
31445 self.write(" ");
31446 self.write_formatted_comment(comment);
31447 }
31448 Ok(())
31449 }
31450
31451 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
31452 if e.percent.is_some() {
31454 self.write_keyword(" PERCENT");
31455 }
31456 if e.rows.is_some() {
31457 self.write_keyword(" ROWS");
31458 }
31459 if e.with_ties.is_some() {
31460 self.write_keyword(" WITH TIES");
31461 } else if e.rows.is_some() {
31462 self.write_keyword(" ONLY");
31463 }
31464 Ok(())
31465 }
31466
31467 fn generate_list(&mut self, e: &List) -> Result<()> {
31468 use crate::dialects::DialectType;
31469 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
31470
31471 if e.expressions.len() == 1 {
31473 if let Expression::Select(_) = &e.expressions[0] {
31474 self.write_keyword("LIST");
31475 self.write("(");
31476 self.generate_expression(&e.expressions[0])?;
31477 self.write(")");
31478 return Ok(());
31479 }
31480 }
31481
31482 if is_materialize {
31484 self.write_keyword("LIST");
31485 self.write("[");
31486 for (i, expr) in e.expressions.iter().enumerate() {
31487 if i > 0 {
31488 self.write(", ");
31489 }
31490 self.generate_expression(expr)?;
31491 }
31492 self.write("]");
31493 } else {
31494 self.write_keyword("LIST");
31496 self.write("(");
31497 for (i, expr) in e.expressions.iter().enumerate() {
31498 if i > 0 {
31499 self.write(", ");
31500 }
31501 self.generate_expression(expr)?;
31502 }
31503 self.write(")");
31504 }
31505 Ok(())
31506 }
31507
31508 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
31509 if let Expression::Select(_) = &*e.this {
31511 self.write_keyword("MAP");
31512 self.write("(");
31513 self.generate_expression(&e.this)?;
31514 self.write(")");
31515 return Ok(());
31516 }
31517
31518 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
31519
31520 self.write_keyword("MAP");
31522 if is_duckdb {
31523 self.write(" {");
31524 } else {
31525 self.write("[");
31526 }
31527 if let Expression::Struct(s) = &*e.this {
31528 for (i, (_, expr)) in s.fields.iter().enumerate() {
31529 if i > 0 {
31530 self.write(", ");
31531 }
31532 if let Expression::PropertyEQ(op) = expr {
31533 self.generate_expression(&op.left)?;
31534 if is_duckdb {
31535 self.write(": ");
31536 } else {
31537 self.write(" => ");
31538 }
31539 self.generate_expression(&op.right)?;
31540 } else {
31541 self.generate_expression(expr)?;
31542 }
31543 }
31544 }
31545 if is_duckdb {
31546 self.write("}");
31547 } else {
31548 self.write("]");
31549 }
31550 Ok(())
31551 }
31552
31553 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
31554 self.write_keyword("LOCALTIME");
31556 if let Some(precision) = &e.this {
31557 self.write("(");
31558 self.generate_expression(precision)?;
31559 self.write(")");
31560 }
31561 Ok(())
31562 }
31563
31564 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
31565 self.write_keyword("LOCALTIMESTAMP");
31567 if let Some(precision) = &e.this {
31568 self.write("(");
31569 self.generate_expression(precision)?;
31570 self.write(")");
31571 }
31572 Ok(())
31573 }
31574
31575 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
31576 self.write_keyword("LOCATION");
31578 self.write_space();
31579 self.generate_expression(&e.this)?;
31580 Ok(())
31581 }
31582
31583 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
31584 if e.update.is_some() {
31586 if e.key.is_some() {
31587 self.write_keyword("FOR NO KEY UPDATE");
31588 } else {
31589 self.write_keyword("FOR UPDATE");
31590 }
31591 } else {
31592 if e.key.is_some() {
31593 self.write_keyword("FOR KEY SHARE");
31594 } else {
31595 self.write_keyword("FOR SHARE");
31596 }
31597 }
31598 if !e.expressions.is_empty() {
31599 self.write_keyword(" OF ");
31600 for (i, expr) in e.expressions.iter().enumerate() {
31601 if i > 0 {
31602 self.write(", ");
31603 }
31604 self.generate_expression(expr)?;
31605 }
31606 }
31607 if let Some(wait) = &e.wait {
31612 match wait.as_ref() {
31613 Expression::Boolean(b) => {
31614 if b.value {
31615 self.write_keyword(" NOWAIT");
31616 } else {
31617 self.write_keyword(" SKIP LOCKED");
31618 }
31619 }
31620 _ => {
31621 self.write_keyword(" WAIT ");
31623 self.generate_expression(wait)?;
31624 }
31625 }
31626 }
31627 Ok(())
31628 }
31629
31630 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
31631 self.write_keyword("LOCK");
31633 self.write_space();
31634 self.generate_expression(&e.this)?;
31635 Ok(())
31636 }
31637
31638 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
31639 self.write_keyword("LOCKING");
31641 self.write_space();
31642 self.write(&e.kind);
31643 if let Some(this) = &e.this {
31644 self.write_space();
31645 self.generate_expression(this)?;
31646 }
31647 if let Some(for_or_in) = &e.for_or_in {
31648 self.write_space();
31649 self.generate_expression(for_or_in)?;
31650 }
31651 if let Some(lock_type) = &e.lock_type {
31652 self.write_space();
31653 self.generate_expression(lock_type)?;
31654 }
31655 if e.override_.is_some() {
31656 self.write_keyword(" OVERRIDE");
31657 }
31658 Ok(())
31659 }
31660
31661 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
31662 self.generate_expression(&e.this)?;
31664 self.write_space();
31665 self.generate_expression(&e.expression)?;
31666 Ok(())
31667 }
31668
31669 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
31670 if e.no.is_some() {
31672 self.write_keyword("NO ");
31673 }
31674 self.write_keyword("LOG");
31675 Ok(())
31676 }
31677
31678 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
31679 self.write_keyword("MD5");
31681 self.write("(");
31682 self.generate_expression(&e.this)?;
31683 for expr in &e.expressions {
31684 self.write(", ");
31685 self.generate_expression(expr)?;
31686 }
31687 self.write(")");
31688 Ok(())
31689 }
31690
31691 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
31692 self.write_keyword("ML.FORECAST");
31694 self.write("(");
31695 self.generate_expression(&e.this)?;
31696 if let Some(expression) = &e.expression {
31697 self.write(", ");
31698 self.generate_expression(expression)?;
31699 }
31700 if let Some(params) = &e.params_struct {
31701 self.write(", ");
31702 self.generate_expression(params)?;
31703 }
31704 self.write(")");
31705 Ok(())
31706 }
31707
31708 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
31709 self.write_keyword("ML.TRANSLATE");
31711 self.write("(");
31712 self.generate_expression(&e.this)?;
31713 self.write(", ");
31714 self.generate_expression(&e.expression)?;
31715 if let Some(params) = &e.params_struct {
31716 self.write(", ");
31717 self.generate_expression(params)?;
31718 }
31719 self.write(")");
31720 Ok(())
31721 }
31722
31723 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
31724 self.write_keyword("MAKE_INTERVAL");
31726 self.write("(");
31727 let mut first = true;
31728 if let Some(year) = &e.year {
31729 self.write("years => ");
31730 self.generate_expression(year)?;
31731 first = false;
31732 }
31733 if let Some(month) = &e.month {
31734 if !first {
31735 self.write(", ");
31736 }
31737 self.write("months => ");
31738 self.generate_expression(month)?;
31739 first = false;
31740 }
31741 if let Some(week) = &e.week {
31742 if !first {
31743 self.write(", ");
31744 }
31745 self.write("weeks => ");
31746 self.generate_expression(week)?;
31747 first = false;
31748 }
31749 if let Some(day) = &e.day {
31750 if !first {
31751 self.write(", ");
31752 }
31753 self.write("days => ");
31754 self.generate_expression(day)?;
31755 first = false;
31756 }
31757 if let Some(hour) = &e.hour {
31758 if !first {
31759 self.write(", ");
31760 }
31761 self.write("hours => ");
31762 self.generate_expression(hour)?;
31763 first = false;
31764 }
31765 if let Some(minute) = &e.minute {
31766 if !first {
31767 self.write(", ");
31768 }
31769 self.write("mins => ");
31770 self.generate_expression(minute)?;
31771 first = false;
31772 }
31773 if let Some(second) = &e.second {
31774 if !first {
31775 self.write(", ");
31776 }
31777 self.write("secs => ");
31778 self.generate_expression(second)?;
31779 }
31780 self.write(")");
31781 Ok(())
31782 }
31783
31784 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
31785 self.write_keyword("MANHATTAN_DISTANCE");
31787 self.write("(");
31788 self.generate_expression(&e.this)?;
31789 self.write(", ");
31790 self.generate_expression(&e.expression)?;
31791 self.write(")");
31792 Ok(())
31793 }
31794
31795 fn generate_map(&mut self, e: &Map) -> Result<()> {
31796 self.write_keyword("MAP");
31798 self.write("(");
31799 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
31800 if i > 0 {
31801 self.write(", ");
31802 }
31803 self.generate_expression(key)?;
31804 self.write(", ");
31805 self.generate_expression(value)?;
31806 }
31807 self.write(")");
31808 Ok(())
31809 }
31810
31811 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
31812 self.write_keyword("MAP_CAT");
31814 self.write("(");
31815 self.generate_expression(&e.this)?;
31816 self.write(", ");
31817 self.generate_expression(&e.expression)?;
31818 self.write(")");
31819 Ok(())
31820 }
31821
31822 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
31823 self.write_keyword("MAP_DELETE");
31825 self.write("(");
31826 self.generate_expression(&e.this)?;
31827 for expr in &e.expressions {
31828 self.write(", ");
31829 self.generate_expression(expr)?;
31830 }
31831 self.write(")");
31832 Ok(())
31833 }
31834
31835 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
31836 self.write_keyword("MAP_INSERT");
31838 self.write("(");
31839 self.generate_expression(&e.this)?;
31840 if let Some(key) = &e.key {
31841 self.write(", ");
31842 self.generate_expression(key)?;
31843 }
31844 if let Some(value) = &e.value {
31845 self.write(", ");
31846 self.generate_expression(value)?;
31847 }
31848 if let Some(update_flag) = &e.update_flag {
31849 self.write(", ");
31850 self.generate_expression(update_flag)?;
31851 }
31852 self.write(")");
31853 Ok(())
31854 }
31855
31856 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
31857 self.write_keyword("MAP_PICK");
31859 self.write("(");
31860 self.generate_expression(&e.this)?;
31861 for expr in &e.expressions {
31862 self.write(", ");
31863 self.generate_expression(expr)?;
31864 }
31865 self.write(")");
31866 Ok(())
31867 }
31868
31869 fn generate_masking_policy_column_constraint(
31870 &mut self,
31871 e: &MaskingPolicyColumnConstraint,
31872 ) -> Result<()> {
31873 self.write_keyword("MASKING POLICY");
31875 self.write_space();
31876 self.generate_expression(&e.this)?;
31877 if !e.expressions.is_empty() {
31878 self.write_keyword(" USING");
31879 self.write(" (");
31880 for (i, expr) in e.expressions.iter().enumerate() {
31881 if i > 0 {
31882 self.write(", ");
31883 }
31884 self.generate_expression(expr)?;
31885 }
31886 self.write(")");
31887 }
31888 Ok(())
31889 }
31890
31891 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
31892 if matches!(
31893 self.config.dialect,
31894 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31895 ) {
31896 if e.expressions.len() > 1 {
31897 self.write("(");
31898 }
31899 for (i, expr) in e.expressions.iter().enumerate() {
31900 if i > 0 {
31901 self.write_keyword(" OR ");
31902 }
31903 self.generate_expression(expr)?;
31904 self.write_space();
31905 self.write("@@");
31906 self.write_space();
31907 self.generate_expression(&e.this)?;
31908 }
31909 if e.expressions.len() > 1 {
31910 self.write(")");
31911 }
31912 return Ok(());
31913 }
31914
31915 self.write_keyword("MATCH");
31917 self.write("(");
31918 for (i, expr) in e.expressions.iter().enumerate() {
31919 if i > 0 {
31920 self.write(", ");
31921 }
31922 self.generate_expression(expr)?;
31923 }
31924 self.write(")");
31925 self.write_keyword(" AGAINST");
31926 self.write("(");
31927 self.generate_expression(&e.this)?;
31928 if let Some(modifier) = &e.modifier {
31929 self.write_space();
31930 self.generate_expression(modifier)?;
31931 }
31932 self.write(")");
31933 Ok(())
31934 }
31935
31936 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
31937 if let Some(window_frame) = &e.window_frame {
31939 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
31940 self.write_space();
31941 }
31942 self.generate_expression(&e.this)?;
31943 Ok(())
31944 }
31945
31946 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
31947 self.write_keyword("MATERIALIZED");
31949 if let Some(this) = &e.this {
31950 self.write_space();
31951 self.generate_expression(this)?;
31952 }
31953 Ok(())
31954 }
31955
31956 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
31957 if let Some(with_) = &e.with_ {
31960 if let Expression::With(with_clause) = with_.as_ref() {
31961 self.generate_with(with_clause)?;
31962 self.write_space();
31963 } else {
31964 self.generate_expression(with_)?;
31965 self.write_space();
31966 }
31967 }
31968 self.write_keyword("MERGE INTO");
31969 self.write_space();
31970 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
31971 if let Expression::Alias(alias) = e.this.as_ref() {
31972 self.generate_expression(&alias.this)?;
31973 self.write_space();
31974 self.generate_identifier(&alias.alias)?;
31975 } else {
31976 self.generate_expression(&e.this)?;
31977 }
31978 } else {
31979 self.generate_expression(&e.this)?;
31980 }
31981
31982 if self.config.pretty {
31984 self.write_newline();
31985 self.write_indent();
31986 } else {
31987 self.write_space();
31988 }
31989 self.write_keyword("USING");
31990 self.write_space();
31991 self.generate_expression(&e.using)?;
31992
31993 if let Some(on) = &e.on {
31995 if self.config.pretty {
31996 self.write_newline();
31997 self.write_indent();
31998 } else {
31999 self.write_space();
32000 }
32001 self.write_keyword("ON");
32002 self.write_space();
32003 self.generate_expression(on)?;
32004 }
32005 if let Some(using_cond) = &e.using_cond {
32007 self.write_space();
32008 self.write_keyword("USING");
32009 self.write_space();
32010 self.write("(");
32011 if let Expression::Tuple(tuple) = using_cond.as_ref() {
32013 for (i, col) in tuple.expressions.iter().enumerate() {
32014 if i > 0 {
32015 self.write(", ");
32016 }
32017 self.generate_expression(col)?;
32018 }
32019 } else {
32020 self.generate_expression(using_cond)?;
32021 }
32022 self.write(")");
32023 }
32024 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
32026 if matches!(
32027 self.config.dialect,
32028 Some(crate::DialectType::PostgreSQL)
32029 | Some(crate::DialectType::Redshift)
32030 | Some(crate::DialectType::Trino)
32031 | Some(crate::DialectType::Presto)
32032 | Some(crate::DialectType::Athena)
32033 ) {
32034 let mut names = Vec::new();
32035 match e.this.as_ref() {
32036 Expression::Alias(a) => {
32037 if let Expression::Table(t) = &a.this {
32039 names.push(t.name.name.clone());
32040 } else if let Expression::Identifier(id) = &a.this {
32041 names.push(id.name.clone());
32042 }
32043 names.push(a.alias.name.clone());
32044 }
32045 Expression::Table(t) => {
32046 names.push(t.name.name.clone());
32047 }
32048 Expression::Identifier(id) => {
32049 names.push(id.name.clone());
32050 }
32051 _ => {}
32052 }
32053 self.merge_strip_qualifiers = names;
32054 }
32055
32056 if let Some(whens) = &e.whens {
32058 if self.config.pretty {
32059 self.write_newline();
32060 self.write_indent();
32061 } else {
32062 self.write_space();
32063 }
32064 self.generate_expression(whens)?;
32065 }
32066
32067 self.merge_strip_qualifiers = saved_merge_strip;
32069
32070 if let Some(returning) = &e.returning {
32072 if self.config.pretty {
32073 self.write_newline();
32074 self.write_indent();
32075 } else {
32076 self.write_space();
32077 }
32078 self.generate_expression(returning)?;
32079 }
32080 Ok(())
32081 }
32082
32083 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
32084 if e.no.is_some() {
32086 self.write_keyword("NO MERGEBLOCKRATIO");
32087 } else if e.default.is_some() {
32088 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
32089 } else {
32090 self.write_keyword("MERGEBLOCKRATIO");
32091 self.write("=");
32092 if let Some(this) = &e.this {
32093 self.generate_expression(this)?;
32094 }
32095 if e.percent.is_some() {
32096 self.write_keyword(" PERCENT");
32097 }
32098 }
32099 Ok(())
32100 }
32101
32102 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
32103 self.write_keyword("TTL");
32105 let pretty_clickhouse = self.config.pretty
32106 && matches!(
32107 self.config.dialect,
32108 Some(crate::dialects::DialectType::ClickHouse)
32109 );
32110
32111 if pretty_clickhouse {
32112 self.write_newline();
32113 self.indent_level += 1;
32114 for (i, expr) in e.expressions.iter().enumerate() {
32115 if i > 0 {
32116 self.write(",");
32117 self.write_newline();
32118 }
32119 self.write_indent();
32120 self.generate_expression(expr)?;
32121 }
32122 self.indent_level -= 1;
32123 } else {
32124 self.write_space();
32125 for (i, expr) in e.expressions.iter().enumerate() {
32126 if i > 0 {
32127 self.write(", ");
32128 }
32129 self.generate_expression(expr)?;
32130 }
32131 }
32132
32133 if let Some(where_) = &e.where_ {
32134 if pretty_clickhouse {
32135 self.write_newline();
32136 if let Expression::Where(w) = where_.as_ref() {
32137 self.write_indent();
32138 self.write_keyword("WHERE");
32139 self.write_newline();
32140 self.indent_level += 1;
32141 self.write_indent();
32142 self.generate_expression(&w.this)?;
32143 self.indent_level -= 1;
32144 } else {
32145 self.write_indent();
32146 self.generate_expression(where_)?;
32147 }
32148 } else {
32149 self.write_space();
32150 self.generate_expression(where_)?;
32151 }
32152 }
32153 if let Some(group) = &e.group {
32154 if pretty_clickhouse {
32155 self.write_newline();
32156 if let Expression::Group(g) = group.as_ref() {
32157 self.write_indent();
32158 self.write_keyword("GROUP BY");
32159 self.write_newline();
32160 self.indent_level += 1;
32161 for (i, expr) in g.expressions.iter().enumerate() {
32162 if i > 0 {
32163 self.write(",");
32164 self.write_newline();
32165 }
32166 self.write_indent();
32167 self.generate_expression(expr)?;
32168 }
32169 self.indent_level -= 1;
32170 } else {
32171 self.write_indent();
32172 self.generate_expression(group)?;
32173 }
32174 } else {
32175 self.write_space();
32176 self.generate_expression(group)?;
32177 }
32178 }
32179 if let Some(aggregates) = &e.aggregates {
32180 if pretty_clickhouse {
32181 self.write_newline();
32182 self.write_indent();
32183 self.write_keyword("SET");
32184 self.write_newline();
32185 self.indent_level += 1;
32186 if let Expression::Tuple(t) = aggregates.as_ref() {
32187 for (i, agg) in t.expressions.iter().enumerate() {
32188 if i > 0 {
32189 self.write(",");
32190 self.write_newline();
32191 }
32192 self.write_indent();
32193 self.generate_expression(agg)?;
32194 }
32195 } else {
32196 self.write_indent();
32197 self.generate_expression(aggregates)?;
32198 }
32199 self.indent_level -= 1;
32200 } else {
32201 self.write_space();
32202 self.write_keyword("SET");
32203 self.write_space();
32204 if let Expression::Tuple(t) = aggregates.as_ref() {
32205 for (i, agg) in t.expressions.iter().enumerate() {
32206 if i > 0 {
32207 self.write(", ");
32208 }
32209 self.generate_expression(agg)?;
32210 }
32211 } else {
32212 self.generate_expression(aggregates)?;
32213 }
32214 }
32215 }
32216 Ok(())
32217 }
32218
32219 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
32220 self.generate_expression(&e.this)?;
32222 if e.delete.is_some() {
32223 self.write_keyword(" DELETE");
32224 }
32225 if let Some(recompress) = &e.recompress {
32226 self.write_keyword(" RECOMPRESS ");
32227 self.generate_expression(recompress)?;
32228 }
32229 if let Some(to_disk) = &e.to_disk {
32230 self.write_keyword(" TO DISK ");
32231 self.generate_expression(to_disk)?;
32232 }
32233 if let Some(to_volume) = &e.to_volume {
32234 self.write_keyword(" TO VOLUME ");
32235 self.generate_expression(to_volume)?;
32236 }
32237 Ok(())
32238 }
32239
32240 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
32241 self.write_keyword("MINHASH");
32243 self.write("(");
32244 self.generate_expression(&e.this)?;
32245 for expr in &e.expressions {
32246 self.write(", ");
32247 self.generate_expression(expr)?;
32248 }
32249 self.write(")");
32250 Ok(())
32251 }
32252
32253 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
32254 self.generate_expression(&e.this)?;
32256 self.write("!");
32257 self.generate_expression(&e.expression)?;
32258 Ok(())
32259 }
32260
32261 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
32262 self.write_keyword("MONTHNAME");
32264 self.write("(");
32265 self.generate_expression(&e.this)?;
32266 self.write(")");
32267 Ok(())
32268 }
32269
32270 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
32271 for comment in &e.leading_comments {
32273 self.write_formatted_comment(comment);
32274 if self.config.pretty {
32275 self.write_newline();
32276 self.write_indent();
32277 } else {
32278 self.write_space();
32279 }
32280 }
32281 self.write_keyword("INSERT");
32283 if e.overwrite {
32284 self.write_space();
32285 self.write_keyword("OVERWRITE");
32286 }
32287 self.write_space();
32288 self.write(&e.kind);
32289 if self.config.pretty {
32290 self.indent_level += 1;
32291 for expr in &e.expressions {
32292 self.write_newline();
32293 self.write_indent();
32294 self.generate_expression(expr)?;
32295 }
32296 self.indent_level -= 1;
32297 } else {
32298 for expr in &e.expressions {
32299 self.write_space();
32300 self.generate_expression(expr)?;
32301 }
32302 }
32303 if let Some(source) = &e.source {
32304 if self.config.pretty {
32305 self.write_newline();
32306 self.write_indent();
32307 } else {
32308 self.write_space();
32309 }
32310 self.generate_expression(source)?;
32311 }
32312 Ok(())
32313 }
32314
32315 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
32316 self.write_keyword("NEXT VALUE FOR");
32318 self.write_space();
32319 self.generate_expression(&e.this)?;
32320 if let Some(order) = &e.order {
32321 self.write_space();
32322 self.write_keyword("OVER");
32323 self.write(" (");
32324 self.generate_expression(order)?;
32325 self.write(")");
32326 }
32327 Ok(())
32328 }
32329
32330 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
32331 self.write_keyword("NORMAL");
32333 self.write("(");
32334 self.generate_expression(&e.this)?;
32335 if let Some(stddev) = &e.stddev {
32336 self.write(", ");
32337 self.generate_expression(stddev)?;
32338 }
32339 if let Some(gen) = &e.gen {
32340 self.write(", ");
32341 self.generate_expression(gen)?;
32342 }
32343 self.write(")");
32344 Ok(())
32345 }
32346
32347 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
32348 if e.is_casefold.is_some() {
32350 self.write_keyword("NORMALIZE_AND_CASEFOLD");
32351 } else {
32352 self.write_keyword("NORMALIZE");
32353 }
32354 self.write("(");
32355 self.generate_expression(&e.this)?;
32356 if let Some(form) = &e.form {
32357 self.write(", ");
32358 self.generate_expression(form)?;
32359 }
32360 self.write(")");
32361 Ok(())
32362 }
32363
32364 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
32365 if e.allow_null.is_none() {
32367 self.write_keyword("NOT ");
32368 }
32369 self.write_keyword("NULL");
32370 Ok(())
32371 }
32372
32373 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
32374 self.write_keyword("NULLIF");
32376 self.write("(");
32377 self.generate_expression(&e.this)?;
32378 self.write(", ");
32379 self.generate_expression(&e.expression)?;
32380 self.write(")");
32381 Ok(())
32382 }
32383
32384 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
32385 self.write_keyword("FORMAT");
32387 self.write("(");
32388 self.generate_expression(&e.this)?;
32389 self.write(", '");
32390 self.write(&e.format);
32391 self.write("'");
32392 if let Some(culture) = &e.culture {
32393 self.write(", ");
32394 self.generate_expression(culture)?;
32395 }
32396 self.write(")");
32397 Ok(())
32398 }
32399
32400 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
32401 self.write_keyword("OBJECT_AGG");
32403 self.write("(");
32404 self.generate_expression(&e.this)?;
32405 self.write(", ");
32406 self.generate_expression(&e.expression)?;
32407 self.write(")");
32408 Ok(())
32409 }
32410
32411 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
32412 self.generate_expression(&e.this)?;
32414 Ok(())
32415 }
32416
32417 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
32418 self.write_keyword("OBJECT_INSERT");
32420 self.write("(");
32421 self.generate_expression(&e.this)?;
32422 if let Some(key) = &e.key {
32423 self.write(", ");
32424 self.generate_expression(key)?;
32425 }
32426 if let Some(value) = &e.value {
32427 self.write(", ");
32428 self.generate_expression(value)?;
32429 }
32430 if let Some(update_flag) = &e.update_flag {
32431 self.write(", ");
32432 self.generate_expression(update_flag)?;
32433 }
32434 self.write(")");
32435 Ok(())
32436 }
32437
32438 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
32439 self.write_keyword("OFFSET");
32441 self.write_space();
32442 self.generate_expression(&e.this)?;
32443 if e.rows == Some(true)
32445 && matches!(
32446 self.config.dialect,
32447 Some(crate::dialects::DialectType::TSQL)
32448 | Some(crate::dialects::DialectType::Oracle)
32449 )
32450 {
32451 self.write_space();
32452 self.write_keyword("ROWS");
32453 }
32454 Ok(())
32455 }
32456
32457 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
32458 self.write_keyword("QUALIFY");
32460 self.write_space();
32461 self.generate_expression(&e.this)?;
32462 Ok(())
32463 }
32464
32465 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
32466 self.write_keyword("ON CLUSTER");
32468 self.write_space();
32469 self.generate_expression(&e.this)?;
32470 Ok(())
32471 }
32472
32473 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
32474 self.write_keyword("ON COMMIT");
32476 if e.delete.is_some() {
32477 self.write_keyword(" DELETE ROWS");
32478 } else {
32479 self.write_keyword(" PRESERVE ROWS");
32480 }
32481 Ok(())
32482 }
32483
32484 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
32485 if let Some(empty) = &e.empty {
32487 self.generate_expression(empty)?;
32488 self.write_keyword(" ON EMPTY");
32489 }
32490 if let Some(error) = &e.error {
32491 if e.empty.is_some() {
32492 self.write_space();
32493 }
32494 self.generate_expression(error)?;
32495 self.write_keyword(" ON ERROR");
32496 }
32497 if let Some(null) = &e.null {
32498 if e.empty.is_some() || e.error.is_some() {
32499 self.write_space();
32500 }
32501 self.generate_expression(null)?;
32502 self.write_keyword(" ON NULL");
32503 }
32504 Ok(())
32505 }
32506
32507 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
32508 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
32510 return Ok(());
32511 }
32512 if e.duplicate.is_some() {
32514 self.write_keyword("ON DUPLICATE KEY UPDATE");
32516 for (i, expr) in e.expressions.iter().enumerate() {
32517 if i > 0 {
32518 self.write(",");
32519 }
32520 self.write_space();
32521 self.generate_expression(expr)?;
32522 }
32523 return Ok(());
32524 } else {
32525 self.write_keyword("ON CONFLICT");
32526 }
32527 if let Some(constraint) = &e.constraint {
32528 self.write_keyword(" ON CONSTRAINT ");
32529 self.generate_expression(constraint)?;
32530 }
32531 if let Some(conflict_keys) = &e.conflict_keys {
32532 if let Expression::Tuple(t) = conflict_keys.as_ref() {
32534 self.write("(");
32535 for (i, expr) in t.expressions.iter().enumerate() {
32536 if i > 0 {
32537 self.write(", ");
32538 }
32539 self.generate_expression(expr)?;
32540 }
32541 self.write(")");
32542 } else {
32543 self.write("(");
32544 self.generate_expression(conflict_keys)?;
32545 self.write(")");
32546 }
32547 }
32548 if let Some(index_predicate) = &e.index_predicate {
32549 self.write_keyword(" WHERE ");
32550 self.generate_expression(index_predicate)?;
32551 }
32552 if let Some(action) = &e.action {
32553 if let Expression::Identifier(id) = action.as_ref() {
32555 if id.name.eq_ignore_ascii_case("NOTHING") {
32556 self.write_keyword(" DO NOTHING");
32557 } else {
32558 self.write_keyword(" DO ");
32559 self.generate_expression(action)?;
32560 }
32561 } else if let Expression::Tuple(t) = action.as_ref() {
32562 self.write_keyword(" DO UPDATE SET ");
32564 for (i, expr) in t.expressions.iter().enumerate() {
32565 if i > 0 {
32566 self.write(", ");
32567 }
32568 self.generate_expression(expr)?;
32569 }
32570 } else {
32571 self.write_keyword(" DO ");
32572 self.generate_expression(action)?;
32573 }
32574 }
32575 if let Some(where_) = &e.where_ {
32577 self.write_keyword(" WHERE ");
32578 self.generate_expression(where_)?;
32579 }
32580 Ok(())
32581 }
32582
32583 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
32584 self.write_keyword("ON");
32586 self.write_space();
32587 self.generate_expression(&e.this)?;
32588 Ok(())
32589 }
32590
32591 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
32592 self.generate_expression(&e.this)?;
32594 self.write_space();
32595 self.generate_expression(&e.expression)?;
32596 Ok(())
32597 }
32598
32599 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
32600 self.write_keyword("OPENJSON");
32602 self.write("(");
32603 self.generate_expression(&e.this)?;
32604 if let Some(path) = &e.path {
32605 self.write(", ");
32606 self.generate_expression(path)?;
32607 }
32608 self.write(")");
32609 if !e.expressions.is_empty() {
32610 self.write_keyword(" WITH");
32611 if self.config.pretty {
32612 self.write(" (\n");
32613 self.indent_level += 2;
32614 for (i, expr) in e.expressions.iter().enumerate() {
32615 if i > 0 {
32616 self.write(",\n");
32617 }
32618 self.write_indent();
32619 self.generate_expression(expr)?;
32620 }
32621 self.write("\n");
32622 self.indent_level -= 2;
32623 self.write(")");
32624 } else {
32625 self.write(" (");
32626 for (i, expr) in e.expressions.iter().enumerate() {
32627 if i > 0 {
32628 self.write(", ");
32629 }
32630 self.generate_expression(expr)?;
32631 }
32632 self.write(")");
32633 }
32634 }
32635 Ok(())
32636 }
32637
32638 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
32639 self.generate_expression(&e.this)?;
32641 self.write_space();
32642 if let Some(ref dt) = e.data_type {
32644 self.generate_data_type(dt)?;
32645 } else if !e.kind.is_empty() {
32646 self.write(&e.kind);
32647 }
32648 if let Some(path) = &e.path {
32649 self.write_space();
32650 self.generate_expression(path)?;
32651 }
32652 if e.as_json.is_some() {
32653 self.write_keyword(" AS JSON");
32654 }
32655 Ok(())
32656 }
32657
32658 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
32659 self.generate_expression(&e.this)?;
32661 self.write_space();
32662 if let Some(op) = &e.operator {
32663 self.write_keyword("OPERATOR");
32664 self.write("(");
32665 self.generate_expression(op)?;
32666 self.write(")");
32667 }
32668 for comment in &e.comments {
32670 self.write_space();
32671 self.write_formatted_comment(comment);
32672 }
32673 self.write_space();
32674 self.generate_expression(&e.expression)?;
32675 Ok(())
32676 }
32677
32678 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
32679 self.write_keyword("ORDER BY");
32681 let pretty_clickhouse_single_paren = self.config.pretty
32682 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
32683 && e.expressions.len() == 1
32684 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
32685 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
32686 && e.expressions.len() == 1
32687 && matches!(e.expressions[0].this, Expression::Tuple(_))
32688 && !e.expressions[0].desc
32689 && e.expressions[0].nulls_first.is_none();
32690
32691 if pretty_clickhouse_single_paren {
32692 self.write_space();
32693 if let Expression::Paren(p) = &e.expressions[0].this {
32694 self.write("(");
32695 self.write_newline();
32696 self.indent_level += 1;
32697 self.write_indent();
32698 self.generate_expression(&p.this)?;
32699 self.indent_level -= 1;
32700 self.write_newline();
32701 self.write(")");
32702 }
32703 return Ok(());
32704 }
32705
32706 if clickhouse_single_tuple {
32707 self.write_space();
32708 if let Expression::Tuple(t) = &e.expressions[0].this {
32709 self.write("(");
32710 for (i, expr) in t.expressions.iter().enumerate() {
32711 if i > 0 {
32712 self.write(", ");
32713 }
32714 self.generate_expression(expr)?;
32715 }
32716 self.write(")");
32717 }
32718 return Ok(());
32719 }
32720
32721 self.write_space();
32722 for (i, ordered) in e.expressions.iter().enumerate() {
32723 if i > 0 {
32724 self.write(", ");
32725 }
32726 self.generate_expression(&ordered.this)?;
32727 if ordered.desc {
32728 self.write_space();
32729 self.write_keyword("DESC");
32730 } else if ordered.explicit_asc {
32731 self.write_space();
32732 self.write_keyword("ASC");
32733 }
32734 if let Some(nulls_first) = ordered.nulls_first {
32735 let skip_nulls_last =
32737 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
32738 if !skip_nulls_last {
32739 self.write_space();
32740 self.write_keyword("NULLS");
32741 self.write_space();
32742 if nulls_first {
32743 self.write_keyword("FIRST");
32744 } else {
32745 self.write_keyword("LAST");
32746 }
32747 }
32748 }
32749 }
32750 Ok(())
32751 }
32752
32753 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
32754 self.write_keyword("OUTPUT");
32756 self.write("(");
32757 if self.config.pretty {
32758 self.indent_level += 1;
32759 self.write_newline();
32760 self.write_indent();
32761 self.generate_expression(&e.this)?;
32762 self.indent_level -= 1;
32763 self.write_newline();
32764 } else {
32765 self.generate_expression(&e.this)?;
32766 }
32767 self.write(")");
32768 Ok(())
32769 }
32770
32771 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
32772 self.write_keyword("TRUNCATE");
32774 if let Some(this) = &e.this {
32775 self.write_space();
32776 self.generate_expression(this)?;
32777 }
32778 if e.with_count.is_some() {
32779 self.write_keyword(" WITH COUNT");
32780 } else {
32781 self.write_keyword(" WITHOUT COUNT");
32782 }
32783 Ok(())
32784 }
32785
32786 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
32787 self.generate_expression(&e.this)?;
32789 self.write("(");
32790 for (i, expr) in e.expressions.iter().enumerate() {
32791 if i > 0 {
32792 self.write(", ");
32793 }
32794 self.generate_expression(expr)?;
32795 }
32796 self.write(")(");
32797 for (i, param) in e.params.iter().enumerate() {
32798 if i > 0 {
32799 self.write(", ");
32800 }
32801 self.generate_expression(param)?;
32802 }
32803 self.write(")");
32804 Ok(())
32805 }
32806
32807 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
32808 self.write_keyword("PARSE_DATETIME");
32810 self.write("(");
32811 if let Some(format) = &e.format {
32812 self.write("'");
32813 self.write(format);
32814 self.write("', ");
32815 }
32816 self.generate_expression(&e.this)?;
32817 if let Some(zone) = &e.zone {
32818 self.write(", ");
32819 self.generate_expression(zone)?;
32820 }
32821 self.write(")");
32822 Ok(())
32823 }
32824
32825 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
32826 self.write_keyword("PARSE_IP");
32828 self.write("(");
32829 self.generate_expression(&e.this)?;
32830 if let Some(type_) = &e.type_ {
32831 self.write(", ");
32832 self.generate_expression(type_)?;
32833 }
32834 if let Some(permissive) = &e.permissive {
32835 self.write(", ");
32836 self.generate_expression(permissive)?;
32837 }
32838 self.write(")");
32839 Ok(())
32840 }
32841
32842 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
32843 self.write_keyword("PARSE_JSON");
32845 self.write("(");
32846 self.generate_expression(&e.this)?;
32847 if let Some(expression) = &e.expression {
32848 self.write(", ");
32849 self.generate_expression(expression)?;
32850 }
32851 self.write(")");
32852 Ok(())
32853 }
32854
32855 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
32856 self.write_keyword("PARSE_TIME");
32858 self.write("(");
32859 self.write(&format!("'{}'", e.format));
32860 self.write(", ");
32861 self.generate_expression(&e.this)?;
32862 self.write(")");
32863 Ok(())
32864 }
32865
32866 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
32867 self.write_keyword("PARSE_URL");
32869 self.write("(");
32870 self.generate_expression(&e.this)?;
32871 if let Some(part) = &e.part_to_extract {
32872 self.write(", ");
32873 self.generate_expression(part)?;
32874 }
32875 if let Some(key) = &e.key {
32876 self.write(", ");
32877 self.generate_expression(key)?;
32878 }
32879 if let Some(permissive) = &e.permissive {
32880 self.write(", ");
32881 self.generate_expression(permissive)?;
32882 }
32883 self.write(")");
32884 Ok(())
32885 }
32886
32887 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
32888 if e.subpartition {
32890 self.write_keyword("SUBPARTITION");
32891 } else {
32892 self.write_keyword("PARTITION");
32893 }
32894 self.write("(");
32895 for (i, expr) in e.expressions.iter().enumerate() {
32896 if i > 0 {
32897 self.write(", ");
32898 }
32899 self.generate_expression(expr)?;
32900 }
32901 self.write(")");
32902 Ok(())
32903 }
32904
32905 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
32906 if let Some(this) = &e.this {
32908 if let Some(expression) = &e.expression {
32909 self.write_keyword("WITH");
32911 self.write(" (");
32912 self.write_keyword("MODULUS");
32913 self.write_space();
32914 self.generate_expression(this)?;
32915 self.write(", ");
32916 self.write_keyword("REMAINDER");
32917 self.write_space();
32918 self.generate_expression(expression)?;
32919 self.write(")");
32920 } else {
32921 self.write_keyword("IN");
32923 self.write(" (");
32924 self.generate_partition_bound_values(this)?;
32925 self.write(")");
32926 }
32927 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
32928 self.write_keyword("FROM");
32930 self.write(" (");
32931 self.generate_partition_bound_values(from)?;
32932 self.write(") ");
32933 self.write_keyword("TO");
32934 self.write(" (");
32935 self.generate_partition_bound_values(to)?;
32936 self.write(")");
32937 }
32938 Ok(())
32939 }
32940
32941 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
32944 if let Expression::Tuple(t) = expr {
32945 for (i, e) in t.expressions.iter().enumerate() {
32946 if i > 0 {
32947 self.write(", ");
32948 }
32949 self.generate_expression(e)?;
32950 }
32951 Ok(())
32952 } else {
32953 self.generate_expression(expr)
32954 }
32955 }
32956
32957 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
32958 self.write_keyword("PARTITION BY LIST");
32960 if let Some(partition_exprs) = &e.partition_expressions {
32961 self.write(" (");
32962 self.generate_doris_partition_expressions(partition_exprs)?;
32964 self.write(")");
32965 }
32966 if let Some(create_exprs) = &e.create_expressions {
32967 self.write(" (");
32968 self.generate_doris_partition_definitions(create_exprs)?;
32970 self.write(")");
32971 }
32972 Ok(())
32973 }
32974
32975 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
32976 self.write_keyword("PARTITION BY RANGE");
32978 if let Some(partition_exprs) = &e.partition_expressions {
32979 self.write(" (");
32980 self.generate_doris_partition_expressions(partition_exprs)?;
32982 self.write(")");
32983 }
32984 if let Some(create_exprs) = &e.create_expressions {
32985 self.write(" (");
32986 self.generate_doris_partition_definitions(create_exprs)?;
32988 self.write(")");
32989 }
32990 Ok(())
32991 }
32992
32993 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
32995 if let Expression::Tuple(t) = expr {
32996 for (i, e) in t.expressions.iter().enumerate() {
32997 if i > 0 {
32998 self.write(", ");
32999 }
33000 self.generate_expression(e)?;
33001 }
33002 } else {
33003 self.generate_expression(expr)?;
33004 }
33005 Ok(())
33006 }
33007
33008 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
33010 match expr {
33011 Expression::Tuple(t) => {
33012 for (i, part) in t.expressions.iter().enumerate() {
33014 if i > 0 {
33015 self.write(", ");
33016 }
33017 if let Expression::Partition(p) = part {
33019 for (j, inner) in p.expressions.iter().enumerate() {
33020 if j > 0 {
33021 self.write(", ");
33022 }
33023 self.generate_expression(inner)?;
33024 }
33025 } else {
33026 self.generate_expression(part)?;
33027 }
33028 }
33029 }
33030 Expression::PartitionByRangePropertyDynamic(_) => {
33031 self.generate_expression(expr)?;
33033 }
33034 _ => {
33035 self.generate_expression(expr)?;
33036 }
33037 }
33038 Ok(())
33039 }
33040
33041 fn generate_partition_by_range_property_dynamic(
33042 &mut self,
33043 e: &PartitionByRangePropertyDynamic,
33044 ) -> Result<()> {
33045 if e.use_start_end {
33046 if let Some(start) = &e.start {
33048 self.write_keyword("START");
33049 self.write(" (");
33050 self.generate_expression(start)?;
33051 self.write(")");
33052 }
33053 if let Some(end) = &e.end {
33054 self.write_space();
33055 self.write_keyword("END");
33056 self.write(" (");
33057 self.generate_expression(end)?;
33058 self.write(")");
33059 }
33060 if let Some(every) = &e.every {
33061 self.write_space();
33062 self.write_keyword("EVERY");
33063 self.write(" (");
33064 self.generate_doris_interval(every)?;
33066 self.write(")");
33067 }
33068 } else {
33069 if let Some(start) = &e.start {
33071 self.write_keyword("FROM");
33072 self.write(" (");
33073 self.generate_expression(start)?;
33074 self.write(")");
33075 }
33076 if let Some(end) = &e.end {
33077 self.write_space();
33078 self.write_keyword("TO");
33079 self.write(" (");
33080 self.generate_expression(end)?;
33081 self.write(")");
33082 }
33083 if let Some(every) = &e.every {
33084 self.write_space();
33085 self.generate_doris_interval(every)?;
33087 }
33088 }
33089 Ok(())
33090 }
33091
33092 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
33094 if let Expression::Interval(interval) = expr {
33095 self.write_keyword("INTERVAL");
33096 if let Some(ref value) = interval.this {
33097 self.write_space();
33098 match value {
33102 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()) => {
33103 if let Literal::String(s) = lit.as_ref() {
33104 self.write(s);
33105 }
33106 }
33107 _ => {
33108 self.generate_expression(value)?;
33109 }
33110 }
33111 }
33112 if let Some(ref unit_spec) = interval.unit {
33113 self.write_space();
33114 self.write_interval_unit_spec(unit_spec)?;
33115 }
33116 Ok(())
33117 } else {
33118 self.generate_expression(expr)
33119 }
33120 }
33121
33122 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
33123 self.write_keyword("TRUNCATE");
33125 self.write("(");
33126 self.generate_expression(&e.expression)?;
33127 self.write(", ");
33128 self.generate_expression(&e.this)?;
33129 self.write(")");
33130 Ok(())
33131 }
33132
33133 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
33134 self.write_keyword("PARTITION");
33136 self.write_space();
33137 self.generate_expression(&e.this)?;
33138 self.write_space();
33139 self.write_keyword("VALUES IN");
33140 self.write(" (");
33141 for (i, expr) in e.expressions.iter().enumerate() {
33142 if i > 0 {
33143 self.write(", ");
33144 }
33145 self.generate_expression(expr)?;
33146 }
33147 self.write(")");
33148 Ok(())
33149 }
33150
33151 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
33152 if e.expressions.is_empty() && e.expression.is_some() {
33155 self.generate_expression(&e.this)?;
33157 self.write_space();
33158 self.write_keyword("TO");
33159 self.write_space();
33160 self.generate_expression(e.expression.as_ref().unwrap())?;
33161 return Ok(());
33162 }
33163
33164 self.write_keyword("PARTITION");
33166 self.write_space();
33167 self.generate_expression(&e.this)?;
33168 self.write_space();
33169
33170 if e.expressions.len() == 1 {
33172 self.write_keyword("VALUES LESS THAN");
33174 self.write(" (");
33175 self.generate_expression(&e.expressions[0])?;
33176 self.write(")");
33177 } else if !e.expressions.is_empty() {
33178 self.write_keyword("VALUES");
33180 self.write(" [");
33181 for (i, expr) in e.expressions.iter().enumerate() {
33182 if i > 0 {
33183 self.write(", ");
33184 }
33185 if let Expression::Tuple(t) = expr {
33187 self.write("(");
33188 for (j, inner) in t.expressions.iter().enumerate() {
33189 if j > 0 {
33190 self.write(", ");
33191 }
33192 self.generate_expression(inner)?;
33193 }
33194 self.write(")");
33195 } else {
33196 self.write("(");
33197 self.generate_expression(expr)?;
33198 self.write(")");
33199 }
33200 }
33201 self.write(")");
33202 }
33203 Ok(())
33204 }
33205
33206 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
33207 self.write_keyword("BUCKET");
33209 self.write("(");
33210 self.generate_expression(&e.this)?;
33211 self.write(", ");
33212 self.generate_expression(&e.expression)?;
33213 self.write(")");
33214 Ok(())
33215 }
33216
33217 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
33218 self.write_keyword("PARTITION BY");
33220 self.write_space();
33221 for (i, expr) in e.expressions.iter().enumerate() {
33222 if i > 0 {
33223 self.write(", ");
33224 }
33225 self.generate_expression(expr)?;
33226 }
33227 Ok(())
33228 }
33229
33230 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
33231 if matches!(
33233 self.config.dialect,
33234 Some(crate::dialects::DialectType::Teradata)
33235 | Some(crate::dialects::DialectType::ClickHouse)
33236 ) {
33237 self.write_keyword("PARTITION BY");
33238 } else {
33239 self.write_keyword("PARTITIONED BY");
33240 }
33241 self.write_space();
33242 if self.config.pretty {
33244 if let Expression::Tuple(ref tuple) = *e.this {
33245 self.write("(");
33246 self.write_newline();
33247 self.indent_level += 1;
33248 for (i, expr) in tuple.expressions.iter().enumerate() {
33249 if i > 0 {
33250 self.write(",");
33251 self.write_newline();
33252 }
33253 self.write_indent();
33254 self.generate_expression(expr)?;
33255 }
33256 self.indent_level -= 1;
33257 self.write_newline();
33258 self.write(")");
33259 } else {
33260 self.generate_expression(&e.this)?;
33261 }
33262 } else {
33263 self.generate_expression(&e.this)?;
33264 }
33265 Ok(())
33266 }
33267
33268 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
33269 self.write_keyword("PARTITION OF");
33271 self.write_space();
33272 self.generate_expression(&e.this)?;
33273 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
33275 self.write_space();
33276 self.write_keyword("FOR VALUES");
33277 self.write_space();
33278 self.generate_expression(&e.expression)?;
33279 } else {
33280 self.write_space();
33281 self.write_keyword("DEFAULT");
33282 }
33283 Ok(())
33284 }
33285
33286 fn generate_period_for_system_time_constraint(
33287 &mut self,
33288 e: &PeriodForSystemTimeConstraint,
33289 ) -> Result<()> {
33290 self.write_keyword("PERIOD FOR SYSTEM_TIME");
33292 self.write(" (");
33293 self.generate_expression(&e.this)?;
33294 self.write(", ");
33295 self.generate_expression(&e.expression)?;
33296 self.write(")");
33297 Ok(())
33298 }
33299
33300 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
33301 self.generate_expression(&e.this)?;
33304 self.write_space();
33305 self.write_keyword("AS");
33306 self.write_space();
33307 if self.config.unpivot_aliases_are_identifiers {
33309 match &e.alias {
33310 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
33311 let Literal::String(s) = lit.as_ref() else {
33312 unreachable!()
33313 };
33314 self.generate_identifier(&Identifier::new(s.clone()))?;
33316 }
33317 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
33318 let Literal::Number(n) = lit.as_ref() else {
33319 unreachable!()
33320 };
33321 let mut id = Identifier::new(n.clone());
33323 id.quoted = true;
33324 self.generate_identifier(&id)?;
33325 }
33326 other => {
33327 self.generate_expression(other)?;
33328 }
33329 }
33330 } else {
33331 self.generate_expression(&e.alias)?;
33332 }
33333 Ok(())
33334 }
33335
33336 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
33337 self.write_keyword("ANY");
33339 if let Some(this) = &e.this {
33340 self.write_space();
33341 self.generate_expression(this)?;
33342 }
33343 Ok(())
33344 }
33345
33346 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
33347 self.write_keyword("ML.PREDICT");
33349 self.write("(");
33350 self.write_keyword("MODEL");
33351 self.write_space();
33352 self.generate_expression(&e.this)?;
33353 self.write(", ");
33354 self.generate_expression(&e.expression)?;
33355 if let Some(params) = &e.params_struct {
33356 self.write(", ");
33357 self.generate_expression(params)?;
33358 }
33359 self.write(")");
33360 Ok(())
33361 }
33362
33363 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
33364 self.write_keyword("PREVIOUS_DAY");
33366 self.write("(");
33367 self.generate_expression(&e.this)?;
33368 self.write(", ");
33369 self.generate_expression(&e.expression)?;
33370 self.write(")");
33371 Ok(())
33372 }
33373
33374 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
33375 self.write_keyword("PRIMARY KEY");
33377 if let Some(name) = &e.this {
33378 self.write_space();
33379 self.generate_expression(name)?;
33380 }
33381 if !e.expressions.is_empty() {
33382 self.write(" (");
33383 for (i, expr) in e.expressions.iter().enumerate() {
33384 if i > 0 {
33385 self.write(", ");
33386 }
33387 self.generate_expression(expr)?;
33388 }
33389 self.write(")");
33390 }
33391 if let Some(include) = &e.include {
33392 self.write_space();
33393 self.generate_expression(include)?;
33394 }
33395 if !e.options.is_empty() {
33396 self.write_space();
33397 for (i, opt) in e.options.iter().enumerate() {
33398 if i > 0 {
33399 self.write_space();
33400 }
33401 self.generate_expression(opt)?;
33402 }
33403 }
33404 Ok(())
33405 }
33406
33407 fn generate_primary_key_column_constraint(
33408 &mut self,
33409 _e: &PrimaryKeyColumnConstraint,
33410 ) -> Result<()> {
33411 self.write_keyword("PRIMARY KEY");
33413 Ok(())
33414 }
33415
33416 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
33417 self.write_keyword("PATH");
33419 self.write_space();
33420 self.generate_expression(&e.this)?;
33421 Ok(())
33422 }
33423
33424 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
33425 self.write_keyword("PROJECTION");
33427 self.write_space();
33428 self.generate_expression(&e.this)?;
33429 self.write(" (");
33430 self.generate_expression(&e.expression)?;
33431 self.write(")");
33432 Ok(())
33433 }
33434
33435 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
33436 for (i, prop) in e.expressions.iter().enumerate() {
33438 if i > 0 {
33439 self.write(", ");
33440 }
33441 self.generate_expression(prop)?;
33442 }
33443 Ok(())
33444 }
33445
33446 fn generate_property(&mut self, e: &Property) -> Result<()> {
33447 self.generate_expression(&e.this)?;
33449 if let Some(value) = &e.value {
33450 self.write("=");
33451 self.generate_expression(value)?;
33452 }
33453 Ok(())
33454 }
33455
33456 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
33457 self.write_keyword("OPTIONS");
33458 if e.entries.is_empty() {
33459 self.write(" ()");
33460 return Ok(());
33461 }
33462
33463 if self.config.pretty {
33464 self.write(" (");
33465 self.write_newline();
33466 self.indent_level += 1;
33467 for (i, entry) in e.entries.iter().enumerate() {
33468 if i > 0 {
33469 self.write(",");
33470 self.write_newline();
33471 }
33472 self.write_indent();
33473 self.generate_identifier(&entry.key)?;
33474 self.write("=");
33475 self.generate_expression(&entry.value)?;
33476 }
33477 self.indent_level -= 1;
33478 self.write_newline();
33479 self.write(")");
33480 } else {
33481 self.write(" (");
33482 for (i, entry) in e.entries.iter().enumerate() {
33483 if i > 0 {
33484 self.write(", ");
33485 }
33486 self.generate_identifier(&entry.key)?;
33487 self.write("=");
33488 self.generate_expression(&entry.value)?;
33489 }
33490 self.write(")");
33491 }
33492 Ok(())
33493 }
33494
33495 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
33497 self.write_keyword("OPTIONS");
33498 self.write(" (");
33499 for (i, opt) in options.iter().enumerate() {
33500 if i > 0 {
33501 self.write(", ");
33502 }
33503 self.generate_option_expression(opt)?;
33504 }
33505 self.write(")");
33506 Ok(())
33507 }
33508
33509 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
33511 self.write_keyword("PROPERTIES");
33512 self.write(" (");
33513 for (i, prop) in properties.iter().enumerate() {
33514 if i > 0 {
33515 self.write(", ");
33516 }
33517 self.generate_option_expression(prop)?;
33518 }
33519 self.write(")");
33520 Ok(())
33521 }
33522
33523 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
33525 self.write_keyword("ENVIRONMENT");
33526 self.write(" (");
33527 for (i, env_item) in environment.iter().enumerate() {
33528 if i > 0 {
33529 self.write(", ");
33530 }
33531 self.generate_environment_expression(env_item)?;
33532 }
33533 self.write(")");
33534 Ok(())
33535 }
33536
33537 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
33539 match expr {
33540 Expression::Eq(eq) => {
33541 self.generate_expression(&eq.left)?;
33543 self.write(" = ");
33544 self.generate_expression(&eq.right)?;
33545 Ok(())
33546 }
33547 _ => self.generate_expression(expr),
33548 }
33549 }
33550
33551 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
33553 self.write_keyword("TBLPROPERTIES");
33554 if self.config.pretty {
33555 self.write(" (");
33556 self.write_newline();
33557 self.indent_level += 1;
33558 for (i, opt) in options.iter().enumerate() {
33559 if i > 0 {
33560 self.write(",");
33561 self.write_newline();
33562 }
33563 self.write_indent();
33564 self.generate_option_expression(opt)?;
33565 }
33566 self.indent_level -= 1;
33567 self.write_newline();
33568 self.write(")");
33569 } else {
33570 self.write(" (");
33571 for (i, opt) in options.iter().enumerate() {
33572 if i > 0 {
33573 self.write(", ");
33574 }
33575 self.generate_option_expression(opt)?;
33576 }
33577 self.write(")");
33578 }
33579 Ok(())
33580 }
33581
33582 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
33584 match expr {
33585 Expression::Eq(eq) => {
33586 self.generate_expression(&eq.left)?;
33588 self.write("=");
33589 self.generate_expression(&eq.right)?;
33590 Ok(())
33591 }
33592 _ => self.generate_expression(expr),
33593 }
33594 }
33595
33596 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
33597 self.generate_expression(&e.this)?;
33599 Ok(())
33600 }
33601
33602 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
33603 self.write_keyword("PUT");
33605 self.write_space();
33606
33607 if e.source_quoted {
33609 self.write("'");
33610 self.write(&e.source);
33611 self.write("'");
33612 } else {
33613 self.write(&e.source);
33614 }
33615
33616 self.write_space();
33617
33618 if let Expression::Literal(lit) = &e.target {
33620 if let Literal::String(s) = lit.as_ref() {
33621 self.write(s);
33622 }
33623 } else {
33624 self.generate_expression(&e.target)?;
33625 }
33626
33627 for param in &e.params {
33629 self.write_space();
33630 self.write(¶m.name);
33631 if let Some(ref value) = param.value {
33632 self.write("=");
33633 self.generate_expression(value)?;
33634 }
33635 }
33636
33637 Ok(())
33638 }
33639
33640 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
33641 self.write_keyword("QUANTILE");
33643 self.write("(");
33644 self.generate_expression(&e.this)?;
33645 if let Some(quantile) = &e.quantile {
33646 self.write(", ");
33647 self.generate_expression(quantile)?;
33648 }
33649 self.write(")");
33650 Ok(())
33651 }
33652
33653 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
33654 if matches!(
33656 self.config.dialect,
33657 Some(crate::dialects::DialectType::Teradata)
33658 ) {
33659 self.write_keyword("SET");
33660 self.write_space();
33661 }
33662 self.write_keyword("QUERY_BAND");
33663 self.write(" = ");
33664 self.generate_expression(&e.this)?;
33665 if e.update.is_some() {
33666 self.write_space();
33667 self.write_keyword("UPDATE");
33668 }
33669 if let Some(scope) = &e.scope {
33670 self.write_space();
33671 self.write_keyword("FOR");
33672 self.write_space();
33673 self.generate_expression(scope)?;
33674 }
33675 Ok(())
33676 }
33677
33678 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
33679 self.generate_expression(&e.this)?;
33681 if let Some(expression) = &e.expression {
33682 self.write(" = ");
33683 self.generate_expression(expression)?;
33684 }
33685 Ok(())
33686 }
33687
33688 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
33689 self.write_keyword("TRANSFORM");
33691 self.write("(");
33692 for (i, expr) in e.expressions.iter().enumerate() {
33693 if i > 0 {
33694 self.write(", ");
33695 }
33696 self.generate_expression(expr)?;
33697 }
33698 self.write(")");
33699 if let Some(row_format_before) = &e.row_format_before {
33700 self.write_space();
33701 self.generate_expression(row_format_before)?;
33702 }
33703 if let Some(record_writer) = &e.record_writer {
33704 self.write_space();
33705 self.write_keyword("RECORDWRITER");
33706 self.write_space();
33707 self.generate_expression(record_writer)?;
33708 }
33709 if let Some(command_script) = &e.command_script {
33710 self.write_space();
33711 self.write_keyword("USING");
33712 self.write_space();
33713 self.generate_expression(command_script)?;
33714 }
33715 if let Some(schema) = &e.schema {
33716 self.write_space();
33717 self.write_keyword("AS");
33718 self.write_space();
33719 self.generate_expression(schema)?;
33720 }
33721 if let Some(row_format_after) = &e.row_format_after {
33722 self.write_space();
33723 self.generate_expression(row_format_after)?;
33724 }
33725 if let Some(record_reader) = &e.record_reader {
33726 self.write_space();
33727 self.write_keyword("RECORDREADER");
33728 self.write_space();
33729 self.generate_expression(record_reader)?;
33730 }
33731 Ok(())
33732 }
33733
33734 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
33735 self.write_keyword("RANDN");
33737 self.write("(");
33738 if let Some(this) = &e.this {
33739 self.generate_expression(this)?;
33740 }
33741 self.write(")");
33742 Ok(())
33743 }
33744
33745 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
33746 self.write_keyword("RANDSTR");
33748 self.write("(");
33749 self.generate_expression(&e.this)?;
33750 if let Some(generator) = &e.generator {
33751 self.write(", ");
33752 self.generate_expression(generator)?;
33753 }
33754 self.write(")");
33755 Ok(())
33756 }
33757
33758 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
33759 self.write_keyword("RANGE_BUCKET");
33761 self.write("(");
33762 self.generate_expression(&e.this)?;
33763 self.write(", ");
33764 self.generate_expression(&e.expression)?;
33765 self.write(")");
33766 Ok(())
33767 }
33768
33769 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
33770 self.write_keyword("RANGE_N");
33772 self.write("(");
33773 self.generate_expression(&e.this)?;
33774 self.write_space();
33775 self.write_keyword("BETWEEN");
33776 self.write_space();
33777 for (i, expr) in e.expressions.iter().enumerate() {
33778 if i > 0 {
33779 self.write(", ");
33780 }
33781 self.generate_expression(expr)?;
33782 }
33783 if let Some(each) = &e.each {
33784 self.write_space();
33785 self.write_keyword("EACH");
33786 self.write_space();
33787 self.generate_expression(each)?;
33788 }
33789 self.write(")");
33790 Ok(())
33791 }
33792
33793 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
33794 self.write_keyword("READ_CSV");
33796 self.write("(");
33797 self.generate_expression(&e.this)?;
33798 for expr in &e.expressions {
33799 self.write(", ");
33800 self.generate_expression(expr)?;
33801 }
33802 self.write(")");
33803 Ok(())
33804 }
33805
33806 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
33807 self.write_keyword("READ_PARQUET");
33809 self.write("(");
33810 for (i, expr) in e.expressions.iter().enumerate() {
33811 if i > 0 {
33812 self.write(", ");
33813 }
33814 self.generate_expression(expr)?;
33815 }
33816 self.write(")");
33817 Ok(())
33818 }
33819
33820 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
33821 if e.kind == "CYCLE" {
33824 self.write_keyword("CYCLE");
33825 } else {
33826 self.write_keyword("SEARCH");
33827 self.write_space();
33828 self.write(&e.kind);
33829 self.write_space();
33830 self.write_keyword("FIRST BY");
33831 }
33832 self.write_space();
33833 self.generate_expression(&e.this)?;
33834 self.write_space();
33835 self.write_keyword("SET");
33836 self.write_space();
33837 self.generate_expression(&e.expression)?;
33838 if let Some(using) = &e.using {
33839 self.write_space();
33840 self.write_keyword("USING");
33841 self.write_space();
33842 self.generate_expression(using)?;
33843 }
33844 Ok(())
33845 }
33846
33847 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
33848 self.write_keyword("REDUCE");
33850 self.write("(");
33851 self.generate_expression(&e.this)?;
33852 if let Some(initial) = &e.initial {
33853 self.write(", ");
33854 self.generate_expression(initial)?;
33855 }
33856 if let Some(merge) = &e.merge {
33857 self.write(", ");
33858 self.generate_expression(merge)?;
33859 }
33860 if let Some(finish) = &e.finish {
33861 self.write(", ");
33862 self.generate_expression(finish)?;
33863 }
33864 self.write(")");
33865 Ok(())
33866 }
33867
33868 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
33869 self.write_keyword("REFERENCES");
33871 self.write_space();
33872 self.generate_expression(&e.this)?;
33873 if !e.expressions.is_empty() {
33874 self.write(" (");
33875 for (i, expr) in e.expressions.iter().enumerate() {
33876 if i > 0 {
33877 self.write(", ");
33878 }
33879 self.generate_expression(expr)?;
33880 }
33881 self.write(")");
33882 }
33883 for opt in &e.options {
33884 self.write_space();
33885 self.generate_expression(opt)?;
33886 }
33887 Ok(())
33888 }
33889
33890 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
33891 self.write_keyword("REFRESH");
33893 if !e.kind.is_empty() {
33894 self.write_space();
33895 self.write_keyword(&e.kind);
33896 }
33897 self.write_space();
33898 self.generate_expression(&e.this)?;
33899 Ok(())
33900 }
33901
33902 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
33903 self.write_keyword("REFRESH");
33905 self.write_space();
33906 self.write_keyword(&e.method);
33907
33908 if let Some(ref kind) = e.kind {
33909 self.write_space();
33910 self.write_keyword("ON");
33911 self.write_space();
33912 self.write_keyword(kind);
33913
33914 if let Some(ref every) = e.every {
33916 self.write_space();
33917 self.write_keyword("EVERY");
33918 self.write_space();
33919 self.generate_expression(every)?;
33920 if let Some(ref unit) = e.unit {
33921 self.write_space();
33922 self.write_keyword(unit);
33923 }
33924 }
33925
33926 if let Some(ref starts) = e.starts {
33928 self.write_space();
33929 self.write_keyword("STARTS");
33930 self.write_space();
33931 self.generate_expression(starts)?;
33932 }
33933 }
33934 Ok(())
33935 }
33936
33937 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
33938 self.write_keyword("REGEXP_COUNT");
33940 self.write("(");
33941 self.generate_expression(&e.this)?;
33942 self.write(", ");
33943 self.generate_expression(&e.expression)?;
33944 if let Some(position) = &e.position {
33945 self.write(", ");
33946 self.generate_expression(position)?;
33947 }
33948 if let Some(parameters) = &e.parameters {
33949 self.write(", ");
33950 self.generate_expression(parameters)?;
33951 }
33952 self.write(")");
33953 Ok(())
33954 }
33955
33956 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
33957 self.write_keyword("REGEXP_EXTRACT_ALL");
33959 self.write("(");
33960 self.generate_expression(&e.this)?;
33961 self.write(", ");
33962 self.generate_expression(&e.expression)?;
33963 if let Some(group) = &e.group {
33964 self.write(", ");
33965 self.generate_expression(group)?;
33966 }
33967 self.write(")");
33968 Ok(())
33969 }
33970
33971 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
33972 self.write_keyword("REGEXP_FULL_MATCH");
33974 self.write("(");
33975 self.generate_expression(&e.this)?;
33976 self.write(", ");
33977 self.generate_expression(&e.expression)?;
33978 self.write(")");
33979 Ok(())
33980 }
33981
33982 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
33983 use crate::dialects::DialectType;
33984 if matches!(
33986 self.config.dialect,
33987 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
33988 ) && e.flag.is_none()
33989 {
33990 self.generate_expression(&e.this)?;
33991 self.write(" ~* ");
33992 self.generate_expression(&e.expression)?;
33993 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33994 self.write_keyword("REGEXP_LIKE");
33996 self.write("(");
33997 self.generate_expression(&e.this)?;
33998 self.write(", ");
33999 self.generate_expression(&e.expression)?;
34000 self.write(", ");
34001 if let Some(flag) = &e.flag {
34002 self.generate_expression(flag)?;
34003 } else {
34004 self.write("'i'");
34005 }
34006 self.write(")");
34007 } else {
34008 self.generate_expression(&e.this)?;
34010 self.write_space();
34011 self.write_keyword("REGEXP_ILIKE");
34012 self.write_space();
34013 self.generate_expression(&e.expression)?;
34014 if let Some(flag) = &e.flag {
34015 self.write(", ");
34016 self.generate_expression(flag)?;
34017 }
34018 }
34019 Ok(())
34020 }
34021
34022 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
34023 self.write_keyword("REGEXP_INSTR");
34025 self.write("(");
34026 self.generate_expression(&e.this)?;
34027 self.write(", ");
34028 self.generate_expression(&e.expression)?;
34029 if let Some(position) = &e.position {
34030 self.write(", ");
34031 self.generate_expression(position)?;
34032 }
34033 if let Some(occurrence) = &e.occurrence {
34034 self.write(", ");
34035 self.generate_expression(occurrence)?;
34036 }
34037 if let Some(option) = &e.option {
34038 self.write(", ");
34039 self.generate_expression(option)?;
34040 }
34041 if let Some(parameters) = &e.parameters {
34042 self.write(", ");
34043 self.generate_expression(parameters)?;
34044 }
34045 if let Some(group) = &e.group {
34046 self.write(", ");
34047 self.generate_expression(group)?;
34048 }
34049 self.write(")");
34050 Ok(())
34051 }
34052
34053 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
34054 self.write_keyword("REGEXP_SPLIT");
34056 self.write("(");
34057 self.generate_expression(&e.this)?;
34058 self.write(", ");
34059 self.generate_expression(&e.expression)?;
34060 if let Some(limit) = &e.limit {
34061 self.write(", ");
34062 self.generate_expression(limit)?;
34063 }
34064 self.write(")");
34065 Ok(())
34066 }
34067
34068 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
34069 self.write_keyword("REGR_AVGX");
34071 self.write("(");
34072 self.generate_expression(&e.this)?;
34073 self.write(", ");
34074 self.generate_expression(&e.expression)?;
34075 self.write(")");
34076 Ok(())
34077 }
34078
34079 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
34080 self.write_keyword("REGR_AVGY");
34082 self.write("(");
34083 self.generate_expression(&e.this)?;
34084 self.write(", ");
34085 self.generate_expression(&e.expression)?;
34086 self.write(")");
34087 Ok(())
34088 }
34089
34090 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
34091 self.write_keyword("REGR_COUNT");
34093 self.write("(");
34094 self.generate_expression(&e.this)?;
34095 self.write(", ");
34096 self.generate_expression(&e.expression)?;
34097 self.write(")");
34098 Ok(())
34099 }
34100
34101 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
34102 self.write_keyword("REGR_INTERCEPT");
34104 self.write("(");
34105 self.generate_expression(&e.this)?;
34106 self.write(", ");
34107 self.generate_expression(&e.expression)?;
34108 self.write(")");
34109 Ok(())
34110 }
34111
34112 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
34113 self.write_keyword("REGR_R2");
34115 self.write("(");
34116 self.generate_expression(&e.this)?;
34117 self.write(", ");
34118 self.generate_expression(&e.expression)?;
34119 self.write(")");
34120 Ok(())
34121 }
34122
34123 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
34124 self.write_keyword("REGR_SLOPE");
34126 self.write("(");
34127 self.generate_expression(&e.this)?;
34128 self.write(", ");
34129 self.generate_expression(&e.expression)?;
34130 self.write(")");
34131 Ok(())
34132 }
34133
34134 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
34135 self.write_keyword("REGR_SXX");
34137 self.write("(");
34138 self.generate_expression(&e.this)?;
34139 self.write(", ");
34140 self.generate_expression(&e.expression)?;
34141 self.write(")");
34142 Ok(())
34143 }
34144
34145 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
34146 self.write_keyword("REGR_SXY");
34148 self.write("(");
34149 self.generate_expression(&e.this)?;
34150 self.write(", ");
34151 self.generate_expression(&e.expression)?;
34152 self.write(")");
34153 Ok(())
34154 }
34155
34156 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
34157 self.write_keyword("REGR_SYY");
34159 self.write("(");
34160 self.generate_expression(&e.this)?;
34161 self.write(", ");
34162 self.generate_expression(&e.expression)?;
34163 self.write(")");
34164 Ok(())
34165 }
34166
34167 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
34168 self.write_keyword("REGR_VALX");
34170 self.write("(");
34171 self.generate_expression(&e.this)?;
34172 self.write(", ");
34173 self.generate_expression(&e.expression)?;
34174 self.write(")");
34175 Ok(())
34176 }
34177
34178 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
34179 self.write_keyword("REGR_VALY");
34181 self.write("(");
34182 self.generate_expression(&e.this)?;
34183 self.write(", ");
34184 self.generate_expression(&e.expression)?;
34185 self.write(")");
34186 Ok(())
34187 }
34188
34189 fn generate_remote_with_connection_model_property(
34190 &mut self,
34191 e: &RemoteWithConnectionModelProperty,
34192 ) -> Result<()> {
34193 self.write_keyword("REMOTE WITH CONNECTION");
34195 self.write_space();
34196 self.generate_expression(&e.this)?;
34197 Ok(())
34198 }
34199
34200 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
34201 self.write_keyword("RENAME COLUMN");
34203 if e.exists {
34204 self.write_space();
34205 self.write_keyword("IF EXISTS");
34206 }
34207 self.write_space();
34208 self.generate_expression(&e.this)?;
34209 if let Some(to) = &e.to {
34210 self.write_space();
34211 self.write_keyword("TO");
34212 self.write_space();
34213 self.generate_expression(to)?;
34214 }
34215 Ok(())
34216 }
34217
34218 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
34219 self.write_keyword("REPLACE PARTITION");
34221 self.write_space();
34222 self.generate_expression(&e.expression)?;
34223 if let Some(source) = &e.source {
34224 self.write_space();
34225 self.write_keyword("FROM");
34226 self.write_space();
34227 self.generate_expression(source)?;
34228 }
34229 Ok(())
34230 }
34231
34232 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
34233 let keyword = match self.config.dialect {
34236 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
34237 _ => "RETURNING",
34238 };
34239 self.write_keyword(keyword);
34240 self.write_space();
34241 for (i, expr) in e.expressions.iter().enumerate() {
34242 if i > 0 {
34243 self.write(", ");
34244 }
34245 self.generate_expression(expr)?;
34246 }
34247 if let Some(into) = &e.into {
34248 self.write_space();
34249 self.write_keyword("INTO");
34250 self.write_space();
34251 self.generate_expression(into)?;
34252 }
34253 Ok(())
34254 }
34255
34256 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
34257 self.write_space();
34259 self.write_keyword("OUTPUT");
34260 self.write_space();
34261 for (i, expr) in output.columns.iter().enumerate() {
34262 if i > 0 {
34263 self.write(", ");
34264 }
34265 self.generate_expression(expr)?;
34266 }
34267 if let Some(into_table) = &output.into_table {
34268 self.write_space();
34269 self.write_keyword("INTO");
34270 self.write_space();
34271 self.generate_expression(into_table)?;
34272 }
34273 Ok(())
34274 }
34275
34276 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
34277 self.write_keyword("RETURNS");
34279 if e.is_table.is_some() {
34280 self.write_space();
34281 self.write_keyword("TABLE");
34282 }
34283 if let Some(table) = &e.table {
34284 self.write_space();
34285 self.generate_expression(table)?;
34286 } else if let Some(this) = &e.this {
34287 self.write_space();
34288 self.generate_expression(this)?;
34289 }
34290 if e.null.is_some() {
34291 self.write_space();
34292 self.write_keyword("NULL ON NULL INPUT");
34293 }
34294 Ok(())
34295 }
34296
34297 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
34298 self.write_keyword("ROLLBACK");
34300
34301 if e.this.is_none()
34303 && matches!(
34304 self.config.dialect,
34305 Some(DialectType::TSQL) | Some(DialectType::Fabric)
34306 )
34307 {
34308 self.write_space();
34309 self.write_keyword("TRANSACTION");
34310 }
34311
34312 if let Some(this) = &e.this {
34314 let is_transaction_marker = matches!(
34316 this.as_ref(),
34317 Expression::Identifier(id) if id.name == "TRANSACTION"
34318 );
34319
34320 self.write_space();
34321 self.write_keyword("TRANSACTION");
34322
34323 if !is_transaction_marker {
34325 self.write_space();
34326 self.generate_expression(this)?;
34327 }
34328 }
34329
34330 if let Some(savepoint) = &e.savepoint {
34332 self.write_space();
34333 self.write_keyword("TO");
34334 self.write_space();
34335 self.generate_expression(savepoint)?;
34336 }
34337 Ok(())
34338 }
34339
34340 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
34341 if e.expressions.is_empty() {
34343 self.write_keyword("WITH ROLLUP");
34344 } else {
34345 self.write_keyword("ROLLUP");
34346 self.write("(");
34347 for (i, expr) in e.expressions.iter().enumerate() {
34348 if i > 0 {
34349 self.write(", ");
34350 }
34351 self.generate_expression(expr)?;
34352 }
34353 self.write(")");
34354 }
34355 Ok(())
34356 }
34357
34358 fn generate_row_format_delimited_property(
34359 &mut self,
34360 e: &RowFormatDelimitedProperty,
34361 ) -> Result<()> {
34362 self.write_keyword("ROW FORMAT DELIMITED");
34364 if let Some(fields) = &e.fields {
34365 self.write_space();
34366 self.write_keyword("FIELDS TERMINATED BY");
34367 self.write_space();
34368 self.generate_expression(fields)?;
34369 }
34370 if let Some(escaped) = &e.escaped {
34371 self.write_space();
34372 self.write_keyword("ESCAPED BY");
34373 self.write_space();
34374 self.generate_expression(escaped)?;
34375 }
34376 if let Some(items) = &e.collection_items {
34377 self.write_space();
34378 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
34379 self.write_space();
34380 self.generate_expression(items)?;
34381 }
34382 if let Some(keys) = &e.map_keys {
34383 self.write_space();
34384 self.write_keyword("MAP KEYS TERMINATED BY");
34385 self.write_space();
34386 self.generate_expression(keys)?;
34387 }
34388 if let Some(lines) = &e.lines {
34389 self.write_space();
34390 self.write_keyword("LINES TERMINATED BY");
34391 self.write_space();
34392 self.generate_expression(lines)?;
34393 }
34394 if let Some(null) = &e.null {
34395 self.write_space();
34396 self.write_keyword("NULL DEFINED AS");
34397 self.write_space();
34398 self.generate_expression(null)?;
34399 }
34400 if let Some(serde) = &e.serde {
34401 self.write_space();
34402 self.generate_expression(serde)?;
34403 }
34404 Ok(())
34405 }
34406
34407 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
34408 self.write_keyword("ROW FORMAT");
34410 self.write_space();
34411 self.generate_expression(&e.this)?;
34412 Ok(())
34413 }
34414
34415 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
34416 self.write_keyword("ROW FORMAT SERDE");
34418 self.write_space();
34419 self.generate_expression(&e.this)?;
34420 if let Some(props) = &e.serde_properties {
34421 self.write_space();
34422 self.generate_expression(props)?;
34424 }
34425 Ok(())
34426 }
34427
34428 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
34429 self.write_keyword("SHA2");
34431 self.write("(");
34432 self.generate_expression(&e.this)?;
34433 if let Some(length) = e.length {
34434 self.write(", ");
34435 self.write(&length.to_string());
34436 }
34437 self.write(")");
34438 Ok(())
34439 }
34440
34441 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
34442 self.write_keyword("SHA2_DIGEST");
34444 self.write("(");
34445 self.generate_expression(&e.this)?;
34446 if let Some(length) = e.length {
34447 self.write(", ");
34448 self.write(&length.to_string());
34449 }
34450 self.write(")");
34451 Ok(())
34452 }
34453
34454 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
34455 let name = if matches!(
34456 self.config.dialect,
34457 Some(crate::dialects::DialectType::Spark)
34458 | Some(crate::dialects::DialectType::Databricks)
34459 ) {
34460 "TRY_ADD"
34461 } else {
34462 "SAFE_ADD"
34463 };
34464 self.write_keyword(name);
34465 self.write("(");
34466 self.generate_expression(&e.this)?;
34467 self.write(", ");
34468 self.generate_expression(&e.expression)?;
34469 self.write(")");
34470 Ok(())
34471 }
34472
34473 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
34474 self.write_keyword("SAFE_DIVIDE");
34476 self.write("(");
34477 self.generate_expression(&e.this)?;
34478 self.write(", ");
34479 self.generate_expression(&e.expression)?;
34480 self.write(")");
34481 Ok(())
34482 }
34483
34484 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
34485 let name = if matches!(
34486 self.config.dialect,
34487 Some(crate::dialects::DialectType::Spark)
34488 | Some(crate::dialects::DialectType::Databricks)
34489 ) {
34490 "TRY_MULTIPLY"
34491 } else {
34492 "SAFE_MULTIPLY"
34493 };
34494 self.write_keyword(name);
34495 self.write("(");
34496 self.generate_expression(&e.this)?;
34497 self.write(", ");
34498 self.generate_expression(&e.expression)?;
34499 self.write(")");
34500 Ok(())
34501 }
34502
34503 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
34504 let name = if matches!(
34505 self.config.dialect,
34506 Some(crate::dialects::DialectType::Spark)
34507 | Some(crate::dialects::DialectType::Databricks)
34508 ) {
34509 "TRY_SUBTRACT"
34510 } else {
34511 "SAFE_SUBTRACT"
34512 };
34513 self.write_keyword(name);
34514 self.write("(");
34515 self.generate_expression(&e.this)?;
34516 self.write(", ");
34517 self.generate_expression(&e.expression)?;
34518 self.write(")");
34519 Ok(())
34520 }
34521
34522 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
34525 if matches!(sample.method, SampleMethod::Bucket) {
34527 self.write(" (");
34528 self.write_keyword("BUCKET");
34529 self.write_space();
34530 if let Some(ref num) = sample.bucket_numerator {
34531 self.generate_expression(num)?;
34532 }
34533 self.write_space();
34534 self.write_keyword("OUT OF");
34535 self.write_space();
34536 if let Some(ref denom) = sample.bucket_denominator {
34537 self.generate_expression(denom)?;
34538 }
34539 if let Some(ref field) = sample.bucket_field {
34540 self.write_space();
34541 self.write_keyword("ON");
34542 self.write_space();
34543 self.generate_expression(field)?;
34544 }
34545 self.write(")");
34546 return Ok(());
34547 }
34548
34549 let is_snowflake = matches!(
34551 self.config.dialect,
34552 Some(crate::dialects::DialectType::Snowflake)
34553 );
34554 let is_postgres = matches!(
34555 self.config.dialect,
34556 Some(crate::dialects::DialectType::PostgreSQL)
34557 | Some(crate::dialects::DialectType::Redshift)
34558 );
34559 let is_databricks = matches!(
34561 self.config.dialect,
34562 Some(crate::dialects::DialectType::Databricks)
34563 );
34564 let is_spark = matches!(
34565 self.config.dialect,
34566 Some(crate::dialects::DialectType::Spark)
34567 );
34568 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
34569 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
34571 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
34572 self.write_space();
34573 if !sample.explicit_method && (is_snowflake || force_method) {
34574 self.write_keyword("BERNOULLI");
34576 } else {
34577 match sample.method {
34578 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
34579 SampleMethod::System => self.write_keyword("SYSTEM"),
34580 SampleMethod::Block => self.write_keyword("BLOCK"),
34581 SampleMethod::Row => self.write_keyword("ROW"),
34582 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
34583 SampleMethod::Percent => self.write_keyword("SYSTEM"),
34584 SampleMethod::Bucket => {} }
34586 }
34587 }
34588
34589 let emit_size_no_parens = !self.config.tablesample_requires_parens;
34591 if emit_size_no_parens {
34592 self.write_space();
34593 match &sample.size {
34594 Expression::Tuple(tuple) => {
34595 for (i, expr) in tuple.expressions.iter().enumerate() {
34596 if i > 0 {
34597 self.write(", ");
34598 }
34599 self.generate_expression(expr)?;
34600 }
34601 }
34602 expr => self.generate_expression(expr)?,
34603 }
34604 } else {
34605 self.write(" (");
34606 self.generate_expression(&sample.size)?;
34607 }
34608
34609 let is_rows_method = matches!(
34611 sample.method,
34612 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
34613 );
34614 let is_percent = matches!(
34615 sample.method,
34616 SampleMethod::Percent
34617 | SampleMethod::System
34618 | SampleMethod::Bernoulli
34619 | SampleMethod::Block
34620 );
34621
34622 let is_presto = matches!(
34626 self.config.dialect,
34627 Some(crate::dialects::DialectType::Presto)
34628 | Some(crate::dialects::DialectType::Trino)
34629 | Some(crate::dialects::DialectType::Athena)
34630 );
34631 let should_output_unit = if is_databricks || is_spark {
34632 is_percent || is_rows_method || sample.unit_after_size
34634 } else if is_snowflake || is_postgres || is_presto {
34635 sample.unit_after_size
34636 } else {
34637 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
34638 };
34639
34640 if should_output_unit {
34641 self.write_space();
34642 if sample.is_percent {
34643 self.write_keyword("PERCENT");
34644 } else if is_rows_method && !sample.unit_after_size {
34645 self.write_keyword("ROWS");
34646 } else if sample.unit_after_size {
34647 match sample.method {
34648 SampleMethod::Percent
34649 | SampleMethod::System
34650 | SampleMethod::Bernoulli
34651 | SampleMethod::Block => {
34652 self.write_keyword("PERCENT");
34653 }
34654 SampleMethod::Row | SampleMethod::Reservoir => {
34655 self.write_keyword("ROWS");
34656 }
34657 _ => self.write_keyword("ROWS"),
34658 }
34659 } else {
34660 self.write_keyword("PERCENT");
34661 }
34662 }
34663
34664 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34665 if let Some(ref offset) = sample.offset {
34666 self.write_space();
34667 self.write_keyword("OFFSET");
34668 self.write_space();
34669 self.generate_expression(offset)?;
34670 }
34671 }
34672 if !emit_size_no_parens {
34673 self.write(")");
34674 }
34675
34676 Ok(())
34677 }
34678
34679 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
34680 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34682 self.write_keyword("SAMPLE BY");
34683 } else {
34684 self.write_keyword("SAMPLE");
34685 }
34686 self.write_space();
34687 self.generate_expression(&e.this)?;
34688 Ok(())
34689 }
34690
34691 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
34692 if let Some(this) = &e.this {
34694 self.generate_expression(this)?;
34695 }
34696 if !e.expressions.is_empty() {
34697 if e.this.is_some() {
34699 self.write_space();
34700 }
34701 self.write("(");
34702 for (i, expr) in e.expressions.iter().enumerate() {
34703 if i > 0 {
34704 self.write(", ");
34705 }
34706 self.generate_expression(expr)?;
34707 }
34708 self.write(")");
34709 }
34710 Ok(())
34711 }
34712
34713 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
34714 self.write_keyword("COMMENT");
34716 self.write_space();
34717 self.generate_expression(&e.this)?;
34718 Ok(())
34719 }
34720
34721 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
34722 if let Some(this) = &e.this {
34724 self.generate_expression(this)?;
34725 self.write("::");
34726 }
34727 self.generate_expression(&e.expression)?;
34728 Ok(())
34729 }
34730
34731 fn generate_search(&mut self, e: &Search) -> Result<()> {
34732 self.write_keyword("SEARCH");
34734 self.write("(");
34735 self.generate_expression(&e.this)?;
34736 self.write(", ");
34737 self.generate_expression(&e.expression)?;
34738 if let Some(json_scope) = &e.json_scope {
34739 self.write(", ");
34740 self.generate_expression(json_scope)?;
34741 }
34742 if let Some(analyzer) = &e.analyzer {
34743 self.write(", ");
34744 self.generate_expression(analyzer)?;
34745 }
34746 if let Some(analyzer_options) = &e.analyzer_options {
34747 self.write(", ");
34748 self.generate_expression(analyzer_options)?;
34749 }
34750 if let Some(search_mode) = &e.search_mode {
34751 self.write(", ");
34752 self.generate_expression(search_mode)?;
34753 }
34754 self.write(")");
34755 Ok(())
34756 }
34757
34758 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
34759 self.write_keyword("SEARCH_IP");
34761 self.write("(");
34762 self.generate_expression(&e.this)?;
34763 self.write(", ");
34764 self.generate_expression(&e.expression)?;
34765 self.write(")");
34766 Ok(())
34767 }
34768
34769 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
34770 self.write_keyword("SECURITY");
34772 self.write_space();
34773 self.generate_expression(&e.this)?;
34774 Ok(())
34775 }
34776
34777 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
34778 self.write("SEMANTIC_VIEW(");
34780
34781 if self.config.pretty {
34782 self.write_newline();
34784 self.indent_level += 1;
34785 self.write_indent();
34786 self.generate_expression(&e.this)?;
34787
34788 if let Some(metrics) = &e.metrics {
34789 self.write_newline();
34790 self.write_indent();
34791 self.write_keyword("METRICS");
34792 self.write_space();
34793 self.generate_semantic_view_tuple(metrics)?;
34794 }
34795 if let Some(dimensions) = &e.dimensions {
34796 self.write_newline();
34797 self.write_indent();
34798 self.write_keyword("DIMENSIONS");
34799 self.write_space();
34800 self.generate_semantic_view_tuple(dimensions)?;
34801 }
34802 if let Some(facts) = &e.facts {
34803 self.write_newline();
34804 self.write_indent();
34805 self.write_keyword("FACTS");
34806 self.write_space();
34807 self.generate_semantic_view_tuple(facts)?;
34808 }
34809 if let Some(where_) = &e.where_ {
34810 self.write_newline();
34811 self.write_indent();
34812 self.write_keyword("WHERE");
34813 self.write_space();
34814 self.generate_expression(where_)?;
34815 }
34816 self.write_newline();
34817 self.indent_level -= 1;
34818 self.write_indent();
34819 } else {
34820 self.generate_expression(&e.this)?;
34822 if let Some(metrics) = &e.metrics {
34823 self.write_space();
34824 self.write_keyword("METRICS");
34825 self.write_space();
34826 self.generate_semantic_view_tuple(metrics)?;
34827 }
34828 if let Some(dimensions) = &e.dimensions {
34829 self.write_space();
34830 self.write_keyword("DIMENSIONS");
34831 self.write_space();
34832 self.generate_semantic_view_tuple(dimensions)?;
34833 }
34834 if let Some(facts) = &e.facts {
34835 self.write_space();
34836 self.write_keyword("FACTS");
34837 self.write_space();
34838 self.generate_semantic_view_tuple(facts)?;
34839 }
34840 if let Some(where_) = &e.where_ {
34841 self.write_space();
34842 self.write_keyword("WHERE");
34843 self.write_space();
34844 self.generate_expression(where_)?;
34845 }
34846 }
34847 self.write(")");
34848 Ok(())
34849 }
34850
34851 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
34853 if let Expression::Tuple(t) = expr {
34854 for (i, e) in t.expressions.iter().enumerate() {
34855 if i > 0 {
34856 self.write(", ");
34857 }
34858 self.generate_expression(e)?;
34859 }
34860 } else {
34861 self.generate_expression(expr)?;
34862 }
34863 Ok(())
34864 }
34865
34866 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
34867 if let Some(start) = &e.start {
34869 self.write_keyword("START WITH");
34870 self.write_space();
34871 self.generate_expression(start)?;
34872 }
34873 if let Some(increment) = &e.increment {
34874 self.write_space();
34875 self.write_keyword("INCREMENT BY");
34876 self.write_space();
34877 self.generate_expression(increment)?;
34878 }
34879 if let Some(minvalue) = &e.minvalue {
34880 self.write_space();
34881 self.write_keyword("MINVALUE");
34882 self.write_space();
34883 self.generate_expression(minvalue)?;
34884 }
34885 if let Some(maxvalue) = &e.maxvalue {
34886 self.write_space();
34887 self.write_keyword("MAXVALUE");
34888 self.write_space();
34889 self.generate_expression(maxvalue)?;
34890 }
34891 if let Some(cache) = &e.cache {
34892 self.write_space();
34893 self.write_keyword("CACHE");
34894 self.write_space();
34895 self.generate_expression(cache)?;
34896 }
34897 if let Some(owned) = &e.owned {
34898 self.write_space();
34899 self.write_keyword("OWNED BY");
34900 self.write_space();
34901 self.generate_expression(owned)?;
34902 }
34903 for opt in &e.options {
34904 self.write_space();
34905 self.generate_expression(opt)?;
34906 }
34907 Ok(())
34908 }
34909
34910 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
34911 if e.with_.is_some() {
34913 self.write_keyword("WITH");
34914 self.write_space();
34915 }
34916 self.write_keyword("SERDEPROPERTIES");
34917 self.write(" (");
34918 for (i, expr) in e.expressions.iter().enumerate() {
34919 if i > 0 {
34920 self.write(", ");
34921 }
34922 match expr {
34924 Expression::Eq(eq) => {
34925 self.generate_expression(&eq.left)?;
34926 self.write("=");
34927 self.generate_expression(&eq.right)?;
34928 }
34929 _ => self.generate_expression(expr)?,
34930 }
34931 }
34932 self.write(")");
34933 Ok(())
34934 }
34935
34936 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
34937 self.write("@@");
34939 if let Some(kind) = &e.kind {
34940 self.write(kind);
34941 self.write(".");
34942 }
34943 self.generate_expression(&e.this)?;
34944 Ok(())
34945 }
34946
34947 fn generate_set(&mut self, e: &Set) -> Result<()> {
34948 if e.unset.is_some() {
34950 self.write_keyword("UNSET");
34951 } else {
34952 self.write_keyword("SET");
34953 }
34954 if e.tag.is_some() {
34955 self.write_space();
34956 self.write_keyword("TAG");
34957 }
34958 if !e.expressions.is_empty() {
34959 self.write_space();
34960 for (i, expr) in e.expressions.iter().enumerate() {
34961 if i > 0 {
34962 self.write(", ");
34963 }
34964 self.generate_expression(expr)?;
34965 }
34966 }
34967 Ok(())
34968 }
34969
34970 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
34971 self.write_keyword("SET");
34973 self.write_space();
34974 self.generate_expression(&e.this)?;
34975 Ok(())
34976 }
34977
34978 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
34979 if let Some(kind) = &e.kind {
34981 self.write_keyword(kind);
34982 self.write_space();
34983 }
34984 self.generate_expression(&e.name)?;
34985 self.write(" = ");
34986 self.generate_expression(&e.value)?;
34987 Ok(())
34988 }
34989
34990 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
34991 if let Some(with_) = &e.with_ {
34993 self.generate_expression(with_)?;
34994 self.write_space();
34995 }
34996 self.generate_expression(&e.this)?;
34997 self.write_space();
34998 if let Some(kind) = &e.kind {
35000 self.write_keyword(kind);
35001 }
35002 if e.distinct {
35003 self.write_space();
35004 self.write_keyword("DISTINCT");
35005 } else {
35006 self.write_space();
35007 self.write_keyword("ALL");
35008 }
35009 if e.by_name.is_some() {
35010 self.write_space();
35011 self.write_keyword("BY NAME");
35012 }
35013 self.write_space();
35014 self.generate_expression(&e.expression)?;
35015 Ok(())
35016 }
35017
35018 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
35019 if e.multi.is_some() {
35021 self.write_keyword("MULTISET");
35022 } else {
35023 self.write_keyword("SET");
35024 }
35025 Ok(())
35026 }
35027
35028 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
35029 self.write_keyword("SETTINGS");
35031 if self.config.pretty && e.expressions.len() > 1 {
35032 self.indent_level += 1;
35034 for (i, expr) in e.expressions.iter().enumerate() {
35035 if i > 0 {
35036 self.write(",");
35037 }
35038 self.write_newline();
35039 self.write_indent();
35040 self.generate_expression(expr)?;
35041 }
35042 self.indent_level -= 1;
35043 } else {
35044 self.write_space();
35045 for (i, expr) in e.expressions.iter().enumerate() {
35046 if i > 0 {
35047 self.write(", ");
35048 }
35049 self.generate_expression(expr)?;
35050 }
35051 }
35052 Ok(())
35053 }
35054
35055 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
35056 self.write_keyword("SHARING");
35058 if let Some(this) = &e.this {
35059 self.write(" = ");
35060 self.generate_expression(this)?;
35061 }
35062 Ok(())
35063 }
35064
35065 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
35066 if let Some(begin) = &e.this {
35068 self.generate_expression(begin)?;
35069 }
35070 self.write(":");
35071 if let Some(end) = &e.expression {
35072 self.generate_expression(end)?;
35073 }
35074 if let Some(step) = &e.step {
35075 self.write(":");
35076 self.generate_expression(step)?;
35077 }
35078 Ok(())
35079 }
35080
35081 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
35082 self.write_keyword("SORT_ARRAY");
35084 self.write("(");
35085 self.generate_expression(&e.this)?;
35086 if let Some(asc) = &e.asc {
35087 self.write(", ");
35088 self.generate_expression(asc)?;
35089 }
35090 self.write(")");
35091 Ok(())
35092 }
35093
35094 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
35095 self.write_keyword("SORT BY");
35097 self.write_space();
35098 for (i, expr) in e.expressions.iter().enumerate() {
35099 if i > 0 {
35100 self.write(", ");
35101 }
35102 self.generate_ordered(expr)?;
35103 }
35104 Ok(())
35105 }
35106
35107 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
35108 if e.compound.is_some() {
35110 self.write_keyword("COMPOUND");
35111 self.write_space();
35112 }
35113 self.write_keyword("SORTKEY");
35114 self.write("(");
35115 if let Expression::Tuple(t) = e.this.as_ref() {
35117 for (i, expr) in t.expressions.iter().enumerate() {
35118 if i > 0 {
35119 self.write(", ");
35120 }
35121 self.generate_expression(expr)?;
35122 }
35123 } else {
35124 self.generate_expression(&e.this)?;
35125 }
35126 self.write(")");
35127 Ok(())
35128 }
35129
35130 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
35131 self.write_keyword("SPLIT_PART");
35133 self.write("(");
35134 self.generate_expression(&e.this)?;
35135 if let Some(delimiter) = &e.delimiter {
35136 self.write(", ");
35137 self.generate_expression(delimiter)?;
35138 }
35139 if let Some(part_index) = &e.part_index {
35140 self.write(", ");
35141 self.generate_expression(part_index)?;
35142 }
35143 self.write(")");
35144 Ok(())
35145 }
35146
35147 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
35148 self.generate_expression(&e.this)?;
35150 Ok(())
35151 }
35152
35153 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
35154 self.write_keyword("SQL SECURITY");
35156 self.write_space();
35157 self.generate_expression(&e.this)?;
35158 Ok(())
35159 }
35160
35161 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
35162 self.write_keyword("ST_DISTANCE");
35164 self.write("(");
35165 self.generate_expression(&e.this)?;
35166 self.write(", ");
35167 self.generate_expression(&e.expression)?;
35168 if let Some(use_spheroid) = &e.use_spheroid {
35169 self.write(", ");
35170 self.generate_expression(use_spheroid)?;
35171 }
35172 self.write(")");
35173 Ok(())
35174 }
35175
35176 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
35177 self.write_keyword("ST_POINT");
35179 self.write("(");
35180 self.generate_expression(&e.this)?;
35181 self.write(", ");
35182 self.generate_expression(&e.expression)?;
35183 self.write(")");
35184 Ok(())
35185 }
35186
35187 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
35188 self.generate_expression(&e.this)?;
35190 Ok(())
35191 }
35192
35193 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
35194 self.write_keyword("STANDARD_HASH");
35196 self.write("(");
35197 self.generate_expression(&e.this)?;
35198 if let Some(expression) = &e.expression {
35199 self.write(", ");
35200 self.generate_expression(expression)?;
35201 }
35202 self.write(")");
35203 Ok(())
35204 }
35205
35206 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
35207 self.write_keyword("STORED BY");
35209 self.write_space();
35210 self.generate_expression(&e.this)?;
35211 Ok(())
35212 }
35213
35214 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
35215 use crate::dialects::DialectType;
35218 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35219 self.write_keyword("CHARINDEX");
35221 self.write("(");
35222 if let Some(substr) = &e.substr {
35223 self.generate_expression(substr)?;
35224 self.write(", ");
35225 }
35226 self.generate_expression(&e.this)?;
35227 if let Some(position) = &e.position {
35228 self.write(", ");
35229 self.generate_expression(position)?;
35230 }
35231 self.write(")");
35232 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
35233 self.write_keyword("POSITION");
35234 self.write("(");
35235 self.generate_expression(&e.this)?;
35236 if let Some(substr) = &e.substr {
35237 self.write(", ");
35238 self.generate_expression(substr)?;
35239 }
35240 if let Some(position) = &e.position {
35241 self.write(", ");
35242 self.generate_expression(position)?;
35243 }
35244 if let Some(occurrence) = &e.occurrence {
35245 self.write(", ");
35246 self.generate_expression(occurrence)?;
35247 }
35248 self.write(")");
35249 } else if matches!(
35250 self.config.dialect,
35251 Some(DialectType::SQLite)
35252 | Some(DialectType::Oracle)
35253 | Some(DialectType::BigQuery)
35254 | Some(DialectType::Teradata)
35255 ) {
35256 self.write_keyword("INSTR");
35257 self.write("(");
35258 self.generate_expression(&e.this)?;
35259 if let Some(substr) = &e.substr {
35260 self.write(", ");
35261 self.generate_expression(substr)?;
35262 }
35263 if let Some(position) = &e.position {
35264 self.write(", ");
35265 self.generate_expression(position)?;
35266 } else if e.occurrence.is_some() {
35267 self.write(", 1");
35270 }
35271 if let Some(occurrence) = &e.occurrence {
35272 self.write(", ");
35273 self.generate_expression(occurrence)?;
35274 }
35275 self.write(")");
35276 } else if matches!(
35277 self.config.dialect,
35278 Some(DialectType::MySQL)
35279 | Some(DialectType::SingleStore)
35280 | Some(DialectType::Doris)
35281 | Some(DialectType::StarRocks)
35282 | Some(DialectType::Hive)
35283 | Some(DialectType::Spark)
35284 | Some(DialectType::Databricks)
35285 ) {
35286 self.write_keyword("LOCATE");
35288 self.write("(");
35289 if let Some(substr) = &e.substr {
35290 self.generate_expression(substr)?;
35291 self.write(", ");
35292 }
35293 self.generate_expression(&e.this)?;
35294 if let Some(position) = &e.position {
35295 self.write(", ");
35296 self.generate_expression(position)?;
35297 }
35298 self.write(")");
35299 } else if matches!(
35300 self.config.dialect,
35301 Some(DialectType::TSQL) | Some(DialectType::Fabric)
35302 ) {
35303 self.write_keyword("CHARINDEX");
35305 self.write("(");
35306 if let Some(substr) = &e.substr {
35307 self.generate_expression(substr)?;
35308 self.write(", ");
35309 }
35310 self.generate_expression(&e.this)?;
35311 if let Some(position) = &e.position {
35312 self.write(", ");
35313 self.generate_expression(position)?;
35314 }
35315 self.write(")");
35316 } else if matches!(
35317 self.config.dialect,
35318 Some(DialectType::PostgreSQL)
35319 | Some(DialectType::Materialize)
35320 | Some(DialectType::RisingWave)
35321 | Some(DialectType::Redshift)
35322 ) {
35323 self.write_keyword("POSITION");
35325 self.write("(");
35326 if let Some(substr) = &e.substr {
35327 self.generate_expression(substr)?;
35328 self.write(" IN ");
35329 }
35330 self.generate_expression(&e.this)?;
35331 self.write(")");
35332 } else {
35333 self.write_keyword("STRPOS");
35334 self.write("(");
35335 self.generate_expression(&e.this)?;
35336 if let Some(substr) = &e.substr {
35337 self.write(", ");
35338 self.generate_expression(substr)?;
35339 }
35340 if let Some(position) = &e.position {
35341 self.write(", ");
35342 self.generate_expression(position)?;
35343 }
35344 if let Some(occurrence) = &e.occurrence {
35345 self.write(", ");
35346 self.generate_expression(occurrence)?;
35347 }
35348 self.write(")");
35349 }
35350 Ok(())
35351 }
35352
35353 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
35354 match self.config.dialect {
35355 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
35356 self.write_keyword("TO_DATE");
35358 self.write("(");
35359 self.generate_expression(&e.this)?;
35360 if let Some(format) = &e.format {
35361 self.write(", '");
35362 self.write(&Self::strftime_to_java_format(format));
35363 self.write("'");
35364 }
35365 self.write(")");
35366 }
35367 Some(DialectType::DuckDB) => {
35368 self.write_keyword("CAST");
35370 self.write("(");
35371 self.write_keyword("STRPTIME");
35372 self.write("(");
35373 self.generate_expression(&e.this)?;
35374 if let Some(format) = &e.format {
35375 self.write(", '");
35376 self.write(format);
35377 self.write("'");
35378 }
35379 self.write(")");
35380 self.write_keyword(" AS ");
35381 self.write_keyword("DATE");
35382 self.write(")");
35383 }
35384 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
35385 self.write_keyword("TO_DATE");
35387 self.write("(");
35388 self.generate_expression(&e.this)?;
35389 if let Some(format) = &e.format {
35390 self.write(", '");
35391 self.write(&Self::strftime_to_postgres_format(format));
35392 self.write("'");
35393 }
35394 self.write(")");
35395 }
35396 Some(DialectType::BigQuery) => {
35397 self.write_keyword("PARSE_DATE");
35399 self.write("(");
35400 if let Some(format) = &e.format {
35401 self.write("'");
35402 self.write(format);
35403 self.write("'");
35404 self.write(", ");
35405 }
35406 self.generate_expression(&e.this)?;
35407 self.write(")");
35408 }
35409 Some(DialectType::Teradata) => {
35410 self.write_keyword("CAST");
35412 self.write("(");
35413 self.generate_expression(&e.this)?;
35414 self.write_keyword(" AS ");
35415 self.write_keyword("DATE");
35416 if let Some(format) = &e.format {
35417 self.write_keyword(" FORMAT ");
35418 self.write("'");
35419 self.write(&Self::strftime_to_teradata_format(format));
35420 self.write("'");
35421 }
35422 self.write(")");
35423 }
35424 _ => {
35425 self.write_keyword("STR_TO_DATE");
35427 self.write("(");
35428 self.generate_expression(&e.this)?;
35429 if let Some(format) = &e.format {
35430 self.write(", '");
35431 self.write(format);
35432 self.write("'");
35433 }
35434 self.write(")");
35435 }
35436 }
35437 Ok(())
35438 }
35439
35440 fn strftime_to_teradata_format(fmt: &str) -> String {
35442 let mut result = String::with_capacity(fmt.len() * 2);
35443 let bytes = fmt.as_bytes();
35444 let len = bytes.len();
35445 let mut i = 0;
35446 while i < len {
35447 if bytes[i] == b'%' && i + 1 < len {
35448 let replacement = match bytes[i + 1] {
35449 b'Y' => "YYYY",
35450 b'y' => "YY",
35451 b'm' => "MM",
35452 b'B' => "MMMM",
35453 b'b' => "MMM",
35454 b'd' => "DD",
35455 b'j' => "DDD",
35456 b'H' => "HH",
35457 b'M' => "MI",
35458 b'S' => "SS",
35459 b'f' => "SSSSSS",
35460 b'A' => "EEEE",
35461 b'a' => "EEE",
35462 _ => {
35463 result.push('%');
35464 i += 1;
35465 continue;
35466 }
35467 };
35468 result.push_str(replacement);
35469 i += 2;
35470 } else {
35471 result.push(bytes[i] as char);
35472 i += 1;
35473 }
35474 }
35475 result
35476 }
35477
35478 pub fn strftime_to_java_format_static(fmt: &str) -> String {
35481 Self::strftime_to_java_format(fmt)
35482 }
35483
35484 fn strftime_to_java_format(fmt: &str) -> String {
35486 let mut result = String::with_capacity(fmt.len() * 2);
35487 let bytes = fmt.as_bytes();
35488 let len = bytes.len();
35489 let mut i = 0;
35490 while i < len {
35491 if bytes[i] == b'%' && i + 1 < len {
35492 if bytes[i + 1] == b'-' && i + 2 < len {
35494 let replacement = match bytes[i + 2] {
35495 b'd' => "d",
35496 b'm' => "M",
35497 b'H' => "H",
35498 b'M' => "m",
35499 b'S' => "s",
35500 _ => {
35501 result.push('%');
35502 i += 1;
35503 continue;
35504 }
35505 };
35506 result.push_str(replacement);
35507 i += 3;
35508 } else {
35509 let replacement = match bytes[i + 1] {
35510 b'Y' => "yyyy",
35511 b'y' => "yy",
35512 b'm' => "MM",
35513 b'B' => "MMMM",
35514 b'b' => "MMM",
35515 b'd' => "dd",
35516 b'j' => "DDD",
35517 b'H' => "HH",
35518 b'M' => "mm",
35519 b'S' => "ss",
35520 b'f' => "SSSSSS",
35521 b'A' => "EEEE",
35522 b'a' => "EEE",
35523 _ => {
35524 result.push('%');
35525 i += 1;
35526 continue;
35527 }
35528 };
35529 result.push_str(replacement);
35530 i += 2;
35531 }
35532 } else {
35533 result.push(bytes[i] as char);
35534 i += 1;
35535 }
35536 }
35537 result
35538 }
35539
35540 fn strftime_to_tsql_format(fmt: &str) -> String {
35543 let mut result = String::with_capacity(fmt.len() * 2);
35544 let bytes = fmt.as_bytes();
35545 let len = bytes.len();
35546 let mut i = 0;
35547 while i < len {
35548 if bytes[i] == b'%' && i + 1 < len {
35549 if bytes[i + 1] == b'-' && i + 2 < len {
35551 let replacement = match bytes[i + 2] {
35552 b'd' => "d",
35553 b'm' => "M",
35554 b'H' => "H",
35555 b'M' => "m",
35556 b'S' => "s",
35557 _ => {
35558 result.push('%');
35559 i += 1;
35560 continue;
35561 }
35562 };
35563 result.push_str(replacement);
35564 i += 3;
35565 } else {
35566 let replacement = match bytes[i + 1] {
35567 b'Y' => "yyyy",
35568 b'y' => "yy",
35569 b'm' => "MM",
35570 b'B' => "MMMM",
35571 b'b' => "MMM",
35572 b'd' => "dd",
35573 b'j' => "DDD",
35574 b'H' => "HH",
35575 b'M' => "mm",
35576 b'S' => "ss",
35577 b'f' => "ffffff",
35578 b'A' => "dddd",
35579 b'a' => "ddd",
35580 _ => {
35581 result.push('%');
35582 i += 1;
35583 continue;
35584 }
35585 };
35586 result.push_str(replacement);
35587 i += 2;
35588 }
35589 } else {
35590 result.push(bytes[i] as char);
35591 i += 1;
35592 }
35593 }
35594 result
35595 }
35596
35597 fn decompose_json_path(path: &str) -> Vec<String> {
35600 let mut parts = Vec::new();
35601 let path = if path.starts_with("$.") {
35603 &path[2..]
35604 } else if path.starts_with('$') {
35605 &path[1..]
35606 } else {
35607 path
35608 };
35609 if path.is_empty() {
35610 return parts;
35611 }
35612 let mut current = String::new();
35613 let chars: Vec<char> = path.chars().collect();
35614 let mut i = 0;
35615 while i < chars.len() {
35616 match chars[i] {
35617 '.' => {
35618 if !current.is_empty() {
35619 parts.push(current.clone());
35620 current.clear();
35621 }
35622 i += 1;
35623 }
35624 '[' => {
35625 if !current.is_empty() {
35626 parts.push(current.clone());
35627 current.clear();
35628 }
35629 i += 1;
35630 let mut bracket_content = String::new();
35632 while i < chars.len() && chars[i] != ']' {
35633 if chars[i] == '"' || chars[i] == '\'' {
35635 let quote = chars[i];
35636 i += 1;
35637 while i < chars.len() && chars[i] != quote {
35638 bracket_content.push(chars[i]);
35639 i += 1;
35640 }
35641 if i < chars.len() {
35642 i += 1;
35643 } } else {
35645 bracket_content.push(chars[i]);
35646 i += 1;
35647 }
35648 }
35649 if i < chars.len() {
35650 i += 1;
35651 } if bracket_content != "*" {
35654 parts.push(bracket_content);
35655 }
35656 }
35657 _ => {
35658 current.push(chars[i]);
35659 i += 1;
35660 }
35661 }
35662 }
35663 if !current.is_empty() {
35664 parts.push(current);
35665 }
35666 parts
35667 }
35668
35669 fn strftime_to_postgres_format(fmt: &str) -> String {
35671 let mut result = String::with_capacity(fmt.len() * 2);
35672 let bytes = fmt.as_bytes();
35673 let len = bytes.len();
35674 let mut i = 0;
35675 while i < len {
35676 if bytes[i] == b'%' && i + 1 < len {
35677 if bytes[i + 1] == b'-' && i + 2 < len {
35679 let replacement = match bytes[i + 2] {
35680 b'd' => "FMDD",
35681 b'm' => "FMMM",
35682 b'H' => "FMHH24",
35683 b'M' => "FMMI",
35684 b'S' => "FMSS",
35685 _ => {
35686 result.push('%');
35687 i += 1;
35688 continue;
35689 }
35690 };
35691 result.push_str(replacement);
35692 i += 3;
35693 } else {
35694 let replacement = match bytes[i + 1] {
35695 b'Y' => "YYYY",
35696 b'y' => "YY",
35697 b'm' => "MM",
35698 b'B' => "Month",
35699 b'b' => "Mon",
35700 b'd' => "DD",
35701 b'j' => "DDD",
35702 b'H' => "HH24",
35703 b'M' => "MI",
35704 b'S' => "SS",
35705 b'f' => "US",
35706 b'A' => "Day",
35707 b'a' => "Dy",
35708 _ => {
35709 result.push('%');
35710 i += 1;
35711 continue;
35712 }
35713 };
35714 result.push_str(replacement);
35715 i += 2;
35716 }
35717 } else {
35718 result.push(bytes[i] as char);
35719 i += 1;
35720 }
35721 }
35722 result
35723 }
35724
35725 fn strftime_to_snowflake_format(fmt: &str) -> String {
35727 let mut result = String::with_capacity(fmt.len() * 2);
35728 let bytes = fmt.as_bytes();
35729 let len = bytes.len();
35730 let mut i = 0;
35731 while i < len {
35732 if bytes[i] == b'%' && i + 1 < len {
35733 if bytes[i + 1] == b'-' && i + 2 < len {
35735 let replacement = match bytes[i + 2] {
35736 b'd' => "dd",
35737 b'm' => "mm",
35738 _ => {
35739 result.push('%');
35740 i += 1;
35741 continue;
35742 }
35743 };
35744 result.push_str(replacement);
35745 i += 3;
35746 } else {
35747 let replacement = match bytes[i + 1] {
35748 b'Y' => "yyyy",
35749 b'y' => "yy",
35750 b'm' => "mm",
35751 b'd' => "DD",
35752 b'H' => "hh24",
35753 b'M' => "mi",
35754 b'S' => "ss",
35755 b'f' => "ff",
35756 _ => {
35757 result.push('%');
35758 i += 1;
35759 continue;
35760 }
35761 };
35762 result.push_str(replacement);
35763 i += 2;
35764 }
35765 } else {
35766 result.push(bytes[i] as char);
35767 i += 1;
35768 }
35769 }
35770 result
35771 }
35772
35773 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
35774 self.write_keyword("STR_TO_MAP");
35776 self.write("(");
35777 self.generate_expression(&e.this)?;
35778 let needs_defaults = matches!(
35780 self.config.dialect,
35781 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
35782 );
35783 if let Some(pair_delim) = &e.pair_delim {
35784 self.write(", ");
35785 self.generate_expression(pair_delim)?;
35786 } else if needs_defaults {
35787 self.write(", ','");
35788 }
35789 if let Some(key_value_delim) = &e.key_value_delim {
35790 self.write(", ");
35791 self.generate_expression(key_value_delim)?;
35792 } else if needs_defaults {
35793 self.write(", ':'");
35794 }
35795 self.write(")");
35796 Ok(())
35797 }
35798
35799 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
35800 let is_strftime = e.format.contains('%');
35802 let to_strftime = |f: &str| -> String {
35804 if is_strftime {
35805 f.to_string()
35806 } else {
35807 Self::snowflake_format_to_strftime(f)
35808 }
35809 };
35810 let to_java = |f: &str| -> String {
35812 if is_strftime {
35813 Self::strftime_to_java_format(f)
35814 } else {
35815 Self::snowflake_format_to_spark(f)
35816 }
35817 };
35818 let to_pg = |f: &str| -> String {
35820 if is_strftime {
35821 Self::strftime_to_postgres_format(f)
35822 } else {
35823 Self::convert_strptime_to_postgres_format(f)
35824 }
35825 };
35826
35827 match self.config.dialect {
35828 Some(DialectType::Exasol) => {
35829 self.write_keyword("TO_DATE");
35830 self.write("(");
35831 self.generate_expression(&e.this)?;
35832 self.write(", '");
35833 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35834 self.write("'");
35835 self.write(")");
35836 }
35837 Some(DialectType::BigQuery) => {
35838 let fmt = to_strftime(&e.format);
35840 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35842 self.write_keyword("PARSE_TIMESTAMP");
35843 self.write("('");
35844 self.write(&fmt);
35845 self.write("', ");
35846 self.generate_expression(&e.this)?;
35847 self.write(")");
35848 }
35849 Some(DialectType::Hive) => {
35850 let java_fmt = to_java(&e.format);
35853 if java_fmt == "yyyy-MM-dd HH:mm:ss"
35854 || java_fmt == "yyyy-MM-dd"
35855 || e.format == "yyyy-MM-dd HH:mm:ss"
35856 || e.format == "yyyy-MM-dd"
35857 {
35858 self.write_keyword("CAST");
35859 self.write("(");
35860 self.generate_expression(&e.this)?;
35861 self.write(" ");
35862 self.write_keyword("AS TIMESTAMP");
35863 self.write(")");
35864 } else {
35865 self.write_keyword("CAST");
35867 self.write("(");
35868 self.write_keyword("FROM_UNIXTIME");
35869 self.write("(");
35870 self.write_keyword("UNIX_TIMESTAMP");
35871 self.write("(");
35872 self.generate_expression(&e.this)?;
35873 self.write(", '");
35874 self.write(&java_fmt);
35875 self.write("')");
35876 self.write(") ");
35877 self.write_keyword("AS TIMESTAMP");
35878 self.write(")");
35879 }
35880 }
35881 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35882 let java_fmt = to_java(&e.format);
35884 self.write_keyword("TO_TIMESTAMP");
35885 self.write("(");
35886 self.generate_expression(&e.this)?;
35887 self.write(", '");
35888 self.write(&java_fmt);
35889 self.write("')");
35890 }
35891 Some(DialectType::MySQL) => {
35892 let mut fmt = to_strftime(&e.format);
35894 fmt = fmt.replace("%-d", "%e");
35896 fmt = fmt.replace("%-m", "%c");
35897 fmt = fmt.replace("%H:%M:%S", "%T");
35898 self.write_keyword("STR_TO_DATE");
35899 self.write("(");
35900 self.generate_expression(&e.this)?;
35901 self.write(", '");
35902 self.write(&fmt);
35903 self.write("')");
35904 }
35905 Some(DialectType::Drill) => {
35906 let java_fmt = to_java(&e.format);
35908 let java_fmt = java_fmt.replace('T', "''T''");
35910 self.write_keyword("TO_TIMESTAMP");
35911 self.write("(");
35912 self.generate_expression(&e.this)?;
35913 self.write(", '");
35914 self.write(&java_fmt);
35915 self.write("')");
35916 }
35917 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35918 let mut fmt = to_strftime(&e.format);
35920 fmt = fmt.replace("%-d", "%e");
35922 fmt = fmt.replace("%-m", "%c");
35923 fmt = fmt.replace("%H:%M:%S", "%T");
35924 self.write_keyword("DATE_PARSE");
35925 self.write("(");
35926 self.generate_expression(&e.this)?;
35927 self.write(", '");
35928 self.write(&fmt);
35929 self.write("')");
35930 }
35931 Some(DialectType::DuckDB) => {
35932 let fmt = to_strftime(&e.format);
35934 self.write_keyword("STRPTIME");
35935 self.write("(");
35936 self.generate_expression(&e.this)?;
35937 self.write(", '");
35938 self.write(&fmt);
35939 self.write("')");
35940 }
35941 Some(DialectType::PostgreSQL)
35942 | Some(DialectType::Redshift)
35943 | Some(DialectType::Materialize) => {
35944 let pg_fmt = to_pg(&e.format);
35946 self.write_keyword("TO_TIMESTAMP");
35947 self.write("(");
35948 self.generate_expression(&e.this)?;
35949 self.write(", '");
35950 self.write(&pg_fmt);
35951 self.write("')");
35952 }
35953 Some(DialectType::Oracle) => {
35954 let pg_fmt = to_pg(&e.format);
35956 self.write_keyword("TO_TIMESTAMP");
35957 self.write("(");
35958 self.generate_expression(&e.this)?;
35959 self.write(", '");
35960 self.write(&pg_fmt);
35961 self.write("')");
35962 }
35963 Some(DialectType::Snowflake) => {
35964 self.write_keyword("TO_TIMESTAMP");
35966 self.write("(");
35967 self.generate_expression(&e.this)?;
35968 self.write(", '");
35969 self.write(&e.format);
35970 self.write("')");
35971 }
35972 _ => {
35973 self.write_keyword("STR_TO_TIME");
35975 self.write("(");
35976 self.generate_expression(&e.this)?;
35977 self.write(", '");
35978 self.write(&e.format);
35979 self.write("'");
35980 self.write(")");
35981 }
35982 }
35983 Ok(())
35984 }
35985
35986 fn snowflake_format_to_strftime(format: &str) -> String {
35988 let mut result = String::new();
35989 let chars: Vec<char> = format.chars().collect();
35990 let mut i = 0;
35991 while i < chars.len() {
35992 let remaining = &format[i..];
35993 if remaining.starts_with("yyyy") {
35994 result.push_str("%Y");
35995 i += 4;
35996 } else if remaining.starts_with("yy") {
35997 result.push_str("%y");
35998 i += 2;
35999 } else if remaining.starts_with("mmmm") {
36000 result.push_str("%B"); i += 4;
36002 } else if remaining.starts_with("mon") {
36003 result.push_str("%b"); i += 3;
36005 } else if remaining.starts_with("mm") {
36006 result.push_str("%m");
36007 i += 2;
36008 } else if remaining.starts_with("DD") {
36009 result.push_str("%d");
36010 i += 2;
36011 } else if remaining.starts_with("dy") {
36012 result.push_str("%a"); i += 2;
36014 } else if remaining.starts_with("hh24") {
36015 result.push_str("%H");
36016 i += 4;
36017 } else if remaining.starts_with("hh12") {
36018 result.push_str("%I");
36019 i += 4;
36020 } else if remaining.starts_with("hh") {
36021 result.push_str("%H");
36022 i += 2;
36023 } else if remaining.starts_with("mi") {
36024 result.push_str("%M");
36025 i += 2;
36026 } else if remaining.starts_with("ss") {
36027 result.push_str("%S");
36028 i += 2;
36029 } else if remaining.starts_with("ff") {
36030 result.push_str("%f");
36032 i += 2;
36033 while i < chars.len() && chars[i].is_ascii_digit() {
36035 i += 1;
36036 }
36037 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
36038 result.push_str("%p");
36039 i += 2;
36040 } else if remaining.starts_with("tz") {
36041 result.push_str("%Z");
36042 i += 2;
36043 } else {
36044 result.push(chars[i]);
36045 i += 1;
36046 }
36047 }
36048 result
36049 }
36050
36051 fn snowflake_format_to_spark(format: &str) -> String {
36053 let mut result = String::new();
36054 let chars: Vec<char> = format.chars().collect();
36055 let mut i = 0;
36056 while i < chars.len() {
36057 let remaining = &format[i..];
36058 if remaining.starts_with("yyyy") {
36059 result.push_str("yyyy");
36060 i += 4;
36061 } else if remaining.starts_with("yy") {
36062 result.push_str("yy");
36063 i += 2;
36064 } else if remaining.starts_with("mmmm") {
36065 result.push_str("MMMM"); i += 4;
36067 } else if remaining.starts_with("mon") {
36068 result.push_str("MMM"); i += 3;
36070 } else if remaining.starts_with("mm") {
36071 result.push_str("MM");
36072 i += 2;
36073 } else if remaining.starts_with("DD") {
36074 result.push_str("dd");
36075 i += 2;
36076 } else if remaining.starts_with("dy") {
36077 result.push_str("EEE"); i += 2;
36079 } else if remaining.starts_with("hh24") {
36080 result.push_str("HH");
36081 i += 4;
36082 } else if remaining.starts_with("hh12") {
36083 result.push_str("hh");
36084 i += 4;
36085 } else if remaining.starts_with("hh") {
36086 result.push_str("HH");
36087 i += 2;
36088 } else if remaining.starts_with("mi") {
36089 result.push_str("mm");
36090 i += 2;
36091 } else if remaining.starts_with("ss") {
36092 result.push_str("ss");
36093 i += 2;
36094 } else if remaining.starts_with("ff") {
36095 result.push_str("SSS"); i += 2;
36097 while i < chars.len() && chars[i].is_ascii_digit() {
36099 i += 1;
36100 }
36101 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
36102 result.push_str("a");
36103 i += 2;
36104 } else if remaining.starts_with("tz") {
36105 result.push_str("z");
36106 i += 2;
36107 } else {
36108 result.push(chars[i]);
36109 i += 1;
36110 }
36111 }
36112 result
36113 }
36114
36115 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
36116 match self.config.dialect {
36117 Some(DialectType::DuckDB) => {
36118 self.write_keyword("EPOCH");
36120 self.write("(");
36121 self.write_keyword("STRPTIME");
36122 self.write("(");
36123 if let Some(this) = &e.this {
36124 self.generate_expression(this)?;
36125 }
36126 if let Some(format) = &e.format {
36127 self.write(", '");
36128 self.write(format);
36129 self.write("'");
36130 }
36131 self.write("))");
36132 }
36133 Some(DialectType::Hive) => {
36134 self.write_keyword("UNIX_TIMESTAMP");
36136 self.write("(");
36137 if let Some(this) = &e.this {
36138 self.generate_expression(this)?;
36139 }
36140 if let Some(format) = &e.format {
36141 let java_fmt = Self::strftime_to_java_format(format);
36142 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
36143 self.write(", '");
36144 self.write(&java_fmt);
36145 self.write("'");
36146 }
36147 }
36148 self.write(")");
36149 }
36150 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36151 self.write_keyword("UNIX_TIMESTAMP");
36153 self.write("(");
36154 if let Some(this) = &e.this {
36155 self.generate_expression(this)?;
36156 }
36157 if let Some(format) = &e.format {
36158 self.write(", '");
36159 self.write(format);
36160 self.write("'");
36161 }
36162 self.write(")");
36163 }
36164 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36165 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
36168 let java_fmt = Self::strftime_to_java_format(c_fmt);
36169 self.write_keyword("TO_UNIXTIME");
36170 self.write("(");
36171 self.write_keyword("COALESCE");
36172 self.write("(");
36173 self.write_keyword("TRY");
36174 self.write("(");
36175 self.write_keyword("DATE_PARSE");
36176 self.write("(");
36177 self.write_keyword("CAST");
36178 self.write("(");
36179 if let Some(this) = &e.this {
36180 self.generate_expression(this)?;
36181 }
36182 self.write(" ");
36183 self.write_keyword("AS VARCHAR");
36184 self.write("), '");
36185 self.write(c_fmt);
36186 self.write("')), ");
36187 self.write_keyword("PARSE_DATETIME");
36188 self.write("(");
36189 self.write_keyword("DATE_FORMAT");
36190 self.write("(");
36191 self.write_keyword("CAST");
36192 self.write("(");
36193 if let Some(this) = &e.this {
36194 self.generate_expression(this)?;
36195 }
36196 self.write(" ");
36197 self.write_keyword("AS TIMESTAMP");
36198 self.write("), '");
36199 self.write(c_fmt);
36200 self.write("'), '");
36201 self.write(&java_fmt);
36202 self.write("')))");
36203 }
36204 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36205 self.write_keyword("UNIX_TIMESTAMP");
36207 self.write("(");
36208 if let Some(this) = &e.this {
36209 self.generate_expression(this)?;
36210 }
36211 if let Some(format) = &e.format {
36212 let java_fmt = Self::strftime_to_java_format(format);
36213 self.write(", '");
36214 self.write(&java_fmt);
36215 self.write("'");
36216 }
36217 self.write(")");
36218 }
36219 _ => {
36220 self.write_keyword("STR_TO_UNIX");
36222 self.write("(");
36223 if let Some(this) = &e.this {
36224 self.generate_expression(this)?;
36225 }
36226 if let Some(format) = &e.format {
36227 self.write(", '");
36228 self.write(format);
36229 self.write("'");
36230 }
36231 self.write(")");
36232 }
36233 }
36234 Ok(())
36235 }
36236
36237 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
36238 self.write_keyword("STRING_TO_ARRAY");
36240 self.write("(");
36241 self.generate_expression(&e.this)?;
36242 if let Some(expression) = &e.expression {
36243 self.write(", ");
36244 self.generate_expression(expression)?;
36245 }
36246 if let Some(null_val) = &e.null {
36247 self.write(", ");
36248 self.generate_expression(null_val)?;
36249 }
36250 self.write(")");
36251 Ok(())
36252 }
36253
36254 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
36255 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36256 self.write_keyword("OBJECT_CONSTRUCT");
36258 self.write("(");
36259 for (i, (name, expr)) in e.fields.iter().enumerate() {
36260 if i > 0 {
36261 self.write(", ");
36262 }
36263 if let Some(name) = name {
36264 self.write("'");
36265 self.write(name);
36266 self.write("'");
36267 self.write(", ");
36268 } else {
36269 self.write("'_");
36270 self.write(&i.to_string());
36271 self.write("'");
36272 self.write(", ");
36273 }
36274 self.generate_expression(expr)?;
36275 }
36276 self.write(")");
36277 } else if self.config.struct_curly_brace_notation {
36278 self.write("{");
36280 for (i, (name, expr)) in e.fields.iter().enumerate() {
36281 if i > 0 {
36282 self.write(", ");
36283 }
36284 if let Some(name) = name {
36285 self.write("'");
36287 self.write(name);
36288 self.write("'");
36289 self.write(": ");
36290 } else {
36291 self.write("'_");
36293 self.write(&i.to_string());
36294 self.write("'");
36295 self.write(": ");
36296 }
36297 self.generate_expression(expr)?;
36298 }
36299 self.write("}");
36300 } else {
36301 let value_as_name = matches!(
36305 self.config.dialect,
36306 Some(DialectType::BigQuery)
36307 | Some(DialectType::Spark)
36308 | Some(DialectType::Databricks)
36309 | Some(DialectType::Hive)
36310 );
36311 self.write_keyword("STRUCT");
36312 self.write("(");
36313 for (i, (name, expr)) in e.fields.iter().enumerate() {
36314 if i > 0 {
36315 self.write(", ");
36316 }
36317 if let Some(name) = name {
36318 if value_as_name {
36319 self.generate_expression(expr)?;
36321 self.write_space();
36322 self.write_keyword("AS");
36323 self.write_space();
36324 let needs_quoting = name.contains(' ') || name.contains('-');
36326 if needs_quoting {
36327 if matches!(
36328 self.config.dialect,
36329 Some(DialectType::Spark)
36330 | Some(DialectType::Databricks)
36331 | Some(DialectType::Hive)
36332 ) {
36333 self.write("`");
36334 self.write(name);
36335 self.write("`");
36336 } else {
36337 self.write(name);
36338 }
36339 } else {
36340 self.write(name);
36341 }
36342 } else {
36343 self.write(name);
36345 self.write_space();
36346 self.write_keyword("AS");
36347 self.write_space();
36348 self.generate_expression(expr)?;
36349 }
36350 } else {
36351 self.generate_expression(expr)?;
36352 }
36353 }
36354 self.write(")");
36355 }
36356 Ok(())
36357 }
36358
36359 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
36360 self.write_keyword("STUFF");
36362 self.write("(");
36363 self.generate_expression(&e.this)?;
36364 if let Some(start) = &e.start {
36365 self.write(", ");
36366 self.generate_expression(start)?;
36367 }
36368 if let Some(length) = e.length {
36369 self.write(", ");
36370 self.write(&length.to_string());
36371 }
36372 self.write(", ");
36373 self.generate_expression(&e.expression)?;
36374 self.write(")");
36375 Ok(())
36376 }
36377
36378 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
36379 self.write_keyword("SUBSTRING_INDEX");
36381 self.write("(");
36382 self.generate_expression(&e.this)?;
36383 if let Some(delimiter) = &e.delimiter {
36384 self.write(", ");
36385 self.generate_expression(delimiter)?;
36386 }
36387 if let Some(count) = &e.count {
36388 self.write(", ");
36389 self.generate_expression(count)?;
36390 }
36391 self.write(")");
36392 Ok(())
36393 }
36394
36395 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
36396 self.write_keyword("SUMMARIZE");
36398 if e.table.is_some() {
36399 self.write_space();
36400 self.write_keyword("TABLE");
36401 }
36402 self.write_space();
36403 self.generate_expression(&e.this)?;
36404 Ok(())
36405 }
36406
36407 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
36408 self.write_keyword("SYSTIMESTAMP");
36410 Ok(())
36411 }
36412
36413 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
36414 if let Some(this) = &e.this {
36416 self.generate_expression(this)?;
36417 }
36418 if !e.columns.is_empty() {
36419 self.write("(");
36420 for (i, col) in e.columns.iter().enumerate() {
36421 if i > 0 {
36422 self.write(", ");
36423 }
36424 self.generate_expression(col)?;
36425 }
36426 self.write(")");
36427 }
36428 Ok(())
36429 }
36430
36431 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
36432 self.write_keyword("TABLE");
36434 self.write("(");
36435 self.generate_expression(&e.this)?;
36436 self.write(")");
36437 if let Some(alias) = &e.alias {
36438 self.write_space();
36439 self.write_keyword("AS");
36440 self.write_space();
36441 self.write(alias);
36442 }
36443 Ok(())
36444 }
36445
36446 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
36447 self.write_keyword("ROWS FROM");
36449 self.write(" (");
36450 for (i, expr) in e.expressions.iter().enumerate() {
36451 if i > 0 {
36452 self.write(", ");
36453 }
36454 match expr {
36458 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
36459 self.generate_expression(&tuple.expressions[0])?;
36461 self.write_space();
36462 self.write_keyword("AS");
36463 self.write_space();
36464 self.generate_expression(&tuple.expressions[1])?;
36465 }
36466 _ => {
36467 self.generate_expression(expr)?;
36468 }
36469 }
36470 }
36471 self.write(")");
36472 if e.ordinality {
36473 self.write_space();
36474 self.write_keyword("WITH ORDINALITY");
36475 }
36476 if let Some(alias) = &e.alias {
36477 self.write_space();
36478 self.write_keyword("AS");
36479 self.write_space();
36480 self.generate_expression(alias)?;
36481 }
36482 Ok(())
36483 }
36484
36485 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
36486 use crate::dialects::DialectType;
36487
36488 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
36490 if self.config.alias_post_tablesample {
36492 if let Expression::Subquery(ref s) = **this {
36494 if let Some(ref alias) = s.alias {
36495 let mut subquery_no_alias = (**s).clone();
36497 subquery_no_alias.alias = None;
36498 subquery_no_alias.column_aliases = Vec::new();
36499 self.generate_expression(&Expression::Subquery(Box::new(
36500 subquery_no_alias,
36501 )))?;
36502 self.write_space();
36503 self.write_keyword(self.config.tablesample_keywords);
36504 self.generate_sample_body(sample)?;
36505 if let Some(ref seed) = sample.seed {
36506 self.write_space();
36507 let use_seed = sample.use_seed_keyword
36508 && !matches!(
36509 self.config.dialect,
36510 Some(crate::dialects::DialectType::Databricks)
36511 | Some(crate::dialects::DialectType::Spark)
36512 );
36513 if use_seed {
36514 self.write_keyword("SEED");
36515 } else {
36516 self.write_keyword("REPEATABLE");
36517 }
36518 self.write(" (");
36519 self.generate_expression(seed)?;
36520 self.write(")");
36521 }
36522 self.write_space();
36523 self.write_keyword("AS");
36524 self.write_space();
36525 self.generate_identifier(alias)?;
36526 return Ok(());
36527 }
36528 } else if let Expression::Alias(ref a) = **this {
36529 self.generate_expression(&a.this)?;
36531 self.write_space();
36532 self.write_keyword(self.config.tablesample_keywords);
36533 self.generate_sample_body(sample)?;
36534 if let Some(ref seed) = sample.seed {
36535 self.write_space();
36536 let use_seed = sample.use_seed_keyword
36537 && !matches!(
36538 self.config.dialect,
36539 Some(crate::dialects::DialectType::Databricks)
36540 | Some(crate::dialects::DialectType::Spark)
36541 );
36542 if use_seed {
36543 self.write_keyword("SEED");
36544 } else {
36545 self.write_keyword("REPEATABLE");
36546 }
36547 self.write(" (");
36548 self.generate_expression(seed)?;
36549 self.write(")");
36550 }
36551 self.write_space();
36553 self.write_keyword("AS");
36554 self.write_space();
36555 self.generate_identifier(&a.alias)?;
36556 return Ok(());
36557 }
36558 }
36559 self.generate_expression(this)?;
36561 self.write_space();
36562 self.write_keyword(self.config.tablesample_keywords);
36563 self.generate_sample_body(sample)?;
36564 if let Some(ref seed) = sample.seed {
36566 self.write_space();
36567 let use_seed = sample.use_seed_keyword
36569 && !matches!(
36570 self.config.dialect,
36571 Some(crate::dialects::DialectType::Databricks)
36572 | Some(crate::dialects::DialectType::Spark)
36573 );
36574 if use_seed {
36575 self.write_keyword("SEED");
36576 } else {
36577 self.write_keyword("REPEATABLE");
36578 }
36579 self.write(" (");
36580 self.generate_expression(seed)?;
36581 self.write(")");
36582 }
36583 return Ok(());
36584 }
36585
36586 self.write_keyword(self.config.tablesample_keywords);
36588 if let Some(method) = &e.method {
36589 self.write_space();
36590 self.write_keyword(method);
36591 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36592 self.write_space();
36594 self.write_keyword("BERNOULLI");
36595 }
36596 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
36597 self.write_space();
36598 self.write_keyword("BUCKET");
36599 self.write_space();
36600 self.generate_expression(numerator)?;
36601 self.write_space();
36602 self.write_keyword("OUT OF");
36603 self.write_space();
36604 self.generate_expression(denominator)?;
36605 if let Some(field) = &e.bucket_field {
36606 self.write_space();
36607 self.write_keyword("ON");
36608 self.write_space();
36609 self.generate_expression(field)?;
36610 }
36611 } else if !e.expressions.is_empty() {
36612 self.write(" (");
36613 for (i, expr) in e.expressions.iter().enumerate() {
36614 if i > 0 {
36615 self.write(", ");
36616 }
36617 self.generate_expression(expr)?;
36618 }
36619 self.write(")");
36620 } else if let Some(percent) = &e.percent {
36621 self.write(" (");
36622 self.generate_expression(percent)?;
36623 self.write_space();
36624 self.write_keyword("PERCENT");
36625 self.write(")");
36626 }
36627 Ok(())
36628 }
36629
36630 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
36631 if let Some(prefix) = &e.prefix {
36633 self.generate_expression(prefix)?;
36634 }
36635 if let Some(this) = &e.this {
36636 self.generate_expression(this)?;
36637 }
36638 if let Some(postfix) = &e.postfix {
36639 self.generate_expression(postfix)?;
36640 }
36641 Ok(())
36642 }
36643
36644 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
36645 self.write_keyword("TAG");
36647 self.write(" (");
36648 for (i, expr) in e.expressions.iter().enumerate() {
36649 if i > 0 {
36650 self.write(", ");
36651 }
36652 self.generate_expression(expr)?;
36653 }
36654 self.write(")");
36655 Ok(())
36656 }
36657
36658 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
36659 if let Some(this) = &e.this {
36661 self.generate_expression(this)?;
36662 self.write_space();
36663 }
36664 self.write_keyword("TEMPORARY");
36665 Ok(())
36666 }
36667
36668 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
36671 self.write_keyword("TIME");
36673 self.write("(");
36674 self.generate_expression(&e.this)?;
36675 self.write(")");
36676 Ok(())
36677 }
36678
36679 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
36680 self.write_keyword("TIME_ADD");
36682 self.write("(");
36683 self.generate_expression(&e.this)?;
36684 self.write(", ");
36685 self.generate_expression(&e.expression)?;
36686 if let Some(unit) = &e.unit {
36687 self.write(", ");
36688 self.write_keyword(unit);
36689 }
36690 self.write(")");
36691 Ok(())
36692 }
36693
36694 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
36695 self.write_keyword("TIME_DIFF");
36697 self.write("(");
36698 self.generate_expression(&e.this)?;
36699 self.write(", ");
36700 self.generate_expression(&e.expression)?;
36701 if let Some(unit) = &e.unit {
36702 self.write(", ");
36703 self.write_keyword(unit);
36704 }
36705 self.write(")");
36706 Ok(())
36707 }
36708
36709 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
36710 self.write_keyword("TIME_FROM_PARTS");
36712 self.write("(");
36713 let mut first = true;
36714 if let Some(hour) = &e.hour {
36715 self.generate_expression(hour)?;
36716 first = false;
36717 }
36718 if let Some(minute) = &e.min {
36719 if !first {
36720 self.write(", ");
36721 }
36722 self.generate_expression(minute)?;
36723 first = false;
36724 }
36725 if let Some(second) = &e.sec {
36726 if !first {
36727 self.write(", ");
36728 }
36729 self.generate_expression(second)?;
36730 first = false;
36731 }
36732 if let Some(ns) = &e.nano {
36733 if !first {
36734 self.write(", ");
36735 }
36736 self.generate_expression(ns)?;
36737 }
36738 self.write(")");
36739 Ok(())
36740 }
36741
36742 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
36743 self.write_keyword("TIME_SLICE");
36745 self.write("(");
36746 self.generate_expression(&e.this)?;
36747 self.write(", ");
36748 self.generate_expression(&e.expression)?;
36749 self.write(", ");
36750 self.write_keyword(&e.unit);
36751 self.write(")");
36752 Ok(())
36753 }
36754
36755 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
36756 self.write_keyword("TIME_STR_TO_TIME");
36758 self.write("(");
36759 self.generate_expression(&e.this)?;
36760 self.write(")");
36761 Ok(())
36762 }
36763
36764 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
36765 self.write_keyword("TIME_SUB");
36767 self.write("(");
36768 self.generate_expression(&e.this)?;
36769 self.write(", ");
36770 self.generate_expression(&e.expression)?;
36771 if let Some(unit) = &e.unit {
36772 self.write(", ");
36773 self.write_keyword(unit);
36774 }
36775 self.write(")");
36776 Ok(())
36777 }
36778
36779 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
36780 match self.config.dialect {
36781 Some(DialectType::Exasol) => {
36782 self.write_keyword("TO_CHAR");
36784 self.write("(");
36785 self.generate_expression(&e.this)?;
36786 self.write(", '");
36787 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
36788 self.write("'");
36789 self.write(")");
36790 }
36791 Some(DialectType::PostgreSQL)
36792 | Some(DialectType::Redshift)
36793 | Some(DialectType::Materialize) => {
36794 self.write_keyword("TO_CHAR");
36796 self.write("(");
36797 self.generate_expression(&e.this)?;
36798 self.write(", '");
36799 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36800 self.write("'");
36801 self.write(")");
36802 }
36803 Some(DialectType::Oracle) => {
36804 self.write_keyword("TO_CHAR");
36806 self.write("(");
36807 self.generate_expression(&e.this)?;
36808 self.write(", '");
36809 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36810 self.write("'");
36811 self.write(")");
36812 }
36813 Some(DialectType::Drill) => {
36814 self.write_keyword("TO_CHAR");
36816 self.write("(");
36817 self.generate_expression(&e.this)?;
36818 self.write(", '");
36819 self.write(&Self::strftime_to_java_format(&e.format));
36820 self.write("'");
36821 self.write(")");
36822 }
36823 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
36824 self.write_keyword("FORMAT");
36826 self.write("(");
36827 self.generate_expression(&e.this)?;
36828 self.write(", '");
36829 self.write(&Self::strftime_to_tsql_format(&e.format));
36830 self.write("'");
36831 self.write(")");
36832 }
36833 Some(DialectType::DuckDB) => {
36834 self.write_keyword("STRFTIME");
36836 self.write("(");
36837 self.generate_expression(&e.this)?;
36838 self.write(", '");
36839 self.write(&e.format);
36840 self.write("'");
36841 self.write(")");
36842 }
36843 Some(DialectType::BigQuery) => {
36844 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
36847 self.write_keyword("FORMAT_DATE");
36848 self.write("('");
36849 self.write(&fmt);
36850 self.write("', ");
36851 self.generate_expression(&e.this)?;
36852 self.write(")");
36853 }
36854 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36855 self.write_keyword("DATE_FORMAT");
36857 self.write("(");
36858 self.generate_expression(&e.this)?;
36859 self.write(", '");
36860 self.write(&Self::strftime_to_java_format(&e.format));
36861 self.write("'");
36862 self.write(")");
36863 }
36864 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
36865 self.write_keyword("DATE_FORMAT");
36867 self.write("(");
36868 self.generate_expression(&e.this)?;
36869 self.write(", '");
36870 self.write(&e.format);
36871 self.write("'");
36872 self.write(")");
36873 }
36874 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36875 self.write_keyword("DATE_FORMAT");
36877 self.write("(");
36878 self.generate_expression(&e.this)?;
36879 self.write(", '");
36880 self.write(&e.format);
36881 self.write("'");
36882 self.write(")");
36883 }
36884 _ => {
36885 self.write_keyword("TIME_TO_STR");
36887 self.write("(");
36888 self.generate_expression(&e.this)?;
36889 self.write(", '");
36890 self.write(&e.format);
36891 self.write("'");
36892 self.write(")");
36893 }
36894 }
36895 Ok(())
36896 }
36897
36898 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36899 match self.config.dialect {
36900 Some(DialectType::DuckDB) => {
36901 self.write_keyword("EPOCH");
36903 self.write("(");
36904 self.generate_expression(&e.this)?;
36905 self.write(")");
36906 }
36907 Some(DialectType::Hive)
36908 | Some(DialectType::Spark)
36909 | Some(DialectType::Databricks)
36910 | Some(DialectType::Doris)
36911 | Some(DialectType::StarRocks)
36912 | Some(DialectType::Drill) => {
36913 self.write_keyword("UNIX_TIMESTAMP");
36915 self.write("(");
36916 self.generate_expression(&e.this)?;
36917 self.write(")");
36918 }
36919 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36920 self.write_keyword("TO_UNIXTIME");
36922 self.write("(");
36923 self.generate_expression(&e.this)?;
36924 self.write(")");
36925 }
36926 _ => {
36927 self.write_keyword("TIME_TO_UNIX");
36929 self.write("(");
36930 self.generate_expression(&e.this)?;
36931 self.write(")");
36932 }
36933 }
36934 Ok(())
36935 }
36936
36937 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36938 match self.config.dialect {
36939 Some(DialectType::Hive) => {
36940 self.write_keyword("TO_DATE");
36942 self.write("(");
36943 self.generate_expression(&e.this)?;
36944 self.write(")");
36945 }
36946 _ => {
36947 self.write_keyword("TIME_STR_TO_DATE");
36949 self.write("(");
36950 self.generate_expression(&e.this)?;
36951 self.write(")");
36952 }
36953 }
36954 Ok(())
36955 }
36956
36957 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
36958 self.write_keyword("TIME_TRUNC");
36960 self.write("(");
36961 self.generate_expression(&e.this)?;
36962 self.write(", ");
36963 self.write_keyword(&e.unit);
36964 self.write(")");
36965 Ok(())
36966 }
36967
36968 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
36969 if let Some(unit) = &e.unit {
36971 self.write_keyword(unit);
36972 }
36973 Ok(())
36974 }
36975
36976 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
36980 use crate::dialects::DialectType;
36981 use crate::expressions::Literal;
36982
36983 match self.config.dialect {
36984 Some(DialectType::Exasol) => {
36986 self.write_keyword("TO_TIMESTAMP");
36987 self.write("(");
36988 if let Some(this) = &e.this {
36990 match this.as_ref() {
36991 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36992 let Literal::String(s) = lit.as_ref() else {
36993 unreachable!()
36994 };
36995 self.write("'");
36996 self.write(s);
36997 self.write("'");
36998 }
36999 _ => {
37000 self.generate_expression(this)?;
37001 }
37002 }
37003 }
37004 self.write(")");
37005 }
37006 _ => {
37008 self.write_keyword("TIMESTAMP");
37009 self.write("(");
37010 if let Some(this) = &e.this {
37011 self.generate_expression(this)?;
37012 }
37013 if let Some(zone) = &e.zone {
37014 self.write(", ");
37015 self.generate_expression(zone)?;
37016 }
37017 self.write(")");
37018 }
37019 }
37020 Ok(())
37021 }
37022
37023 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
37024 self.write_keyword("TIMESTAMP_ADD");
37026 self.write("(");
37027 self.generate_expression(&e.this)?;
37028 self.write(", ");
37029 self.generate_expression(&e.expression)?;
37030 if let Some(unit) = &e.unit {
37031 self.write(", ");
37032 self.write_keyword(unit);
37033 }
37034 self.write(")");
37035 Ok(())
37036 }
37037
37038 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
37039 self.write_keyword("TIMESTAMP_DIFF");
37041 self.write("(");
37042 self.generate_expression(&e.this)?;
37043 self.write(", ");
37044 self.generate_expression(&e.expression)?;
37045 if let Some(unit) = &e.unit {
37046 self.write(", ");
37047 self.write_keyword(unit);
37048 }
37049 self.write(")");
37050 Ok(())
37051 }
37052
37053 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
37054 self.write_keyword("TIMESTAMP_FROM_PARTS");
37056 self.write("(");
37057 if let Some(this) = &e.this {
37058 self.generate_expression(this)?;
37059 }
37060 if let Some(expression) = &e.expression {
37061 self.write(", ");
37062 self.generate_expression(expression)?;
37063 }
37064 if let Some(zone) = &e.zone {
37065 self.write(", ");
37066 self.generate_expression(zone)?;
37067 }
37068 if let Some(milli) = &e.milli {
37069 self.write(", ");
37070 self.generate_expression(milli)?;
37071 }
37072 self.write(")");
37073 Ok(())
37074 }
37075
37076 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
37077 self.write_keyword("TIMESTAMP_SUB");
37079 self.write("(");
37080 self.generate_expression(&e.this)?;
37081 self.write(", ");
37082 self.write_keyword("INTERVAL");
37083 self.write_space();
37084 self.generate_expression(&e.expression)?;
37085 if let Some(unit) = &e.unit {
37086 self.write_space();
37087 self.write_keyword(unit);
37088 }
37089 self.write(")");
37090 Ok(())
37091 }
37092
37093 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
37094 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
37096 self.write("(");
37097 if let Some(zone) = &e.zone {
37098 self.generate_expression(zone)?;
37099 }
37100 self.write(")");
37101 Ok(())
37102 }
37103
37104 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
37105 self.write_keyword("TO_BINARY");
37107 self.write("(");
37108 self.generate_expression(&e.this)?;
37109 if let Some(format) = &e.format {
37110 self.write(", '");
37111 self.write(format);
37112 self.write("'");
37113 }
37114 self.write(")");
37115 Ok(())
37116 }
37117
37118 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
37119 self.write_keyword("TO_BOOLEAN");
37121 self.write("(");
37122 self.generate_expression(&e.this)?;
37123 self.write(")");
37124 Ok(())
37125 }
37126
37127 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
37128 self.write_keyword("TO_CHAR");
37130 self.write("(");
37131 self.generate_expression(&e.this)?;
37132 if let Some(format) = &e.format {
37133 self.write(", '");
37134 self.write(format);
37135 self.write("'");
37136 }
37137 if let Some(nlsparam) = &e.nlsparam {
37138 self.write(", ");
37139 self.generate_expression(nlsparam)?;
37140 }
37141 self.write(")");
37142 Ok(())
37143 }
37144
37145 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
37146 self.write_keyword("TO_DECFLOAT");
37148 self.write("(");
37149 self.generate_expression(&e.this)?;
37150 if let Some(format) = &e.format {
37151 self.write(", '");
37152 self.write(format);
37153 self.write("'");
37154 }
37155 self.write(")");
37156 Ok(())
37157 }
37158
37159 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
37160 self.write_keyword("TO_DOUBLE");
37162 self.write("(");
37163 self.generate_expression(&e.this)?;
37164 if let Some(format) = &e.format {
37165 self.write(", '");
37166 self.write(format);
37167 self.write("'");
37168 }
37169 self.write(")");
37170 Ok(())
37171 }
37172
37173 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
37174 self.write_keyword("TO_FILE");
37176 self.write("(");
37177 self.generate_expression(&e.this)?;
37178 if let Some(path) = &e.path {
37179 self.write(", ");
37180 self.generate_expression(path)?;
37181 }
37182 self.write(")");
37183 Ok(())
37184 }
37185
37186 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
37187 let is_safe = e.safe.is_some();
37190 if is_safe {
37191 self.write_keyword("TRY_TO_NUMBER");
37192 } else {
37193 self.write_keyword("TO_NUMBER");
37194 }
37195 self.write("(");
37196 self.generate_expression(&e.this)?;
37197 let precision_is_snowflake_default = e.precision.is_none()
37198 || matches!(
37199 e.precision.as_deref(),
37200 Some(Expression::Literal(lit))
37201 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
37202 );
37203 let is_snowflake_default_precision =
37204 matches!(self.config.dialect, Some(DialectType::Snowflake))
37205 && e.nlsparam.is_none()
37206 && e.scale.is_none()
37207 && matches!(
37208 e.format.as_deref(),
37209 Some(Expression::Literal(lit))
37210 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
37211 )
37212 && precision_is_snowflake_default;
37213
37214 if !is_snowflake_default_precision {
37215 if let Some(format) = &e.format {
37216 self.write(", ");
37217 self.generate_expression(format)?;
37218 }
37219 if let Some(nlsparam) = &e.nlsparam {
37220 self.write(", ");
37221 self.generate_expression(nlsparam)?;
37222 }
37223 if let Some(precision) = &e.precision {
37224 self.write(", ");
37225 self.generate_expression(precision)?;
37226 }
37227 if let Some(scale) = &e.scale {
37228 self.write(", ");
37229 self.generate_expression(scale)?;
37230 }
37231 }
37232 self.write(")");
37233 Ok(())
37234 }
37235
37236 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
37237 self.write_keyword("TO_TABLE");
37239 self.write_space();
37240 self.generate_expression(&e.this)?;
37241 Ok(())
37242 }
37243
37244 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
37245 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
37247 Expression::Identifier(id) => id.name.clone(),
37248 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
37249 let Literal::String(s) = lit.as_ref() else {
37250 unreachable!()
37251 };
37252 s.clone()
37253 }
37254 _ => String::new(),
37255 });
37256
37257 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
37258 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
37259 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
37260 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
37261 });
37262
37263 let use_start_transaction = matches!(
37265 self.config.dialect,
37266 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
37267 );
37268 let strip_transaction = matches!(
37270 self.config.dialect,
37271 Some(DialectType::Snowflake)
37272 | Some(DialectType::PostgreSQL)
37273 | Some(DialectType::Redshift)
37274 | Some(DialectType::MySQL)
37275 | Some(DialectType::Hive)
37276 | Some(DialectType::Spark)
37277 | Some(DialectType::Databricks)
37278 | Some(DialectType::DuckDB)
37279 | Some(DialectType::Oracle)
37280 | Some(DialectType::Doris)
37281 | Some(DialectType::StarRocks)
37282 | Some(DialectType::Materialize)
37283 | Some(DialectType::ClickHouse)
37284 );
37285
37286 if is_start || use_start_transaction {
37287 self.write_keyword("START TRANSACTION");
37289 if let Some(modes) = &e.modes {
37290 self.write_space();
37291 self.generate_expression(modes)?;
37292 }
37293 } else {
37294 self.write_keyword("BEGIN");
37296
37297 let is_kind = e.this.as_ref().map_or(false, |t| {
37299 if let Expression::Identifier(id) = t.as_ref() {
37300 id.name.eq_ignore_ascii_case("DEFERRED")
37301 || id.name.eq_ignore_ascii_case("IMMEDIATE")
37302 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
37303 } else {
37304 false
37305 }
37306 });
37307
37308 if is_kind {
37310 if let Some(this) = &e.this {
37311 self.write_space();
37312 if let Expression::Identifier(id) = this.as_ref() {
37313 self.write_keyword(&id.name);
37314 }
37315 }
37316 }
37317
37318 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
37320 self.write_space();
37321 self.write_keyword("TRANSACTION");
37322 }
37323
37324 if !is_kind {
37326 if let Some(this) = &e.this {
37327 self.write_space();
37328 self.generate_expression(this)?;
37329 }
37330 }
37331
37332 if has_with_mark {
37334 self.write_space();
37335 self.write_keyword("WITH MARK");
37336 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
37337 if let Literal::String(desc) = lit.as_ref() {
37338 if !desc.is_empty() {
37339 self.write_space();
37340 self.write(&format!("'{}'", desc));
37341 }
37342 }
37343 }
37344 }
37345
37346 if let Some(modes) = &e.modes {
37348 self.write_space();
37349 self.generate_expression(modes)?;
37350 }
37351 }
37352 Ok(())
37353 }
37354
37355 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
37356 self.write_keyword("TRANSFORM");
37358 self.write("(");
37359 self.generate_expression(&e.this)?;
37360 self.write(", ");
37361 self.generate_expression(&e.expression)?;
37362 self.write(")");
37363 Ok(())
37364 }
37365
37366 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
37367 self.write_keyword("TRANSFORM");
37369 self.write("(");
37370 if self.config.pretty && !e.expressions.is_empty() {
37371 self.indent_level += 1;
37372 for (i, expr) in e.expressions.iter().enumerate() {
37373 if i > 0 {
37374 self.write(",");
37375 }
37376 self.write_newline();
37377 self.write_indent();
37378 self.generate_expression(expr)?;
37379 }
37380 self.indent_level -= 1;
37381 self.write_newline();
37382 self.write(")");
37383 } else {
37384 for (i, expr) in e.expressions.iter().enumerate() {
37385 if i > 0 {
37386 self.write(", ");
37387 }
37388 self.generate_expression(expr)?;
37389 }
37390 self.write(")");
37391 }
37392 Ok(())
37393 }
37394
37395 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
37396 use crate::dialects::DialectType;
37397 if let Some(this) = &e.this {
37399 self.generate_expression(this)?;
37400 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
37401 self.write_space();
37402 }
37403 }
37404 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
37405 self.write_keyword("TRANSIENT");
37406 }
37407 Ok(())
37408 }
37409
37410 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
37411 self.write_keyword("TRANSLATE");
37413 self.write("(");
37414 self.generate_expression(&e.this)?;
37415 if let Some(from) = &e.from_ {
37416 self.write(", ");
37417 self.generate_expression(from)?;
37418 }
37419 if let Some(to) = &e.to {
37420 self.write(", ");
37421 self.generate_expression(to)?;
37422 }
37423 self.write(")");
37424 Ok(())
37425 }
37426
37427 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
37428 self.write_keyword("TRANSLATE");
37430 self.write("(");
37431 self.generate_expression(&e.this)?;
37432 self.write_space();
37433 self.write_keyword("USING");
37434 self.write_space();
37435 self.generate_expression(&e.expression)?;
37436 if e.with_error.is_some() {
37437 self.write_space();
37438 self.write_keyword("WITH ERROR");
37439 }
37440 self.write(")");
37441 Ok(())
37442 }
37443
37444 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
37445 self.write_keyword("TRUNCATE TABLE");
37447 self.write_space();
37448 for (i, expr) in e.expressions.iter().enumerate() {
37449 if i > 0 {
37450 self.write(", ");
37451 }
37452 self.generate_expression(expr)?;
37453 }
37454 Ok(())
37455 }
37456
37457 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
37458 self.write_keyword("TRY_BASE64_DECODE_BINARY");
37460 self.write("(");
37461 self.generate_expression(&e.this)?;
37462 if let Some(alphabet) = &e.alphabet {
37463 self.write(", ");
37464 self.generate_expression(alphabet)?;
37465 }
37466 self.write(")");
37467 Ok(())
37468 }
37469
37470 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
37471 self.write_keyword("TRY_BASE64_DECODE_STRING");
37473 self.write("(");
37474 self.generate_expression(&e.this)?;
37475 if let Some(alphabet) = &e.alphabet {
37476 self.write(", ");
37477 self.generate_expression(alphabet)?;
37478 }
37479 self.write(")");
37480 Ok(())
37481 }
37482
37483 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
37484 self.write_keyword("TRY_TO_DECFLOAT");
37486 self.write("(");
37487 self.generate_expression(&e.this)?;
37488 if let Some(format) = &e.format {
37489 self.write(", '");
37490 self.write(format);
37491 self.write("'");
37492 }
37493 self.write(")");
37494 Ok(())
37495 }
37496
37497 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
37498 self.write_keyword("TS_OR_DS_ADD");
37500 self.write("(");
37501 self.generate_expression(&e.this)?;
37502 self.write(", ");
37503 self.generate_expression(&e.expression)?;
37504 if let Some(unit) = &e.unit {
37505 self.write(", ");
37506 self.write_keyword(unit);
37507 }
37508 if let Some(return_type) = &e.return_type {
37509 self.write(", ");
37510 self.generate_expression(return_type)?;
37511 }
37512 self.write(")");
37513 Ok(())
37514 }
37515
37516 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
37517 self.write_keyword("TS_OR_DS_DIFF");
37519 self.write("(");
37520 self.generate_expression(&e.this)?;
37521 self.write(", ");
37522 self.generate_expression(&e.expression)?;
37523 if let Some(unit) = &e.unit {
37524 self.write(", ");
37525 self.write_keyword(unit);
37526 }
37527 self.write(")");
37528 Ok(())
37529 }
37530
37531 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
37532 let default_time_format = "%Y-%m-%d %H:%M:%S";
37533 let default_date_format = "%Y-%m-%d";
37534 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
37535 f != default_time_format && f != default_date_format
37536 });
37537
37538 if has_non_default_format {
37539 let fmt = e.format.as_ref().unwrap();
37541 match self.config.dialect {
37542 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
37543 let str_to_time = crate::expressions::StrToTime {
37546 this: Box::new((*e.this).clone()),
37547 format: fmt.clone(),
37548 zone: None,
37549 safe: None,
37550 target_type: None,
37551 };
37552 self.generate_str_to_time(&str_to_time)?;
37553 }
37554 Some(DialectType::Hive)
37555 | Some(DialectType::Spark)
37556 | Some(DialectType::Databricks) => {
37557 self.write_keyword("TO_DATE");
37559 self.write("(");
37560 self.generate_expression(&e.this)?;
37561 self.write(", '");
37562 self.write(&Self::strftime_to_java_format(fmt));
37563 self.write("')");
37564 }
37565 Some(DialectType::Snowflake) => {
37566 self.write_keyword("TO_DATE");
37568 self.write("(");
37569 self.generate_expression(&e.this)?;
37570 self.write(", '");
37571 self.write(&Self::strftime_to_snowflake_format(fmt));
37572 self.write("')");
37573 }
37574 Some(DialectType::Doris) => {
37575 self.write_keyword("TO_DATE");
37577 self.write("(");
37578 self.generate_expression(&e.this)?;
37579 self.write(")");
37580 }
37581 _ => {
37582 self.write_keyword("CAST");
37584 self.write("(");
37585 let str_to_time = crate::expressions::StrToTime {
37586 this: Box::new((*e.this).clone()),
37587 format: fmt.clone(),
37588 zone: None,
37589 safe: None,
37590 target_type: None,
37591 };
37592 self.generate_str_to_time(&str_to_time)?;
37593 self.write_keyword(" AS ");
37594 self.write_keyword("DATE");
37595 self.write(")");
37596 }
37597 }
37598 } else {
37599 match self.config.dialect {
37601 Some(DialectType::MySQL)
37602 | Some(DialectType::SQLite)
37603 | Some(DialectType::StarRocks) => {
37604 self.write_keyword("DATE");
37606 self.write("(");
37607 self.generate_expression(&e.this)?;
37608 self.write(")");
37609 }
37610 Some(DialectType::Hive)
37611 | Some(DialectType::Spark)
37612 | Some(DialectType::Databricks)
37613 | Some(DialectType::Snowflake)
37614 | Some(DialectType::Doris) => {
37615 self.write_keyword("TO_DATE");
37617 self.write("(");
37618 self.generate_expression(&e.this)?;
37619 self.write(")");
37620 }
37621 Some(DialectType::Presto)
37622 | Some(DialectType::Trino)
37623 | Some(DialectType::Athena) => {
37624 self.write_keyword("CAST");
37626 self.write("(");
37627 self.write_keyword("CAST");
37628 self.write("(");
37629 self.generate_expression(&e.this)?;
37630 self.write_keyword(" AS ");
37631 self.write_keyword("TIMESTAMP");
37632 self.write(")");
37633 self.write_keyword(" AS ");
37634 self.write_keyword("DATE");
37635 self.write(")");
37636 }
37637 Some(DialectType::ClickHouse) => {
37638 self.write_keyword("CAST");
37640 self.write("(");
37641 self.generate_expression(&e.this)?;
37642 self.write_keyword(" AS ");
37643 self.write("Nullable(DATE)");
37644 self.write(")");
37645 }
37646 _ => {
37647 self.write_keyword("CAST");
37649 self.write("(");
37650 self.generate_expression(&e.this)?;
37651 self.write_keyword(" AS ");
37652 self.write_keyword("DATE");
37653 self.write(")");
37654 }
37655 }
37656 }
37657 Ok(())
37658 }
37659
37660 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
37661 self.write_keyword("TS_OR_DS_TO_TIME");
37663 self.write("(");
37664 self.generate_expression(&e.this)?;
37665 if let Some(format) = &e.format {
37666 self.write(", '");
37667 self.write(format);
37668 self.write("'");
37669 }
37670 self.write(")");
37671 Ok(())
37672 }
37673
37674 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
37675 self.write_keyword("UNHEX");
37677 self.write("(");
37678 self.generate_expression(&e.this)?;
37679 if let Some(expression) = &e.expression {
37680 self.write(", ");
37681 self.generate_expression(expression)?;
37682 }
37683 self.write(")");
37684 Ok(())
37685 }
37686
37687 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
37688 self.write("U&");
37690 self.generate_expression(&e.this)?;
37691 if let Some(escape) = &e.escape {
37692 self.write_space();
37693 self.write_keyword("UESCAPE");
37694 self.write_space();
37695 self.generate_expression(escape)?;
37696 }
37697 Ok(())
37698 }
37699
37700 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
37701 self.write_keyword("UNIFORM");
37703 self.write("(");
37704 self.generate_expression(&e.this)?;
37705 self.write(", ");
37706 self.generate_expression(&e.expression)?;
37707 if let Some(gen) = &e.gen {
37708 self.write(", ");
37709 self.generate_expression(gen)?;
37710 }
37711 if let Some(seed) = &e.seed {
37712 self.write(", ");
37713 self.generate_expression(seed)?;
37714 }
37715 self.write(")");
37716 Ok(())
37717 }
37718
37719 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
37720 self.write_keyword("UNIQUE");
37722 if e.nulls.is_some() {
37724 self.write(" NULLS NOT DISTINCT");
37725 }
37726 if let Some(this) = &e.this {
37727 self.write_space();
37728 self.generate_expression(this)?;
37729 }
37730 if let Some(index_type) = &e.index_type {
37731 self.write(" USING ");
37732 self.generate_expression(index_type)?;
37733 }
37734 if let Some(on_conflict) = &e.on_conflict {
37735 self.write_space();
37736 self.generate_expression(on_conflict)?;
37737 }
37738 for opt in &e.options {
37739 self.write_space();
37740 self.generate_expression(opt)?;
37741 }
37742 Ok(())
37743 }
37744
37745 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
37746 self.write_keyword("UNIQUE KEY");
37748 self.write(" (");
37749 for (i, expr) in e.expressions.iter().enumerate() {
37750 if i > 0 {
37751 self.write(", ");
37752 }
37753 self.generate_expression(expr)?;
37754 }
37755 self.write(")");
37756 Ok(())
37757 }
37758
37759 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
37760 self.write_keyword("ROLLUP");
37762 self.write(" (");
37763 for (i, index) in e.expressions.iter().enumerate() {
37764 if i > 0 {
37765 self.write(", ");
37766 }
37767 self.generate_identifier(&index.name)?;
37768 self.write("(");
37769 for (j, col) in index.expressions.iter().enumerate() {
37770 if j > 0 {
37771 self.write(", ");
37772 }
37773 self.generate_identifier(col)?;
37774 }
37775 self.write(")");
37776 }
37777 self.write(")");
37778 Ok(())
37779 }
37780
37781 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
37782 match self.config.dialect {
37783 Some(DialectType::DuckDB) => {
37784 self.write_keyword("STRFTIME");
37786 self.write("(");
37787 self.write_keyword("TO_TIMESTAMP");
37788 self.write("(");
37789 self.generate_expression(&e.this)?;
37790 self.write("), '");
37791 if let Some(format) = &e.format {
37792 self.write(format);
37793 }
37794 self.write("')");
37795 }
37796 Some(DialectType::Hive) => {
37797 self.write_keyword("FROM_UNIXTIME");
37799 self.write("(");
37800 self.generate_expression(&e.this)?;
37801 if let Some(format) = &e.format {
37802 if format != "yyyy-MM-dd HH:mm:ss" {
37803 self.write(", '");
37804 self.write(format);
37805 self.write("'");
37806 }
37807 }
37808 self.write(")");
37809 }
37810 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37811 self.write_keyword("DATE_FORMAT");
37813 self.write("(");
37814 self.write_keyword("FROM_UNIXTIME");
37815 self.write("(");
37816 self.generate_expression(&e.this)?;
37817 self.write("), '");
37818 if let Some(format) = &e.format {
37819 self.write(format);
37820 }
37821 self.write("')");
37822 }
37823 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37824 self.write_keyword("FROM_UNIXTIME");
37826 self.write("(");
37827 self.generate_expression(&e.this)?;
37828 if let Some(format) = &e.format {
37829 self.write(", '");
37830 self.write(format);
37831 self.write("'");
37832 }
37833 self.write(")");
37834 }
37835 _ => {
37836 self.write_keyword("UNIX_TO_STR");
37838 self.write("(");
37839 self.generate_expression(&e.this)?;
37840 if let Some(format) = &e.format {
37841 self.write(", '");
37842 self.write(format);
37843 self.write("'");
37844 }
37845 self.write(")");
37846 }
37847 }
37848 Ok(())
37849 }
37850
37851 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
37852 use crate::dialects::DialectType;
37853 let scale = e.scale.unwrap_or(0); match self.config.dialect {
37856 Some(DialectType::Snowflake) => {
37857 self.write_keyword("TO_TIMESTAMP");
37859 self.write("(");
37860 self.generate_expression(&e.this)?;
37861 if let Some(s) = e.scale {
37862 if s > 0 {
37863 self.write(", ");
37864 self.write(&s.to_string());
37865 }
37866 }
37867 self.write(")");
37868 }
37869 Some(DialectType::BigQuery) => {
37870 match scale {
37873 0 => {
37874 self.write_keyword("TIMESTAMP_SECONDS");
37875 self.write("(");
37876 self.generate_expression(&e.this)?;
37877 self.write(")");
37878 }
37879 3 => {
37880 self.write_keyword("TIMESTAMP_MILLIS");
37881 self.write("(");
37882 self.generate_expression(&e.this)?;
37883 self.write(")");
37884 }
37885 6 => {
37886 self.write_keyword("TIMESTAMP_MICROS");
37887 self.write("(");
37888 self.generate_expression(&e.this)?;
37889 self.write(")");
37890 }
37891 _ => {
37892 self.write_keyword("TIMESTAMP_SECONDS");
37894 self.write("(CAST(");
37895 self.generate_expression(&e.this)?;
37896 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
37897 }
37898 }
37899 }
37900 Some(DialectType::Spark) => {
37901 match scale {
37906 0 => {
37907 self.write_keyword("CAST");
37908 self.write("(");
37909 self.write_keyword("FROM_UNIXTIME");
37910 self.write("(");
37911 self.generate_expression(&e.this)?;
37912 self.write(") ");
37913 self.write_keyword("AS TIMESTAMP");
37914 self.write(")");
37915 }
37916 3 => {
37917 self.write_keyword("TIMESTAMP_MILLIS");
37918 self.write("(");
37919 self.generate_expression(&e.this)?;
37920 self.write(")");
37921 }
37922 6 => {
37923 self.write_keyword("TIMESTAMP_MICROS");
37924 self.write("(");
37925 self.generate_expression(&e.this)?;
37926 self.write(")");
37927 }
37928 _ => {
37929 self.write_keyword("TIMESTAMP_SECONDS");
37930 self.write("(");
37931 self.generate_expression(&e.this)?;
37932 self.write(&format!(" / POWER(10, {}))", scale));
37933 }
37934 }
37935 }
37936 Some(DialectType::Databricks) => {
37937 match scale {
37941 0 => {
37942 self.write_keyword("CAST");
37943 self.write("(");
37944 self.write_keyword("FROM_UNIXTIME");
37945 self.write("(");
37946 self.generate_expression(&e.this)?;
37947 self.write(") ");
37948 self.write_keyword("AS TIMESTAMP");
37949 self.write(")");
37950 }
37951 3 => {
37952 self.write_keyword("TIMESTAMP_MILLIS");
37953 self.write("(");
37954 self.generate_expression(&e.this)?;
37955 self.write(")");
37956 }
37957 6 => {
37958 self.write_keyword("TIMESTAMP_MICROS");
37959 self.write("(");
37960 self.generate_expression(&e.this)?;
37961 self.write(")");
37962 }
37963 _ => {
37964 self.write_keyword("TIMESTAMP_SECONDS");
37965 self.write("(");
37966 self.generate_expression(&e.this)?;
37967 self.write(&format!(" / POWER(10, {}))", scale));
37968 }
37969 }
37970 }
37971 Some(DialectType::Hive) => {
37972 if scale == 0 {
37974 self.write_keyword("FROM_UNIXTIME");
37975 self.write("(");
37976 self.generate_expression(&e.this)?;
37977 self.write(")");
37978 } else {
37979 self.write_keyword("FROM_UNIXTIME");
37980 self.write("(");
37981 self.generate_expression(&e.this)?;
37982 self.write(&format!(" / POWER(10, {})", scale));
37983 self.write(")");
37984 }
37985 }
37986 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37987 if scale == 0 {
37990 self.write_keyword("FROM_UNIXTIME");
37991 self.write("(");
37992 self.generate_expression(&e.this)?;
37993 self.write(")");
37994 } else {
37995 self.write_keyword("FROM_UNIXTIME");
37996 self.write("(CAST(");
37997 self.generate_expression(&e.this)?;
37998 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
37999 }
38000 }
38001 Some(DialectType::DuckDB) => {
38002 match scale {
38006 0 => {
38007 self.write_keyword("TO_TIMESTAMP");
38008 self.write("(");
38009 self.generate_expression(&e.this)?;
38010 self.write(")");
38011 }
38012 3 => {
38013 self.write_keyword("EPOCH_MS");
38014 self.write("(");
38015 self.generate_expression(&e.this)?;
38016 self.write(")");
38017 }
38018 6 => {
38019 self.write_keyword("MAKE_TIMESTAMP");
38020 self.write("(");
38021 self.generate_expression(&e.this)?;
38022 self.write(")");
38023 }
38024 _ => {
38025 self.write_keyword("TO_TIMESTAMP");
38026 self.write("(");
38027 self.generate_expression(&e.this)?;
38028 self.write(&format!(" / POWER(10, {}))", scale));
38029 self.write_keyword(" AT TIME ZONE");
38030 self.write(" 'UTC'");
38031 }
38032 }
38033 }
38034 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
38035 self.write_keyword("FROM_UNIXTIME");
38037 self.write("(");
38038 self.generate_expression(&e.this)?;
38039 self.write(")");
38040 }
38041 Some(DialectType::Oracle) => {
38042 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
38044 self.generate_expression(&e.this)?;
38045 self.write(" / 86400)");
38046 }
38047 Some(DialectType::Redshift) => {
38048 self.write("(TIMESTAMP 'epoch' + ");
38051 if scale == 0 {
38052 self.generate_expression(&e.this)?;
38053 } else {
38054 self.write("(");
38055 self.generate_expression(&e.this)?;
38056 self.write(&format!(" / POWER(10, {}))", scale));
38057 }
38058 self.write(" * INTERVAL '1 SECOND')");
38059 }
38060 Some(DialectType::Exasol) => {
38061 self.write_keyword("FROM_POSIX_TIME");
38063 self.write("(");
38064 self.generate_expression(&e.this)?;
38065 self.write(")");
38066 }
38067 _ => {
38068 self.write_keyword("TO_TIMESTAMP");
38070 self.write("(");
38071 self.generate_expression(&e.this)?;
38072 if let Some(s) = e.scale {
38073 self.write(", ");
38074 self.write(&s.to_string());
38075 }
38076 self.write(")");
38077 }
38078 }
38079 Ok(())
38080 }
38081
38082 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
38083 if !matches!(&*e.this, Expression::Null(_)) {
38085 self.write_keyword("NAME");
38086 self.write_space();
38087 self.generate_expression(&e.this)?;
38088 }
38089 if !e.expressions.is_empty() {
38090 self.write_space();
38091 self.write_keyword("VALUE");
38092 self.write_space();
38093 for (i, expr) in e.expressions.iter().enumerate() {
38094 if i > 0 {
38095 self.write(", ");
38096 }
38097 self.generate_expression(expr)?;
38098 }
38099 }
38100 Ok(())
38101 }
38102
38103 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
38104 if e.wrapped.is_some() {
38106 self.write("(");
38107 }
38108 self.generate_expression(&e.this)?;
38109 if e.wrapped.is_some() {
38110 self.write(")");
38111 }
38112 self.write("(");
38113 for (i, expr) in e.expressions.iter().enumerate() {
38114 if i > 0 {
38115 self.write(", ");
38116 }
38117 self.generate_expression(expr)?;
38118 }
38119 self.write(")");
38120 Ok(())
38121 }
38122
38123 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
38124 self.write_keyword("USING TEMPLATE");
38126 self.write_space();
38127 self.generate_expression(&e.this)?;
38128 Ok(())
38129 }
38130
38131 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
38132 self.write_keyword("UTC_TIME");
38134 Ok(())
38135 }
38136
38137 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
38138 if matches!(
38139 self.config.dialect,
38140 Some(crate::dialects::DialectType::ClickHouse)
38141 ) {
38142 self.write_keyword("CURRENT_TIMESTAMP");
38143 self.write("('UTC')");
38144 } else {
38145 self.write_keyword("UTC_TIMESTAMP");
38146 }
38147 Ok(())
38148 }
38149
38150 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
38151 use crate::dialects::DialectType;
38152 let func_name = match self.config.dialect {
38154 Some(DialectType::Snowflake) => "UUID_STRING",
38155 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
38156 Some(DialectType::BigQuery) => "GENERATE_UUID",
38157 _ => {
38158 if let Some(name) = &e.name {
38159 name.as_str()
38160 } else {
38161 "UUID"
38162 }
38163 }
38164 };
38165 self.write_keyword(func_name);
38166 self.write("(");
38167 if let Some(this) = &e.this {
38168 self.generate_expression(this)?;
38169 }
38170 self.write(")");
38171 Ok(())
38172 }
38173
38174 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
38175 self.write_keyword("MAP");
38177 self.write("(");
38178 let mut first = true;
38179 for (k, v) in e.keys.iter().zip(e.values.iter()) {
38180 if !first {
38181 self.write(", ");
38182 }
38183 self.generate_expression(k)?;
38184 self.write(", ");
38185 self.generate_expression(v)?;
38186 first = false;
38187 }
38188 self.write(")");
38189 Ok(())
38190 }
38191
38192 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
38193 self.write_keyword("VECTOR_SEARCH");
38195 self.write("(");
38196 self.generate_expression(&e.this)?;
38197 if let Some(col) = &e.column_to_search {
38198 self.write(", ");
38199 self.generate_expression(col)?;
38200 }
38201 if let Some(query_table) = &e.query_table {
38202 self.write(", ");
38203 self.generate_expression(query_table)?;
38204 }
38205 if let Some(query_col) = &e.query_column_to_search {
38206 self.write(", ");
38207 self.generate_expression(query_col)?;
38208 }
38209 if let Some(top_k) = &e.top_k {
38210 self.write(", ");
38211 self.generate_expression(top_k)?;
38212 }
38213 if let Some(dist_type) = &e.distance_type {
38214 self.write(", ");
38215 self.generate_expression(dist_type)?;
38216 }
38217 self.write(")");
38218 Ok(())
38219 }
38220
38221 fn generate_version(&mut self, e: &Version) -> Result<()> {
38222 use crate::dialects::DialectType;
38228 let skip_for = matches!(
38229 self.config.dialect,
38230 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
38231 );
38232 if !skip_for {
38233 self.write_keyword("FOR");
38234 self.write_space();
38235 }
38236 match e.this.as_ref() {
38238 Expression::Identifier(ident) => {
38239 self.write_keyword(&ident.name);
38240 }
38241 _ => {
38242 self.generate_expression(&e.this)?;
38243 }
38244 }
38245 self.write_space();
38246 self.write_keyword(&e.kind);
38247 if let Some(expression) = &e.expression {
38248 self.write_space();
38249 self.generate_expression(expression)?;
38250 }
38251 Ok(())
38252 }
38253
38254 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
38255 self.generate_expression(&e.this)?;
38257 Ok(())
38258 }
38259
38260 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
38261 if e.this.is_some() {
38263 self.write_keyword("NOT VOLATILE");
38264 } else {
38265 self.write_keyword("VOLATILE");
38266 }
38267 Ok(())
38268 }
38269
38270 fn generate_watermark_column_constraint(
38271 &mut self,
38272 e: &WatermarkColumnConstraint,
38273 ) -> Result<()> {
38274 self.write_keyword("WATERMARK FOR");
38276 self.write_space();
38277 self.generate_expression(&e.this)?;
38278 self.write_space();
38279 self.write_keyword("AS");
38280 self.write_space();
38281 self.generate_expression(&e.expression)?;
38282 Ok(())
38283 }
38284
38285 fn generate_week(&mut self, e: &Week) -> Result<()> {
38286 self.write_keyword("WEEK");
38288 self.write("(");
38289 self.generate_expression(&e.this)?;
38290 if let Some(mode) = &e.mode {
38291 self.write(", ");
38292 self.generate_expression(mode)?;
38293 }
38294 self.write(")");
38295 Ok(())
38296 }
38297
38298 fn generate_when(&mut self, e: &When) -> Result<()> {
38299 self.write_keyword("WHEN");
38303 self.write_space();
38304
38305 if let Some(matched) = &e.matched {
38307 match matched.as_ref() {
38309 Expression::Boolean(b) if b.value => {
38310 self.write_keyword("MATCHED");
38311 }
38312 _ => {
38313 self.write_keyword("NOT MATCHED");
38314 }
38315 }
38316 } else {
38317 self.write_keyword("NOT MATCHED");
38318 }
38319
38320 if self.config.matched_by_source {
38325 if let Some(source) = &e.source {
38326 if let Expression::Boolean(b) = source.as_ref() {
38327 if b.value {
38328 self.write_space();
38330 self.write_keyword("BY SOURCE");
38331 }
38332 } else {
38334 self.write_space();
38336 self.write_keyword("BY SOURCE");
38337 }
38338 }
38339 }
38340
38341 if let Some(condition) = &e.condition {
38343 self.write_space();
38344 self.write_keyword("AND");
38345 self.write_space();
38346 self.generate_expression(condition)?;
38347 }
38348
38349 self.write_space();
38350 self.write_keyword("THEN");
38351 self.write_space();
38352
38353 self.generate_merge_action(&e.then)?;
38356
38357 Ok(())
38358 }
38359
38360 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
38361 match action {
38362 Expression::Tuple(tuple) => {
38363 let elements = &tuple.expressions;
38364 if elements.is_empty() {
38365 return self.generate_expression(action);
38366 }
38367 match &elements[0] {
38369 Expression::Var(v) if v.this == "INSERT" => {
38370 self.write_keyword("INSERT");
38371 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
38373 self.write(" *");
38374 if let Some(Expression::Where(w)) = elements.get(2) {
38375 self.write_space();
38376 self.generate_where(w)?;
38377 }
38378 } else {
38379 let mut values_idx = 1;
38380 if elements.len() > 1 {
38382 if let Expression::Tuple(cols) = &elements[1] {
38383 if elements.len() > 2 {
38385 self.write(" (");
38387 for (i, col) in cols.expressions.iter().enumerate() {
38388 if i > 0 {
38389 self.write(", ");
38390 }
38391 if !self.merge_strip_qualifiers.is_empty() {
38393 let stripped = self.strip_merge_qualifier(col);
38394 self.generate_expression(&stripped)?;
38395 } else {
38396 self.generate_expression(col)?;
38397 }
38398 }
38399 self.write(")");
38400 values_idx = 2;
38401 } else {
38402 values_idx = 1;
38404 }
38405 }
38406 }
38407 let mut next_idx = values_idx;
38408 if values_idx < elements.len()
38410 && !matches!(&elements[values_idx], Expression::Where(_))
38411 {
38412 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
38414 if !is_row {
38415 self.write_space();
38416 self.write_keyword("VALUES");
38417 }
38418 self.write(" ");
38419 if let Expression::Tuple(vals) = &elements[values_idx] {
38420 self.write("(");
38421 for (i, val) in vals.expressions.iter().enumerate() {
38422 if i > 0 {
38423 self.write(", ");
38424 }
38425 self.generate_expression(val)?;
38426 }
38427 self.write(")");
38428 } else {
38429 self.generate_expression(&elements[values_idx])?;
38430 }
38431 next_idx += 1;
38432 }
38433 if let Some(Expression::Where(w)) = elements.get(next_idx) {
38434 self.write_space();
38435 self.generate_where(w)?;
38436 }
38437 } }
38439 Expression::Var(v) if v.this == "UPDATE" => {
38440 self.write_keyword("UPDATE");
38441 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
38443 self.write(" *");
38444 if let Some(Expression::Where(w)) = elements.get(2) {
38445 self.write_space();
38446 self.generate_where(w)?;
38447 }
38448 } else if elements.len() > 1 {
38449 self.write_space();
38450 self.write_keyword("SET");
38451 if self.config.pretty {
38453 self.write_newline();
38454 self.indent_level += 1;
38455 self.write_indent();
38456 } else {
38457 self.write_space();
38458 }
38459 if let Expression::Tuple(assignments) = &elements[1] {
38460 for (i, assignment) in assignments.expressions.iter().enumerate() {
38461 if i > 0 {
38462 if self.config.pretty {
38463 self.write(",");
38464 self.write_newline();
38465 self.write_indent();
38466 } else {
38467 self.write(", ");
38468 }
38469 }
38470 if !self.merge_strip_qualifiers.is_empty() {
38472 self.generate_merge_set_assignment(assignment)?;
38473 } else {
38474 self.generate_expression(assignment)?;
38475 }
38476 }
38477 } else {
38478 self.generate_expression(&elements[1])?;
38479 }
38480 if self.config.pretty {
38481 self.indent_level -= 1;
38482 }
38483 if let Some(Expression::Where(w)) = elements.get(2) {
38484 self.write_space();
38485 self.generate_where(w)?;
38486 }
38487 }
38488 }
38489 Expression::Var(v) if v.this == "DELETE" => {
38490 self.write_keyword("DELETE");
38491 if let Some(Expression::Where(w)) = elements.get(1) {
38492 self.write_space();
38493 self.generate_where(w)?;
38494 }
38495 }
38496 _ => {
38497 self.generate_expression(action)?;
38499 }
38500 }
38501 }
38502 Expression::Var(v)
38503 if v.this == "INSERT"
38504 || v.this == "UPDATE"
38505 || v.this == "DELETE"
38506 || v.this == "DO NOTHING" =>
38507 {
38508 self.write_keyword(&v.this);
38509 }
38510 _ => {
38511 self.generate_expression(action)?;
38512 }
38513 }
38514 Ok(())
38515 }
38516
38517 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
38519 match assignment {
38520 Expression::Eq(eq) => {
38521 let stripped_left = self.strip_merge_qualifier(&eq.left);
38523 self.generate_expression(&stripped_left)?;
38524 self.write(" = ");
38525 self.generate_expression(&eq.right)?;
38526 Ok(())
38527 }
38528 other => self.generate_expression(other),
38529 }
38530 }
38531
38532 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
38534 match expr {
38535 Expression::Column(col) => {
38536 if let Some(ref table_ident) = col.table {
38537 if self
38538 .merge_strip_qualifiers
38539 .iter()
38540 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
38541 {
38542 let mut col = col.clone();
38544 col.table = None;
38545 return Expression::Column(col);
38546 }
38547 }
38548 expr.clone()
38549 }
38550 Expression::Dot(dot) => {
38551 if let Expression::Identifier(id) = &dot.this {
38553 if self
38554 .merge_strip_qualifiers
38555 .iter()
38556 .any(|n| n.eq_ignore_ascii_case(&id.name))
38557 {
38558 return Expression::Identifier(dot.field.clone());
38559 }
38560 }
38561 expr.clone()
38562 }
38563 _ => expr.clone(),
38564 }
38565 }
38566
38567 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
38568 for (i, expr) in e.expressions.iter().enumerate() {
38570 if i > 0 {
38571 if self.config.pretty {
38573 self.write_newline();
38574 self.write_indent();
38575 } else {
38576 self.write_space();
38577 }
38578 }
38579 self.generate_expression(expr)?;
38580 }
38581 Ok(())
38582 }
38583
38584 fn generate_where(&mut self, e: &Where) -> Result<()> {
38585 self.write_keyword("WHERE");
38587 self.write_space();
38588 self.generate_expression(&e.this)?;
38589 Ok(())
38590 }
38591
38592 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
38593 self.write_keyword("WIDTH_BUCKET");
38595 self.write("(");
38596 self.generate_expression(&e.this)?;
38597 if let Some(min_value) = &e.min_value {
38598 self.write(", ");
38599 self.generate_expression(min_value)?;
38600 }
38601 if let Some(max_value) = &e.max_value {
38602 self.write(", ");
38603 self.generate_expression(max_value)?;
38604 }
38605 if let Some(num_buckets) = &e.num_buckets {
38606 self.write(", ");
38607 self.generate_expression(num_buckets)?;
38608 }
38609 self.write(")");
38610 Ok(())
38611 }
38612
38613 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
38614 self.generate_window_spec(e)
38616 }
38617
38618 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
38619 let mut has_content = false;
38621
38622 if !e.partition_by.is_empty() {
38624 self.write_keyword("PARTITION BY");
38625 self.write_space();
38626 for (i, expr) in e.partition_by.iter().enumerate() {
38627 if i > 0 {
38628 self.write(", ");
38629 }
38630 self.generate_expression(expr)?;
38631 }
38632 has_content = true;
38633 }
38634
38635 if !e.order_by.is_empty() {
38637 if has_content {
38638 self.write_space();
38639 }
38640 self.write_keyword("ORDER BY");
38641 self.write_space();
38642 for (i, ordered) in e.order_by.iter().enumerate() {
38643 if i > 0 {
38644 self.write(", ");
38645 }
38646 self.generate_expression(&ordered.this)?;
38647 if ordered.desc {
38648 self.write_space();
38649 self.write_keyword("DESC");
38650 } else if ordered.explicit_asc {
38651 self.write_space();
38652 self.write_keyword("ASC");
38653 }
38654 if let Some(nulls_first) = ordered.nulls_first {
38655 self.write_space();
38656 self.write_keyword("NULLS");
38657 self.write_space();
38658 if nulls_first {
38659 self.write_keyword("FIRST");
38660 } else {
38661 self.write_keyword("LAST");
38662 }
38663 }
38664 }
38665 has_content = true;
38666 }
38667
38668 if let Some(frame) = &e.frame {
38670 if has_content {
38671 self.write_space();
38672 }
38673 self.generate_window_frame(frame)?;
38674 }
38675
38676 Ok(())
38677 }
38678
38679 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
38680 self.write_keyword("WITH");
38682 self.write_space();
38683 if e.no.is_some() {
38684 self.write_keyword("NO");
38685 self.write_space();
38686 }
38687 self.write_keyword("DATA");
38688
38689 if let Some(statistics) = &e.statistics {
38691 self.write_space();
38692 self.write_keyword("AND");
38693 self.write_space();
38694 match statistics.as_ref() {
38696 Expression::Boolean(b) if !b.value => {
38697 self.write_keyword("NO");
38698 self.write_space();
38699 }
38700 _ => {}
38701 }
38702 self.write_keyword("STATISTICS");
38703 }
38704 Ok(())
38705 }
38706
38707 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
38708 self.write_keyword("WITH FILL");
38710
38711 if let Some(from_) = &e.from_ {
38712 self.write_space();
38713 self.write_keyword("FROM");
38714 self.write_space();
38715 self.generate_expression(from_)?;
38716 }
38717
38718 if let Some(to) = &e.to {
38719 self.write_space();
38720 self.write_keyword("TO");
38721 self.write_space();
38722 self.generate_expression(to)?;
38723 }
38724
38725 if let Some(step) = &e.step {
38726 self.write_space();
38727 self.write_keyword("STEP");
38728 self.write_space();
38729 self.generate_expression(step)?;
38730 }
38731
38732 if let Some(staleness) = &e.staleness {
38733 self.write_space();
38734 self.write_keyword("STALENESS");
38735 self.write_space();
38736 self.generate_expression(staleness)?;
38737 }
38738
38739 if let Some(interpolate) = &e.interpolate {
38740 self.write_space();
38741 self.write_keyword("INTERPOLATE");
38742 self.write(" (");
38743 self.generate_interpolate_item(interpolate)?;
38745 self.write(")");
38746 }
38747
38748 Ok(())
38749 }
38750
38751 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
38753 match expr {
38754 Expression::Alias(alias) => {
38755 self.generate_identifier(&alias.alias)?;
38757 self.write_space();
38758 self.write_keyword("AS");
38759 self.write_space();
38760 self.generate_expression(&alias.this)?;
38761 }
38762 Expression::Tuple(tuple) => {
38763 for (i, item) in tuple.expressions.iter().enumerate() {
38764 if i > 0 {
38765 self.write(", ");
38766 }
38767 self.generate_interpolate_item(item)?;
38768 }
38769 }
38770 other => {
38771 self.generate_expression(other)?;
38772 }
38773 }
38774 Ok(())
38775 }
38776
38777 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
38778 self.write_keyword("WITH JOURNAL TABLE");
38780 self.write("=");
38781 self.generate_expression(&e.this)?;
38782 Ok(())
38783 }
38784
38785 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
38786 self.generate_expression(&e.this)?;
38788 self.write_space();
38789 self.write_keyword("WITH");
38790 self.write_space();
38791 self.write_keyword(&e.op);
38792 Ok(())
38793 }
38794
38795 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
38796 self.write_keyword("WITH");
38798 self.write_space();
38799 for (i, expr) in e.expressions.iter().enumerate() {
38800 if i > 0 {
38801 self.write(", ");
38802 }
38803 self.generate_expression(expr)?;
38804 }
38805 Ok(())
38806 }
38807
38808 fn generate_with_schema_binding_property(
38809 &mut self,
38810 e: &WithSchemaBindingProperty,
38811 ) -> Result<()> {
38812 self.write_keyword("WITH");
38814 self.write_space();
38815 self.generate_expression(&e.this)?;
38816 Ok(())
38817 }
38818
38819 fn generate_with_system_versioning_property(
38820 &mut self,
38821 e: &WithSystemVersioningProperty,
38822 ) -> Result<()> {
38823 let mut parts = Vec::new();
38829
38830 if let Some(this) = &e.this {
38831 let mut s = String::from("HISTORY_TABLE=");
38833 let mut gen = Generator::new();
38834 gen.generate_expression(this)?;
38835 s.push_str(&gen.output);
38836 parts.push(s);
38837 }
38838
38839 if let Some(data_consistency) = &e.data_consistency {
38840 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
38841 let mut gen = Generator::new();
38842 gen.generate_expression(data_consistency)?;
38843 s.push_str(&gen.output);
38844 parts.push(s);
38845 }
38846
38847 if let Some(retention_period) = &e.retention_period {
38848 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
38849 let mut gen = Generator::new();
38850 gen.generate_expression(retention_period)?;
38851 s.push_str(&gen.output);
38852 parts.push(s);
38853 }
38854
38855 self.write_keyword("SYSTEM_VERSIONING");
38856 self.write("=");
38857
38858 if !parts.is_empty() {
38859 self.write_keyword("ON");
38860 self.write("(");
38861 self.write(&parts.join(", "));
38862 self.write(")");
38863 } else if e.on.is_some() {
38864 self.write_keyword("ON");
38865 } else {
38866 self.write_keyword("OFF");
38867 }
38868
38869 if e.with_.is_some() {
38871 let inner = self.output.clone();
38872 self.output.clear();
38873 self.write("WITH(");
38874 self.write(&inner);
38875 self.write(")");
38876 }
38877
38878 Ok(())
38879 }
38880
38881 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
38882 self.write_keyword("WITH");
38884 self.write(" (");
38885 for (i, expr) in e.expressions.iter().enumerate() {
38886 if i > 0 {
38887 self.write(", ");
38888 }
38889 self.generate_expression(expr)?;
38890 }
38891 self.write(")");
38892 Ok(())
38893 }
38894
38895 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
38896 self.write_keyword("XMLELEMENT");
38899 self.write("(");
38900
38901 if e.evalname.is_some() {
38902 self.write_keyword("EVALNAME");
38903 } else {
38904 self.write_keyword("NAME");
38905 }
38906 self.write_space();
38907 self.generate_expression(&e.this)?;
38908
38909 for expr in &e.expressions {
38910 self.write(", ");
38911 self.generate_expression(expr)?;
38912 }
38913 self.write(")");
38914 Ok(())
38915 }
38916
38917 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
38918 self.write_keyword("XMLGET");
38920 self.write("(");
38921 self.generate_expression(&e.this)?;
38922 self.write(", ");
38923 self.generate_expression(&e.expression)?;
38924 if let Some(instance) = &e.instance {
38925 self.write(", ");
38926 self.generate_expression(instance)?;
38927 }
38928 self.write(")");
38929 Ok(())
38930 }
38931
38932 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
38933 self.generate_expression(&e.this)?;
38935 if let Some(expression) = &e.expression {
38936 self.write("(");
38937 self.generate_expression(expression)?;
38938 self.write(")");
38939 }
38940 Ok(())
38941 }
38942
38943 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
38944 self.write_keyword("XMLTABLE");
38946 self.write("(");
38947
38948 if self.config.pretty {
38949 self.indent_level += 1;
38950 self.write_newline();
38951 self.write_indent();
38952 self.generate_expression(&e.this)?;
38953
38954 if let Some(passing) = &e.passing {
38955 self.write_newline();
38956 self.write_indent();
38957 self.write_keyword("PASSING");
38958 if let Expression::Tuple(tuple) = passing.as_ref() {
38959 for expr in &tuple.expressions {
38960 self.write_newline();
38961 self.indent_level += 1;
38962 self.write_indent();
38963 self.generate_expression(expr)?;
38964 self.indent_level -= 1;
38965 }
38966 } else {
38967 self.write_newline();
38968 self.indent_level += 1;
38969 self.write_indent();
38970 self.generate_expression(passing)?;
38971 self.indent_level -= 1;
38972 }
38973 }
38974
38975 if e.by_ref.is_some() {
38976 self.write_newline();
38977 self.write_indent();
38978 self.write_keyword("RETURNING SEQUENCE BY REF");
38979 }
38980
38981 if !e.columns.is_empty() {
38982 self.write_newline();
38983 self.write_indent();
38984 self.write_keyword("COLUMNS");
38985 for (i, col) in e.columns.iter().enumerate() {
38986 self.write_newline();
38987 self.indent_level += 1;
38988 self.write_indent();
38989 self.generate_expression(col)?;
38990 self.indent_level -= 1;
38991 if i < e.columns.len() - 1 {
38992 self.write(",");
38993 }
38994 }
38995 }
38996
38997 self.indent_level -= 1;
38998 self.write_newline();
38999 self.write_indent();
39000 self.write(")");
39001 return Ok(());
39002 }
39003
39004 if let Some(namespaces) = &e.namespaces {
39006 self.write_keyword("XMLNAMESPACES");
39007 self.write("(");
39008 if let Expression::Tuple(tuple) = namespaces.as_ref() {
39010 for (i, expr) in tuple.expressions.iter().enumerate() {
39011 if i > 0 {
39012 self.write(", ");
39013 }
39014 if !matches!(expr, Expression::Alias(_)) {
39017 self.write_keyword("DEFAULT");
39018 self.write_space();
39019 }
39020 self.generate_expression(expr)?;
39021 }
39022 } else {
39023 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
39025 self.write_keyword("DEFAULT");
39026 self.write_space();
39027 }
39028 self.generate_expression(namespaces)?;
39029 }
39030 self.write("), ");
39031 }
39032
39033 self.generate_expression(&e.this)?;
39035
39036 if let Some(passing) = &e.passing {
39038 self.write_space();
39039 self.write_keyword("PASSING");
39040 self.write_space();
39041 if let Expression::Tuple(tuple) = passing.as_ref() {
39043 for (i, expr) in tuple.expressions.iter().enumerate() {
39044 if i > 0 {
39045 self.write(", ");
39046 }
39047 self.generate_expression(expr)?;
39048 }
39049 } else {
39050 self.generate_expression(passing)?;
39051 }
39052 }
39053
39054 if e.by_ref.is_some() {
39056 self.write_space();
39057 self.write_keyword("RETURNING SEQUENCE BY REF");
39058 }
39059
39060 if !e.columns.is_empty() {
39062 self.write_space();
39063 self.write_keyword("COLUMNS");
39064 self.write_space();
39065 for (i, col) in e.columns.iter().enumerate() {
39066 if i > 0 {
39067 self.write(", ");
39068 }
39069 self.generate_expression(col)?;
39070 }
39071 }
39072
39073 self.write(")");
39074 Ok(())
39075 }
39076
39077 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
39078 if let Some(this) = &e.this {
39081 self.generate_expression(this)?;
39082 if let Some(expression) = &e.expression {
39083 self.write_space();
39084 self.write_keyword("XOR");
39085 self.write_space();
39086 self.generate_expression(expression)?;
39087 }
39088 }
39089
39090 for (i, expr) in e.expressions.iter().enumerate() {
39092 if i > 0 || e.this.is_some() {
39093 self.write_space();
39094 self.write_keyword("XOR");
39095 self.write_space();
39096 }
39097 self.generate_expression(expr)?;
39098 }
39099 Ok(())
39100 }
39101
39102 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
39103 self.write_keyword("ZIPF");
39105 self.write("(");
39106 self.generate_expression(&e.this)?;
39107 if let Some(elementcount) = &e.elementcount {
39108 self.write(", ");
39109 self.generate_expression(elementcount)?;
39110 }
39111 if let Some(gen) = &e.gen {
39112 self.write(", ");
39113 self.generate_expression(gen)?;
39114 }
39115 self.write(")");
39116 Ok(())
39117 }
39118}
39119
39120impl Default for Generator {
39121 fn default() -> Self {
39122 Self::new()
39123 }
39124}
39125
39126#[cfg(test)]
39127mod tests {
39128 use super::*;
39129 use crate::parser::Parser;
39130
39131 fn roundtrip(sql: &str) -> String {
39132 let ast = Parser::parse_sql(sql).unwrap();
39133 Generator::sql(&ast[0]).unwrap()
39134 }
39135
39136 #[test]
39137 fn test_simple_select() {
39138 let result = roundtrip("SELECT 1");
39139 assert_eq!(result, "SELECT 1");
39140 }
39141
39142 #[test]
39143 fn test_select_from() {
39144 let result = roundtrip("SELECT a, b FROM t");
39145 assert_eq!(result, "SELECT a, b FROM t");
39146 }
39147
39148 #[test]
39149 fn test_select_where() {
39150 let result = roundtrip("SELECT * FROM t WHERE x = 1");
39151 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
39152 }
39153
39154 #[test]
39155 fn test_select_join() {
39156 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
39157 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
39158 }
39159
39160 #[test]
39161 fn test_insert() {
39162 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
39163 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
39164 }
39165
39166 #[test]
39167 fn test_pretty_print() {
39168 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
39169 let result = Generator::pretty_sql(&ast[0]).unwrap();
39170 assert!(result.contains('\n'));
39171 }
39172
39173 #[test]
39174 fn test_window_function() {
39175 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
39176 assert_eq!(
39177 result,
39178 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
39179 );
39180 }
39181
39182 #[test]
39183 fn test_window_function_with_frame() {
39184 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
39185 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
39186 }
39187
39188 #[test]
39189 fn test_aggregate_with_filter() {
39190 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
39191 assert_eq!(
39192 result,
39193 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
39194 );
39195 }
39196
39197 #[test]
39198 fn test_subscript() {
39199 let result = roundtrip("SELECT arr[0]");
39200 assert_eq!(result, "SELECT arr[0]");
39201 }
39202
39203 #[test]
39205 fn test_create_table() {
39206 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
39207 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
39208 }
39209
39210 #[test]
39211 fn test_create_table_with_constraints() {
39212 let result = roundtrip(
39213 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
39214 );
39215 assert_eq!(
39216 result,
39217 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
39218 );
39219 }
39220
39221 #[test]
39222 fn test_create_table_if_not_exists() {
39223 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
39224 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
39225 }
39226
39227 #[test]
39228 fn test_drop_table() {
39229 let result = roundtrip("DROP TABLE users");
39230 assert_eq!(result, "DROP TABLE users");
39231 }
39232
39233 #[test]
39234 fn test_drop_table_if_exists_cascade() {
39235 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
39236 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
39237 }
39238
39239 #[test]
39240 fn test_alter_table_add_column() {
39241 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
39242 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
39243 }
39244
39245 #[test]
39246 fn test_alter_table_drop_column() {
39247 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
39248 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
39249 }
39250
39251 #[test]
39252 fn test_create_index() {
39253 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
39254 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
39255 }
39256
39257 #[test]
39258 fn test_create_unique_index() {
39259 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
39260 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
39261 }
39262
39263 #[test]
39264 fn test_drop_index() {
39265 let result = roundtrip("DROP INDEX idx_name");
39266 assert_eq!(result, "DROP INDEX idx_name");
39267
39268 let result = roundtrip(r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#);
39269 assert_eq!(
39270 result,
39271 r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#
39272 );
39273
39274 let result = roundtrip(r#"DROP INDEX "public"."IdxMixed""#);
39275 assert_eq!(result, r#"DROP INDEX "public"."IdxMixed""#);
39276 }
39277
39278 #[test]
39279 fn test_create_view() {
39280 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
39281 assert_eq!(
39282 result,
39283 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
39284 );
39285 }
39286
39287 #[test]
39288 fn test_drop_view() {
39289 let result = roundtrip("DROP VIEW active_users");
39290 assert_eq!(result, "DROP VIEW active_users");
39291 }
39292
39293 #[test]
39294 fn test_truncate() {
39295 let result = roundtrip("TRUNCATE TABLE users");
39296 assert_eq!(result, "TRUNCATE TABLE users");
39297 }
39298
39299 #[test]
39300 fn test_string_literal_escaping_default() {
39301 let result = roundtrip("SELECT 'hello'");
39303 assert_eq!(result, "SELECT 'hello'");
39304
39305 let result = roundtrip("SELECT 'it''s a test'");
39307 assert_eq!(result, "SELECT 'it''s a test'");
39308 }
39309
39310 #[test]
39311 fn test_not_in_style_prefix_default_generic() {
39312 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
39313 assert_eq!(
39314 result,
39315 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
39316 );
39317 }
39318
39319 #[test]
39320 fn test_not_in_style_infix_generic_override() {
39321 let ast =
39322 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
39323 .unwrap();
39324 let config = GeneratorConfig {
39325 not_in_style: NotInStyle::Infix,
39326 ..Default::default()
39327 };
39328 let mut gen = Generator::with_config(config);
39329 let result = gen.generate(&ast[0]).unwrap();
39330 assert_eq!(
39331 result,
39332 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
39333 );
39334 }
39335
39336 #[test]
39337 fn test_string_literal_escaping_mysql() {
39338 use crate::dialects::DialectType;
39339
39340 let config = GeneratorConfig {
39341 dialect: Some(DialectType::MySQL),
39342 ..Default::default()
39343 };
39344
39345 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39346 let mut gen = Generator::with_config(config.clone());
39347 let result = gen.generate(&ast[0]).unwrap();
39348 assert_eq!(result, "SELECT 'hello'");
39349
39350 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39352 let mut gen = Generator::with_config(config.clone());
39353 let result = gen.generate(&ast[0]).unwrap();
39354 assert_eq!(result, "SELECT 'it''s'");
39355 }
39356
39357 #[test]
39358 fn test_string_literal_escaping_postgres() {
39359 use crate::dialects::DialectType;
39360
39361 let config = GeneratorConfig {
39362 dialect: Some(DialectType::PostgreSQL),
39363 ..Default::default()
39364 };
39365
39366 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39367 let mut gen = Generator::with_config(config.clone());
39368 let result = gen.generate(&ast[0]).unwrap();
39369 assert_eq!(result, "SELECT 'hello'");
39370
39371 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39373 let mut gen = Generator::with_config(config.clone());
39374 let result = gen.generate(&ast[0]).unwrap();
39375 assert_eq!(result, "SELECT 'it''s'");
39376 }
39377
39378 #[test]
39379 fn test_string_literal_escaping_bigquery() {
39380 use crate::dialects::DialectType;
39381
39382 let config = GeneratorConfig {
39383 dialect: Some(DialectType::BigQuery),
39384 ..Default::default()
39385 };
39386
39387 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39388 let mut gen = Generator::with_config(config.clone());
39389 let result = gen.generate(&ast[0]).unwrap();
39390 assert_eq!(result, "SELECT 'hello'");
39391
39392 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39394 let mut gen = Generator::with_config(config.clone());
39395 let result = gen.generate(&ast[0]).unwrap();
39396 assert_eq!(result, "SELECT 'it\\'s'");
39397 }
39398
39399 #[test]
39400 fn test_generate_deep_and_chain_without_stack_growth() {
39401 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
39402 Expression::column("c0"),
39403 Expression::number(0),
39404 )));
39405
39406 for i in 1..2500 {
39407 let predicate = Expression::Eq(Box::new(BinaryOp::new(
39408 Expression::column(format!("c{i}")),
39409 Expression::number(i as i64),
39410 )));
39411 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
39412 }
39413
39414 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
39415 assert!(sql.contains("c2499 = 2499"), "{}", sql);
39416 }
39417
39418 #[test]
39419 fn test_generate_deep_or_chain_without_stack_growth() {
39420 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
39421 Expression::column("c0"),
39422 Expression::number(0),
39423 )));
39424
39425 for i in 1..2500 {
39426 let predicate = Expression::Eq(Box::new(BinaryOp::new(
39427 Expression::column(format!("c{i}")),
39428 Expression::number(i as i64),
39429 )));
39430 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
39431 }
39432
39433 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
39434 assert!(sql.contains("c2499 = 2499"), "{}", sql);
39435 }
39436}