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 self.write_keyword("LISTAGG");
20373 self.write("(");
20374 if f.distinct {
20375 self.write_keyword("DISTINCT");
20376 self.write_space();
20377 }
20378 self.generate_expression(&f.this)?;
20379 if let Some(ref sep) = f.separator {
20380 self.write(", ");
20381 self.generate_expression(sep)?;
20382 } else if matches!(
20383 self.config.dialect,
20384 Some(DialectType::Trino) | Some(DialectType::Presto)
20385 ) {
20386 self.write(", ','");
20388 }
20389 if let Some(ref overflow) = f.on_overflow {
20390 self.write_space();
20391 self.write_keyword("ON OVERFLOW");
20392 self.write_space();
20393 match overflow {
20394 ListAggOverflow::Error => self.write_keyword("ERROR"),
20395 ListAggOverflow::Truncate { filler, with_count } => {
20396 self.write_keyword("TRUNCATE");
20397 if let Some(ref fill) = filler {
20398 self.write_space();
20399 self.generate_expression(fill)?;
20400 }
20401 if *with_count {
20402 self.write_space();
20403 self.write_keyword("WITH COUNT");
20404 } else {
20405 self.write_space();
20406 self.write_keyword("WITHOUT COUNT");
20407 }
20408 }
20409 }
20410 }
20411 self.write(")");
20412 if let Some(ref order_by) = f.order_by {
20413 self.write_space();
20414 self.write_keyword("WITHIN GROUP");
20415 self.write(" (");
20416 self.write_keyword("ORDER BY");
20417 self.write_space();
20418 for (i, ord) in order_by.iter().enumerate() {
20419 if i > 0 {
20420 self.write(", ");
20421 }
20422 self.generate_ordered(ord)?;
20423 }
20424 self.write(")");
20425 }
20426 if let Some(ref filter) = f.filter {
20427 self.write_space();
20428 self.write_keyword("FILTER");
20429 self.write("(");
20430 self.write_keyword("WHERE");
20431 self.write_space();
20432 self.generate_expression(filter)?;
20433 self.write(")");
20434 }
20435 Ok(())
20436 }
20437
20438 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
20439 self.write_keyword("SUM_IF");
20440 self.write("(");
20441 self.generate_expression(&f.this)?;
20442 self.write(", ");
20443 self.generate_expression(&f.condition)?;
20444 self.write(")");
20445 if let Some(ref filter) = f.filter {
20446 self.write_space();
20447 self.write_keyword("FILTER");
20448 self.write("(");
20449 self.write_keyword("WHERE");
20450 self.write_space();
20451 self.generate_expression(filter)?;
20452 self.write(")");
20453 }
20454 Ok(())
20455 }
20456
20457 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
20458 self.write_keyword("APPROX_PERCENTILE");
20459 self.write("(");
20460 self.generate_expression(&f.this)?;
20461 self.write(", ");
20462 self.generate_expression(&f.percentile)?;
20463 if let Some(ref acc) = f.accuracy {
20464 self.write(", ");
20465 self.generate_expression(acc)?;
20466 }
20467 self.write(")");
20468 if let Some(ref filter) = f.filter {
20469 self.write_space();
20470 self.write_keyword("FILTER");
20471 self.write("(");
20472 self.write_keyword("WHERE");
20473 self.write_space();
20474 self.generate_expression(filter)?;
20475 self.write(")");
20476 }
20477 Ok(())
20478 }
20479
20480 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
20481 self.write_keyword(name);
20482 self.write("(");
20483 self.generate_expression(&f.percentile)?;
20484 self.write(")");
20485 if let Some(ref order_by) = f.order_by {
20486 self.write_space();
20487 self.write_keyword("WITHIN GROUP");
20488 self.write(" (");
20489 self.write_keyword("ORDER BY");
20490 self.write_space();
20491 self.generate_expression(&f.this)?;
20492 for ord in order_by.iter() {
20493 if ord.desc {
20494 self.write_space();
20495 self.write_keyword("DESC");
20496 }
20497 }
20498 self.write(")");
20499 }
20500 if let Some(ref filter) = f.filter {
20501 self.write_space();
20502 self.write_keyword("FILTER");
20503 self.write("(");
20504 self.write_keyword("WHERE");
20505 self.write_space();
20506 self.generate_expression(filter)?;
20507 self.write(")");
20508 }
20509 Ok(())
20510 }
20511
20512 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
20515 self.write_keyword("NTILE");
20516 self.write("(");
20517 if let Some(num_buckets) = &f.num_buckets {
20518 self.generate_expression(num_buckets)?;
20519 }
20520 if let Some(order_by) = &f.order_by {
20521 self.write_keyword(" ORDER BY ");
20522 for (i, ob) in order_by.iter().enumerate() {
20523 if i > 0 {
20524 self.write(", ");
20525 }
20526 self.generate_ordered(ob)?;
20527 }
20528 }
20529 self.write(")");
20530 Ok(())
20531 }
20532
20533 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
20534 self.write_keyword(name);
20535 self.write("(");
20536 self.generate_expression(&f.this)?;
20537 if let Some(ref offset) = f.offset {
20538 self.write(", ");
20539 self.generate_expression(offset)?;
20540 if let Some(ref default) = f.default {
20541 self.write(", ");
20542 self.generate_expression(default)?;
20543 }
20544 }
20545 if self.config.ignore_nulls_in_func {
20547 match f.ignore_nulls {
20548 Some(true) => {
20549 self.write_space();
20550 self.write_keyword("IGNORE NULLS");
20551 }
20552 Some(false) => {
20553 self.write_space();
20554 self.write_keyword("RESPECT NULLS");
20555 }
20556 None => {}
20557 }
20558 }
20559 self.write(")");
20560 if !self.config.ignore_nulls_in_func {
20562 match f.ignore_nulls {
20563 Some(true) => {
20564 self.write_space();
20565 self.write_keyword("IGNORE NULLS");
20566 }
20567 Some(false) => {
20568 self.write_space();
20569 self.write_keyword("RESPECT NULLS");
20570 }
20571 None => {}
20572 }
20573 }
20574 Ok(())
20575 }
20576
20577 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
20578 self.write_keyword(name);
20579 self.write("(");
20580 self.generate_expression(&f.this)?;
20581 if !f.order_by.is_empty() {
20583 self.write_space();
20584 self.write_keyword("ORDER BY");
20585 self.write_space();
20586 for (i, ordered) in f.order_by.iter().enumerate() {
20587 if i > 0 {
20588 self.write(", ");
20589 }
20590 self.generate_ordered(ordered)?;
20591 }
20592 }
20593 if self.config.ignore_nulls_in_func {
20595 match f.ignore_nulls {
20596 Some(true) => {
20597 self.write_space();
20598 self.write_keyword("IGNORE NULLS");
20599 }
20600 Some(false) => {
20601 self.write_space();
20602 self.write_keyword("RESPECT NULLS");
20603 }
20604 None => {}
20605 }
20606 }
20607 self.write(")");
20608 if !self.config.ignore_nulls_in_func {
20610 match f.ignore_nulls {
20611 Some(true) => {
20612 self.write_space();
20613 self.write_keyword("IGNORE NULLS");
20614 }
20615 Some(false) => {
20616 self.write_space();
20617 self.write_keyword("RESPECT NULLS");
20618 }
20619 None => {}
20620 }
20621 }
20622 Ok(())
20623 }
20624
20625 fn generate_value_func_with_ignore_nulls_bool(
20628 &mut self,
20629 name: &str,
20630 f: &ValueFunc,
20631 ) -> Result<()> {
20632 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
20633 self.write_keyword(name);
20634 self.write("(");
20635 self.generate_expression(&f.this)?;
20636 self.write(", ");
20637 self.write_keyword("TRUE");
20638 self.write(")");
20639 return Ok(());
20640 }
20641 self.generate_value_func(name, f)
20642 }
20643
20644 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
20645 self.write_keyword("NTH_VALUE");
20646 self.write("(");
20647 self.generate_expression(&f.this)?;
20648 self.write(", ");
20649 self.generate_expression(&f.offset)?;
20650 if self.config.ignore_nulls_in_func {
20652 match f.ignore_nulls {
20653 Some(true) => {
20654 self.write_space();
20655 self.write_keyword("IGNORE NULLS");
20656 }
20657 Some(false) => {
20658 self.write_space();
20659 self.write_keyword("RESPECT NULLS");
20660 }
20661 None => {}
20662 }
20663 }
20664 self.write(")");
20665 if matches!(
20667 self.config.dialect,
20668 Some(crate::dialects::DialectType::Snowflake)
20669 ) {
20670 match f.from_first {
20671 Some(true) => {
20672 self.write_space();
20673 self.write_keyword("FROM FIRST");
20674 }
20675 Some(false) => {
20676 self.write_space();
20677 self.write_keyword("FROM LAST");
20678 }
20679 None => {}
20680 }
20681 }
20682 if !self.config.ignore_nulls_in_func {
20684 match f.ignore_nulls {
20685 Some(true) => {
20686 self.write_space();
20687 self.write_keyword("IGNORE NULLS");
20688 }
20689 Some(false) => {
20690 self.write_space();
20691 self.write_keyword("RESPECT NULLS");
20692 }
20693 None => {}
20694 }
20695 }
20696 Ok(())
20697 }
20698
20699 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
20702 if matches!(
20705 self.config.dialect,
20706 Some(crate::dialects::DialectType::ClickHouse)
20707 ) {
20708 self.write_keyword("POSITION");
20709 self.write("(");
20710 self.generate_expression(&f.string)?;
20711 self.write(", ");
20712 self.generate_expression(&f.substring)?;
20713 if let Some(ref start) = f.start {
20714 self.write(", ");
20715 self.generate_expression(start)?;
20716 }
20717 self.write(")");
20718 return Ok(());
20719 }
20720
20721 self.write_keyword("POSITION");
20722 self.write("(");
20723 self.generate_expression(&f.substring)?;
20724 self.write_space();
20725 self.write_keyword("IN");
20726 self.write_space();
20727 self.generate_expression(&f.string)?;
20728 if let Some(ref start) = f.start {
20729 self.write(", ");
20730 self.generate_expression(start)?;
20731 }
20732 self.write(")");
20733 Ok(())
20734 }
20735
20736 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
20739 if f.lower.is_some() || f.upper.is_some() {
20741 self.write_keyword("RANDOM");
20742 self.write("(");
20743 if let Some(ref lower) = f.lower {
20744 self.generate_expression(lower)?;
20745 }
20746 if let Some(ref upper) = f.upper {
20747 self.write(", ");
20748 self.generate_expression(upper)?;
20749 }
20750 self.write(")");
20751 return Ok(());
20752 }
20753 let func_name = match self.config.dialect {
20755 Some(crate::dialects::DialectType::Snowflake)
20756 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
20757 _ => "RAND",
20758 };
20759 self.write_keyword(func_name);
20760 self.write("(");
20761 if !matches!(
20763 self.config.dialect,
20764 Some(crate::dialects::DialectType::DuckDB)
20765 ) {
20766 if let Some(ref seed) = f.seed {
20767 self.generate_expression(seed)?;
20768 }
20769 }
20770 self.write(")");
20771 Ok(())
20772 }
20773
20774 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
20775 self.write_keyword("TRUNCATE");
20776 self.write("(");
20777 self.generate_expression(&f.this)?;
20778 if let Some(ref decimals) = f.decimals {
20779 self.write(", ");
20780 self.generate_expression(decimals)?;
20781 }
20782 self.write(")");
20783 Ok(())
20784 }
20785
20786 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
20789 self.write_keyword("DECODE");
20790 self.write("(");
20791 self.generate_expression(&f.this)?;
20792 for (search, result) in &f.search_results {
20793 self.write(", ");
20794 self.generate_expression(search)?;
20795 self.write(", ");
20796 self.generate_expression(result)?;
20797 }
20798 if let Some(ref default) = f.default {
20799 self.write(", ");
20800 self.generate_expression(default)?;
20801 }
20802 self.write(")");
20803 Ok(())
20804 }
20805
20806 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
20809 self.write_keyword(name);
20810 self.write("(");
20811 self.generate_expression(&f.this)?;
20812 self.write(", ");
20813 self.generate_expression(&f.format)?;
20814 self.write(")");
20815 Ok(())
20816 }
20817
20818 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
20819 self.write_keyword("FROM_UNIXTIME");
20820 self.write("(");
20821 self.generate_expression(&f.this)?;
20822 if let Some(ref format) = f.format {
20823 self.write(", ");
20824 self.generate_expression(format)?;
20825 }
20826 self.write(")");
20827 Ok(())
20828 }
20829
20830 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
20831 self.write_keyword("UNIX_TIMESTAMP");
20832 self.write("(");
20833 if let Some(ref expr) = f.this {
20834 self.generate_expression(expr)?;
20835 if let Some(ref format) = f.format {
20836 self.write(", ");
20837 self.generate_expression(format)?;
20838 }
20839 } else if matches!(
20840 self.config.dialect,
20841 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
20842 ) {
20843 self.write_keyword("CURRENT_TIMESTAMP");
20845 self.write("()");
20846 }
20847 self.write(")");
20848 Ok(())
20849 }
20850
20851 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
20852 self.write_keyword("MAKE_DATE");
20853 self.write("(");
20854 self.generate_expression(&f.year)?;
20855 self.write(", ");
20856 self.generate_expression(&f.month)?;
20857 self.write(", ");
20858 self.generate_expression(&f.day)?;
20859 self.write(")");
20860 Ok(())
20861 }
20862
20863 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
20864 self.write_keyword("MAKE_TIMESTAMP");
20865 self.write("(");
20866 self.generate_expression(&f.year)?;
20867 self.write(", ");
20868 self.generate_expression(&f.month)?;
20869 self.write(", ");
20870 self.generate_expression(&f.day)?;
20871 self.write(", ");
20872 self.generate_expression(&f.hour)?;
20873 self.write(", ");
20874 self.generate_expression(&f.minute)?;
20875 self.write(", ");
20876 self.generate_expression(&f.second)?;
20877 if let Some(ref tz) = f.timezone {
20878 self.write(", ");
20879 self.generate_expression(tz)?;
20880 }
20881 self.write(")");
20882 Ok(())
20883 }
20884
20885 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
20887 match expr {
20888 Expression::Struct(s) => {
20889 if s.fields.iter().all(|(name, _)| name.is_some()) {
20890 Some(
20891 s.fields
20892 .iter()
20893 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
20894 .collect(),
20895 )
20896 } else {
20897 None
20898 }
20899 }
20900 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20901 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
20903 Some(
20904 f.args
20905 .iter()
20906 .filter_map(|a| {
20907 if let Expression::Alias(alias) = a {
20908 Some(alias.alias.name.clone())
20909 } else {
20910 None
20911 }
20912 })
20913 .collect(),
20914 )
20915 } else {
20916 None
20917 }
20918 }
20919 _ => None,
20920 }
20921 }
20922
20923 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
20925 match expr {
20926 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
20927 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20928 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
20929 }
20930 _ => false,
20931 }
20932 }
20933
20934 fn struct_field_count(expr: &Expression) -> usize {
20936 match expr {
20937 Expression::Struct(s) => s.fields.len(),
20938 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
20939 _ => 0,
20940 }
20941 }
20942
20943 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
20945 match expr {
20946 Expression::Struct(s) => {
20947 let mut new_fields = Vec::with_capacity(s.fields.len());
20948 for (i, (name, value)) in s.fields.iter().enumerate() {
20949 if name.is_none() && i < field_names.len() {
20950 new_fields.push((Some(field_names[i].clone()), value.clone()));
20951 } else {
20952 new_fields.push((name.clone(), value.clone()));
20953 }
20954 }
20955 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
20956 }
20957 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20958 let mut new_args = Vec::with_capacity(f.args.len());
20959 for (i, arg) in f.args.iter().enumerate() {
20960 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
20961 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
20963 this: arg.clone(),
20964 alias: crate::expressions::Identifier::new(field_names[i].clone()),
20965 column_aliases: Vec::new(),
20966 alias_explicit_as: false,
20967 alias_keyword: None,
20968 pre_alias_comments: Vec::new(),
20969 trailing_comments: Vec::new(),
20970 inferred_type: None,
20971 })));
20972 } else {
20973 new_args.push(arg.clone());
20974 }
20975 }
20976 Expression::Function(Box::new(crate::expressions::Function {
20977 name: f.name.clone(),
20978 args: new_args,
20979 distinct: f.distinct,
20980 trailing_comments: f.trailing_comments.clone(),
20981 use_bracket_syntax: f.use_bracket_syntax,
20982 no_parens: f.no_parens,
20983 quoted: f.quoted,
20984 span: None,
20985 inferred_type: None,
20986 }))
20987 }
20988 _ => expr.clone(),
20989 }
20990 }
20991
20992 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
20996 let first = match expressions.first() {
20997 Some(e) => e,
20998 None => return expressions.to_vec(),
20999 };
21000
21001 let field_names = match Self::extract_struct_field_names(first) {
21002 Some(names) if !names.is_empty() => names,
21003 _ => return expressions.to_vec(),
21004 };
21005
21006 let mut result = Vec::with_capacity(expressions.len());
21007 for (idx, expr) in expressions.iter().enumerate() {
21008 if idx == 0 {
21009 result.push(expr.clone());
21010 continue;
21011 }
21012 if Self::struct_field_count(expr) == field_names.len()
21014 && Self::struct_has_unnamed_fields(expr)
21015 {
21016 result.push(Self::apply_struct_field_names(expr, &field_names));
21017 } else {
21018 result.push(expr.clone());
21019 }
21020 }
21021 result
21022 }
21023
21024 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
21027 let needs_inheritance = matches!(
21030 self.config.dialect,
21031 Some(DialectType::DuckDB)
21032 | Some(DialectType::Spark)
21033 | Some(DialectType::Databricks)
21034 | Some(DialectType::Hive)
21035 | Some(DialectType::Snowflake)
21036 | Some(DialectType::Presto)
21037 | Some(DialectType::Trino)
21038 );
21039 let propagated: Vec<Expression>;
21040 let expressions = if needs_inheritance && f.expressions.len() > 1 {
21041 propagated = Self::inherit_struct_field_names(&f.expressions);
21042 &propagated
21043 } else {
21044 &f.expressions
21045 };
21046
21047 let should_split = if self.config.pretty && !expressions.is_empty() {
21049 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
21050 for expr in expressions {
21051 let mut temp_gen = Generator::with_arc_config(self.config.clone());
21052 Arc::make_mut(&mut temp_gen.config).pretty = false;
21053 temp_gen.generate_expression(expr)?;
21054 expr_strings.push(temp_gen.output);
21055 }
21056 self.too_wide(&expr_strings)
21057 } else {
21058 false
21059 };
21060
21061 if f.bracket_notation {
21062 let (open, close) = match self.config.dialect {
21066 None
21067 | Some(DialectType::Generic)
21068 | Some(DialectType::Spark)
21069 | Some(DialectType::Databricks)
21070 | Some(DialectType::Hive) => {
21071 self.write_keyword("ARRAY");
21072 ("(", ")")
21073 }
21074 Some(DialectType::Presto)
21075 | Some(DialectType::Trino)
21076 | Some(DialectType::PostgreSQL)
21077 | Some(DialectType::Redshift)
21078 | Some(DialectType::Materialize)
21079 | Some(DialectType::RisingWave)
21080 | Some(DialectType::CockroachDB) => {
21081 self.write_keyword("ARRAY");
21082 ("[", "]")
21083 }
21084 _ => ("[", "]"),
21085 };
21086 self.write(open);
21087 if should_split {
21088 self.write_newline();
21089 self.indent_level += 1;
21090 for (i, expr) in expressions.iter().enumerate() {
21091 self.write_indent();
21092 self.generate_expression(expr)?;
21093 if i + 1 < expressions.len() {
21094 self.write(",");
21095 }
21096 self.write_newline();
21097 }
21098 self.indent_level -= 1;
21099 self.write_indent();
21100 } else {
21101 for (i, expr) in expressions.iter().enumerate() {
21102 if i > 0 {
21103 self.write(", ");
21104 }
21105 self.generate_expression(expr)?;
21106 }
21107 }
21108 self.write(close);
21109 } else {
21110 if f.use_list_keyword {
21112 self.write_keyword("LIST");
21113 } else {
21114 self.write_keyword("ARRAY");
21115 }
21116 let has_subquery = expressions
21119 .iter()
21120 .any(|e| matches!(e, Expression::Select(_)));
21121 let (open, close) = if matches!(
21122 self.config.dialect,
21123 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
21124 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
21125 && has_subquery)
21126 {
21127 ("(", ")")
21128 } else {
21129 ("[", "]")
21130 };
21131 self.write(open);
21132 if should_split {
21133 self.write_newline();
21134 self.indent_level += 1;
21135 for (i, expr) in expressions.iter().enumerate() {
21136 self.write_indent();
21137 self.generate_expression(expr)?;
21138 if i + 1 < expressions.len() {
21139 self.write(",");
21140 }
21141 self.write_newline();
21142 }
21143 self.indent_level -= 1;
21144 self.write_indent();
21145 } else {
21146 for (i, expr) in expressions.iter().enumerate() {
21147 if i > 0 {
21148 self.write(", ");
21149 }
21150 self.generate_expression(expr)?;
21151 }
21152 }
21153 self.write(close);
21154 }
21155 Ok(())
21156 }
21157
21158 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
21159 self.write_keyword("ARRAY_SORT");
21160 self.write("(");
21161 self.generate_expression(&f.this)?;
21162 if let Some(ref comp) = f.comparator {
21163 self.write(", ");
21164 self.generate_expression(comp)?;
21165 }
21166 self.write(")");
21167 Ok(())
21168 }
21169
21170 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
21171 self.write_keyword(name);
21172 self.write("(");
21173 self.generate_expression(&f.this)?;
21174 self.write(", ");
21175 self.generate_expression(&f.separator)?;
21176 if let Some(ref null_rep) = f.null_replacement {
21177 self.write(", ");
21178 self.generate_expression(null_rep)?;
21179 }
21180 self.write(")");
21181 Ok(())
21182 }
21183
21184 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
21185 self.write_keyword("UNNEST");
21186 self.write("(");
21187 self.generate_expression(&f.this)?;
21188 for extra in &f.expressions {
21189 self.write(", ");
21190 self.generate_expression(extra)?;
21191 }
21192 self.write(")");
21193 if f.with_ordinality {
21194 self.write_space();
21195 if self.config.unnest_with_ordinality {
21196 self.write_keyword("WITH ORDINALITY");
21198 } else if f.offset_alias.is_some() {
21199 if let Some(ref alias) = f.alias {
21202 self.write_keyword("AS");
21203 self.write_space();
21204 self.generate_identifier(alias)?;
21205 self.write_space();
21206 }
21207 self.write_keyword("WITH OFFSET");
21208 if let Some(ref offset_alias) = f.offset_alias {
21209 self.write_space();
21210 self.write_keyword("AS");
21211 self.write_space();
21212 self.generate_identifier(offset_alias)?;
21213 }
21214 } else {
21215 self.write_keyword("WITH OFFSET");
21217 if f.alias.is_none() {
21218 self.write(" AS offset");
21219 }
21220 }
21221 }
21222 if let Some(ref alias) = f.alias {
21223 let should_add_alias = if !f.with_ordinality {
21225 true
21226 } else if self.config.unnest_with_ordinality {
21227 true
21229 } else if f.offset_alias.is_some() {
21230 false
21232 } else {
21233 true
21235 };
21236 if should_add_alias {
21237 self.write_space();
21238 self.write_keyword("AS");
21239 self.write_space();
21240 self.generate_identifier(alias)?;
21241 }
21242 }
21243 Ok(())
21244 }
21245
21246 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
21247 self.write_keyword("FILTER");
21248 self.write("(");
21249 self.generate_expression(&f.this)?;
21250 self.write(", ");
21251 self.generate_expression(&f.filter)?;
21252 self.write(")");
21253 Ok(())
21254 }
21255
21256 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
21257 self.write_keyword("TRANSFORM");
21258 self.write("(");
21259 self.generate_expression(&f.this)?;
21260 self.write(", ");
21261 self.generate_expression(&f.transform)?;
21262 self.write(")");
21263 Ok(())
21264 }
21265
21266 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
21267 self.write_keyword(name);
21268 self.write("(");
21269 self.generate_expression(&f.start)?;
21270 self.write(", ");
21271 self.generate_expression(&f.stop)?;
21272 if let Some(ref step) = f.step {
21273 self.write(", ");
21274 self.generate_expression(step)?;
21275 }
21276 self.write(")");
21277 Ok(())
21278 }
21279
21280 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
21283 self.write_keyword("STRUCT");
21284 self.write("(");
21285 for (i, (name, expr)) in f.fields.iter().enumerate() {
21286 if i > 0 {
21287 self.write(", ");
21288 }
21289 if let Some(ref id) = name {
21290 self.generate_identifier(id)?;
21291 self.write(" ");
21292 self.write_keyword("AS");
21293 self.write(" ");
21294 }
21295 self.generate_expression(expr)?;
21296 }
21297 self.write(")");
21298 Ok(())
21299 }
21300
21301 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
21303 let mut names: Vec<Option<String>> = Vec::new();
21306 let mut values: Vec<&Expression> = Vec::new();
21307 let mut all_named = true;
21308
21309 for arg in &func.args {
21310 match arg {
21311 Expression::Alias(a) => {
21312 names.push(Some(a.alias.name.clone()));
21313 values.push(&a.this);
21314 }
21315 _ => {
21316 names.push(None);
21317 values.push(arg);
21318 all_named = false;
21319 }
21320 }
21321 }
21322
21323 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
21324 self.write("{");
21326 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21327 if i > 0 {
21328 self.write(", ");
21329 }
21330 if let Some(n) = name {
21331 self.write("'");
21332 self.write(n);
21333 self.write("'");
21334 } else {
21335 self.write("'_");
21336 self.write(&i.to_string());
21337 self.write("'");
21338 }
21339 self.write(": ");
21340 self.generate_expression(value)?;
21341 }
21342 self.write("}");
21343 return Ok(());
21344 }
21345
21346 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21347 self.write_keyword("OBJECT_CONSTRUCT");
21349 self.write("(");
21350 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21351 if i > 0 {
21352 self.write(", ");
21353 }
21354 if let Some(n) = name {
21355 self.write("'");
21356 self.write(n);
21357 self.write("'");
21358 } else {
21359 self.write("'_");
21360 self.write(&i.to_string());
21361 self.write("'");
21362 }
21363 self.write(", ");
21364 self.generate_expression(value)?;
21365 }
21366 self.write(")");
21367 return Ok(());
21368 }
21369
21370 if matches!(
21371 self.config.dialect,
21372 Some(DialectType::Presto) | Some(DialectType::Trino)
21373 ) {
21374 if all_named && !names.is_empty() {
21375 self.write_keyword("CAST");
21378 self.write("(");
21379 self.write_keyword("ROW");
21380 self.write("(");
21381 for (i, value) in values.iter().enumerate() {
21382 if i > 0 {
21383 self.write(", ");
21384 }
21385 self.generate_expression(value)?;
21386 }
21387 self.write(")");
21388 self.write(" ");
21389 self.write_keyword("AS");
21390 self.write(" ");
21391 self.write_keyword("ROW");
21392 self.write("(");
21393 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
21394 if i > 0 {
21395 self.write(", ");
21396 }
21397 if let Some(n) = name {
21398 self.write(n);
21399 }
21400 self.write(" ");
21401 let type_str = Self::infer_sql_type_for_presto(value);
21402 self.write_keyword(&type_str);
21403 }
21404 self.write(")");
21405 self.write(")");
21406 } else {
21407 self.write_keyword("ROW");
21409 self.write("(");
21410 for (i, value) in values.iter().enumerate() {
21411 if i > 0 {
21412 self.write(", ");
21413 }
21414 self.generate_expression(value)?;
21415 }
21416 self.write(")");
21417 }
21418 return Ok(());
21419 }
21420
21421 self.write_keyword("ROW");
21423 self.write("(");
21424 for (i, value) in values.iter().enumerate() {
21425 if i > 0 {
21426 self.write(", ");
21427 }
21428 self.generate_expression(value)?;
21429 }
21430 self.write(")");
21431 Ok(())
21432 }
21433
21434 fn infer_sql_type_for_presto(expr: &Expression) -> String {
21436 match expr {
21437 Expression::Literal(lit)
21438 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
21439 {
21440 "VARCHAR".to_string()
21441 }
21442 Expression::Literal(lit)
21443 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
21444 {
21445 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
21446 unreachable!()
21447 };
21448 if n.contains('.') {
21449 "DOUBLE".to_string()
21450 } else {
21451 "INTEGER".to_string()
21452 }
21453 }
21454 Expression::Boolean(_) => "BOOLEAN".to_string(),
21455 Expression::Literal(lit)
21456 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
21457 {
21458 "DATE".to_string()
21459 }
21460 Expression::Literal(lit)
21461 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
21462 {
21463 "TIMESTAMP".to_string()
21464 }
21465 Expression::Literal(lit)
21466 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
21467 {
21468 "TIMESTAMP".to_string()
21469 }
21470 Expression::Array(_) | Expression::ArrayFunc(_) => {
21471 "ARRAY(VARCHAR)".to_string()
21473 }
21474 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
21476 Expression::Function(f) => {
21477 if f.name.eq_ignore_ascii_case("STRUCT") {
21478 "ROW".to_string()
21479 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
21480 "DATE".to_string()
21481 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
21482 || f.name.eq_ignore_ascii_case("NOW")
21483 {
21484 "TIMESTAMP".to_string()
21485 } else {
21486 "VARCHAR".to_string()
21487 }
21488 }
21489 _ => "VARCHAR".to_string(),
21490 }
21491 }
21492
21493 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
21494 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
21496 self.write_keyword("STRUCT_EXTRACT");
21497 self.write("(");
21498 self.generate_expression(&f.this)?;
21499 self.write(", ");
21500 self.write("'");
21502 self.write(&f.field.name);
21503 self.write("'");
21504 self.write(")");
21505 return Ok(());
21506 }
21507 self.generate_expression(&f.this)?;
21508 self.write(".");
21509 self.generate_identifier(&f.field)
21510 }
21511
21512 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
21513 if matches!(
21514 self.config.dialect,
21515 Some(DialectType::Spark | DialectType::Databricks)
21516 ) {
21517 self.write_keyword("STRUCT");
21518 self.write("(");
21519 for (i, (name, value)) in f.pairs.iter().enumerate() {
21520 if i > 0 {
21521 self.write(", ");
21522 }
21523 self.generate_expression(value)?;
21524 self.write(" ");
21525 self.write_keyword("AS");
21526 self.write(" ");
21527 if let Expression::Literal(lit) = name {
21528 if let Literal::String(field_name) = lit.as_ref() {
21529 self.generate_identifier(&Identifier::new(field_name))?;
21530 } else {
21531 self.generate_expression(name)?;
21532 }
21533 } else {
21534 self.generate_expression(name)?;
21535 }
21536 }
21537 self.write(")");
21538 return Ok(());
21539 }
21540
21541 self.write_keyword("NAMED_STRUCT");
21542 self.write("(");
21543 for (i, (name, value)) in f.pairs.iter().enumerate() {
21544 if i > 0 {
21545 self.write(", ");
21546 }
21547 self.generate_expression(name)?;
21548 self.write(", ");
21549 self.generate_expression(value)?;
21550 }
21551 self.write(")");
21552 Ok(())
21553 }
21554
21555 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
21558 if f.curly_brace_syntax {
21559 if f.with_map_keyword {
21561 self.write_keyword("MAP");
21562 self.write(" ");
21563 }
21564 self.write("{");
21565 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
21566 if i > 0 {
21567 self.write(", ");
21568 }
21569 self.generate_expression(key)?;
21570 self.write(": ");
21571 self.generate_expression(val)?;
21572 }
21573 self.write("}");
21574 } else {
21575 self.write_keyword("MAP");
21577 self.write("(");
21578 self.write_keyword("ARRAY");
21579 self.write("[");
21580 for (i, key) in f.keys.iter().enumerate() {
21581 if i > 0 {
21582 self.write(", ");
21583 }
21584 self.generate_expression(key)?;
21585 }
21586 self.write("], ");
21587 self.write_keyword("ARRAY");
21588 self.write("[");
21589 for (i, val) in f.values.iter().enumerate() {
21590 if i > 0 {
21591 self.write(", ");
21592 }
21593 self.generate_expression(val)?;
21594 }
21595 self.write("])");
21596 }
21597 Ok(())
21598 }
21599
21600 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
21601 self.write_keyword(name);
21602 self.write("(");
21603 self.generate_expression(&f.this)?;
21604 self.write(", ");
21605 self.generate_expression(&f.transform)?;
21606 self.write(")");
21607 Ok(())
21608 }
21609
21610 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
21613 use crate::dialects::DialectType;
21614
21615 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
21617
21618 if use_arrow {
21619 self.generate_expression(&f.this)?;
21621 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
21622 self.write(" ->> ");
21623 } else {
21624 self.write(" -> ");
21625 }
21626 self.generate_expression(&f.path)?;
21627 return Ok(());
21628 }
21629
21630 if f.hash_arrow_syntax
21632 && matches!(
21633 self.config.dialect,
21634 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21635 )
21636 {
21637 self.generate_expression(&f.this)?;
21638 self.write(" #>> ");
21639 self.generate_expression(&f.path)?;
21640 return Ok(());
21641 }
21642
21643 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21646 match name {
21647 "JSON_EXTRACT_SCALAR"
21648 | "JSON_EXTRACT_PATH_TEXT"
21649 | "JSON_EXTRACT"
21650 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
21651 _ => name,
21652 }
21653 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
21654 match name {
21655 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
21656 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
21657 _ => name,
21658 }
21659 } else {
21660 name
21661 };
21662
21663 self.write_keyword(func_name);
21664 self.write("(");
21665 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21667 if let Expression::Cast(ref cast) = f.this {
21668 if matches!(cast.to, crate::expressions::DataType::Json) {
21669 self.generate_expression(&cast.this)?;
21670 } else {
21671 self.generate_expression(&f.this)?;
21672 }
21673 } else {
21674 self.generate_expression(&f.this)?;
21675 }
21676 } else {
21677 self.generate_expression(&f.this)?;
21678 }
21679 if matches!(
21682 self.config.dialect,
21683 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21684 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
21685 {
21686 if let Expression::Literal(ref lit) = f.path {
21687 if let Literal::String(ref s) = lit.as_ref() {
21688 let parts = Self::decompose_json_path(s);
21689 for part in &parts {
21690 self.write(", '");
21691 self.write(part);
21692 self.write("'");
21693 }
21694 }
21695 } else {
21696 self.write(", ");
21697 self.generate_expression(&f.path)?;
21698 }
21699 } else {
21700 self.write(", ");
21701 self.generate_expression(&f.path)?;
21702 }
21703
21704 if let Some(ref wrapper) = f.wrapper_option {
21707 self.write_space();
21708 self.write_keyword(wrapper);
21709 }
21710 if let Some(ref quotes) = f.quotes_option {
21711 self.write_space();
21712 self.write_keyword(quotes);
21713 if f.on_scalar_string {
21714 self.write_space();
21715 self.write_keyword("ON SCALAR STRING");
21716 }
21717 }
21718 if let Some(ref on_err) = f.on_error {
21719 self.write_space();
21720 self.write_keyword(on_err);
21721 }
21722 if let Some(ref ret_type) = f.returning {
21723 self.write_space();
21724 self.write_keyword("RETURNING");
21725 self.write_space();
21726 self.generate_data_type(ret_type)?;
21727 }
21728
21729 self.write(")");
21730 Ok(())
21731 }
21732
21733 fn dialect_supports_json_arrow(&self) -> bool {
21735 use crate::dialects::DialectType;
21736 match self.config.dialect {
21737 Some(DialectType::PostgreSQL) => true,
21739 Some(DialectType::MySQL) => true,
21740 Some(DialectType::DuckDB) => true,
21741 Some(DialectType::CockroachDB) => true,
21742 Some(DialectType::StarRocks) => true,
21743 Some(DialectType::SQLite) => true,
21744 _ => false,
21746 }
21747 }
21748
21749 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
21750 use crate::dialects::DialectType;
21751
21752 if matches!(
21754 self.config.dialect,
21755 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21756 ) && name == "JSON_EXTRACT_PATH"
21757 {
21758 self.generate_expression(&f.this)?;
21759 self.write(" #> ");
21760 if f.paths.len() == 1 {
21761 self.generate_expression(&f.paths[0])?;
21762 } else {
21763 self.write_keyword("ARRAY");
21765 self.write("[");
21766 for (i, path) in f.paths.iter().enumerate() {
21767 if i > 0 {
21768 self.write(", ");
21769 }
21770 self.generate_expression(path)?;
21771 }
21772 self.write("]");
21773 }
21774 return Ok(());
21775 }
21776
21777 self.write_keyword(name);
21778 self.write("(");
21779 self.generate_expression(&f.this)?;
21780 for path in &f.paths {
21781 self.write(", ");
21782 self.generate_expression(path)?;
21783 }
21784 self.write(")");
21785 Ok(())
21786 }
21787
21788 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
21789 use crate::dialects::DialectType;
21790
21791 self.write_keyword("JSON_OBJECT");
21792 self.write("(");
21793 if f.star {
21794 self.write("*");
21795 } else {
21796 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
21800 || matches!(
21801 self.config.dialect,
21802 Some(DialectType::BigQuery)
21803 | Some(DialectType::MySQL)
21804 | Some(DialectType::SQLite)
21805 );
21806
21807 for (i, (key, value)) in f.pairs.iter().enumerate() {
21808 if i > 0 {
21809 self.write(", ");
21810 }
21811 self.generate_expression(key)?;
21812 if use_comma_syntax {
21813 self.write(", ");
21814 } else {
21815 self.write(": ");
21816 }
21817 self.generate_expression(value)?;
21818 }
21819 }
21820 if let Some(null_handling) = f.null_handling {
21821 self.write_space();
21822 match null_handling {
21823 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21824 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21825 }
21826 }
21827 if f.with_unique_keys {
21828 self.write_space();
21829 self.write_keyword("WITH UNIQUE KEYS");
21830 }
21831 if let Some(ref ret_type) = f.returning_type {
21832 self.write_space();
21833 self.write_keyword("RETURNING");
21834 self.write_space();
21835 self.generate_data_type(ret_type)?;
21836 if f.format_json {
21837 self.write_space();
21838 self.write_keyword("FORMAT JSON");
21839 }
21840 if let Some(ref enc) = f.encoding {
21841 self.write_space();
21842 self.write_keyword("ENCODING");
21843 self.write_space();
21844 self.write(enc);
21845 }
21846 }
21847 self.write(")");
21848 Ok(())
21849 }
21850
21851 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
21852 self.write_keyword(name);
21853 self.write("(");
21854 self.generate_expression(&f.this)?;
21855 for (path, value) in &f.path_values {
21856 self.write(", ");
21857 self.generate_expression(path)?;
21858 self.write(", ");
21859 self.generate_expression(value)?;
21860 }
21861 self.write(")");
21862 Ok(())
21863 }
21864
21865 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
21866 self.write_keyword("JSON_ARRAYAGG");
21867 self.write("(");
21868 self.generate_expression(&f.this)?;
21869 if let Some(ref order_by) = f.order_by {
21870 self.write_space();
21871 self.write_keyword("ORDER BY");
21872 self.write_space();
21873 for (i, ord) in order_by.iter().enumerate() {
21874 if i > 0 {
21875 self.write(", ");
21876 }
21877 self.generate_ordered(ord)?;
21878 }
21879 }
21880 if let Some(null_handling) = f.null_handling {
21881 self.write_space();
21882 match null_handling {
21883 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21884 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21885 }
21886 }
21887 self.write(")");
21888 if let Some(ref filter) = f.filter {
21889 self.write_space();
21890 self.write_keyword("FILTER");
21891 self.write("(");
21892 self.write_keyword("WHERE");
21893 self.write_space();
21894 self.generate_expression(filter)?;
21895 self.write(")");
21896 }
21897 Ok(())
21898 }
21899
21900 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
21901 self.write_keyword("JSON_OBJECTAGG");
21902 self.write("(");
21903 self.generate_expression(&f.key)?;
21904 self.write(": ");
21905 self.generate_expression(&f.value)?;
21906 if let Some(null_handling) = f.null_handling {
21907 self.write_space();
21908 match null_handling {
21909 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21910 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21911 }
21912 }
21913 self.write(")");
21914 if let Some(ref filter) = f.filter {
21915 self.write_space();
21916 self.write_keyword("FILTER");
21917 self.write("(");
21918 self.write_keyword("WHERE");
21919 self.write_space();
21920 self.generate_expression(filter)?;
21921 self.write(")");
21922 }
21923 Ok(())
21924 }
21925
21926 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
21929 use crate::dialects::DialectType;
21930
21931 if self.config.dialect == Some(DialectType::Redshift) {
21933 self.write_keyword("CAST");
21934 self.write("(");
21935 self.generate_expression(&f.this)?;
21936 self.write_space();
21937 self.write_keyword("AS");
21938 self.write_space();
21939 self.generate_data_type(&f.to)?;
21940 self.write(")");
21941 return Ok(());
21942 }
21943
21944 self.write_keyword("CONVERT");
21945 self.write("(");
21946 self.generate_data_type(&f.to)?;
21947 self.write(", ");
21948 self.generate_expression(&f.this)?;
21949 if let Some(ref style) = f.style {
21950 self.write(", ");
21951 self.generate_expression(style)?;
21952 }
21953 self.write(")");
21954 Ok(())
21955 }
21956
21957 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
21960 if f.colon {
21961 self.write_keyword("LAMBDA");
21963 self.write_space();
21964 for (i, param) in f.parameters.iter().enumerate() {
21965 if i > 0 {
21966 self.write(", ");
21967 }
21968 self.generate_identifier(param)?;
21969 }
21970 self.write(" : ");
21971 } else {
21972 if f.parameters.len() == 1 {
21974 self.generate_identifier(&f.parameters[0])?;
21975 } else {
21976 self.write("(");
21977 for (i, param) in f.parameters.iter().enumerate() {
21978 if i > 0 {
21979 self.write(", ");
21980 }
21981 self.generate_identifier(param)?;
21982 }
21983 self.write(")");
21984 }
21985 self.write(" -> ");
21986 }
21987 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21988 if let Expression::Lambda(inner) = &f.body {
21989 self.generate_lambda_with_parenthesized_single_param(inner)?;
21990 return Ok(());
21991 }
21992 }
21993
21994 self.generate_expression(&f.body)
21995 }
21996
21997 fn generate_lambda_with_parenthesized_single_param(&mut self, f: &LambdaExpr) -> Result<()> {
21998 if f.colon {
21999 return self.generate_lambda(f);
22000 }
22001
22002 self.write("(");
22003 for (i, param) in f.parameters.iter().enumerate() {
22004 if i > 0 {
22005 self.write(", ");
22006 }
22007 self.generate_identifier(param)?;
22008 }
22009 self.write(") -> ");
22010 self.generate_expression(&f.body)
22011 }
22012
22013 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
22014 self.generate_identifier(&f.name)?;
22015 match f.separator {
22016 NamedArgSeparator::DArrow => self.write(" => "),
22017 NamedArgSeparator::ColonEq => self.write(" := "),
22018 NamedArgSeparator::Eq => self.write(" = "),
22019 }
22020 self.generate_expression(&f.value)
22021 }
22022
22023 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
22024 self.write_keyword(&f.prefix);
22025 self.write(" ");
22026 self.generate_expression(&f.this)
22027 }
22028
22029 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
22030 match f.style {
22031 ParameterStyle::Question => self.write("?"),
22032 ParameterStyle::Dollar => {
22033 self.write("$");
22034 if let Some(idx) = f.index {
22035 self.write(&idx.to_string());
22036 } else if let Some(ref name) = f.name {
22037 self.write(name);
22039 }
22040 }
22041 ParameterStyle::DollarBrace => {
22042 self.write("${");
22044 if let Some(ref name) = f.name {
22045 self.write(name);
22046 }
22047 if let Some(ref expr) = f.expression {
22048 self.write(":");
22049 self.write(expr);
22050 }
22051 self.write("}");
22052 }
22053 ParameterStyle::Colon => {
22054 self.write(":");
22055 if let Some(idx) = f.index {
22056 self.write(&idx.to_string());
22057 } else if let Some(ref name) = f.name {
22058 self.write(name);
22059 }
22060 }
22061 ParameterStyle::At => {
22062 self.write("@");
22063 if let Some(ref name) = f.name {
22064 if f.string_quoted {
22065 self.write("'");
22066 self.write(name);
22067 self.write("'");
22068 } else if f.quoted {
22069 self.write("\"");
22070 self.write(name);
22071 self.write("\"");
22072 } else {
22073 self.write(name);
22074 }
22075 }
22076 }
22077 ParameterStyle::DoubleAt => {
22078 self.write("@@");
22079 if let Some(ref name) = f.name {
22080 self.write(name);
22081 }
22082 }
22083 ParameterStyle::DoubleDollar => {
22084 self.write("$$");
22085 if let Some(ref name) = f.name {
22086 self.write(name);
22087 }
22088 }
22089 ParameterStyle::Percent => {
22090 if let Some(ref name) = f.name {
22091 self.write("%(");
22093 self.write(name);
22094 self.write(")s");
22095 } else {
22096 self.write("%s");
22098 }
22099 }
22100 ParameterStyle::Brace => {
22101 self.write("{");
22104 if let Some(ref name) = f.name {
22105 self.write(name);
22106 }
22107 if let Some(ref expr) = f.expression {
22108 self.write(": ");
22109 self.write(expr);
22110 }
22111 self.write("}");
22112 }
22113 }
22114 Ok(())
22115 }
22116
22117 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
22118 self.write("?");
22119 if let Some(idx) = f.index {
22120 self.write(&idx.to_string());
22121 }
22122 Ok(())
22123 }
22124
22125 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
22126 if f.is_block {
22127 self.write("/*");
22128 self.write(&f.text);
22129 self.write("*/");
22130 } else {
22131 self.write("--");
22132 self.write(&f.text);
22133 }
22134 Ok(())
22135 }
22136
22137 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
22140 self.generate_expression(&f.this)?;
22141 if f.not {
22142 self.write_space();
22143 self.write_keyword("NOT");
22144 }
22145 self.write_space();
22146 self.write_keyword("SIMILAR TO");
22147 self.write_space();
22148 self.generate_expression(&f.pattern)?;
22149 if let Some(ref escape) = f.escape {
22150 self.write_space();
22151 self.write_keyword("ESCAPE");
22152 self.write_space();
22153 self.generate_expression(escape)?;
22154 }
22155 Ok(())
22156 }
22157
22158 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
22159 self.generate_expression(&f.this)?;
22160 self.write_space();
22161 if let Some(op) = &f.op {
22163 match op {
22164 QuantifiedOp::Eq => self.write("="),
22165 QuantifiedOp::Neq => self.write("<>"),
22166 QuantifiedOp::Lt => self.write("<"),
22167 QuantifiedOp::Lte => self.write("<="),
22168 QuantifiedOp::Gt => self.write(">"),
22169 QuantifiedOp::Gte => self.write(">="),
22170 }
22171 self.write_space();
22172 }
22173 self.write_keyword(name);
22174
22175 if matches!(&f.subquery, Expression::Subquery(_)) {
22177 self.write_space();
22178 self.generate_expression(&f.subquery)?;
22179 } else {
22180 let is_statement = matches!(
22181 &f.subquery,
22182 Expression::Select(_)
22183 | Expression::Union(_)
22184 | Expression::Intersect(_)
22185 | Expression::Except(_)
22186 );
22187 if is_statement
22188 && !self.config.quantified_no_paren_space
22189 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
22190 {
22191 self.write_space();
22192 }
22193 self.write("(");
22194
22195 if self.config.pretty && is_statement {
22196 self.write_newline();
22197 self.indent_level += 1;
22198 self.write_indent();
22199 }
22200 self.generate_expression(&f.subquery)?;
22201 if self.config.pretty && is_statement {
22202 self.write_newline();
22203 self.indent_level -= 1;
22204 self.write_indent();
22205 }
22206 self.write(")");
22207 }
22208 Ok(())
22209 }
22210
22211 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
22212 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
22214 self.generate_expression(this)?;
22215 self.write_space();
22216 self.write_keyword("OVERLAPS");
22217 self.write_space();
22218 self.generate_expression(expr)?;
22219 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
22220 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
22221 {
22222 self.write("(");
22224 self.generate_expression(ls)?;
22225 self.write(", ");
22226 self.generate_expression(le)?;
22227 self.write(")");
22228 self.write_space();
22229 self.write_keyword("OVERLAPS");
22230 self.write_space();
22231 self.write("(");
22232 self.generate_expression(rs)?;
22233 self.write(", ");
22234 self.generate_expression(re)?;
22235 self.write(")");
22236 }
22237 Ok(())
22238 }
22239
22240 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
22243 use crate::dialects::DialectType;
22244
22245 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
22247 self.generate_expression(&cast.this)?;
22248 self.write(" !:> ");
22249 self.generate_data_type(&cast.to)?;
22250 return Ok(());
22251 }
22252
22253 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
22255 self.write_keyword("TRYCAST");
22256 self.write("(");
22257 self.generate_expression(&cast.this)?;
22258 self.write_space();
22259 self.write_keyword("AS");
22260 self.write_space();
22261 self.generate_data_type(&cast.to)?;
22262 self.write(")");
22263 return Ok(());
22264 }
22265
22266 let keyword = if matches!(
22268 self.config.dialect,
22269 Some(DialectType::Hive)
22270 | Some(DialectType::MySQL)
22271 | Some(DialectType::SQLite)
22272 | Some(DialectType::Oracle)
22273 | Some(DialectType::ClickHouse)
22274 | Some(DialectType::Redshift)
22275 | Some(DialectType::PostgreSQL)
22276 | Some(DialectType::StarRocks)
22277 | Some(DialectType::Doris)
22278 ) {
22279 "CAST"
22280 } else {
22281 "TRY_CAST"
22282 };
22283
22284 self.write_keyword(keyword);
22285 self.write("(");
22286 self.generate_expression(&cast.this)?;
22287 self.write_space();
22288 self.write_keyword("AS");
22289 self.write_space();
22290 self.generate_data_type(&cast.to)?;
22291
22292 if let Some(format) = &cast.format {
22294 self.write_space();
22295 self.write_keyword("FORMAT");
22296 self.write_space();
22297 self.generate_expression(format)?;
22298 }
22299
22300 self.write(")");
22301 Ok(())
22302 }
22303
22304 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
22305 self.write_keyword("SAFE_CAST");
22306 self.write("(");
22307 self.generate_expression(&cast.this)?;
22308 self.write_space();
22309 self.write_keyword("AS");
22310 self.write_space();
22311 self.generate_data_type(&cast.to)?;
22312
22313 if let Some(format) = &cast.format {
22315 self.write_space();
22316 self.write_keyword("FORMAT");
22317 self.write_space();
22318 self.generate_expression(format)?;
22319 }
22320
22321 self.write(")");
22322 Ok(())
22323 }
22324
22325 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
22328 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
22332 if needs_parens {
22333 self.write("(");
22334 }
22335 self.generate_expression(&s.this)?;
22336 if needs_parens {
22337 self.write(")");
22338 }
22339 self.write("[");
22340 self.generate_expression(&s.index)?;
22341 self.write("]");
22342 Ok(())
22343 }
22344
22345 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
22346 self.generate_expression(&d.this)?;
22347 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
22350 && matches!(
22351 &d.this,
22352 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
22353 );
22354 if use_colon {
22355 self.write(":");
22356 } else {
22357 self.write(".");
22358 }
22359 self.generate_identifier(&d.field)
22360 }
22361
22362 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
22363 self.generate_expression(&m.this)?;
22364 self.write(".");
22365 if m.method.quoted {
22368 let q = self.config.identifier_quote;
22369 self.write(&format!("{}{}{}", q, m.method.name, q));
22370 } else {
22371 self.write(&m.method.name);
22372 }
22373 self.write("(");
22374 for (i, arg) in m.args.iter().enumerate() {
22375 if i > 0 {
22376 self.write(", ");
22377 }
22378 self.generate_expression(arg)?;
22379 }
22380 self.write(")");
22381 Ok(())
22382 }
22383
22384 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
22385 let needs_parens = matches!(
22388 &s.this,
22389 Expression::JsonExtract(f) if f.arrow_syntax
22390 ) || matches!(
22391 &s.this,
22392 Expression::JsonExtractScalar(f) if f.arrow_syntax
22393 );
22394
22395 if needs_parens {
22396 self.write("(");
22397 }
22398 self.generate_expression(&s.this)?;
22399 if needs_parens {
22400 self.write(")");
22401 }
22402 self.write("[");
22403 if let Some(start) = &s.start {
22404 self.generate_expression(start)?;
22405 }
22406 self.write(":");
22407 if let Some(end) = &s.end {
22408 self.generate_expression(end)?;
22409 }
22410 self.write("]");
22411 Ok(())
22412 }
22413
22414 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22415 match &op.left {
22419 Expression::Column(col) => {
22420 if let Some(table) = &col.table {
22423 self.generate_identifier(table)?;
22424 self.write(".");
22425 }
22426 self.generate_identifier(&col.name)?;
22427 if col.join_mark && self.config.supports_column_join_marks {
22429 self.write(" (+)");
22430 }
22431 if op.left_comments.is_empty() {
22433 for comment in &col.trailing_comments {
22434 self.write_space();
22435 self.write_formatted_comment(comment);
22436 }
22437 }
22438 }
22439 Expression::Add(inner_op)
22440 | Expression::Sub(inner_op)
22441 | Expression::Mul(inner_op)
22442 | Expression::Div(inner_op)
22443 | Expression::Concat(inner_op) => {
22444 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22446 Expression::Add(_) => "+",
22447 Expression::Sub(_) => "-",
22448 Expression::Mul(_) => "*",
22449 Expression::Div(_) => "/",
22450 Expression::Concat(_) => "||",
22451 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22452 })?;
22453 }
22454 _ => {
22455 self.generate_expression(&op.left)?;
22456 }
22457 }
22458 for comment in &op.left_comments {
22460 self.write_space();
22461 self.write_formatted_comment(comment);
22462 }
22463 if self.config.pretty
22464 && matches!(self.config.dialect, Some(DialectType::Snowflake))
22465 && (operator == "AND" || operator == "OR")
22466 {
22467 self.write_newline();
22468 self.write_indent();
22469 self.write_keyword(operator);
22470 } else {
22471 self.write_space();
22472 if operator.chars().all(|c| c.is_alphabetic()) {
22473 self.write_keyword(operator);
22474 } else {
22475 self.write(operator);
22476 }
22477 }
22478 for comment in &op.operator_comments {
22480 self.write_space();
22481 self.write_formatted_comment(comment);
22482 }
22483 self.write_space();
22484 self.generate_expression(&op.right)?;
22485 for comment in &op.trailing_comments {
22487 self.write_space();
22488 self.write_formatted_comment(comment);
22489 }
22490 Ok(())
22491 }
22492
22493 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
22494 let keyword = connector.keyword();
22495 let Some(terms) = self.flatten_connector_terms(op, connector) else {
22496 return self.generate_binary_op(op, keyword);
22497 };
22498
22499 let wrap_clickhouse_or_term = |generator: &mut Self, term: &Expression| -> Result<()> {
22500 let should_wrap = matches!(connector, ConnectorOperator::Or)
22501 && matches!(generator.config.dialect, Some(DialectType::ClickHouse))
22502 && matches!(
22503 generator.config.source_dialect,
22504 Some(DialectType::ClickHouse)
22505 )
22506 && matches!(term, Expression::And(_));
22507 if should_wrap {
22508 generator.write("(");
22509 generator.generate_expression(term)?;
22510 generator.write(")");
22511 } else {
22512 generator.generate_expression(term)?;
22513 }
22514 Ok(())
22515 };
22516
22517 wrap_clickhouse_or_term(self, terms[0])?;
22518 for term in terms.iter().skip(1) {
22519 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
22520 self.write_newline();
22521 self.write_indent();
22522 self.write_keyword(keyword);
22523 } else {
22524 self.write_space();
22525 self.write_keyword(keyword);
22526 }
22527 self.write_space();
22528 wrap_clickhouse_or_term(self, term)?;
22529 }
22530
22531 Ok(())
22532 }
22533
22534 fn flatten_connector_terms<'a>(
22535 &self,
22536 root: &'a BinaryOp,
22537 connector: ConnectorOperator,
22538 ) -> Option<Vec<&'a Expression>> {
22539 if !root.left_comments.is_empty()
22540 || !root.operator_comments.is_empty()
22541 || !root.trailing_comments.is_empty()
22542 {
22543 return None;
22544 }
22545
22546 let mut terms = Vec::new();
22547 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
22548
22549 while let Some(expr) = stack.pop() {
22550 match (connector, expr) {
22551 (ConnectorOperator::And, Expression::And(inner))
22552 if inner.left_comments.is_empty()
22553 && inner.operator_comments.is_empty()
22554 && inner.trailing_comments.is_empty() =>
22555 {
22556 stack.push(&inner.right);
22557 stack.push(&inner.left);
22558 }
22559 (ConnectorOperator::Or, Expression::Or(inner))
22560 if inner.left_comments.is_empty()
22561 && inner.operator_comments.is_empty()
22562 && inner.trailing_comments.is_empty() =>
22563 {
22564 stack.push(&inner.right);
22565 stack.push(&inner.left);
22566 }
22567 _ => terms.push(expr),
22568 }
22569 }
22570
22571 if terms.len() > 1 {
22572 Some(terms)
22573 } else {
22574 None
22575 }
22576 }
22577
22578 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22580 self.generate_like_op_inner(op, operator, false)
22581 }
22582
22583 fn generate_like_op_negated(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22584 self.generate_like_op_inner(op, operator, true)
22585 }
22586
22587 fn generate_like_op_inner(&mut self, op: &LikeOp, operator: &str, negated: bool) -> Result<()> {
22588 if negated
22589 && matches!(
22590 self.config.dialect,
22591 Some(DialectType::ClickHouse)
22592 | Some(DialectType::DataFusion)
22593 | Some(DialectType::TSQL)
22594 | Some(DialectType::Fabric)
22595 )
22596 {
22597 self.write_keyword("NOT");
22598 self.write_space();
22599 return self.generate_like_op_inner(op, operator, false);
22600 }
22601
22602 self.generate_expression(&op.left)?;
22603 self.write_space();
22604 if negated {
22605 self.write_keyword("NOT");
22606 self.write_space();
22607 }
22608 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
22610 self.write("`ILIKE`");
22611 } else {
22612 self.write_keyword(operator);
22613 }
22614 if let Some(quantifier) = &op.quantifier {
22615 self.write_space();
22616 self.write_keyword(quantifier);
22617 let is_any =
22622 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
22623 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
22624 self.write_space();
22625 }
22626 } else {
22627 self.write_space();
22628 }
22629 self.generate_expression(&op.right)?;
22630 if let Some(escape) = &op.escape {
22631 self.write_space();
22632 self.write_keyword("ESCAPE");
22633 self.write_space();
22634 self.generate_expression(escape)?;
22635 }
22636 Ok(())
22637 }
22638
22639 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
22642 use crate::dialects::DialectType;
22643 self.generate_expression(&op.left)?;
22644 self.write_space();
22645 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
22646 self.write("<=>");
22647 } else {
22648 self.write_keyword("IS NOT DISTINCT FROM");
22649 }
22650 self.write_space();
22651 self.generate_expression(&op.right)?;
22652 Ok(())
22653 }
22654
22655 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
22657 self.generate_expression(&op.left)?;
22658 self.write_space();
22659 self.write_keyword("IS DISTINCT FROM");
22660 self.write_space();
22661 self.generate_expression(&op.right)?;
22662 Ok(())
22663 }
22664
22665 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22667 match &op.left {
22669 Expression::Column(col) => {
22670 if let Some(table) = &col.table {
22671 self.generate_identifier(table)?;
22672 self.write(".");
22673 }
22674 self.generate_identifier(&col.name)?;
22675 if col.join_mark && self.config.supports_column_join_marks {
22677 self.write(" (+)");
22678 }
22679 }
22680 Expression::Add(inner_op)
22681 | Expression::Sub(inner_op)
22682 | Expression::Mul(inner_op)
22683 | Expression::Div(inner_op)
22684 | Expression::Concat(inner_op) => {
22685 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22686 Expression::Add(_) => "+",
22687 Expression::Sub(_) => "-",
22688 Expression::Mul(_) => "*",
22689 Expression::Div(_) => "/",
22690 Expression::Concat(_) => "||",
22691 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22692 })?;
22693 }
22694 _ => {
22695 self.generate_expression(&op.left)?;
22696 }
22697 }
22698 for comment in &op.left_comments {
22700 self.write_space();
22701 self.write_formatted_comment(comment);
22702 }
22703 self.write_space();
22704 if operator.chars().all(|c| c.is_alphabetic()) {
22705 self.write_keyword(operator);
22706 } else {
22707 self.write(operator);
22708 }
22709 for comment in &op.operator_comments {
22711 self.write_space();
22712 self.write_formatted_comment(comment);
22713 }
22714 self.write_space();
22715 match &op.right {
22718 Expression::Column(col) => {
22719 if let Some(table) = &col.table {
22720 self.generate_identifier(table)?;
22721 self.write(".");
22722 }
22723 self.generate_identifier(&col.name)?;
22724 if col.join_mark && self.config.supports_column_join_marks {
22726 self.write(" (+)");
22727 }
22728 }
22729 _ => {
22730 self.generate_expression(&op.right)?;
22731 }
22732 }
22733 Ok(())
22735 }
22736
22737 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
22738 if operator.chars().all(|c| c.is_alphabetic()) {
22739 self.write_keyword(operator);
22740 self.write_space();
22741 } else {
22742 self.write(operator);
22743 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
22745 self.write_space();
22746 }
22747 }
22748 self.generate_expression(&op.this)
22749 }
22750
22751 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
22752 let is_generic =
22756 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22757 let use_prefix_not =
22758 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
22759 if use_prefix_not {
22760 self.write_keyword("NOT");
22761 self.write_space();
22762 }
22763 self.generate_expression(&in_expr.this)?;
22764 if in_expr.global {
22765 self.write_space();
22766 self.write_keyword("GLOBAL");
22767 }
22768 if in_expr.not && !use_prefix_not {
22769 self.write_space();
22770 self.write_keyword("NOT");
22771 }
22772 self.write_space();
22773 self.write_keyword("IN");
22774
22775 if let Some(unnest_expr) = &in_expr.unnest {
22777 self.write_space();
22778 self.write_keyword("UNNEST");
22779 self.write("(");
22780 self.generate_expression(unnest_expr)?;
22781 self.write(")");
22782 return Ok(());
22783 }
22784
22785 if let Some(query) = &in_expr.query {
22786 let is_bare = in_expr.expressions.is_empty()
22789 && !matches!(
22790 query,
22791 Expression::Select(_)
22792 | Expression::Union(_)
22793 | Expression::Intersect(_)
22794 | Expression::Except(_)
22795 | Expression::Subquery(_)
22796 );
22797 if is_bare {
22798 self.write_space();
22800 self.generate_expression(query)?;
22801 } else {
22802 self.write(" (");
22804 let is_statement = matches!(
22805 query,
22806 Expression::Select(_)
22807 | Expression::Union(_)
22808 | Expression::Intersect(_)
22809 | Expression::Except(_)
22810 | Expression::Subquery(_)
22811 );
22812 if self.config.pretty && is_statement {
22813 self.write_newline();
22814 self.indent_level += 1;
22815 self.write_indent();
22816 }
22817 self.generate_expression(query)?;
22818 if self.config.pretty && is_statement {
22819 self.write_newline();
22820 self.indent_level -= 1;
22821 self.write_indent();
22822 }
22823 self.write(")");
22824 }
22825 } else {
22826 let is_duckdb = matches!(
22830 self.config.dialect,
22831 Some(crate::dialects::DialectType::DuckDB)
22832 );
22833 let is_clickhouse = matches!(
22834 self.config.dialect,
22835 Some(crate::dialects::DialectType::ClickHouse)
22836 );
22837 let single_expr = in_expr.expressions.len() == 1;
22838 if is_clickhouse && single_expr {
22839 if let Expression::Array(arr) = &in_expr.expressions[0] {
22840 self.write(" (");
22842 for (i, expr) in arr.expressions.iter().enumerate() {
22843 if i > 0 {
22844 self.write(", ");
22845 }
22846 self.generate_expression(expr)?;
22847 }
22848 self.write(")");
22849 } else if in_expr.is_field {
22850 self.write_space();
22851 self.generate_expression(&in_expr.expressions[0])?;
22852 } else {
22853 self.write(" (");
22854 self.generate_expression(&in_expr.expressions[0])?;
22855 self.write(")");
22856 }
22857 } else {
22858 let is_bare_ref = single_expr
22859 && matches!(
22860 &in_expr.expressions[0],
22861 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
22862 );
22863 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
22864 self.write_space();
22867 self.generate_expression(&in_expr.expressions[0])?;
22868 } else {
22869 self.write(" (");
22871 for (i, expr) in in_expr.expressions.iter().enumerate() {
22872 if i > 0 {
22873 self.write(", ");
22874 }
22875 self.generate_expression(expr)?;
22876 }
22877 self.write(")");
22878 }
22879 }
22880 }
22881
22882 Ok(())
22883 }
22884
22885 fn generate_between(&mut self, between: &Between) -> Result<()> {
22886 let use_prefix_not = between.not
22888 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
22889 if use_prefix_not {
22890 self.write_keyword("NOT");
22891 self.write_space();
22892 }
22893 self.generate_expression(&between.this)?;
22894 if between.not && !use_prefix_not {
22895 self.write_space();
22896 self.write_keyword("NOT");
22897 }
22898 self.write_space();
22899 self.write_keyword("BETWEEN");
22900 if let Some(sym) = between.symmetric {
22902 if sym {
22903 self.write(" SYMMETRIC");
22904 } else {
22905 self.write(" ASYMMETRIC");
22906 }
22907 }
22908 self.write_space();
22909 self.generate_expression(&between.low)?;
22910 self.write_space();
22911 self.write_keyword("AND");
22912 self.write_space();
22913 self.generate_expression(&between.high)
22914 }
22915
22916 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
22917 let use_prefix_not = is_null.not
22919 && (self.config.dialect.is_none()
22920 || self.config.dialect == Some(DialectType::Generic)
22921 || is_null.postfix_form);
22922 if use_prefix_not {
22923 self.write_keyword("NOT");
22925 self.write_space();
22926 self.generate_expression(&is_null.this)?;
22927 self.write_space();
22928 self.write_keyword("IS");
22929 self.write_space();
22930 self.write_keyword("NULL");
22931 } else {
22932 self.generate_expression(&is_null.this)?;
22933 self.write_space();
22934 self.write_keyword("IS");
22935 if is_null.not {
22936 self.write_space();
22937 self.write_keyword("NOT");
22938 }
22939 self.write_space();
22940 self.write_keyword("NULL");
22941 }
22942 Ok(())
22943 }
22944
22945 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
22946 self.generate_expression(&is_true.this)?;
22947 self.write_space();
22948 self.write_keyword("IS");
22949 if is_true.not {
22950 self.write_space();
22951 self.write_keyword("NOT");
22952 }
22953 self.write_space();
22954 self.write_keyword("TRUE");
22955 Ok(())
22956 }
22957
22958 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
22959 self.generate_expression(&is_false.this)?;
22960 self.write_space();
22961 self.write_keyword("IS");
22962 if is_false.not {
22963 self.write_space();
22964 self.write_keyword("NOT");
22965 }
22966 self.write_space();
22967 self.write_keyword("FALSE");
22968 Ok(())
22969 }
22970
22971 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
22972 self.generate_expression(&is_json.this)?;
22973 self.write_space();
22974 self.write_keyword("IS");
22975 if is_json.negated {
22976 self.write_space();
22977 self.write_keyword("NOT");
22978 }
22979 self.write_space();
22980 self.write_keyword("JSON");
22981
22982 if let Some(ref json_type) = is_json.json_type {
22984 self.write_space();
22985 self.write_keyword(json_type);
22986 }
22987
22988 match &is_json.unique_keys {
22990 Some(JsonUniqueKeys::With) => {
22991 self.write_space();
22992 self.write_keyword("WITH UNIQUE KEYS");
22993 }
22994 Some(JsonUniqueKeys::Without) => {
22995 self.write_space();
22996 self.write_keyword("WITHOUT UNIQUE KEYS");
22997 }
22998 Some(JsonUniqueKeys::Shorthand) => {
22999 self.write_space();
23000 self.write_keyword("UNIQUE KEYS");
23001 }
23002 None => {}
23003 }
23004
23005 Ok(())
23006 }
23007
23008 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
23009 self.generate_expression(&is_expr.left)?;
23010 self.write_space();
23011 self.write_keyword("IS");
23012 self.write_space();
23013 self.generate_expression(&is_expr.right)
23014 }
23015
23016 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
23017 if exists.not {
23018 self.write_keyword("NOT");
23019 self.write_space();
23020 }
23021 self.write_keyword("EXISTS");
23022 self.write("(");
23023 let is_statement = matches!(
23024 &exists.this,
23025 Expression::Select(_)
23026 | Expression::Union(_)
23027 | Expression::Intersect(_)
23028 | Expression::Except(_)
23029 );
23030 if self.config.pretty && is_statement {
23031 self.write_newline();
23032 self.indent_level += 1;
23033 self.write_indent();
23034 self.generate_expression(&exists.this)?;
23035 self.write_newline();
23036 self.indent_level -= 1;
23037 self.write_indent();
23038 self.write(")");
23039 } else {
23040 self.generate_expression(&exists.this)?;
23041 self.write(")");
23042 }
23043 Ok(())
23044 }
23045
23046 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
23047 self.generate_expression(&op.left)?;
23048 self.write_space();
23049 self.write_keyword("MEMBER OF");
23050 self.write("(");
23051 self.generate_expression(&op.right)?;
23052 self.write(")");
23053 Ok(())
23054 }
23055
23056 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
23057 if subquery.lateral {
23058 self.write_keyword("LATERAL");
23059 self.write_space();
23060 }
23061
23062 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
23066 matches!(
23067 &p.this,
23068 Expression::Select(_)
23069 | Expression::Union(_)
23070 | Expression::Intersect(_)
23071 | Expression::Except(_)
23072 | Expression::Subquery(_)
23073 )
23074 } else {
23075 false
23076 };
23077
23078 let is_statement = matches!(
23080 &subquery.this,
23081 Expression::Select(_)
23082 | Expression::Union(_)
23083 | Expression::Intersect(_)
23084 | Expression::Except(_)
23085 | Expression::Merge(_)
23086 );
23087
23088 if !skip_outer_parens {
23089 self.write("(");
23090 if self.config.pretty && is_statement {
23091 self.write_newline();
23092 self.indent_level += 1;
23093 self.write_indent();
23094 }
23095 }
23096 self.generate_expression(&subquery.this)?;
23097
23098 if subquery.modifiers_inside {
23100 if let Some(order_by) = &subquery.order_by {
23102 self.write_space();
23103 self.write_keyword("ORDER BY");
23104 self.write_space();
23105 for (i, ord) in order_by.expressions.iter().enumerate() {
23106 if i > 0 {
23107 self.write(", ");
23108 }
23109 self.generate_ordered(ord)?;
23110 }
23111 }
23112
23113 if let Some(limit) = &subquery.limit {
23114 self.write_space();
23115 self.write_keyword("LIMIT");
23116 self.write_space();
23117 self.generate_expression(&limit.this)?;
23118 if limit.percent {
23119 self.write_space();
23120 self.write_keyword("PERCENT");
23121 }
23122 }
23123
23124 if let Some(offset) = &subquery.offset {
23125 self.write_space();
23126 self.write_keyword("OFFSET");
23127 self.write_space();
23128 self.generate_expression(&offset.this)?;
23129 }
23130 }
23131
23132 if !skip_outer_parens {
23133 if self.config.pretty && is_statement {
23134 self.write_newline();
23135 self.indent_level -= 1;
23136 self.write_indent();
23137 }
23138 self.write(")");
23139 }
23140
23141 if !subquery.modifiers_inside {
23143 if let Some(order_by) = &subquery.order_by {
23144 self.write_space();
23145 self.write_keyword("ORDER BY");
23146 self.write_space();
23147 for (i, ord) in order_by.expressions.iter().enumerate() {
23148 if i > 0 {
23149 self.write(", ");
23150 }
23151 self.generate_ordered(ord)?;
23152 }
23153 }
23154
23155 if let Some(limit) = &subquery.limit {
23156 self.write_space();
23157 self.write_keyword("LIMIT");
23158 self.write_space();
23159 self.generate_expression(&limit.this)?;
23160 if limit.percent {
23161 self.write_space();
23162 self.write_keyword("PERCENT");
23163 }
23164 }
23165
23166 if let Some(offset) = &subquery.offset {
23167 self.write_space();
23168 self.write_keyword("OFFSET");
23169 self.write_space();
23170 self.generate_expression(&offset.this)?;
23171 }
23172
23173 if let Some(distribute_by) = &subquery.distribute_by {
23175 self.write_space();
23176 self.write_keyword("DISTRIBUTE BY");
23177 self.write_space();
23178 for (i, expr) in distribute_by.expressions.iter().enumerate() {
23179 if i > 0 {
23180 self.write(", ");
23181 }
23182 self.generate_expression(expr)?;
23183 }
23184 }
23185
23186 if let Some(sort_by) = &subquery.sort_by {
23188 self.write_space();
23189 self.write_keyword("SORT BY");
23190 self.write_space();
23191 for (i, ord) in sort_by.expressions.iter().enumerate() {
23192 if i > 0 {
23193 self.write(", ");
23194 }
23195 self.generate_ordered(ord)?;
23196 }
23197 }
23198
23199 if let Some(cluster_by) = &subquery.cluster_by {
23201 self.write_space();
23202 self.write_keyword("CLUSTER BY");
23203 self.write_space();
23204 for (i, ord) in cluster_by.expressions.iter().enumerate() {
23205 if i > 0 {
23206 self.write(", ");
23207 }
23208 self.generate_ordered(ord)?;
23209 }
23210 }
23211 }
23212
23213 if let Some(alias) = &subquery.alias {
23214 self.write_space();
23215 let skip_as = matches!(self.config.dialect, Some(DialectType::Oracle))
23216 || (matches!(self.config.dialect, Some(DialectType::ClickHouse))
23217 && !subquery.alias_explicit_as);
23218 if !skip_as {
23219 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23220 self.write(subquery.alias_keyword.as_deref().unwrap_or("AS"));
23221 } else {
23222 self.write_keyword("AS");
23223 }
23224 self.write_space();
23225 }
23226 self.generate_identifier(alias)?;
23227 if !subquery.column_aliases.is_empty() {
23228 self.write("(");
23229 for (i, col) in subquery.column_aliases.iter().enumerate() {
23230 if i > 0 {
23231 self.write(", ");
23232 }
23233 self.generate_identifier(col)?;
23234 }
23235 self.write(")");
23236 }
23237 }
23238 for comment in &subquery.trailing_comments {
23240 self.write(" ");
23241 self.write_formatted_comment(comment);
23242 }
23243 Ok(())
23244 }
23245
23246 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
23247 if let Some(ref with) = pivot.with {
23249 self.generate_with(with)?;
23250 self.write_space();
23251 }
23252
23253 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
23254
23255 let is_redshift_unpivot = pivot.unpivot
23259 && pivot.expressions.is_empty()
23260 && pivot.fields.is_empty()
23261 && pivot.using.is_empty()
23262 && pivot.into.is_none()
23263 && !matches!(&pivot.this, Expression::Null(_));
23264
23265 if is_redshift_unpivot {
23266 self.write_keyword("UNPIVOT");
23268 self.write_space();
23269 self.generate_expression(&pivot.this)?;
23270 if let Some(alias) = &pivot.alias {
23272 self.write_space();
23273 self.write_keyword("AS");
23274 self.write_space();
23275 self.write(&alias.name);
23277 }
23278 return Ok(());
23279 }
23280
23281 let is_simplified = !pivot.using.is_empty()
23283 || pivot.into.is_some()
23284 || (pivot.fields.is_empty()
23285 && !pivot.expressions.is_empty()
23286 && !matches!(&pivot.this, Expression::Null(_)));
23287
23288 if is_simplified {
23289 self.write_keyword(direction);
23293 self.write_space();
23294 self.generate_expression(&pivot.this)?;
23295
23296 if !pivot.expressions.is_empty() {
23297 self.write_space();
23298 self.write_keyword("ON");
23299 self.write_space();
23300 for (i, expr) in pivot.expressions.iter().enumerate() {
23301 if i > 0 {
23302 self.write(", ");
23303 }
23304 self.generate_expression(expr)?;
23305 }
23306 }
23307
23308 if let Some(into) = &pivot.into {
23310 self.write_space();
23311 self.write_keyword("INTO");
23312 self.write_space();
23313 self.generate_expression(into)?;
23314 }
23315
23316 if !pivot.using.is_empty() {
23318 self.write_space();
23319 self.write_keyword("USING");
23320 self.write_space();
23321 for (i, expr) in pivot.using.iter().enumerate() {
23322 if i > 0 {
23323 self.write(", ");
23324 }
23325 self.generate_expression(expr)?;
23326 }
23327 }
23328
23329 if let Some(group) = &pivot.group {
23331 self.write_space();
23332 self.generate_expression(group)?;
23333 }
23334 } else {
23335 if !matches!(&pivot.this, Expression::Null(_)) {
23340 self.generate_expression(&pivot.this)?;
23341 self.write_space();
23342 }
23343 self.write_keyword(direction);
23344 self.write("(");
23345
23346 for (i, expr) in pivot.expressions.iter().enumerate() {
23348 if i > 0 {
23349 self.write(", ");
23350 }
23351 self.generate_expression(expr)?;
23352 }
23353
23354 if !pivot.fields.is_empty() {
23356 if !pivot.expressions.is_empty() {
23357 self.write_space();
23358 }
23359 self.write_keyword("FOR");
23360 self.write_space();
23361 for (i, field) in pivot.fields.iter().enumerate() {
23362 if i > 0 {
23363 self.write_space();
23364 }
23365 self.generate_expression(field)?;
23367 }
23368 }
23369
23370 if let Some(default_val) = &pivot.default_on_null {
23372 self.write_space();
23373 self.write_keyword("DEFAULT ON NULL");
23374 self.write(" (");
23375 self.generate_expression(default_val)?;
23376 self.write(")");
23377 }
23378
23379 if let Some(group) = &pivot.group {
23381 self.write_space();
23382 self.generate_expression(group)?;
23383 }
23384
23385 self.write(")");
23386 }
23387
23388 if let Some(alias) = &pivot.alias {
23390 self.write_space();
23391 self.write_keyword("AS");
23392 self.write_space();
23393 self.generate_identifier(alias)?;
23394 self.generate_alias_column_list(&pivot.alias_columns)?;
23395 }
23396
23397 Ok(())
23398 }
23399
23400 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
23401 self.generate_expression(&unpivot.this)?;
23402 self.write_space();
23403 self.write_keyword("UNPIVOT");
23404 if let Some(include) = unpivot.include_nulls {
23406 self.write_space();
23407 if include {
23408 self.write_keyword("INCLUDE NULLS");
23409 } else {
23410 self.write_keyword("EXCLUDE NULLS");
23411 }
23412 self.write_space();
23413 }
23414 self.write("(");
23415 if unpivot.value_column_parenthesized {
23416 self.write("(");
23417 }
23418 self.generate_identifier(&unpivot.value_column)?;
23419 for extra_col in &unpivot.extra_value_columns {
23421 self.write(", ");
23422 self.generate_identifier(extra_col)?;
23423 }
23424 if unpivot.value_column_parenthesized {
23425 self.write(")");
23426 }
23427 self.write_space();
23428 self.write_keyword("FOR");
23429 self.write_space();
23430 self.generate_identifier(&unpivot.name_column)?;
23431 self.write_space();
23432 self.write_keyword("IN");
23433 self.write(" (");
23434 for (i, col) in unpivot.columns.iter().enumerate() {
23435 if i > 0 {
23436 self.write(", ");
23437 }
23438 self.generate_expression(col)?;
23439 }
23440 self.write("))");
23441 if let Some(alias) = &unpivot.alias {
23442 self.write_space();
23443 self.write_keyword("AS");
23444 self.write_space();
23445 self.generate_identifier(alias)?;
23446 self.generate_alias_column_list(&unpivot.alias_columns)?;
23447 }
23448 Ok(())
23449 }
23450
23451 fn generate_alias_column_list(&mut self, columns: &[Identifier]) -> Result<()> {
23452 if columns.is_empty() {
23453 return Ok(());
23454 }
23455
23456 self.write("(");
23457 for (i, column) in columns.iter().enumerate() {
23458 if i > 0 {
23459 self.write(", ");
23460 }
23461 self.generate_identifier(column)?;
23462 }
23463 self.write(")");
23464 Ok(())
23465 }
23466
23467 fn generate_values(&mut self, values: &Values) -> Result<()> {
23468 self.write_keyword("VALUES");
23469 for (i, row) in values.expressions.iter().enumerate() {
23470 if i > 0 {
23471 self.write(",");
23472 }
23473 self.write(" (");
23474 for (j, expr) in row.expressions.iter().enumerate() {
23475 if j > 0 {
23476 self.write(", ");
23477 }
23478 self.generate_expression(expr)?;
23479 }
23480 self.write(")");
23481 }
23482 if let Some(alias) = &values.alias {
23483 self.write_space();
23484 self.write_keyword("AS");
23485 self.write_space();
23486 self.generate_identifier(alias)?;
23487 if !values.column_aliases.is_empty() {
23488 self.write("(");
23489 for (i, col) in values.column_aliases.iter().enumerate() {
23490 if i > 0 {
23491 self.write(", ");
23492 }
23493 self.generate_identifier(col)?;
23494 }
23495 self.write(")");
23496 }
23497 }
23498 Ok(())
23499 }
23500
23501 fn generate_array(&mut self, arr: &Array) -> Result<()> {
23502 let needs_inheritance = matches!(
23504 self.config.dialect,
23505 Some(DialectType::DuckDB)
23506 | Some(DialectType::Spark)
23507 | Some(DialectType::Databricks)
23508 | Some(DialectType::Hive)
23509 | Some(DialectType::Snowflake)
23510 | Some(DialectType::Presto)
23511 | Some(DialectType::Trino)
23512 );
23513 let propagated: Vec<Expression>;
23514 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
23515 propagated = Self::inherit_struct_field_names(&arr.expressions);
23516 &propagated
23517 } else {
23518 &arr.expressions
23519 };
23520
23521 let use_parens =
23524 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
23525 if !self.config.array_bracket_only {
23526 self.write_keyword("ARRAY");
23527 }
23528 if use_parens {
23529 self.write("(");
23530 } else {
23531 self.write("[");
23532 }
23533 for (i, expr) in expressions.iter().enumerate() {
23534 if i > 0 {
23535 self.write(", ");
23536 }
23537 self.generate_expression(expr)?;
23538 }
23539 if use_parens {
23540 self.write(")");
23541 } else {
23542 self.write("]");
23543 }
23544 Ok(())
23545 }
23546
23547 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
23548 if tuple.expressions.len() == 2 {
23551 if let Expression::TableAlias(_) = &tuple.expressions[1] {
23552 self.generate_expression(&tuple.expressions[0])?;
23554 self.write_space();
23555 self.write_keyword("AS");
23556 self.write_space();
23557 self.generate_expression(&tuple.expressions[1])?;
23558 return Ok(());
23559 }
23560 }
23561
23562 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
23565 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
23566 for expr in &tuple.expressions {
23567 expr_strings.push(self.generate_to_string(expr)?);
23568 }
23569 self.too_wide(&expr_strings)
23570 } else {
23571 false
23572 };
23573
23574 if expand_tuple {
23575 self.write("(");
23576 self.write_newline();
23577 self.indent_level += 1;
23578 for (i, expr) in tuple.expressions.iter().enumerate() {
23579 if i > 0 {
23580 self.write(",");
23581 self.write_newline();
23582 }
23583 self.write_indent();
23584 self.generate_expression(expr)?;
23585 }
23586 self.indent_level -= 1;
23587 self.write_newline();
23588 self.write_indent();
23589 self.write(")");
23590 } else {
23591 self.write("(");
23592 for (i, expr) in tuple.expressions.iter().enumerate() {
23593 if i > 0 {
23594 self.write(", ");
23595 }
23596 self.generate_expression(expr)?;
23597 }
23598 self.write(")");
23599 }
23600 Ok(())
23601 }
23602
23603 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
23604 self.generate_expression(&pipe.this)?;
23605 self.write(" |> ");
23606 self.generate_expression(&pipe.expression)?;
23607 Ok(())
23608 }
23609
23610 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
23611 let unsupported_tsql_null_ordering = ordered.nulls_first.is_some()
23612 && !self.config.null_ordering_supported
23613 && matches!(
23614 self.config.dialect,
23615 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23616 );
23617 let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
23618 let emulate_tsql_null_ordering = if let Some(nulls_first) = ordered.nulls_first {
23619 let target_default_nulls_first = !ordered.desc;
23620
23621 unsupported_tsql_null_ordering
23622 && nulls_first != target_default_nulls_first
23623 && !random_ordering
23624 } else {
23625 false
23626 };
23627
23628 if emulate_tsql_null_ordering {
23629 self.write_keyword("CASE WHEN");
23630 self.write_space();
23631 self.generate_expression(&ordered.this)?;
23632 self.write_space();
23633 self.write_keyword("IS NULL THEN 1 ELSE 0 END");
23634 if ordered.nulls_first == Some(true) {
23635 self.write_space();
23636 self.write_keyword("DESC");
23637 }
23638 self.write(", ");
23639 }
23640
23641 self.generate_expression(&ordered.this)?;
23642 if ordered.desc {
23643 self.write_space();
23644 self.write_keyword("DESC");
23645 } else if ordered.explicit_asc {
23646 self.write_space();
23647 self.write_keyword("ASC");
23648 }
23649 if let Some(nulls_first) = ordered.nulls_first {
23650 if !unsupported_tsql_null_ordering
23651 && (self.config.null_ordering_supported
23652 || !matches!(self.config.dialect, Some(DialectType::Fabric)))
23653 {
23654 let is_asc = !ordered.desc;
23668 let is_nulls_are_large = matches!(
23669 self.config.dialect,
23670 Some(DialectType::Oracle)
23671 | Some(DialectType::PostgreSQL)
23672 | Some(DialectType::Redshift)
23673 | Some(DialectType::Snowflake)
23674 );
23675 let is_nulls_are_last = matches!(
23676 self.config.dialect,
23677 Some(DialectType::Dremio)
23678 | Some(DialectType::DuckDB)
23679 | Some(DialectType::Presto)
23680 | Some(DialectType::Trino)
23681 | Some(DialectType::Athena)
23682 | Some(DialectType::ClickHouse)
23683 | Some(DialectType::Drill)
23684 | Some(DialectType::Exasol)
23685 );
23686
23687 let is_default_nulls = if is_nulls_are_large {
23689 (is_asc && !nulls_first) || (!is_asc && nulls_first)
23691 } else if is_nulls_are_last {
23692 !nulls_first
23694 } else {
23695 false
23696 };
23697
23698 if !is_default_nulls {
23699 self.write_space();
23700 self.write_keyword("NULLS");
23701 self.write_space();
23702 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
23703 }
23704 }
23705 }
23706 if let Some(ref with_fill) = ordered.with_fill {
23708 self.write_space();
23709 self.generate_with_fill(with_fill)?;
23710 }
23711 Ok(())
23712 }
23713
23714 fn write_clickhouse_type(&mut self, type_str: &str) {
23716 if self.clickhouse_nullable_depth < 0 {
23717 self.write(type_str);
23719 } else {
23720 self.write(&format!("Nullable({})", type_str));
23721 }
23722 }
23723
23724 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
23725 use crate::dialects::DialectType;
23726
23727 match dt {
23728 DataType::Boolean => {
23729 match self.config.dialect {
23731 Some(DialectType::TSQL) => self.write_keyword("BIT"),
23732 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
23734 self.write_keyword("NUMBER(1)")
23736 }
23737 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
23739 }
23740 }
23741 DataType::TinyInt { length } => {
23742 match self.config.dialect {
23746 Some(DialectType::PostgreSQL)
23747 | Some(DialectType::Redshift)
23748 | Some(DialectType::Oracle)
23749 | Some(DialectType::Exasol) => {
23750 self.write_keyword("SMALLINT");
23751 }
23752 Some(DialectType::Teradata) => {
23753 self.write_keyword("BYTEINT");
23755 }
23756 Some(DialectType::Dremio) => {
23757 self.write_keyword("INT");
23759 }
23760 Some(DialectType::ClickHouse) => {
23761 self.write_clickhouse_type("Int8");
23762 }
23763 _ => {
23764 self.write_keyword("TINYINT");
23765 }
23766 }
23767 if let Some(n) = length {
23768 if !matches!(
23769 self.config.dialect,
23770 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
23771 ) {
23772 self.write(&format!("({})", n));
23773 }
23774 }
23775 }
23776 DataType::SmallInt { length } => {
23777 match self.config.dialect {
23779 Some(DialectType::Dremio) => {
23780 self.write_keyword("INT");
23781 }
23782 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
23783 self.write_keyword("INTEGER");
23784 }
23785 Some(DialectType::BigQuery) => {
23786 self.write_keyword("INT64");
23787 }
23788 Some(DialectType::ClickHouse) => {
23789 self.write_clickhouse_type("Int16");
23790 }
23791 _ => {
23792 self.write_keyword("SMALLINT");
23793 if let Some(n) = length {
23794 self.write(&format!("({})", n));
23795 }
23796 }
23797 }
23798 }
23799 DataType::Int {
23800 length,
23801 integer_spelling: _,
23802 } => {
23803 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
23805 self.write_keyword("INT64");
23806 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23807 self.write_clickhouse_type("Int32");
23808 } else {
23809 let use_integer = match self.config.dialect {
23811 Some(DialectType::TSQL)
23812 | Some(DialectType::Fabric)
23813 | Some(DialectType::Presto)
23814 | Some(DialectType::Trino)
23815 | Some(DialectType::SQLite)
23816 | Some(DialectType::Redshift) => true,
23817 _ => false,
23818 };
23819 if use_integer {
23820 self.write_keyword("INTEGER");
23821 } else {
23822 self.write_keyword("INT");
23823 }
23824 if let Some(n) = length {
23825 self.write(&format!("({})", n));
23826 }
23827 }
23828 }
23829 DataType::BigInt { length } => {
23830 match self.config.dialect {
23832 Some(DialectType::Oracle) => {
23833 self.write_keyword("INT");
23835 }
23836 Some(DialectType::ClickHouse) => {
23837 self.write_clickhouse_type("Int64");
23838 }
23839 _ => {
23840 self.write_keyword("BIGINT");
23841 if let Some(n) = length {
23842 self.write(&format!("({})", n));
23843 }
23844 }
23845 }
23846 }
23847 DataType::Float {
23848 precision,
23849 scale,
23850 real_spelling,
23851 } => {
23852 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23856 self.write_clickhouse_type("Float32");
23857 } else if *real_spelling
23858 && !matches!(
23859 self.config.dialect,
23860 Some(DialectType::Spark)
23861 | Some(DialectType::Databricks)
23862 | Some(DialectType::Hive)
23863 | Some(DialectType::Snowflake)
23864 | Some(DialectType::MySQL)
23865 | Some(DialectType::BigQuery)
23866 )
23867 {
23868 self.write_keyword("REAL")
23869 } else {
23870 match self.config.dialect {
23871 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
23872 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23873 _ => self.write_keyword("FLOAT"),
23874 }
23875 }
23876 if !matches!(
23879 self.config.dialect,
23880 Some(DialectType::Spark)
23881 | Some(DialectType::Databricks)
23882 | Some(DialectType::Hive)
23883 | Some(DialectType::Presto)
23884 | Some(DialectType::Trino)
23885 ) {
23886 if let Some(p) = precision {
23887 self.write(&format!("({}", p));
23888 if let Some(s) = scale {
23889 self.write(&format!(", {})", s));
23890 } else {
23891 self.write(")");
23892 }
23893 }
23894 }
23895 }
23896 DataType::Double { precision, scale } => {
23897 match self.config.dialect {
23899 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23900 self.write_keyword("FLOAT")
23901 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
23903 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
23904 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23905 Some(DialectType::SQLite) => self.write_keyword("REAL"),
23906 Some(DialectType::PostgreSQL)
23907 | Some(DialectType::Redshift)
23908 | Some(DialectType::Teradata)
23909 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
23910 _ => self.write_keyword("DOUBLE"),
23911 }
23912 if let Some(p) = precision {
23914 self.write(&format!("({}", p));
23915 if let Some(s) = scale {
23916 self.write(&format!(", {})", s));
23917 } else {
23918 self.write(")");
23919 }
23920 }
23921 }
23922 DataType::Decimal { precision, scale } => {
23923 match self.config.dialect {
23925 Some(DialectType::ClickHouse) => {
23926 self.write("Decimal");
23927 if let Some(p) = precision {
23928 self.write(&format!("({}", p));
23929 if let Some(s) = scale {
23930 self.write(&format!(", {}", s));
23931 }
23932 self.write(")");
23933 }
23934 }
23935 Some(DialectType::Oracle) => {
23936 self.write_keyword("NUMBER");
23938 if let Some(p) = precision {
23939 self.write(&format!("({}", p));
23940 if let Some(s) = scale {
23941 self.write(&format!(", {}", s));
23942 }
23943 self.write(")");
23944 }
23945 }
23946 Some(DialectType::BigQuery) => {
23947 self.write_keyword("NUMERIC");
23949 if let Some(p) = precision {
23950 self.write(&format!("({}", p));
23951 if let Some(s) = scale {
23952 self.write(&format!(", {}", s));
23953 }
23954 self.write(")");
23955 }
23956 }
23957 _ => {
23958 self.write_keyword("DECIMAL");
23959 if let Some(p) = precision {
23960 self.write(&format!("({}", p));
23961 if let Some(s) = scale {
23962 self.write(&format!(", {}", s));
23963 }
23964 self.write(")");
23965 }
23966 }
23967 }
23968 }
23969 DataType::Char { length } => {
23970 match self.config.dialect {
23972 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23973 self.write_keyword("TEXT");
23975 }
23976 Some(DialectType::Hive)
23977 | Some(DialectType::Spark)
23978 | Some(DialectType::Databricks) => {
23979 if length.is_some()
23982 && !matches!(self.config.dialect, Some(DialectType::Hive))
23983 {
23984 self.write_keyword("CHAR");
23985 if let Some(n) = length {
23986 self.write(&format!("({})", n));
23987 }
23988 } else {
23989 self.write_keyword("STRING");
23990 }
23991 }
23992 Some(DialectType::Dremio) => {
23993 self.write_keyword("VARCHAR");
23995 if let Some(n) = length {
23996 self.write(&format!("({})", n));
23997 }
23998 }
23999 _ => {
24000 self.write_keyword("CHAR");
24001 if let Some(n) = length {
24002 self.write(&format!("({})", n));
24003 }
24004 }
24005 }
24006 }
24007 DataType::VarChar {
24008 length,
24009 parenthesized_length,
24010 } => {
24011 match self.config.dialect {
24013 Some(DialectType::Oracle) => {
24014 self.write_keyword("VARCHAR2");
24015 if let Some(n) = length {
24016 self.write(&format!("({})", n));
24017 }
24018 }
24019 Some(DialectType::DuckDB) => {
24020 self.write_keyword("TEXT");
24022 if let Some(n) = length {
24023 self.write(&format!("({})", n));
24024 }
24025 }
24026 Some(DialectType::SQLite) => {
24027 self.write_keyword("TEXT");
24029 if let Some(n) = length {
24030 self.write(&format!("({})", n));
24031 }
24032 }
24033 Some(DialectType::MySQL) if length.is_none() => {
24034 self.write_keyword("TEXT");
24036 }
24037 Some(DialectType::Hive)
24038 | Some(DialectType::Spark)
24039 | Some(DialectType::Databricks)
24040 if length.is_none() =>
24041 {
24042 self.write_keyword("STRING");
24044 }
24045 _ => {
24046 self.write_keyword("VARCHAR");
24047 if let Some(n) = length {
24048 if *parenthesized_length {
24050 self.write(&format!("(({}))", n));
24051 } else {
24052 self.write(&format!("({})", n));
24053 }
24054 }
24055 }
24056 }
24057 }
24058 DataType::Text => {
24059 match self.config.dialect {
24061 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
24062 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24063 self.write_keyword("VARCHAR(MAX)")
24064 }
24065 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24066 Some(DialectType::Snowflake)
24067 | Some(DialectType::Dremio)
24068 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
24069 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
24070 Some(DialectType::Presto)
24071 | Some(DialectType::Trino)
24072 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24073 Some(DialectType::Spark)
24074 | Some(DialectType::Databricks)
24075 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24076 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
24077 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
24078 self.write_keyword("STRING")
24079 }
24080 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
24081 _ => self.write_keyword("TEXT"),
24082 }
24083 }
24084 DataType::TextWithLength { length } => {
24085 match self.config.dialect {
24087 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
24088 Some(DialectType::Hive)
24089 | Some(DialectType::Spark)
24090 | Some(DialectType::Databricks) => {
24091 self.write(&format!("VARCHAR({})", length));
24092 }
24093 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
24094 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
24095 Some(DialectType::Snowflake)
24096 | Some(DialectType::Presto)
24097 | Some(DialectType::Trino)
24098 | Some(DialectType::Athena)
24099 | Some(DialectType::Drill)
24100 | Some(DialectType::Dremio) => {
24101 self.write(&format!("VARCHAR({})", length));
24102 }
24103 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24104 self.write(&format!("VARCHAR({})", length))
24105 }
24106 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
24107 self.write(&format!("STRING({})", length))
24108 }
24109 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
24110 _ => self.write(&format!("TEXT({})", length)),
24111 }
24112 }
24113 DataType::String { length } => {
24114 match self.config.dialect {
24116 Some(DialectType::ClickHouse) => {
24117 self.write("String");
24119 if let Some(n) = length {
24120 self.write(&format!("({})", n));
24121 }
24122 }
24123 Some(DialectType::BigQuery)
24124 | Some(DialectType::Hive)
24125 | Some(DialectType::Spark)
24126 | Some(DialectType::Databricks)
24127 | Some(DialectType::StarRocks)
24128 | Some(DialectType::Doris) => {
24129 self.write_keyword("STRING");
24130 if let Some(n) = length {
24131 self.write(&format!("({})", n));
24132 }
24133 }
24134 Some(DialectType::PostgreSQL) => {
24135 if let Some(n) = length {
24137 self.write_keyword("VARCHAR");
24138 self.write(&format!("({})", n));
24139 } else {
24140 self.write_keyword("TEXT");
24141 }
24142 }
24143 Some(DialectType::Redshift) => {
24144 if let Some(n) = length {
24146 self.write_keyword("VARCHAR");
24147 self.write(&format!("({})", n));
24148 } else {
24149 self.write_keyword("VARCHAR(MAX)");
24150 }
24151 }
24152 Some(DialectType::MySQL) => {
24153 if let Some(n) = length {
24155 self.write_keyword("VARCHAR");
24156 self.write(&format!("({})", n));
24157 } else {
24158 self.write_keyword("TEXT");
24159 }
24160 }
24161 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24162 if let Some(n) = length {
24164 self.write_keyword("VARCHAR");
24165 self.write(&format!("({})", n));
24166 } else {
24167 self.write_keyword("VARCHAR(MAX)");
24168 }
24169 }
24170 Some(DialectType::Oracle) => {
24171 self.write_keyword("CLOB");
24173 }
24174 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
24175 self.write_keyword("TEXT");
24177 if let Some(n) = length {
24178 self.write(&format!("({})", n));
24179 }
24180 }
24181 Some(DialectType::Presto)
24182 | Some(DialectType::Trino)
24183 | Some(DialectType::Drill)
24184 | Some(DialectType::Dremio) => {
24185 self.write_keyword("VARCHAR");
24187 if let Some(n) = length {
24188 self.write(&format!("({})", n));
24189 }
24190 }
24191 Some(DialectType::Snowflake) => {
24192 self.write_keyword("STRING");
24195 if let Some(n) = length {
24196 self.write(&format!("({})", n));
24197 }
24198 }
24199 _ => {
24200 self.write_keyword("STRING");
24202 if let Some(n) = length {
24203 self.write(&format!("({})", n));
24204 }
24205 }
24206 }
24207 }
24208 DataType::Binary { length } => {
24209 match self.config.dialect {
24211 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
24212 self.write_keyword("BYTEA");
24213 if let Some(n) = length {
24214 self.write(&format!("({})", n));
24215 }
24216 }
24217 Some(DialectType::Redshift) => {
24218 self.write_keyword("VARBYTE");
24219 if let Some(n) = length {
24220 self.write(&format!("({})", n));
24221 }
24222 }
24223 Some(DialectType::DuckDB)
24224 | Some(DialectType::SQLite)
24225 | Some(DialectType::Oracle) => {
24226 self.write_keyword("BLOB");
24228 if let Some(n) = length {
24229 self.write(&format!("({})", n));
24230 }
24231 }
24232 Some(DialectType::Presto)
24233 | Some(DialectType::Trino)
24234 | Some(DialectType::Athena)
24235 | Some(DialectType::Drill)
24236 | Some(DialectType::Dremio) => {
24237 self.write_keyword("VARBINARY");
24239 if let Some(n) = length {
24240 self.write(&format!("({})", n));
24241 }
24242 }
24243 Some(DialectType::ClickHouse) => {
24244 if self.clickhouse_nullable_depth < 0 {
24246 self.write("BINARY");
24247 } else {
24248 self.write("Nullable(BINARY");
24249 }
24250 if let Some(n) = length {
24251 self.write(&format!("({})", n));
24252 }
24253 if self.clickhouse_nullable_depth >= 0 {
24254 self.write(")");
24255 }
24256 }
24257 _ => {
24258 self.write_keyword("BINARY");
24259 if let Some(n) = length {
24260 self.write(&format!("({})", n));
24261 }
24262 }
24263 }
24264 }
24265 DataType::VarBinary { length } => {
24266 match self.config.dialect {
24268 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
24269 self.write_keyword("BYTEA");
24270 if let Some(n) = length {
24271 self.write(&format!("({})", n));
24272 }
24273 }
24274 Some(DialectType::Redshift) => {
24275 self.write_keyword("VARBYTE");
24276 if let Some(n) = length {
24277 self.write(&format!("({})", n));
24278 }
24279 }
24280 Some(DialectType::DuckDB)
24281 | Some(DialectType::SQLite)
24282 | Some(DialectType::Oracle) => {
24283 self.write_keyword("BLOB");
24285 if let Some(n) = length {
24286 self.write(&format!("({})", n));
24287 }
24288 }
24289 Some(DialectType::Exasol) => {
24290 self.write_keyword("VARCHAR");
24292 }
24293 Some(DialectType::Spark)
24294 | Some(DialectType::Hive)
24295 | Some(DialectType::Databricks) => {
24296 self.write_keyword("BINARY");
24298 if let Some(n) = length {
24299 self.write(&format!("({})", n));
24300 }
24301 }
24302 Some(DialectType::ClickHouse) => {
24303 self.write_clickhouse_type("String");
24305 }
24306 _ => {
24307 self.write_keyword("VARBINARY");
24308 if let Some(n) = length {
24309 self.write(&format!("({})", n));
24310 }
24311 }
24312 }
24313 }
24314 DataType::Blob => {
24315 match self.config.dialect {
24317 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
24318 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
24319 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
24320 self.write_keyword("VARBINARY")
24321 }
24322 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24323 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
24324 Some(DialectType::Presto)
24325 | Some(DialectType::Trino)
24326 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24327 Some(DialectType::DuckDB) => {
24328 self.write_keyword("VARBINARY");
24331 }
24332 Some(DialectType::Spark)
24333 | Some(DialectType::Databricks)
24334 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
24335 Some(DialectType::ClickHouse) => {
24336 self.write("Nullable(String)");
24340 }
24341 _ => self.write_keyword("BLOB"),
24342 }
24343 }
24344 DataType::Bit { length } => {
24345 match self.config.dialect {
24347 Some(DialectType::Dremio)
24348 | Some(DialectType::Spark)
24349 | Some(DialectType::Databricks)
24350 | Some(DialectType::Hive)
24351 | Some(DialectType::Snowflake)
24352 | Some(DialectType::BigQuery)
24353 | Some(DialectType::Presto)
24354 | Some(DialectType::Trino)
24355 | Some(DialectType::ClickHouse)
24356 | Some(DialectType::Redshift) => {
24357 self.write_keyword("BOOLEAN");
24359 }
24360 _ => {
24361 self.write_keyword("BIT");
24362 if let Some(n) = length {
24363 self.write(&format!("({})", n));
24364 }
24365 }
24366 }
24367 }
24368 DataType::VarBit { length } => {
24369 self.write_keyword("VARBIT");
24370 if let Some(n) = length {
24371 self.write(&format!("({})", n));
24372 }
24373 }
24374 DataType::Date => self.write_keyword("DATE"),
24375 DataType::Time {
24376 precision,
24377 timezone,
24378 } => {
24379 if *timezone {
24380 match self.config.dialect {
24382 Some(DialectType::DuckDB) => {
24383 self.write_keyword("TIMETZ");
24385 }
24386 Some(DialectType::PostgreSQL) => {
24387 self.write_keyword("TIMETZ");
24389 if let Some(p) = precision {
24390 self.write(&format!("({})", p));
24391 }
24392 }
24393 _ => {
24394 self.write_keyword("TIME");
24396 if let Some(p) = precision {
24397 self.write(&format!("({})", p));
24398 }
24399 self.write_keyword(" WITH TIME ZONE");
24400 }
24401 }
24402 } else {
24403 if matches!(
24405 self.config.dialect,
24406 Some(DialectType::Spark)
24407 | Some(DialectType::Databricks)
24408 | Some(DialectType::Hive)
24409 ) {
24410 self.write_keyword("TIMESTAMP");
24411 } else {
24412 self.write_keyword("TIME");
24413 if let Some(p) = precision {
24414 self.write(&format!("({})", p));
24415 }
24416 }
24417 }
24418 }
24419 DataType::Timestamp {
24420 precision,
24421 timezone,
24422 } => {
24423 match self.config.dialect {
24425 Some(DialectType::Snowflake) if *timezone => {
24426 self.write_keyword("TIMESTAMPTZ");
24427 if let Some(p) = precision {
24428 self.write(&format!("({})", p));
24429 }
24430 }
24431 Some(DialectType::ClickHouse) => {
24432 self.write("DateTime");
24433 if let Some(p) = precision {
24434 self.write(&format!("({})", p));
24435 }
24436 }
24437 Some(DialectType::TSQL) => {
24438 if *timezone {
24439 self.write_keyword("DATETIMEOFFSET");
24440 } else {
24441 self.write_keyword("DATETIME2");
24442 }
24443 if let Some(p) = precision {
24444 self.write(&format!("({})", p));
24445 }
24446 }
24447 Some(DialectType::MySQL) => {
24448 self.write_keyword("TIMESTAMP");
24450 if let Some(p) = precision {
24451 self.write(&format!("({})", p));
24452 }
24453 }
24454 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
24455 self.write_keyword("DATETIME");
24457 if let Some(p) = precision {
24458 self.write(&format!("({})", p));
24459 }
24460 }
24461 Some(DialectType::BigQuery) => {
24462 if *timezone {
24464 self.write_keyword("TIMESTAMP");
24465 } else {
24466 self.write_keyword("DATETIME");
24467 }
24468 }
24469 Some(DialectType::DuckDB) => {
24470 if *timezone {
24472 self.write_keyword("TIMESTAMPTZ");
24473 } else {
24474 self.write_keyword("TIMESTAMP");
24475 if let Some(p) = precision {
24476 self.write(&format!("({})", p));
24477 }
24478 }
24479 }
24480 _ => {
24481 if *timezone && !self.config.tz_to_with_time_zone {
24482 self.write_keyword("TIMESTAMPTZ");
24484 if let Some(p) = precision {
24485 self.write(&format!("({})", p));
24486 }
24487 } else {
24488 self.write_keyword("TIMESTAMP");
24489 if let Some(p) = precision {
24490 self.write(&format!("({})", p));
24491 }
24492 if *timezone {
24493 self.write_space();
24494 self.write_keyword("WITH TIME ZONE");
24495 }
24496 }
24497 }
24498 }
24499 }
24500 DataType::Interval { unit, to } => {
24501 self.write_keyword("INTERVAL");
24502 if let Some(u) = unit {
24503 self.write_space();
24504 self.write_keyword(u);
24505 }
24506 if let Some(t) = to {
24508 self.write_space();
24509 self.write_keyword("TO");
24510 self.write_space();
24511 self.write_keyword(t);
24512 }
24513 }
24514 DataType::Json => {
24515 match self.config.dialect {
24517 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
24520 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24521 _ => self.write_keyword("JSON"),
24522 }
24523 }
24524 DataType::JsonB => {
24525 match self.config.dialect {
24527 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
24528 Some(DialectType::Doris) => self.write_keyword("JSONB"),
24529 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24530 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24531 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
24534 }
24535 DataType::Uuid => {
24536 match self.config.dialect {
24538 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
24539 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
24540 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
24541 Some(DialectType::BigQuery)
24542 | Some(DialectType::Spark)
24543 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
24544 _ => self.write_keyword("UUID"),
24545 }
24546 }
24547 DataType::Array {
24548 element_type,
24549 dimension,
24550 } => {
24551 match self.config.dialect {
24553 Some(DialectType::PostgreSQL)
24554 | Some(DialectType::Redshift)
24555 | Some(DialectType::DuckDB) => {
24556 self.generate_data_type(element_type)?;
24558 if let Some(dim) = dimension {
24559 self.write(&format!("[{}]", dim));
24560 } else {
24561 self.write("[]");
24562 }
24563 }
24564 Some(DialectType::BigQuery) => {
24565 self.write_keyword("ARRAY<");
24566 self.generate_data_type(element_type)?;
24567 self.write(">");
24568 }
24569 Some(DialectType::Snowflake)
24570 | Some(DialectType::Presto)
24571 | Some(DialectType::Trino)
24572 | Some(DialectType::ClickHouse) => {
24573 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24575 self.write("Array(");
24576 } else {
24577 self.write_keyword("ARRAY(");
24578 }
24579 self.generate_data_type(element_type)?;
24580 self.write(")");
24581 }
24582 Some(DialectType::TSQL)
24583 | Some(DialectType::MySQL)
24584 | Some(DialectType::Oracle) => {
24585 match self.config.dialect {
24588 Some(DialectType::MySQL) => self.write_keyword("JSON"),
24589 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24590 _ => self.write_keyword("JSON"),
24591 }
24592 }
24593 _ => {
24594 self.write_keyword("ARRAY<");
24596 self.generate_data_type(element_type)?;
24597 self.write(">");
24598 }
24599 }
24600 }
24601 DataType::List { element_type } => {
24602 self.generate_data_type(element_type)?;
24604 self.write_keyword(" LIST");
24605 }
24606 DataType::Map {
24607 key_type,
24608 value_type,
24609 } => {
24610 match self.config.dialect {
24612 Some(DialectType::Materialize) => {
24613 self.write_keyword("MAP[");
24615 self.generate_data_type(key_type)?;
24616 self.write(" => ");
24617 self.generate_data_type(value_type)?;
24618 self.write("]");
24619 }
24620 Some(DialectType::Snowflake)
24621 | Some(DialectType::RisingWave)
24622 | Some(DialectType::DuckDB)
24623 | Some(DialectType::Presto)
24624 | Some(DialectType::Trino)
24625 | Some(DialectType::Athena) => {
24626 self.write_keyword("MAP(");
24627 self.generate_data_type(key_type)?;
24628 self.write(", ");
24629 self.generate_data_type(value_type)?;
24630 self.write(")");
24631 }
24632 Some(DialectType::ClickHouse) => {
24633 self.write("Map(");
24636 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
24638 self.clickhouse_nullable_depth = 0;
24639 self.write(", ");
24640 self.generate_data_type(value_type)?;
24641 self.write(")");
24642 }
24643 _ => {
24644 self.write_keyword("MAP<");
24645 self.generate_data_type(key_type)?;
24646 self.write(", ");
24647 self.generate_data_type(value_type)?;
24648 self.write(">");
24649 }
24650 }
24651 }
24652 DataType::Vector {
24653 element_type,
24654 dimension,
24655 } => {
24656 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
24657 self.write_keyword("VECTOR(");
24659 if let Some(dim) = dimension {
24660 self.write(&dim.to_string());
24661 }
24662 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
24664 DataType::TinyInt { .. } => Some("I8"),
24665 DataType::SmallInt { .. } => Some("I16"),
24666 DataType::Int { .. } => Some("I32"),
24667 DataType::BigInt { .. } => Some("I64"),
24668 DataType::Float { .. } => Some("F32"),
24669 DataType::Double { .. } => Some("F64"),
24670 _ => None,
24671 });
24672 if let Some(alias) = type_alias {
24673 if dimension.is_some() {
24674 self.write(", ");
24675 }
24676 self.write(alias);
24677 }
24678 self.write(")");
24679 } else {
24680 self.write_keyword("VECTOR(");
24682 if let Some(ref et) = element_type {
24683 self.generate_data_type(et)?;
24684 if dimension.is_some() {
24685 self.write(", ");
24686 }
24687 }
24688 if let Some(dim) = dimension {
24689 self.write(&dim.to_string());
24690 }
24691 self.write(")");
24692 }
24693 }
24694 DataType::Object { fields, modifier } => {
24695 self.write_keyword("OBJECT(");
24696 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
24697 if i > 0 {
24698 self.write(", ");
24699 }
24700 self.write(name);
24701 self.write(" ");
24702 self.generate_data_type(dt)?;
24703 if *not_null {
24704 self.write_keyword(" NOT NULL");
24705 }
24706 }
24707 self.write(")");
24708 if let Some(mod_str) = modifier {
24709 self.write(" ");
24710 self.write_keyword(mod_str);
24711 }
24712 }
24713 DataType::Struct { fields, nested } => {
24714 match self.config.dialect {
24716 Some(DialectType::Snowflake) => {
24717 self.write_keyword("OBJECT(");
24719 for (i, field) in fields.iter().enumerate() {
24720 if i > 0 {
24721 self.write(", ");
24722 }
24723 if !field.name.is_empty() {
24724 self.write(&field.name);
24725 self.write(" ");
24726 }
24727 self.generate_data_type(&field.data_type)?;
24728 }
24729 self.write(")");
24730 }
24731 Some(DialectType::Presto) | Some(DialectType::Trino) => {
24732 self.write_keyword("ROW(");
24734 for (i, field) in fields.iter().enumerate() {
24735 if i > 0 {
24736 self.write(", ");
24737 }
24738 if !field.name.is_empty() {
24739 self.write(&field.name);
24740 self.write(" ");
24741 }
24742 self.generate_data_type(&field.data_type)?;
24743 }
24744 self.write(")");
24745 }
24746 Some(DialectType::DuckDB) => {
24747 self.write_keyword("STRUCT(");
24749 for (i, field) in fields.iter().enumerate() {
24750 if i > 0 {
24751 self.write(", ");
24752 }
24753 if !field.name.is_empty() {
24754 self.write(&field.name);
24755 self.write(" ");
24756 }
24757 self.generate_data_type(&field.data_type)?;
24758 }
24759 self.write(")");
24760 }
24761 Some(DialectType::ClickHouse) => {
24762 self.write("Tuple(");
24764 for (i, field) in fields.iter().enumerate() {
24765 if i > 0 {
24766 self.write(", ");
24767 }
24768 if !field.name.is_empty() {
24769 self.write(&field.name);
24770 self.write(" ");
24771 }
24772 self.generate_data_type(&field.data_type)?;
24773 }
24774 self.write(")");
24775 }
24776 Some(DialectType::SingleStore) => {
24777 self.write_keyword("RECORD(");
24779 for (i, field) in fields.iter().enumerate() {
24780 if i > 0 {
24781 self.write(", ");
24782 }
24783 if !field.name.is_empty() {
24784 self.write(&field.name);
24785 self.write(" ");
24786 }
24787 self.generate_data_type(&field.data_type)?;
24788 }
24789 self.write(")");
24790 }
24791 _ => {
24792 let force_angle_brackets = matches!(
24794 self.config.dialect,
24795 Some(DialectType::Hive)
24796 | Some(DialectType::Spark)
24797 | Some(DialectType::Databricks)
24798 );
24799 if *nested && !force_angle_brackets {
24800 self.write_keyword("STRUCT(");
24801 for (i, field) in fields.iter().enumerate() {
24802 if i > 0 {
24803 self.write(", ");
24804 }
24805 if !field.name.is_empty() {
24806 self.write(&field.name);
24807 self.write(" ");
24808 }
24809 self.generate_data_type(&field.data_type)?;
24810 }
24811 self.write(")");
24812 } else {
24813 self.write_keyword("STRUCT<");
24814 for (i, field) in fields.iter().enumerate() {
24815 if i > 0 {
24816 self.write(", ");
24817 }
24818 if !field.name.is_empty() {
24819 self.write(&field.name);
24821 self.write(self.config.struct_field_sep);
24822 }
24823 self.generate_data_type(&field.data_type)?;
24825 if let Some(comment) = &field.comment {
24827 self.write(" COMMENT '");
24828 self.write(comment);
24829 self.write("'");
24830 }
24831 if !field.options.is_empty() {
24833 self.write(" ");
24834 self.generate_options_clause(&field.options)?;
24835 }
24836 }
24837 self.write(">");
24838 }
24839 }
24840 }
24841 }
24842 DataType::Enum {
24843 values,
24844 assignments,
24845 } => {
24846 if self.config.dialect == Some(DialectType::ClickHouse) {
24849 self.write("Enum(");
24850 } else {
24851 self.write_keyword("ENUM(");
24852 }
24853 for (i, val) in values.iter().enumerate() {
24854 if i > 0 {
24855 self.write(", ");
24856 }
24857 self.write("'");
24858 self.write(val);
24859 self.write("'");
24860 if let Some(Some(assignment)) = assignments.get(i) {
24861 self.write(" = ");
24862 self.write(assignment);
24863 }
24864 }
24865 self.write(")");
24866 }
24867 DataType::Set { values } => {
24868 self.write_keyword("SET(");
24870 for (i, val) in values.iter().enumerate() {
24871 if i > 0 {
24872 self.write(", ");
24873 }
24874 self.write("'");
24875 self.write(val);
24876 self.write("'");
24877 }
24878 self.write(")");
24879 }
24880 DataType::Union { fields } => {
24881 self.write_keyword("UNION(");
24883 for (i, (name, dt)) in fields.iter().enumerate() {
24884 if i > 0 {
24885 self.write(", ");
24886 }
24887 if !name.is_empty() {
24888 self.write(name);
24889 self.write(" ");
24890 }
24891 self.generate_data_type(dt)?;
24892 }
24893 self.write(")");
24894 }
24895 DataType::Nullable { inner } => {
24896 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24898 self.write("Nullable(");
24899 let saved_depth = self.clickhouse_nullable_depth;
24901 self.clickhouse_nullable_depth = -1;
24902 self.generate_data_type(inner)?;
24903 self.clickhouse_nullable_depth = saved_depth;
24904 self.write(")");
24905 } else {
24906 match inner.as_ref() {
24908 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
24909 self.generate_data_type(&DataType::Timestamp {
24910 precision: None,
24911 timezone: false,
24912 })?;
24913 }
24914 _ => {
24915 self.generate_data_type(inner)?;
24916 }
24917 }
24918 }
24919 }
24920 DataType::Custom { name } => {
24921 let name_upper = name.to_ascii_uppercase();
24923 match self.config.dialect {
24924 Some(DialectType::ClickHouse) => {
24925 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
24926 (name_upper[..idx].to_string(), &name[idx..])
24927 } else {
24928 (name_upper.clone(), "")
24929 };
24930 let mapped = match base_upper.as_str() {
24931 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
24932 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
24933 "DATETIME64" => "DateTime64",
24934 "DATE32" => "Date32",
24935 "INT" => "Int32",
24936 "MEDIUMINT" => "Int32",
24937 "INT8" => "Int8",
24938 "INT16" => "Int16",
24939 "INT32" => "Int32",
24940 "INT64" => "Int64",
24941 "INT128" => "Int128",
24942 "INT256" => "Int256",
24943 "UINT8" => "UInt8",
24944 "UINT16" => "UInt16",
24945 "UINT32" => "UInt32",
24946 "UINT64" => "UInt64",
24947 "UINT128" => "UInt128",
24948 "UINT256" => "UInt256",
24949 "FLOAT32" => "Float32",
24950 "FLOAT64" => "Float64",
24951 "DECIMAL32" => "Decimal32",
24952 "DECIMAL64" => "Decimal64",
24953 "DECIMAL128" => "Decimal128",
24954 "DECIMAL256" => "Decimal256",
24955 "ENUM" => "Enum",
24956 "ENUM8" => "Enum8",
24957 "ENUM16" => "Enum16",
24958 "FIXEDSTRING" => "FixedString",
24959 "NESTED" => "Nested",
24960 "LOWCARDINALITY" => "LowCardinality",
24961 "NULLABLE" => "Nullable",
24962 "IPV4" => "IPv4",
24963 "IPV6" => "IPv6",
24964 "POINT" => "Point",
24965 "RING" => "Ring",
24966 "LINESTRING" => "LineString",
24967 "MULTILINESTRING" => "MultiLineString",
24968 "POLYGON" => "Polygon",
24969 "MULTIPOLYGON" => "MultiPolygon",
24970 "AGGREGATEFUNCTION" => "AggregateFunction",
24971 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
24972 "DYNAMIC" => "Dynamic",
24973 _ => "",
24974 };
24975 if mapped.is_empty() {
24976 self.write(name);
24977 } else {
24978 self.write(mapped);
24979 if matches!(base_upper.as_str(), "ENUM8" | "ENUM16")
24980 && !suffix.is_empty()
24981 {
24982 let escaped_suffix = suffix
24983 .replace('\\', "\\\\")
24984 .replace('\t', "\\t")
24985 .replace('\n', "\\n")
24986 .replace('\r', "\\r");
24987 self.write(&escaped_suffix);
24988 } else {
24989 self.write(suffix);
24990 }
24991 }
24992 }
24993 Some(DialectType::MySQL)
24994 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
24995 {
24996 self.write_keyword("TIMESTAMP");
24998 }
24999 Some(DialectType::Snowflake) => {
25000 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
25001 (name_upper[..idx].to_string(), &name[idx..])
25002 } else {
25003 (name_upper.clone(), "")
25004 };
25005
25006 match base_upper.as_str() {
25007 "TIMESTAMPNTZ" | "TIMESTAMP_NTZ" => {
25008 self.write_keyword("TIMESTAMPNTZ");
25009 self.write(suffix);
25010 }
25011 "TIMESTAMPLTZ" | "TIMESTAMP_LTZ" => {
25012 self.write_keyword("TIMESTAMPLTZ");
25013 self.write(suffix);
25014 }
25015 "TIMESTAMPTZ" | "TIMESTAMP_TZ" => {
25016 self.write_keyword("TIMESTAMPTZ");
25017 self.write(suffix);
25018 }
25019 _ => self.write(name),
25020 }
25021 }
25022 Some(DialectType::Fabric) => {
25023 let (base_upper, args_str) = if let Some(idx) = name.find('(') {
25024 (name_upper[..idx].to_string(), Some(&name[idx..]))
25025 } else {
25026 (name_upper.clone(), None)
25027 };
25028
25029 match base_upper.as_str() {
25030 "NVARCHAR" => {
25031 self.write_keyword("VARCHAR");
25032 if let Some(args) = args_str {
25033 self.write(args);
25034 }
25035 }
25036 "NCHAR" => {
25037 self.write_keyword("CHAR");
25038 if let Some(args) = args_str {
25039 self.write(args);
25040 }
25041 }
25042 _ => self.write(name),
25043 }
25044 }
25045 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
25046 self.write_keyword("SQL_VARIANT");
25047 }
25048 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
25049 self.write_keyword("DECIMAL(38, 5)");
25050 }
25051 Some(DialectType::Exasol) => {
25052 match name_upper.as_str() {
25054 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
25056 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
25058 "MEDIUMINT" => self.write_keyword("INT"),
25060 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
25062 self.write_keyword("DECIMAL")
25063 }
25064 "DATETIME" => self.write_keyword("TIMESTAMP"),
25066 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
25067 _ => self.write(name),
25068 }
25069 }
25070 Some(DialectType::Dremio) => {
25071 match name_upper.as_str() {
25073 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
25074 "ARRAY" => self.write_keyword("LIST"),
25075 "NCHAR" => self.write_keyword("VARCHAR"),
25076 _ => self.write(name),
25077 }
25078 }
25079 _ => {
25081 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
25083 (name_upper[..idx].to_string(), Some(&name[idx..]))
25084 } else {
25085 (name_upper.clone(), None)
25086 };
25087
25088 match base_upper.as_str() {
25089 "INT64"
25090 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25091 {
25092 self.write_keyword("BIGINT");
25093 }
25094 "FLOAT64"
25095 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25096 {
25097 self.write_keyword("DOUBLE");
25098 }
25099 "BOOL"
25100 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25101 {
25102 self.write_keyword("BOOLEAN");
25103 }
25104 "BYTES"
25105 if matches!(
25106 self.config.dialect,
25107 Some(DialectType::Spark)
25108 | Some(DialectType::Hive)
25109 | Some(DialectType::Databricks)
25110 ) =>
25111 {
25112 self.write_keyword("BINARY");
25113 }
25114 "BYTES"
25115 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
25116 {
25117 self.write_keyword("VARBINARY");
25118 }
25119 "DATETIME2" | "SMALLDATETIME"
25121 if !matches!(
25122 self.config.dialect,
25123 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25124 ) =>
25125 {
25126 if matches!(
25128 self.config.dialect,
25129 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25130 ) {
25131 self.write_keyword("TIMESTAMP");
25132 if let Some(args) = _args_str {
25133 self.write(args);
25134 }
25135 } else {
25136 self.write_keyword("TIMESTAMP");
25137 }
25138 }
25139 "DATETIMEOFFSET"
25141 if !matches!(
25142 self.config.dialect,
25143 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25144 ) =>
25145 {
25146 if matches!(
25147 self.config.dialect,
25148 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25149 ) {
25150 self.write_keyword("TIMESTAMPTZ");
25151 if let Some(args) = _args_str {
25152 self.write(args);
25153 }
25154 } else {
25155 self.write_keyword("TIMESTAMPTZ");
25156 }
25157 }
25158 "UNIQUEIDENTIFIER"
25160 if !matches!(
25161 self.config.dialect,
25162 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25163 ) =>
25164 {
25165 match self.config.dialect {
25166 Some(DialectType::Spark)
25167 | Some(DialectType::Databricks)
25168 | Some(DialectType::Hive) => self.write_keyword("STRING"),
25169 _ => self.write_keyword("UUID"),
25170 }
25171 }
25172 "BIT"
25174 if !matches!(
25175 self.config.dialect,
25176 Some(DialectType::TSQL)
25177 | Some(DialectType::Fabric)
25178 | Some(DialectType::PostgreSQL)
25179 | Some(DialectType::MySQL)
25180 | Some(DialectType::DuckDB)
25181 ) =>
25182 {
25183 self.write_keyword("BOOLEAN");
25184 }
25185 "NVARCHAR"
25187 if !matches!(
25188 self.config.dialect,
25189 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25190 ) =>
25191 {
25192 match self.config.dialect {
25193 Some(DialectType::Oracle) => {
25194 self.write_keyword("NVARCHAR2");
25196 if let Some(args) = _args_str {
25197 self.write(args);
25198 }
25199 }
25200 Some(DialectType::BigQuery) => {
25201 self.write_keyword("STRING");
25203 }
25204 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
25205 self.write_keyword("TEXT");
25206 if let Some(args) = _args_str {
25207 self.write(args);
25208 }
25209 }
25210 Some(DialectType::Hive) => {
25211 self.write_keyword("STRING");
25213 }
25214 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
25215 if _args_str.is_some() {
25216 self.write_keyword("VARCHAR");
25217 self.write(_args_str.unwrap());
25218 } else {
25219 self.write_keyword("STRING");
25220 }
25221 }
25222 _ => {
25223 self.write_keyword("VARCHAR");
25224 if let Some(args) = _args_str {
25225 self.write(args);
25226 }
25227 }
25228 }
25229 }
25230 "NCHAR"
25232 if !matches!(
25233 self.config.dialect,
25234 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25235 ) =>
25236 {
25237 match self.config.dialect {
25238 Some(DialectType::Oracle) => {
25239 self.write_keyword("NCHAR");
25241 if let Some(args) = _args_str {
25242 self.write(args);
25243 }
25244 }
25245 Some(DialectType::BigQuery) => {
25246 self.write_keyword("STRING");
25248 }
25249 Some(DialectType::Hive) => {
25250 self.write_keyword("STRING");
25252 }
25253 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
25254 self.write_keyword("TEXT");
25255 if let Some(args) = _args_str {
25256 self.write(args);
25257 }
25258 }
25259 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
25260 if _args_str.is_some() {
25261 self.write_keyword("CHAR");
25262 self.write(_args_str.unwrap());
25263 } else {
25264 self.write_keyword("STRING");
25265 }
25266 }
25267 _ => {
25268 self.write_keyword("CHAR");
25269 if let Some(args) = _args_str {
25270 self.write(args);
25271 }
25272 }
25273 }
25274 }
25275 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
25278 Some(DialectType::MySQL)
25279 | Some(DialectType::SingleStore)
25280 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
25281 Some(DialectType::Spark)
25282 | Some(DialectType::Databricks)
25283 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
25284 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
25285 Some(DialectType::Presto)
25286 | Some(DialectType::Trino)
25287 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
25288 Some(DialectType::Snowflake)
25289 | Some(DialectType::Redshift)
25290 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
25291 _ => self.write_keyword("TEXT"),
25292 },
25293 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
25296 Some(DialectType::MySQL)
25297 | Some(DialectType::SingleStore)
25298 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
25299 Some(DialectType::Spark)
25300 | Some(DialectType::Databricks)
25301 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
25302 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
25303 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
25304 Some(DialectType::Presto)
25305 | Some(DialectType::Trino)
25306 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
25307 Some(DialectType::Snowflake)
25308 | Some(DialectType::Redshift)
25309 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
25310 _ => self.write_keyword("BLOB"),
25311 },
25312 "LONGVARCHAR" => match self.config.dialect {
25314 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
25315 _ => self.write_keyword("VARCHAR"),
25316 },
25317 "DATETIME" => {
25319 match self.config.dialect {
25320 Some(DialectType::MySQL)
25321 | Some(DialectType::Doris)
25322 | Some(DialectType::StarRocks)
25323 | Some(DialectType::TSQL)
25324 | Some(DialectType::Fabric)
25325 | Some(DialectType::BigQuery)
25326 | Some(DialectType::SQLite)
25327 | Some(DialectType::Snowflake) => {
25328 self.write_keyword("DATETIME");
25329 if let Some(args) = _args_str {
25330 self.write(args);
25331 }
25332 }
25333 Some(_) => {
25334 self.write_keyword("TIMESTAMP");
25336 if let Some(args) = _args_str {
25337 self.write(args);
25338 }
25339 }
25340 None => {
25341 self.write(name);
25343 }
25344 }
25345 }
25346 "VARCHAR2"
25348 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
25349 {
25350 match self.config.dialect {
25351 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25352 self.write_keyword("TEXT");
25353 }
25354 Some(DialectType::Hive)
25355 | Some(DialectType::Spark)
25356 | Some(DialectType::Databricks)
25357 | Some(DialectType::BigQuery)
25358 | Some(DialectType::ClickHouse)
25359 | Some(DialectType::StarRocks)
25360 | Some(DialectType::Doris) => {
25361 self.write_keyword("STRING");
25362 }
25363 _ => {
25364 self.write_keyword("VARCHAR");
25365 if let Some(args) = _args_str {
25366 self.write(args);
25367 }
25368 }
25369 }
25370 }
25371 "NVARCHAR2"
25372 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
25373 {
25374 match self.config.dialect {
25375 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
25376 self.write_keyword("TEXT");
25377 }
25378 Some(DialectType::Hive)
25379 | Some(DialectType::Spark)
25380 | Some(DialectType::Databricks)
25381 | Some(DialectType::BigQuery)
25382 | Some(DialectType::ClickHouse)
25383 | Some(DialectType::StarRocks)
25384 | Some(DialectType::Doris) => {
25385 self.write_keyword("STRING");
25386 }
25387 _ => {
25388 self.write_keyword("VARCHAR");
25389 if let Some(args) = _args_str {
25390 self.write(args);
25391 }
25392 }
25393 }
25394 }
25395 _ => self.write(name),
25396 }
25397 }
25398 }
25399 }
25400 DataType::Geometry { subtype, srid } => {
25401 match self.config.dialect {
25403 Some(DialectType::MySQL) => {
25404 if let Some(sub) = subtype {
25406 self.write_keyword(sub);
25407 if let Some(s) = srid {
25408 self.write(" SRID ");
25409 self.write(&s.to_string());
25410 }
25411 } else {
25412 self.write_keyword("GEOMETRY");
25413 }
25414 }
25415 Some(DialectType::BigQuery) => {
25416 self.write_keyword("GEOGRAPHY");
25418 }
25419 Some(DialectType::Teradata) => {
25420 self.write_keyword("ST_GEOMETRY");
25422 if subtype.is_some() || srid.is_some() {
25423 self.write("(");
25424 if let Some(sub) = subtype {
25425 self.write_keyword(sub);
25426 }
25427 if let Some(s) = srid {
25428 if subtype.is_some() {
25429 self.write(", ");
25430 }
25431 self.write(&s.to_string());
25432 }
25433 self.write(")");
25434 }
25435 }
25436 _ => {
25437 self.write_keyword("GEOMETRY");
25439 if subtype.is_some() || srid.is_some() {
25440 self.write("(");
25441 if let Some(sub) = subtype {
25442 self.write_keyword(sub);
25443 }
25444 if let Some(s) = srid {
25445 if subtype.is_some() {
25446 self.write(", ");
25447 }
25448 self.write(&s.to_string());
25449 }
25450 self.write(")");
25451 }
25452 }
25453 }
25454 }
25455 DataType::Geography { subtype, srid } => {
25456 match self.config.dialect {
25458 Some(DialectType::MySQL) => {
25459 if let Some(sub) = subtype {
25461 self.write_keyword(sub);
25462 } else {
25463 self.write_keyword("GEOMETRY");
25464 }
25465 let effective_srid = srid.unwrap_or(4326);
25467 self.write(" SRID ");
25468 self.write(&effective_srid.to_string());
25469 }
25470 Some(DialectType::BigQuery) => {
25471 self.write_keyword("GEOGRAPHY");
25473 }
25474 Some(DialectType::Snowflake) => {
25475 self.write_keyword("GEOGRAPHY");
25477 }
25478 _ => {
25479 self.write_keyword("GEOGRAPHY");
25481 if subtype.is_some() || srid.is_some() {
25482 self.write("(");
25483 if let Some(sub) = subtype {
25484 self.write_keyword(sub);
25485 }
25486 if let Some(s) = srid {
25487 if subtype.is_some() {
25488 self.write(", ");
25489 }
25490 self.write(&s.to_string());
25491 }
25492 self.write(")");
25493 }
25494 }
25495 }
25496 }
25497 DataType::CharacterSet { name } => {
25498 self.write_keyword("CHAR CHARACTER SET ");
25500 self.write(name);
25501 }
25502 _ => self.write("UNKNOWN"),
25503 }
25504 Ok(())
25505 }
25506
25507 #[inline]
25510 fn write(&mut self, s: &str) {
25511 self.output.push_str(s);
25512 }
25513
25514 #[inline]
25515 fn write_space(&mut self) {
25516 self.output.push(' ');
25517 }
25518
25519 #[inline]
25520 fn write_keyword(&mut self, keyword: &str) {
25521 if self.config.uppercase_keywords {
25522 self.output.push_str(keyword);
25523 } else {
25524 for b in keyword.bytes() {
25525 self.output.push(b.to_ascii_lowercase() as char);
25526 }
25527 }
25528 }
25529
25530 fn write_func_name(&mut self, name: &str) {
25532 let normalized = self.normalize_func_name(name);
25533 self.output.push_str(normalized.as_ref());
25534 }
25535
25536 fn convert_strptime_to_exasol_format(format: &str) -> String {
25540 let mut result = String::new();
25541 let chars: Vec<char> = format.chars().collect();
25542 let mut i = 0;
25543 while i < chars.len() {
25544 if chars[i] == '%' && i + 1 < chars.len() {
25545 let spec = chars[i + 1];
25546 let exasol_spec = match spec {
25547 'Y' => "YYYY",
25548 'y' => "YY",
25549 'm' => "MM",
25550 'd' => "DD",
25551 'H' => "HH",
25552 'M' => "MI",
25553 'S' => "SS",
25554 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
25566 result.push('%');
25568 result.push(spec);
25569 i += 2;
25570 continue;
25571 }
25572 };
25573 result.push_str(exasol_spec);
25574 i += 2;
25575 } else {
25576 result.push(chars[i]);
25577 i += 1;
25578 }
25579 }
25580 result
25581 }
25582
25583 fn convert_strptime_to_postgres_format(format: &str) -> String {
25587 let mut result = String::new();
25588 let chars: Vec<char> = format.chars().collect();
25589 let mut i = 0;
25590 while i < chars.len() {
25591 if chars[i] == '%' && i + 1 < chars.len() {
25592 if chars[i + 1] == '-' && i + 2 < chars.len() {
25594 let spec = chars[i + 2];
25595 let pg_spec = match spec {
25596 'd' => "FMDD",
25597 'm' => "FMMM",
25598 'H' => "FMHH24",
25599 'M' => "FMMI",
25600 'S' => "FMSS",
25601 _ => {
25602 result.push('%');
25603 result.push('-');
25604 result.push(spec);
25605 i += 3;
25606 continue;
25607 }
25608 };
25609 result.push_str(pg_spec);
25610 i += 3;
25611 continue;
25612 }
25613 let spec = chars[i + 1];
25614 let pg_spec = match spec {
25615 'Y' => "YYYY",
25616 'y' => "YY",
25617 'm' => "MM",
25618 'd' => "DD",
25619 'H' => "HH24",
25620 'I' => "HH12",
25621 'M' => "MI",
25622 'S' => "SS",
25623 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
25634 result.push('%');
25636 result.push(spec);
25637 i += 2;
25638 continue;
25639 }
25640 };
25641 result.push_str(pg_spec);
25642 i += 2;
25643 } else {
25644 result.push(chars[i]);
25645 i += 1;
25646 }
25647 }
25648 result
25649 }
25650
25651 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
25653 if self.config.limit_only_literals {
25654 if let Some(value) = Self::try_evaluate_constant(expr) {
25655 self.write(&value.to_string());
25656 return Ok(());
25657 }
25658 }
25659 self.generate_expression(expr)
25660 }
25661
25662 fn write_formatted_comment(&mut self, comment: &str) {
25666 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
25669 &comment[2..comment.len() - 2]
25672 } else if comment.starts_with("--") {
25673 &comment[2..]
25676 } else {
25677 comment
25679 };
25680 if content.trim().is_empty() {
25682 return;
25683 }
25684 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
25687 let content = &sanitized;
25688 self.output.push_str("/*");
25690 if !content.starts_with(' ') {
25691 self.output.push(' ');
25692 }
25693 self.output.push_str(content);
25694 if !content.ends_with(' ') {
25695 self.output.push(' ');
25696 }
25697 self.output.push_str("*/");
25698 }
25699
25700 fn escape_block_for_single_quote(&self, block: &str) -> String {
25703 let escape_backslash = matches!(
25704 self.config.dialect,
25705 Some(crate::dialects::DialectType::Snowflake)
25706 );
25707 let mut escaped = String::with_capacity(block.len() + 4);
25708 for ch in block.chars() {
25709 if ch == '\'' {
25710 escaped.push('\\');
25711 escaped.push('\'');
25712 } else if escape_backslash && ch == '\\' {
25713 escaped.push('\\');
25714 escaped.push('\\');
25715 } else {
25716 escaped.push(ch);
25717 }
25718 }
25719 escaped
25720 }
25721
25722 fn write_newline(&mut self) {
25723 self.output.push('\n');
25724 }
25725
25726 fn write_indent(&mut self) {
25727 for _ in 0..self.indent_level {
25728 self.output.push_str(self.config.indent);
25729 }
25730 }
25731
25732 fn too_wide(&self, args: &[String]) -> bool {
25738 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
25739 }
25740
25741 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
25744 let config = GeneratorConfig {
25745 pretty: false,
25746 dialect: self.config.dialect,
25747 ..Default::default()
25748 };
25749 let mut gen = Generator::with_config(config);
25750 gen.generate_expression(expr)?;
25751 Ok(gen.output)
25752 }
25753
25754 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
25757 if self.config.pretty {
25758 self.write_newline();
25759 self.write_indent();
25760 self.write_keyword(keyword);
25761 self.write_newline();
25762 self.indent_level += 1;
25763 self.write_indent();
25764 self.generate_expression(condition)?;
25765 self.indent_level -= 1;
25766 } else {
25767 self.write_space();
25768 self.write_keyword(keyword);
25769 self.write_space();
25770 self.generate_expression(condition)?;
25771 }
25772 Ok(())
25773 }
25774
25775 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
25778 if exprs.is_empty() {
25779 return Ok(());
25780 }
25781
25782 if self.config.pretty {
25783 self.write_newline();
25784 self.write_indent();
25785 self.write_keyword(keyword);
25786 self.write_newline();
25787 self.indent_level += 1;
25788 for (i, expr) in exprs.iter().enumerate() {
25789 if i > 0 {
25790 self.write(",");
25791 self.write_newline();
25792 }
25793 self.write_indent();
25794 self.generate_expression(expr)?;
25795 }
25796 self.indent_level -= 1;
25797 } else {
25798 self.write_space();
25799 self.write_keyword(keyword);
25800 self.write_space();
25801 for (i, expr) in exprs.iter().enumerate() {
25802 if i > 0 {
25803 self.write(", ");
25804 }
25805 self.generate_expression(expr)?;
25806 }
25807 }
25808 Ok(())
25809 }
25810
25811 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
25813 if orderings.is_empty() {
25814 return Ok(());
25815 }
25816
25817 if self.config.pretty {
25818 self.write_newline();
25819 self.write_indent();
25820 self.write_keyword(keyword);
25821 self.write_newline();
25822 self.indent_level += 1;
25823 for (i, ordered) in orderings.iter().enumerate() {
25824 if i > 0 {
25825 self.write(",");
25826 self.write_newline();
25827 }
25828 self.write_indent();
25829 self.generate_ordered(ordered)?;
25830 }
25831 self.indent_level -= 1;
25832 } else {
25833 self.write_space();
25834 self.write_keyword(keyword);
25835 self.write_space();
25836 for (i, ordered) in orderings.iter().enumerate() {
25837 if i > 0 {
25838 self.write(", ");
25839 }
25840 self.generate_ordered(ordered)?;
25841 }
25842 }
25843 Ok(())
25844 }
25845
25846 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
25848 if windows.is_empty() {
25849 return Ok(());
25850 }
25851
25852 if self.config.pretty {
25853 self.write_newline();
25854 self.write_indent();
25855 self.write_keyword("WINDOW");
25856 self.write_newline();
25857 self.indent_level += 1;
25858 for (i, named_window) in windows.iter().enumerate() {
25859 if i > 0 {
25860 self.write(",");
25861 self.write_newline();
25862 }
25863 self.write_indent();
25864 self.generate_identifier(&named_window.name)?;
25865 self.write_space();
25866 self.write_keyword("AS");
25867 self.write(" (");
25868 self.generate_over(&named_window.spec)?;
25869 self.write(")");
25870 }
25871 self.indent_level -= 1;
25872 } else {
25873 self.write_space();
25874 self.write_keyword("WINDOW");
25875 self.write_space();
25876 for (i, named_window) in windows.iter().enumerate() {
25877 if i > 0 {
25878 self.write(", ");
25879 }
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 }
25888 Ok(())
25889 }
25890
25891 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
25893 self.write_keyword("AI_AGG");
25895 self.write("(");
25896 self.generate_expression(&e.this)?;
25897 self.write(", ");
25898 self.generate_expression(&e.expression)?;
25899 self.write(")");
25900 Ok(())
25901 }
25902
25903 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
25904 self.write_keyword("AI_CLASSIFY");
25906 self.write("(");
25907 self.generate_expression(&e.this)?;
25908 if let Some(categories) = &e.categories {
25909 self.write(", ");
25910 self.generate_expression(categories)?;
25911 }
25912 if let Some(config) = &e.config {
25913 self.write(", ");
25914 self.generate_expression(config)?;
25915 }
25916 self.write(")");
25917 Ok(())
25918 }
25919
25920 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
25921 self.write_keyword("ADD");
25923 self.write_space();
25924 if e.exists {
25925 self.write_keyword("IF NOT EXISTS");
25926 self.write_space();
25927 }
25928 self.generate_expression(&e.this)?;
25929 if let Some(location) = &e.location {
25930 self.write_space();
25931 self.generate_expression(location)?;
25932 }
25933 Ok(())
25934 }
25935
25936 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
25937 self.write_keyword("ALGORITHM");
25939 self.write("=");
25940 self.generate_expression(&e.this)?;
25941 Ok(())
25942 }
25943
25944 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
25945 self.generate_expression(&e.this)?;
25947 self.write_space();
25948 self.write_keyword("AS");
25949 self.write(" (");
25950 for (i, expr) in e.expressions.iter().enumerate() {
25951 if i > 0 {
25952 self.write(", ");
25953 }
25954 self.generate_expression(expr)?;
25955 }
25956 self.write(")");
25957 Ok(())
25958 }
25959
25960 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
25961 self.write_keyword("ALLOWED_VALUES");
25963 self.write_space();
25964 for (i, expr) in e.expressions.iter().enumerate() {
25965 if i > 0 {
25966 self.write(", ");
25967 }
25968 self.generate_expression(expr)?;
25969 }
25970 Ok(())
25971 }
25972
25973 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
25974 self.write_keyword("ALTER COLUMN");
25976 self.write_space();
25977 self.generate_expression(&e.this)?;
25978
25979 if let Some(dtype) = &e.dtype {
25980 self.write_space();
25981 self.write_keyword("SET DATA TYPE");
25982 self.write_space();
25983 self.generate_expression(dtype)?;
25984 if let Some(collate) = &e.collate {
25985 self.write_space();
25986 self.write_keyword("COLLATE");
25987 self.write_space();
25988 self.generate_expression(collate)?;
25989 }
25990 if let Some(using) = &e.using {
25991 self.write_space();
25992 self.write_keyword("USING");
25993 self.write_space();
25994 self.generate_expression(using)?;
25995 }
25996 } else if let Some(default) = &e.default {
25997 self.write_space();
25998 self.write_keyword("SET DEFAULT");
25999 self.write_space();
26000 self.generate_expression(default)?;
26001 } else if let Some(comment) = &e.comment {
26002 self.write_space();
26003 self.write_keyword("COMMENT");
26004 self.write_space();
26005 self.generate_expression(comment)?;
26006 } else if let Some(drop) = &e.drop {
26007 self.write_space();
26008 self.write_keyword("DROP");
26009 self.write_space();
26010 self.generate_expression(drop)?;
26011 } else if let Some(visible) = &e.visible {
26012 self.write_space();
26013 self.generate_expression(visible)?;
26014 } else if let Some(rename_to) = &e.rename_to {
26015 self.write_space();
26016 self.write_keyword("RENAME TO");
26017 self.write_space();
26018 self.generate_expression(rename_to)?;
26019 } else if let Some(allow_null) = &e.allow_null {
26020 self.write_space();
26021 self.generate_expression(allow_null)?;
26022 }
26023 Ok(())
26024 }
26025
26026 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
26027 self.write_keyword("ALTER SESSION");
26029 self.write_space();
26030 if e.unset.is_some() {
26031 self.write_keyword("UNSET");
26032 } else {
26033 self.write_keyword("SET");
26034 }
26035 self.write_space();
26036 for (i, expr) in e.expressions.iter().enumerate() {
26037 if i > 0 {
26038 self.write(", ");
26039 }
26040 self.generate_expression(expr)?;
26041 }
26042 Ok(())
26043 }
26044
26045 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
26046 self.write_keyword("SET");
26048
26049 if let Some(opt) = &e.option {
26051 self.write_space();
26052 self.generate_expression(opt)?;
26053 }
26054
26055 if !e.expressions.is_empty() {
26058 let is_properties = e
26060 .expressions
26061 .iter()
26062 .any(|expr| matches!(expr, Expression::Eq(_)));
26063 if is_properties && e.option.is_none() {
26064 self.write_space();
26065 self.write_keyword("PROPERTIES");
26066 }
26067 self.write_space();
26068 for (i, expr) in e.expressions.iter().enumerate() {
26069 if i > 0 {
26070 self.write(", ");
26071 }
26072 self.generate_expression(expr)?;
26073 }
26074 }
26075
26076 if let Some(file_format) = &e.file_format {
26078 self.write(" ");
26079 self.write_keyword("STAGE_FILE_FORMAT");
26080 self.write(" = (");
26081 self.generate_space_separated_properties(file_format)?;
26082 self.write(")");
26083 }
26084
26085 if let Some(copy_options) = &e.copy_options {
26087 self.write(" ");
26088 self.write_keyword("STAGE_COPY_OPTIONS");
26089 self.write(" = (");
26090 self.generate_space_separated_properties(copy_options)?;
26091 self.write(")");
26092 }
26093
26094 if let Some(tag) = &e.tag {
26096 self.write(" ");
26097 self.write_keyword("TAG");
26098 self.write(" ");
26099 self.generate_expression(tag)?;
26100 }
26101
26102 Ok(())
26103 }
26104
26105 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
26107 match expr {
26108 Expression::Tuple(t) => {
26109 for (i, prop) in t.expressions.iter().enumerate() {
26110 if i > 0 {
26111 self.write(" ");
26112 }
26113 self.generate_expression(prop)?;
26114 }
26115 }
26116 _ => {
26117 self.generate_expression(expr)?;
26118 }
26119 }
26120 Ok(())
26121 }
26122
26123 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
26124 self.write_keyword("ALTER");
26126 if e.compound.is_some() {
26127 self.write_space();
26128 self.write_keyword("COMPOUND");
26129 }
26130 self.write_space();
26131 self.write_keyword("SORTKEY");
26132 self.write_space();
26133 if let Some(this) = &e.this {
26134 self.generate_expression(this)?;
26135 } else if !e.expressions.is_empty() {
26136 self.write("(");
26137 for (i, expr) in e.expressions.iter().enumerate() {
26138 if i > 0 {
26139 self.write(", ");
26140 }
26141 self.generate_expression(expr)?;
26142 }
26143 self.write(")");
26144 }
26145 Ok(())
26146 }
26147
26148 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
26149 self.write_keyword("ANALYZE");
26151 if !e.options.is_empty() {
26152 self.write_space();
26153 for (i, opt) in e.options.iter().enumerate() {
26154 if i > 0 {
26155 self.write_space();
26156 }
26157 if let Expression::Identifier(id) = opt {
26159 self.write_keyword(&id.name);
26160 } else {
26161 self.generate_expression(opt)?;
26162 }
26163 }
26164 }
26165 if let Some(kind) = &e.kind {
26166 self.write_space();
26167 self.write_keyword(kind);
26168 }
26169 if let Some(this) = &e.this {
26170 self.write_space();
26171 self.generate_expression(this)?;
26172 }
26173 if !e.columns.is_empty() {
26175 self.write("(");
26176 for (i, col) in e.columns.iter().enumerate() {
26177 if i > 0 {
26178 self.write(", ");
26179 }
26180 self.write(col);
26181 }
26182 self.write(")");
26183 }
26184 if let Some(partition) = &e.partition {
26185 self.write_space();
26186 self.generate_expression(partition)?;
26187 }
26188 if let Some(mode) = &e.mode {
26189 self.write_space();
26190 self.generate_expression(mode)?;
26191 }
26192 if let Some(expression) = &e.expression {
26193 self.write_space();
26194 self.generate_expression(expression)?;
26195 }
26196 if !e.properties.is_empty() {
26197 self.write_space();
26198 self.write_keyword(self.config.with_properties_prefix);
26199 self.write(" (");
26200 for (i, prop) in e.properties.iter().enumerate() {
26201 if i > 0 {
26202 self.write(", ");
26203 }
26204 self.generate_expression(prop)?;
26205 }
26206 self.write(")");
26207 }
26208 Ok(())
26209 }
26210
26211 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
26212 self.write_keyword("DELETE");
26214 if let Some(kind) = &e.kind {
26215 self.write_space();
26216 self.write_keyword(kind);
26217 }
26218 self.write_space();
26219 self.write_keyword("STATISTICS");
26220 Ok(())
26221 }
26222
26223 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
26224 if let Expression::Identifier(id) = e.this.as_ref() {
26227 self.write_keyword(&id.name);
26228 } else {
26229 self.generate_expression(&e.this)?;
26230 }
26231 self.write_space();
26232 self.write_keyword("HISTOGRAM ON");
26233 self.write_space();
26234 for (i, expr) in e.expressions.iter().enumerate() {
26235 if i > 0 {
26236 self.write(", ");
26237 }
26238 self.generate_expression(expr)?;
26239 }
26240 if let Some(expression) = &e.expression {
26241 self.write_space();
26242 self.generate_expression(expression)?;
26243 }
26244 if let Some(update_options) = &e.update_options {
26245 self.write_space();
26246 self.generate_expression(update_options)?;
26247 self.write_space();
26248 self.write_keyword("UPDATE");
26249 }
26250 Ok(())
26251 }
26252
26253 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
26254 self.write_keyword("LIST CHAINED ROWS");
26256 if let Some(expression) = &e.expression {
26257 self.write_space();
26258 self.write_keyword("INTO");
26259 self.write_space();
26260 self.generate_expression(expression)?;
26261 }
26262 Ok(())
26263 }
26264
26265 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
26266 self.write_keyword("SAMPLE");
26268 self.write_space();
26269 if let Some(sample) = &e.sample {
26270 self.generate_expression(sample)?;
26271 self.write_space();
26272 }
26273 self.write_keyword(&e.kind);
26274 Ok(())
26275 }
26276
26277 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
26278 self.write_keyword(&e.kind);
26280 if let Some(option) = &e.option {
26281 self.write_space();
26282 self.generate_expression(option)?;
26283 }
26284 self.write_space();
26285 self.write_keyword("STATISTICS");
26286 if let Some(this) = &e.this {
26287 self.write_space();
26288 self.generate_expression(this)?;
26289 }
26290 if !e.expressions.is_empty() {
26291 self.write_space();
26292 for (i, expr) in e.expressions.iter().enumerate() {
26293 if i > 0 {
26294 self.write(", ");
26295 }
26296 self.generate_expression(expr)?;
26297 }
26298 }
26299 Ok(())
26300 }
26301
26302 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
26303 self.write_keyword("VALIDATE");
26305 self.write_space();
26306 self.write_keyword(&e.kind);
26307 if let Some(this) = &e.this {
26308 self.write_space();
26309 if let Expression::Identifier(id) = this.as_ref() {
26311 self.write_keyword(&id.name);
26312 } else {
26313 self.generate_expression(this)?;
26314 }
26315 }
26316 if let Some(expression) = &e.expression {
26317 self.write_space();
26318 self.write_keyword("INTO");
26319 self.write_space();
26320 self.generate_expression(expression)?;
26321 }
26322 Ok(())
26323 }
26324
26325 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
26326 self.write_keyword("WITH");
26328 self.write_space();
26329 for (i, expr) in e.expressions.iter().enumerate() {
26330 if i > 0 {
26331 self.write(", ");
26332 }
26333 self.generate_expression(expr)?;
26334 }
26335 Ok(())
26336 }
26337
26338 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
26339 self.generate_expression(&e.this)?;
26342 self.write("(");
26343 for (i, arg) in e.expressions.iter().enumerate() {
26344 if i > 0 {
26345 self.write(", ");
26346 }
26347 self.generate_expression(arg)?;
26348 }
26349 self.write(")");
26350 Ok(())
26351 }
26352
26353 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
26354 self.generate_expression(&e.this)?;
26356 self.write("(");
26357 for (i, arg) in e.expressions.iter().enumerate() {
26358 if i > 0 {
26359 self.write(", ");
26360 }
26361 self.generate_expression(arg)?;
26362 }
26363 self.write(")");
26364 Ok(())
26365 }
26366
26367 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
26368 self.generate_expression(&e.this)?;
26370 self.write_space();
26371 self.write_keyword("APPLY");
26372 self.write("(");
26373 self.generate_expression(&e.expression)?;
26374 self.write(")");
26375 Ok(())
26376 }
26377
26378 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
26379 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
26381 self.write("(");
26382 self.generate_expression(&e.this)?;
26383 if let Some(percentile) = &e.percentile {
26384 self.write(", ");
26385 self.generate_expression(percentile)?;
26386 }
26387 self.write(")");
26388 Ok(())
26389 }
26390
26391 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
26392 self.write_keyword("APPROX_QUANTILE");
26394 self.write("(");
26395 self.generate_expression(&e.this)?;
26396 if let Some(quantile) = &e.quantile {
26397 self.write(", ");
26398 self.generate_expression(quantile)?;
26399 }
26400 if let Some(accuracy) = &e.accuracy {
26401 self.write(", ");
26402 self.generate_expression(accuracy)?;
26403 }
26404 if let Some(weight) = &e.weight {
26405 self.write(", ");
26406 self.generate_expression(weight)?;
26407 }
26408 self.write(")");
26409 Ok(())
26410 }
26411
26412 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
26413 self.write_keyword("APPROX_QUANTILES");
26415 self.write("(");
26416 self.generate_expression(&e.this)?;
26417 if let Some(expression) = &e.expression {
26418 self.write(", ");
26419 self.generate_expression(expression)?;
26420 }
26421 self.write(")");
26422 Ok(())
26423 }
26424
26425 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
26426 self.write_keyword("APPROX_TOP_K");
26428 self.write("(");
26429 self.generate_expression(&e.this)?;
26430 if let Some(expression) = &e.expression {
26431 self.write(", ");
26432 self.generate_expression(expression)?;
26433 }
26434 if let Some(counters) = &e.counters {
26435 self.write(", ");
26436 self.generate_expression(counters)?;
26437 }
26438 self.write(")");
26439 Ok(())
26440 }
26441
26442 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
26443 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
26445 self.write("(");
26446 self.generate_expression(&e.this)?;
26447 if let Some(expression) = &e.expression {
26448 self.write(", ");
26449 self.generate_expression(expression)?;
26450 }
26451 self.write(")");
26452 Ok(())
26453 }
26454
26455 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
26456 self.write_keyword("APPROX_TOP_K_COMBINE");
26458 self.write("(");
26459 self.generate_expression(&e.this)?;
26460 if let Some(expression) = &e.expression {
26461 self.write(", ");
26462 self.generate_expression(expression)?;
26463 }
26464 self.write(")");
26465 Ok(())
26466 }
26467
26468 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
26469 self.write_keyword("APPROX_TOP_K_ESTIMATE");
26471 self.write("(");
26472 self.generate_expression(&e.this)?;
26473 if let Some(expression) = &e.expression {
26474 self.write(", ");
26475 self.generate_expression(expression)?;
26476 }
26477 self.write(")");
26478 Ok(())
26479 }
26480
26481 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
26482 self.write_keyword("APPROX_TOP_SUM");
26484 self.write("(");
26485 self.generate_expression(&e.this)?;
26486 self.write(", ");
26487 self.generate_expression(&e.expression)?;
26488 if let Some(count) = &e.count {
26489 self.write(", ");
26490 self.generate_expression(count)?;
26491 }
26492 self.write(")");
26493 Ok(())
26494 }
26495
26496 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
26497 self.write_keyword("ARG_MAX");
26499 self.write("(");
26500 self.generate_expression(&e.this)?;
26501 self.write(", ");
26502 self.generate_expression(&e.expression)?;
26503 if let Some(count) = &e.count {
26504 self.write(", ");
26505 self.generate_expression(count)?;
26506 }
26507 self.write(")");
26508 Ok(())
26509 }
26510
26511 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
26512 self.write_keyword("ARG_MIN");
26514 self.write("(");
26515 self.generate_expression(&e.this)?;
26516 self.write(", ");
26517 self.generate_expression(&e.expression)?;
26518 if let Some(count) = &e.count {
26519 self.write(", ");
26520 self.generate_expression(count)?;
26521 }
26522 self.write(")");
26523 Ok(())
26524 }
26525
26526 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
26527 self.write_keyword("ARRAY_ALL");
26529 self.write("(");
26530 self.generate_expression(&e.this)?;
26531 self.write(", ");
26532 self.generate_expression(&e.expression)?;
26533 self.write(")");
26534 Ok(())
26535 }
26536
26537 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
26538 self.write_keyword("ARRAY_ANY");
26540 self.write("(");
26541 self.generate_expression(&e.this)?;
26542 self.write(", ");
26543 self.generate_expression(&e.expression)?;
26544 self.write(")");
26545 Ok(())
26546 }
26547
26548 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
26549 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
26551 self.write("(");
26552 for (i, expr) in e.expressions.iter().enumerate() {
26553 if i > 0 {
26554 self.write(", ");
26555 }
26556 self.generate_expression(expr)?;
26557 }
26558 self.write(")");
26559 Ok(())
26560 }
26561
26562 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
26563 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26565 self.write("arraySum");
26566 } else {
26567 self.write_keyword("ARRAY_SUM");
26568 }
26569 self.write("(");
26570 self.generate_expression(&e.this)?;
26571 if let Some(expression) = &e.expression {
26572 self.write(", ");
26573 self.generate_expression(expression)?;
26574 }
26575 self.write(")");
26576 Ok(())
26577 }
26578
26579 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
26580 self.generate_expression(&e.this)?;
26582 self.write_space();
26583 self.write_keyword("AT");
26584 self.write_space();
26585 self.generate_expression(&e.expression)?;
26586 Ok(())
26587 }
26588
26589 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
26590 self.write_keyword("ATTACH");
26592 if e.exists {
26593 self.write_space();
26594 self.write_keyword("IF NOT EXISTS");
26595 }
26596 self.write_space();
26597 self.generate_expression(&e.this)?;
26598 if !e.expressions.is_empty() {
26599 self.write(" (");
26600 for (i, expr) in e.expressions.iter().enumerate() {
26601 if i > 0 {
26602 self.write(", ");
26603 }
26604 self.generate_expression(expr)?;
26605 }
26606 self.write(")");
26607 }
26608 Ok(())
26609 }
26610
26611 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
26612 self.generate_expression(&e.this)?;
26615 if let Some(expression) = &e.expression {
26616 self.write_space();
26617 self.generate_expression(expression)?;
26618 }
26619 Ok(())
26620 }
26621
26622 fn generate_auto_increment_keyword(
26626 &mut self,
26627 col: &crate::expressions::ColumnDef,
26628 ) -> Result<()> {
26629 use crate::dialects::DialectType;
26630 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
26631 self.write_keyword("IDENTITY");
26632 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26633 self.write("(");
26634 if let Some(ref start) = col.auto_increment_start {
26635 self.generate_expression(start)?;
26636 } else {
26637 self.write("0");
26638 }
26639 self.write(", ");
26640 if let Some(ref inc) = col.auto_increment_increment {
26641 self.generate_expression(inc)?;
26642 } else {
26643 self.write("1");
26644 }
26645 self.write(")");
26646 }
26647 } else if matches!(
26648 self.config.dialect,
26649 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
26650 ) {
26651 self.write_keyword("AUTOINCREMENT");
26652 if let Some(ref start) = col.auto_increment_start {
26653 self.write_space();
26654 self.write_keyword("START");
26655 self.write_space();
26656 self.generate_expression(start)?;
26657 }
26658 if let Some(ref inc) = col.auto_increment_increment {
26659 self.write_space();
26660 self.write_keyword("INCREMENT");
26661 self.write_space();
26662 self.generate_expression(inc)?;
26663 }
26664 if let Some(order) = col.auto_increment_order {
26665 self.write_space();
26666 if order {
26667 self.write_keyword("ORDER");
26668 } else {
26669 self.write_keyword("NOORDER");
26670 }
26671 }
26672 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
26673 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26674 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26675 self.write(" (");
26676 let mut first = true;
26677 if let Some(ref start) = col.auto_increment_start {
26678 self.write_keyword("START WITH");
26679 self.write_space();
26680 self.generate_expression(start)?;
26681 first = false;
26682 }
26683 if let Some(ref inc) = col.auto_increment_increment {
26684 if !first {
26685 self.write_space();
26686 }
26687 self.write_keyword("INCREMENT BY");
26688 self.write_space();
26689 self.generate_expression(inc)?;
26690 }
26691 self.write(")");
26692 }
26693 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
26694 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26697 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26698 } else {
26699 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
26700 }
26701 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26702 self.write(" (");
26703 let mut first = true;
26704 if let Some(ref start) = col.auto_increment_start {
26705 self.write_keyword("START WITH");
26706 self.write_space();
26707 self.generate_expression(start)?;
26708 first = false;
26709 }
26710 if let Some(ref inc) = col.auto_increment_increment {
26711 if !first {
26712 self.write_space();
26713 }
26714 self.write_keyword("INCREMENT BY");
26715 self.write_space();
26716 self.generate_expression(inc)?;
26717 }
26718 self.write(")");
26719 }
26720 } else if matches!(
26721 self.config.dialect,
26722 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26723 ) {
26724 self.write_keyword("IDENTITY");
26725 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26726 self.write("(");
26727 if let Some(ref start) = col.auto_increment_start {
26728 self.generate_expression(start)?;
26729 } else {
26730 self.write("0");
26731 }
26732 self.write(", ");
26733 if let Some(ref inc) = col.auto_increment_increment {
26734 self.generate_expression(inc)?;
26735 } else {
26736 self.write("1");
26737 }
26738 self.write(")");
26739 }
26740 } else {
26741 self.write_keyword("AUTO_INCREMENT");
26742 if let Some(ref start) = col.auto_increment_start {
26743 self.write_space();
26744 self.write_keyword("START");
26745 self.write_space();
26746 self.generate_expression(start)?;
26747 }
26748 if let Some(ref inc) = col.auto_increment_increment {
26749 self.write_space();
26750 self.write_keyword("INCREMENT");
26751 self.write_space();
26752 self.generate_expression(inc)?;
26753 }
26754 if let Some(order) = col.auto_increment_order {
26755 self.write_space();
26756 if order {
26757 self.write_keyword("ORDER");
26758 } else {
26759 self.write_keyword("NOORDER");
26760 }
26761 }
26762 }
26763 Ok(())
26764 }
26765
26766 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
26767 self.write_keyword("AUTO_INCREMENT");
26769 self.write("=");
26770 self.generate_expression(&e.this)?;
26771 Ok(())
26772 }
26773
26774 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
26775 self.write_keyword("AUTO_REFRESH");
26777 self.write("=");
26778 self.generate_expression(&e.this)?;
26779 Ok(())
26780 }
26781
26782 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
26783 self.write_keyword("BACKUP");
26785 self.write_space();
26786 self.generate_expression(&e.this)?;
26787 Ok(())
26788 }
26789
26790 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
26791 self.write_keyword("BASE64_DECODE_BINARY");
26793 self.write("(");
26794 self.generate_expression(&e.this)?;
26795 if let Some(alphabet) = &e.alphabet {
26796 self.write(", ");
26797 self.generate_expression(alphabet)?;
26798 }
26799 self.write(")");
26800 Ok(())
26801 }
26802
26803 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
26804 self.write_keyword("BASE64_DECODE_STRING");
26806 self.write("(");
26807 self.generate_expression(&e.this)?;
26808 if let Some(alphabet) = &e.alphabet {
26809 self.write(", ");
26810 self.generate_expression(alphabet)?;
26811 }
26812 self.write(")");
26813 Ok(())
26814 }
26815
26816 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
26817 self.write_keyword("BASE64_ENCODE");
26819 self.write("(");
26820 self.generate_expression(&e.this)?;
26821 if let Some(max_line_length) = &e.max_line_length {
26822 self.write(", ");
26823 self.generate_expression(max_line_length)?;
26824 }
26825 if let Some(alphabet) = &e.alphabet {
26826 self.write(", ");
26827 self.generate_expression(alphabet)?;
26828 }
26829 self.write(")");
26830 Ok(())
26831 }
26832
26833 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
26834 self.write_keyword("BLOCKCOMPRESSION");
26836 self.write("=");
26837 if let Some(autotemp) = &e.autotemp {
26838 self.write_keyword("AUTOTEMP");
26839 self.write("(");
26840 self.generate_expression(autotemp)?;
26841 self.write(")");
26842 }
26843 if let Some(always) = &e.always {
26844 self.generate_expression(always)?;
26845 }
26846 if let Some(default) = &e.default {
26847 self.generate_expression(default)?;
26848 }
26849 if let Some(manual) = &e.manual {
26850 self.generate_expression(manual)?;
26851 }
26852 if let Some(never) = &e.never {
26853 self.generate_expression(never)?;
26854 }
26855 Ok(())
26856 }
26857
26858 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
26859 self.write("((");
26861 self.generate_expression(&e.this)?;
26862 self.write(") ");
26863 self.write_keyword("AND");
26864 self.write(" (");
26865 self.generate_expression(&e.expression)?;
26866 self.write("))");
26867 Ok(())
26868 }
26869
26870 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
26871 self.write("((");
26873 self.generate_expression(&e.this)?;
26874 self.write(") ");
26875 self.write_keyword("OR");
26876 self.write(" (");
26877 self.generate_expression(&e.expression)?;
26878 self.write("))");
26879 Ok(())
26880 }
26881
26882 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
26883 self.write_keyword("BUILD");
26885 self.write_space();
26886 self.generate_expression(&e.this)?;
26887 Ok(())
26888 }
26889
26890 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
26891 self.generate_expression(&e.this)?;
26893 Ok(())
26894 }
26895
26896 fn generate_case_specific_column_constraint(
26897 &mut self,
26898 e: &CaseSpecificColumnConstraint,
26899 ) -> Result<()> {
26900 if e.not_.is_some() {
26902 self.write_keyword("NOT");
26903 self.write_space();
26904 }
26905 self.write_keyword("CASESPECIFIC");
26906 Ok(())
26907 }
26908
26909 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
26910 self.write_keyword("CAST");
26912 self.write("(");
26913 self.generate_expression(&e.this)?;
26914 if self.config.dialect == Some(DialectType::ClickHouse) {
26915 self.write(", ");
26917 } else {
26918 self.write_space();
26919 self.write_keyword("AS");
26920 self.write_space();
26921 }
26922 if let Some(to) = &e.to {
26923 self.generate_expression(to)?;
26924 }
26925 self.write(")");
26926 Ok(())
26927 }
26928
26929 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
26930 self.write_keyword("CHANGES");
26933 self.write(" (");
26934 if let Some(information) = &e.information {
26935 self.write_keyword("INFORMATION");
26936 self.write(" => ");
26937 self.generate_expression(information)?;
26938 }
26939 self.write(")");
26940 if let Some(at_before) = &e.at_before {
26942 self.write(" ");
26943 self.generate_expression(at_before)?;
26944 }
26945 if let Some(end) = &e.end {
26946 self.write(" ");
26947 self.generate_expression(end)?;
26948 }
26949 Ok(())
26950 }
26951
26952 fn generate_character_set_column_constraint(
26953 &mut self,
26954 e: &CharacterSetColumnConstraint,
26955 ) -> Result<()> {
26956 self.write_keyword("CHARACTER SET");
26958 self.write_space();
26959 self.generate_expression(&e.this)?;
26960 Ok(())
26961 }
26962
26963 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
26964 if e.default.is_some() {
26966 self.write_keyword("DEFAULT");
26967 self.write_space();
26968 }
26969 self.write_keyword("CHARACTER SET");
26970 self.write("=");
26971 self.generate_expression(&e.this)?;
26972 Ok(())
26973 }
26974
26975 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
26976 self.write_keyword("CHECK");
26978 self.write(" (");
26979 self.generate_expression(&e.this)?;
26980 self.write(")");
26981 if e.enforced.is_some() {
26982 self.write_space();
26983 self.write_keyword("ENFORCED");
26984 }
26985 Ok(())
26986 }
26987
26988 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
26989 self.write_keyword("ASSUME");
26991 self.write(" (");
26992 self.generate_expression(&e.this)?;
26993 self.write(")");
26994 Ok(())
26995 }
26996
26997 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
26998 self.write_keyword("CHECK_JSON");
27000 self.write("(");
27001 self.generate_expression(&e.this)?;
27002 self.write(")");
27003 Ok(())
27004 }
27005
27006 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
27007 self.write_keyword("CHECK_XML");
27009 self.write("(");
27010 self.generate_expression(&e.this)?;
27011 self.write(")");
27012 Ok(())
27013 }
27014
27015 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
27016 self.write_keyword("CHECKSUM");
27018 self.write("=");
27019 if e.on.is_some() {
27020 self.write_keyword("ON");
27021 } else if e.default.is_some() {
27022 self.write_keyword("DEFAULT");
27023 } else {
27024 self.write_keyword("OFF");
27025 }
27026 Ok(())
27027 }
27028
27029 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
27030 if e.shallow.is_some() {
27032 self.write_keyword("SHALLOW");
27033 self.write_space();
27034 }
27035 if e.copy.is_some() {
27036 self.write_keyword("COPY");
27037 } else {
27038 self.write_keyword("CLONE");
27039 }
27040 self.write_space();
27041 self.generate_expression(&e.this)?;
27042 Ok(())
27043 }
27044
27045 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
27046 self.write_keyword("CLUSTER BY");
27048 self.write(" (");
27049 for (i, ord) in e.expressions.iter().enumerate() {
27050 if i > 0 {
27051 self.write(", ");
27052 }
27053 self.generate_ordered(ord)?;
27054 }
27055 self.write(")");
27056 Ok(())
27057 }
27058
27059 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
27060 self.write_keyword("CLUSTER BY");
27062 self.write_space();
27063 for (i, col) in e.columns.iter().enumerate() {
27064 if i > 0 {
27065 self.write(", ");
27066 }
27067 self.generate_identifier(col)?;
27068 }
27069 Ok(())
27070 }
27071
27072 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
27073 self.write_keyword("CLUSTERED BY");
27075 self.write(" (");
27076 for (i, expr) in e.expressions.iter().enumerate() {
27077 if i > 0 {
27078 self.write(", ");
27079 }
27080 self.generate_expression(expr)?;
27081 }
27082 self.write(")");
27083 if let Some(sorted_by) = &e.sorted_by {
27084 self.write_space();
27085 self.write_keyword("SORTED BY");
27086 self.write(" (");
27087 if let Expression::Tuple(t) = sorted_by.as_ref() {
27089 for (i, expr) in t.expressions.iter().enumerate() {
27090 if i > 0 {
27091 self.write(", ");
27092 }
27093 self.generate_expression(expr)?;
27094 }
27095 } else {
27096 self.generate_expression(sorted_by)?;
27097 }
27098 self.write(")");
27099 }
27100 if let Some(buckets) = &e.buckets {
27101 self.write_space();
27102 self.write_keyword("INTO");
27103 self.write_space();
27104 self.generate_expression(buckets)?;
27105 self.write_space();
27106 self.write_keyword("BUCKETS");
27107 }
27108 Ok(())
27109 }
27110
27111 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
27112 if e.default.is_some() {
27116 self.write_keyword("DEFAULT");
27117 self.write_space();
27118 }
27119 self.write_keyword("COLLATE");
27120 match self.config.dialect {
27122 Some(DialectType::BigQuery) => self.write_space(),
27123 _ => self.write("="),
27124 }
27125 self.generate_expression(&e.this)?;
27126 Ok(())
27127 }
27128
27129 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
27130 match e {
27132 ColumnConstraint::NotNull => {
27133 self.write_keyword("NOT NULL");
27134 }
27135 ColumnConstraint::Null => {
27136 self.write_keyword("NULL");
27137 }
27138 ColumnConstraint::Unique => {
27139 self.write_keyword("UNIQUE");
27140 }
27141 ColumnConstraint::PrimaryKey => {
27142 self.write_keyword("PRIMARY KEY");
27143 }
27144 ColumnConstraint::Default(expr) => {
27145 self.write_keyword("DEFAULT");
27146 self.write_space();
27147 self.generate_expression(expr)?;
27148 }
27149 ColumnConstraint::Check(expr) => {
27150 self.write_keyword("CHECK");
27151 self.write(" (");
27152 self.generate_expression(expr)?;
27153 self.write(")");
27154 }
27155 ColumnConstraint::References(fk_ref) => {
27156 if fk_ref.has_foreign_key_keywords {
27157 self.write_keyword("FOREIGN KEY");
27158 self.write_space();
27159 }
27160 self.write_keyword("REFERENCES");
27161 self.write_space();
27162 self.generate_table(&fk_ref.table)?;
27163 if !fk_ref.columns.is_empty() {
27164 self.write(" (");
27165 for (i, col) in fk_ref.columns.iter().enumerate() {
27166 if i > 0 {
27167 self.write(", ");
27168 }
27169 self.generate_identifier(col)?;
27170 }
27171 self.write(")");
27172 }
27173 }
27174 ColumnConstraint::GeneratedAsIdentity(gen) => {
27175 self.write_keyword("GENERATED");
27176 self.write_space();
27177 if gen.always {
27178 self.write_keyword("ALWAYS");
27179 } else {
27180 self.write_keyword("BY DEFAULT");
27181 if gen.on_null {
27182 self.write_space();
27183 self.write_keyword("ON NULL");
27184 }
27185 }
27186 self.write_space();
27187 self.write_keyword("AS IDENTITY");
27188 }
27189 ColumnConstraint::Collate(collation) => {
27190 self.write_keyword("COLLATE");
27191 self.write_space();
27192 self.generate_identifier(collation)?;
27193 }
27194 ColumnConstraint::Comment(comment) => {
27195 self.write_keyword("COMMENT");
27196 self.write(" '");
27197 self.write(comment);
27198 self.write("'");
27199 }
27200 ColumnConstraint::ComputedColumn(cc) => {
27201 self.generate_computed_column_inline(cc)?;
27202 }
27203 ColumnConstraint::GeneratedAsRow(gar) => {
27204 self.generate_generated_as_row_inline(gar)?;
27205 }
27206 ColumnConstraint::Tags(tags) => {
27207 self.write_keyword("TAG");
27208 self.write(" (");
27209 for (i, expr) in tags.expressions.iter().enumerate() {
27210 if i > 0 {
27211 self.write(", ");
27212 }
27213 self.generate_expression(expr)?;
27214 }
27215 self.write(")");
27216 }
27217 ColumnConstraint::Path(path_expr) => {
27218 self.write_keyword("PATH");
27219 self.write_space();
27220 self.generate_expression(path_expr)?;
27221 }
27222 }
27223 Ok(())
27224 }
27225
27226 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
27227 match e {
27229 ColumnPosition::First => {
27230 self.write_keyword("FIRST");
27231 }
27232 ColumnPosition::After(ident) => {
27233 self.write_keyword("AFTER");
27234 self.write_space();
27235 self.generate_identifier(ident)?;
27236 }
27237 }
27238 Ok(())
27239 }
27240
27241 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
27242 self.generate_expression(&e.this)?;
27244 self.write("(");
27245 self.generate_expression(&e.expression)?;
27246 self.write(")");
27247 Ok(())
27248 }
27249
27250 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
27251 if let Some(ref unpack) = e.unpack {
27254 if let Expression::Boolean(b) = unpack.as_ref() {
27255 if b.value {
27256 self.write("*");
27257 }
27258 }
27259 }
27260 self.write_keyword("COLUMNS");
27261 self.write("(");
27262 self.generate_expression(&e.this)?;
27263 self.write(")");
27264 Ok(())
27265 }
27266
27267 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
27268 self.generate_expression(&e.this)?;
27270 self.write("(");
27271 for (i, expr) in e.expressions.iter().enumerate() {
27272 if i > 0 {
27273 self.write(", ");
27274 }
27275 self.generate_expression(expr)?;
27276 }
27277 self.write(")");
27278 Ok(())
27279 }
27280
27281 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
27282 self.generate_expression(&e.this)?;
27284 self.write("(");
27285 for (i, param) in e.params.iter().enumerate() {
27286 if i > 0 {
27287 self.write(", ");
27288 }
27289 self.generate_expression(param)?;
27290 }
27291 self.write(")(");
27292 for (i, expr) in e.expressions.iter().enumerate() {
27293 if i > 0 {
27294 self.write(", ");
27295 }
27296 self.generate_expression(expr)?;
27297 }
27298 self.write(")");
27299 Ok(())
27300 }
27301
27302 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
27303 self.write_keyword("COMMIT");
27305
27306 if e.this.is_none()
27308 && matches!(
27309 self.config.dialect,
27310 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27311 )
27312 {
27313 self.write_space();
27314 self.write_keyword("TRANSACTION");
27315 }
27316
27317 if let Some(this) = &e.this {
27319 let is_transaction_marker = matches!(
27321 this.as_ref(),
27322 Expression::Identifier(id) if id.name == "TRANSACTION"
27323 );
27324
27325 self.write_space();
27326 self.write_keyword("TRANSACTION");
27327
27328 if !is_transaction_marker {
27330 self.write_space();
27331 self.generate_expression(this)?;
27332 }
27333 }
27334
27335 if let Some(durability) = &e.durability {
27337 self.write_space();
27338 self.write_keyword("WITH");
27339 self.write(" (");
27340 self.write_keyword("DELAYED_DURABILITY");
27341 self.write(" = ");
27342 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
27343 self.write_keyword("ON");
27344 } else {
27345 self.write_keyword("OFF");
27346 }
27347 self.write(")");
27348 }
27349
27350 if let Some(chain) = &e.chain {
27352 self.write_space();
27353 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
27354 self.write_keyword("AND NO CHAIN");
27355 } else {
27356 self.write_keyword("AND CHAIN");
27357 }
27358 }
27359 Ok(())
27360 }
27361
27362 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
27363 self.write("[");
27365 self.generate_expression(&e.this)?;
27366 self.write_space();
27367 self.write_keyword("FOR");
27368 self.write_space();
27369 self.generate_expression(&e.expression)?;
27370 if let Some(pos) = &e.position {
27372 self.write(", ");
27373 self.generate_expression(pos)?;
27374 }
27375 if let Some(iterator) = &e.iterator {
27376 self.write_space();
27377 self.write_keyword("IN");
27378 self.write_space();
27379 self.generate_expression(iterator)?;
27380 }
27381 if let Some(condition) = &e.condition {
27382 self.write_space();
27383 self.write_keyword("IF");
27384 self.write_space();
27385 self.generate_expression(condition)?;
27386 }
27387 self.write("]");
27388 Ok(())
27389 }
27390
27391 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
27392 self.write_keyword("COMPRESS");
27394 self.write("(");
27395 self.generate_expression(&e.this)?;
27396 if let Some(method) = &e.method {
27397 self.write(", '");
27398 self.write(method);
27399 self.write("'");
27400 }
27401 self.write(")");
27402 Ok(())
27403 }
27404
27405 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
27406 self.write_keyword("COMPRESS");
27408 if let Some(this) = &e.this {
27409 self.write_space();
27410 self.generate_expression(this)?;
27411 }
27412 Ok(())
27413 }
27414
27415 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
27416 self.write_keyword("AS");
27418 self.write_space();
27419 self.generate_expression(&e.this)?;
27420 if e.not_null.is_some() {
27421 self.write_space();
27422 self.write_keyword("PERSISTED NOT NULL");
27423 } else if e.persisted.is_some() {
27424 self.write_space();
27425 self.write_keyword("PERSISTED");
27426 }
27427 Ok(())
27428 }
27429
27430 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
27434 let computed_expr = if matches!(
27435 self.config.dialect,
27436 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27437 ) {
27438 match &*cc.expression {
27439 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27440 {
27441 let wrapped = Expression::Cast(Box::new(Cast {
27442 this: y.this.clone(),
27443 to: DataType::Date,
27444 trailing_comments: Vec::new(),
27445 double_colon_syntax: false,
27446 format: None,
27447 default: None,
27448 inferred_type: None,
27449 }));
27450 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
27451 }
27452 Expression::Function(f)
27453 if f.name.eq_ignore_ascii_case("YEAR")
27454 && f.args.len() == 1
27455 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
27456 {
27457 let wrapped = Expression::Cast(Box::new(Cast {
27458 this: f.args[0].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::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
27467 }
27468 _ => *cc.expression.clone(),
27469 }
27470 } else {
27471 *cc.expression.clone()
27472 };
27473
27474 match cc.persistence_kind.as_deref() {
27475 Some("STORED") | Some("VIRTUAL") => {
27476 self.write_keyword("GENERATED ALWAYS AS");
27478 self.write(" (");
27479 self.generate_expression(&computed_expr)?;
27480 self.write(")");
27481 self.write_space();
27482 if cc.persisted {
27483 self.write_keyword("STORED");
27484 } else {
27485 self.write_keyword("VIRTUAL");
27486 }
27487 }
27488 Some("PERSISTED") => {
27489 self.write_keyword("AS");
27491 self.write(" (");
27492 self.generate_expression(&computed_expr)?;
27493 self.write(")");
27494 self.write_space();
27495 self.write_keyword("PERSISTED");
27496 if let Some(ref dt) = cc.data_type {
27498 self.write_space();
27499 self.generate_data_type(dt)?;
27500 }
27501 if cc.not_null {
27502 self.write_space();
27503 self.write_keyword("NOT NULL");
27504 }
27505 }
27506 _ => {
27507 if matches!(
27510 self.config.dialect,
27511 Some(DialectType::Spark)
27512 | Some(DialectType::Databricks)
27513 | Some(DialectType::Hive)
27514 ) {
27515 self.write_keyword("GENERATED ALWAYS AS");
27516 self.write(" (");
27517 self.generate_expression(&computed_expr)?;
27518 self.write(")");
27519 } else if matches!(
27520 self.config.dialect,
27521 Some(DialectType::TSQL) | Some(DialectType::Fabric)
27522 ) {
27523 self.write_keyword("AS");
27524 let omit_parens = matches!(computed_expr, Expression::Year(_))
27525 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
27526 if omit_parens {
27527 self.write_space();
27528 self.generate_expression(&computed_expr)?;
27529 } else {
27530 self.write(" (");
27531 self.generate_expression(&computed_expr)?;
27532 self.write(")");
27533 }
27534 } else {
27535 self.write_keyword("AS");
27536 self.write(" (");
27537 self.generate_expression(&computed_expr)?;
27538 self.write(")");
27539 }
27540 }
27541 }
27542 Ok(())
27543 }
27544
27545 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
27548 self.write_keyword("GENERATED ALWAYS AS ROW ");
27549 if gar.start {
27550 self.write_keyword("START");
27551 } else {
27552 self.write_keyword("END");
27553 }
27554 if gar.hidden {
27555 self.write_space();
27556 self.write_keyword("HIDDEN");
27557 }
27558 Ok(())
27559 }
27560
27561 fn generate_system_versioning_content(
27563 &mut self,
27564 e: &WithSystemVersioningProperty,
27565 ) -> Result<()> {
27566 let mut parts = Vec::new();
27567
27568 if let Some(this) = &e.this {
27569 let mut s = String::from("HISTORY_TABLE=");
27570 let mut gen = Generator::with_arc_config(self.config.clone());
27571 gen.generate_expression(this)?;
27572 s.push_str(&gen.output);
27573 parts.push(s);
27574 }
27575
27576 if let Some(data_consistency) = &e.data_consistency {
27577 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
27578 let mut gen = Generator::with_arc_config(self.config.clone());
27579 gen.generate_expression(data_consistency)?;
27580 s.push_str(&gen.output);
27581 parts.push(s);
27582 }
27583
27584 if let Some(retention_period) = &e.retention_period {
27585 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
27586 let mut gen = Generator::with_arc_config(self.config.clone());
27587 gen.generate_expression(retention_period)?;
27588 s.push_str(&gen.output);
27589 parts.push(s);
27590 }
27591
27592 self.write_keyword("SYSTEM_VERSIONING");
27593 self.write("=");
27594
27595 if !parts.is_empty() {
27596 self.write_keyword("ON");
27597 self.write("(");
27598 self.write(&parts.join(", "));
27599 self.write(")");
27600 } else if e.on.is_some() {
27601 self.write_keyword("ON");
27602 } else {
27603 self.write_keyword("OFF");
27604 }
27605
27606 Ok(())
27607 }
27608
27609 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
27610 if e.else_.is_some() {
27613 self.write_keyword("ELSE");
27614 self.write_space();
27615 } else if let Some(expression) = &e.expression {
27616 self.write_keyword("WHEN");
27617 self.write_space();
27618 self.generate_expression(expression)?;
27619 self.write_space();
27620 self.write_keyword("THEN");
27621 self.write_space();
27622 }
27623
27624 if let Expression::Insert(insert) = e.this.as_ref() {
27627 self.write_keyword("INTO");
27628 self.write_space();
27629 self.generate_table(&insert.table)?;
27630
27631 if !insert.columns.is_empty() {
27633 self.write(" (");
27634 for (i, col) in insert.columns.iter().enumerate() {
27635 if i > 0 {
27636 self.write(", ");
27637 }
27638 self.generate_identifier(col)?;
27639 }
27640 self.write(")");
27641 }
27642
27643 if !insert.values.is_empty() {
27645 self.write_space();
27646 self.write_keyword("VALUES");
27647 for (row_idx, row) in insert.values.iter().enumerate() {
27648 if row_idx > 0 {
27649 self.write(", ");
27650 }
27651 self.write(" (");
27652 for (i, val) in row.iter().enumerate() {
27653 if i > 0 {
27654 self.write(", ");
27655 }
27656 self.generate_expression(val)?;
27657 }
27658 self.write(")");
27659 }
27660 }
27661 } else {
27662 self.generate_expression(&e.this)?;
27664 }
27665 Ok(())
27666 }
27667
27668 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
27669 self.write_keyword("CONSTRAINT");
27671 self.write_space();
27672 self.generate_expression(&e.this)?;
27673 if !e.expressions.is_empty() {
27674 self.write_space();
27675 for (i, expr) in e.expressions.iter().enumerate() {
27676 if i > 0 {
27677 self.write_space();
27678 }
27679 self.generate_expression(expr)?;
27680 }
27681 }
27682 Ok(())
27683 }
27684
27685 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
27686 self.write_keyword("CONVERT_TIMEZONE");
27688 self.write("(");
27689 let mut first = true;
27690 if let Some(source_tz) = &e.source_tz {
27691 self.generate_expression(source_tz)?;
27692 first = false;
27693 }
27694 if let Some(target_tz) = &e.target_tz {
27695 if !first {
27696 self.write(", ");
27697 }
27698 self.generate_expression(target_tz)?;
27699 first = false;
27700 }
27701 if let Some(timestamp) = &e.timestamp {
27702 if !first {
27703 self.write(", ");
27704 }
27705 self.generate_expression(timestamp)?;
27706 }
27707 self.write(")");
27708 Ok(())
27709 }
27710
27711 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
27712 self.write_keyword("CONVERT");
27714 self.write("(");
27715 self.generate_expression(&e.this)?;
27716 if let Some(dest) = &e.dest {
27717 self.write_space();
27718 self.write_keyword("USING");
27719 self.write_space();
27720 self.generate_expression(dest)?;
27721 }
27722 self.write(")");
27723 Ok(())
27724 }
27725
27726 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
27727 self.write_keyword("COPY");
27728 if e.is_into {
27729 self.write_space();
27730 self.write_keyword("INTO");
27731 }
27732 self.write_space();
27733
27734 if let Expression::Literal(lit) = &e.this {
27736 if let Literal::String(s) = lit.as_ref() {
27737 if s.starts_with('@') {
27738 self.write(s);
27739 } else {
27740 self.generate_expression(&e.this)?;
27741 }
27742 }
27743 } else {
27744 self.generate_expression(&e.this)?;
27745 }
27746
27747 if e.kind {
27749 if self.config.pretty {
27751 self.write_newline();
27752 } else {
27753 self.write_space();
27754 }
27755 self.write_keyword("FROM");
27756 self.write_space();
27757 } else if !e.files.is_empty() {
27758 if self.config.pretty {
27760 self.write_newline();
27761 } else {
27762 self.write_space();
27763 }
27764 self.write_keyword("TO");
27765 self.write_space();
27766 }
27767
27768 for (i, file) in e.files.iter().enumerate() {
27770 if i > 0 {
27771 self.write_space();
27772 }
27773 if let Expression::Literal(lit) = file {
27775 if let Literal::String(s) = lit.as_ref() {
27776 if s.starts_with('@') {
27777 self.write(s);
27778 } else {
27779 self.generate_expression(file)?;
27780 }
27781 }
27782 } else if let Expression::Identifier(id) = file {
27783 if id.quoted {
27785 self.write("`");
27786 self.write(&id.name);
27787 self.write("`");
27788 } else {
27789 self.generate_expression(file)?;
27790 }
27791 } else {
27792 self.generate_expression(file)?;
27793 }
27794 }
27795
27796 if !e.with_wrapped {
27798 if let Some(ref creds) = e.credentials {
27799 if let Some(ref storage) = creds.storage {
27800 if self.config.pretty {
27801 self.write_newline();
27802 } else {
27803 self.write_space();
27804 }
27805 self.write_keyword("STORAGE_INTEGRATION");
27806 self.write(" = ");
27807 self.write(storage);
27808 }
27809 if creds.credentials.is_empty() {
27810 if self.config.pretty {
27812 self.write_newline();
27813 } else {
27814 self.write_space();
27815 }
27816 self.write_keyword("CREDENTIALS");
27817 self.write(" = ()");
27818 } else {
27819 if self.config.pretty {
27820 self.write_newline();
27821 } else {
27822 self.write_space();
27823 }
27824 self.write_keyword("CREDENTIALS");
27825 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
27828 self.write(" '");
27830 self.write(&creds.credentials[0].1);
27831 self.write("'");
27832 } else {
27833 self.write(" = (");
27835 for (i, (k, v)) in creds.credentials.iter().enumerate() {
27836 if i > 0 {
27837 self.write_space();
27838 }
27839 self.write(k);
27840 self.write("='");
27841 self.write(v);
27842 self.write("'");
27843 }
27844 self.write(")");
27845 }
27846 }
27847 if let Some(ref encryption) = creds.encryption {
27848 self.write_space();
27849 self.write_keyword("ENCRYPTION");
27850 self.write(" = ");
27851 self.write(encryption);
27852 }
27853 }
27854 }
27855
27856 if !e.params.is_empty() {
27858 if e.with_wrapped {
27859 self.write_space();
27861 self.write_keyword("WITH");
27862 self.write(" (");
27863 for (i, param) in e.params.iter().enumerate() {
27864 if i > 0 {
27865 self.write(", ");
27866 }
27867 self.generate_copy_param_with_format(param)?;
27868 }
27869 self.write(")");
27870 } else {
27871 for param in &e.params {
27875 if self.config.pretty {
27876 self.write_newline();
27877 } else {
27878 self.write_space();
27879 }
27880 self.write(¶m.name);
27882 if let Some(ref value) = param.value {
27883 if param.eq {
27885 self.write(" = ");
27886 } else {
27887 self.write(" ");
27888 }
27889 if !param.values.is_empty() {
27890 self.write("(");
27891 for (i, v) in param.values.iter().enumerate() {
27892 if i > 0 {
27893 self.write_space();
27894 }
27895 self.generate_copy_nested_param(v)?;
27896 }
27897 self.write(")");
27898 } else {
27899 self.generate_copy_param_value(value)?;
27901 }
27902 } else if !param.values.is_empty() {
27903 if param.eq {
27905 self.write(" = (");
27906 } else {
27907 self.write(" (");
27908 }
27909 let is_key_value_pairs = param
27914 .values
27915 .first()
27916 .map_or(false, |v| matches!(v, Expression::Eq(_)));
27917 let sep = if is_key_value_pairs && param.eq {
27918 " "
27919 } else {
27920 ", "
27921 };
27922 for (i, v) in param.values.iter().enumerate() {
27923 if i > 0 {
27924 self.write(sep);
27925 }
27926 self.generate_copy_nested_param(v)?;
27927 }
27928 self.write(")");
27929 }
27930 }
27931 }
27932 }
27933
27934 Ok(())
27935 }
27936
27937 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
27940 self.write_keyword(¶m.name);
27941 if !param.values.is_empty() {
27942 self.write(" = (");
27944 for (i, v) in param.values.iter().enumerate() {
27945 if i > 0 {
27946 self.write(", ");
27947 }
27948 self.generate_copy_nested_param(v)?;
27949 }
27950 self.write(")");
27951 } else if let Some(ref value) = param.value {
27952 if param.eq {
27953 self.write(" = ");
27954 } else {
27955 self.write(" ");
27956 }
27957 self.generate_expression(value)?;
27958 }
27959 Ok(())
27960 }
27961
27962 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
27964 match expr {
27965 Expression::Eq(eq) => {
27966 match &eq.left {
27968 Expression::Column(c) => self.write(&c.name.name),
27969 _ => self.generate_expression(&eq.left)?,
27970 }
27971 self.write("=");
27972 match &eq.right {
27974 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27975 let Literal::String(s) = lit.as_ref() else {
27976 unreachable!()
27977 };
27978 self.write("'");
27979 self.write(s);
27980 self.write("'");
27981 }
27982 Expression::Tuple(t) => {
27983 self.write("(");
27985 if self.config.pretty {
27986 self.write_newline();
27987 self.indent_level += 1;
27988 for (i, item) in t.expressions.iter().enumerate() {
27989 if i > 0 {
27990 self.write(", ");
27991 }
27992 self.write_indent();
27993 self.generate_expression(item)?;
27994 }
27995 self.write_newline();
27996 self.indent_level -= 1;
27997 } else {
27998 for (i, item) in t.expressions.iter().enumerate() {
27999 if i > 0 {
28000 self.write(", ");
28001 }
28002 self.generate_expression(item)?;
28003 }
28004 }
28005 self.write(")");
28006 }
28007 _ => self.generate_expression(&eq.right)?,
28008 }
28009 Ok(())
28010 }
28011 Expression::Column(c) => {
28012 self.write(&c.name.name);
28014 Ok(())
28015 }
28016 _ => self.generate_expression(expr),
28017 }
28018 }
28019
28020 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
28023 match expr {
28024 Expression::Column(c) => {
28025 if c.name.quoted {
28027 self.write("\"");
28028 self.write(&c.name.name);
28029 self.write("\"");
28030 } else {
28031 self.write(&c.name.name);
28032 }
28033 Ok(())
28034 }
28035 Expression::Identifier(id) => {
28036 if id.quoted {
28038 self.write("\"");
28039 self.write(&id.name);
28040 self.write("\"");
28041 } else {
28042 self.write(&id.name);
28043 }
28044 Ok(())
28045 }
28046 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28047 let Literal::String(s) = lit.as_ref() else {
28048 unreachable!()
28049 };
28050 self.write("'");
28052 self.write(s);
28053 self.write("'");
28054 Ok(())
28055 }
28056 _ => self.generate_expression(expr),
28057 }
28058 }
28059
28060 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
28061 self.write_keyword(&e.name);
28062 if let Some(ref value) = e.value {
28063 if e.eq {
28064 self.write(" = ");
28065 } else {
28066 self.write(" ");
28067 }
28068 self.generate_expression(value)?;
28069 }
28070 if !e.values.is_empty() {
28071 if e.eq {
28072 self.write(" = ");
28073 } else {
28074 self.write(" ");
28075 }
28076 self.write("(");
28077 for (i, v) in e.values.iter().enumerate() {
28078 if i > 0 {
28079 self.write(", ");
28080 }
28081 self.generate_expression(v)?;
28082 }
28083 self.write(")");
28084 }
28085 Ok(())
28086 }
28087
28088 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
28089 self.write_keyword("CORR");
28091 self.write("(");
28092 self.generate_expression(&e.this)?;
28093 self.write(", ");
28094 self.generate_expression(&e.expression)?;
28095 self.write(")");
28096 Ok(())
28097 }
28098
28099 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
28100 self.write_keyword("COSINE_DISTANCE");
28102 self.write("(");
28103 self.generate_expression(&e.this)?;
28104 self.write(", ");
28105 self.generate_expression(&e.expression)?;
28106 self.write(")");
28107 Ok(())
28108 }
28109
28110 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
28111 self.write_keyword("COVAR_POP");
28113 self.write("(");
28114 self.generate_expression(&e.this)?;
28115 self.write(", ");
28116 self.generate_expression(&e.expression)?;
28117 self.write(")");
28118 Ok(())
28119 }
28120
28121 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
28122 self.write_keyword("COVAR_SAMP");
28124 self.write("(");
28125 self.generate_expression(&e.this)?;
28126 self.write(", ");
28127 self.generate_expression(&e.expression)?;
28128 self.write(")");
28129 Ok(())
28130 }
28131
28132 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
28133 self.write_keyword("CREDENTIALS");
28135 self.write(" (");
28136 for (i, (key, value)) in e.credentials.iter().enumerate() {
28137 if i > 0 {
28138 self.write(", ");
28139 }
28140 self.write(key);
28141 self.write("='");
28142 self.write(value);
28143 self.write("'");
28144 }
28145 self.write(")");
28146 Ok(())
28147 }
28148
28149 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
28150 self.write_keyword("CREDENTIALS");
28152 self.write("=(");
28153 for (i, expr) in e.expressions.iter().enumerate() {
28154 if i > 0 {
28155 self.write(", ");
28156 }
28157 self.generate_expression(expr)?;
28158 }
28159 self.write(")");
28160 Ok(())
28161 }
28162
28163 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
28164 use crate::dialects::DialectType;
28165
28166 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
28169 self.generate_expression(&e.this)?;
28170 self.write_space();
28171 self.write_keyword("AS");
28172 self.write_space();
28173 self.generate_identifier(&e.alias)?;
28174 return Ok(());
28175 }
28176 self.write(&e.alias.name);
28177
28178 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
28180
28181 if !e.columns.is_empty() && !skip_cte_columns {
28182 self.write("(");
28183 for (i, col) in e.columns.iter().enumerate() {
28184 if i > 0 {
28185 self.write(", ");
28186 }
28187 self.write(&col.name);
28188 }
28189 self.write(")");
28190 }
28191 if !e.key_expressions.is_empty() {
28193 self.write_space();
28194 self.write_keyword("USING KEY");
28195 self.write(" (");
28196 for (i, key) in e.key_expressions.iter().enumerate() {
28197 if i > 0 {
28198 self.write(", ");
28199 }
28200 self.write(&key.name);
28201 }
28202 self.write(")");
28203 }
28204 self.write_space();
28205 self.write_keyword("AS");
28206 self.write_space();
28207 if let Some(materialized) = e.materialized {
28208 if materialized {
28209 self.write_keyword("MATERIALIZED");
28210 } else {
28211 self.write_keyword("NOT MATERIALIZED");
28212 }
28213 self.write_space();
28214 }
28215 self.write("(");
28216 self.generate_expression(&e.this)?;
28217 self.write(")");
28218 Ok(())
28219 }
28220
28221 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
28222 if e.expressions.is_empty() {
28224 self.write_keyword("WITH CUBE");
28225 } else {
28226 self.write_keyword("CUBE");
28227 self.write("(");
28228 for (i, expr) in e.expressions.iter().enumerate() {
28229 if i > 0 {
28230 self.write(", ");
28231 }
28232 self.generate_expression(expr)?;
28233 }
28234 self.write(")");
28235 }
28236 Ok(())
28237 }
28238
28239 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
28240 self.write_keyword("CURRENT_DATETIME");
28242 if let Some(this) = &e.this {
28243 self.write("(");
28244 self.generate_expression(this)?;
28245 self.write(")");
28246 }
28247 Ok(())
28248 }
28249
28250 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
28251 self.write_keyword("CURRENT_SCHEMA");
28253 Ok(())
28254 }
28255
28256 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
28257 self.write_keyword("CURRENT_SCHEMAS");
28259 self.write("(");
28260 if !matches!(
28262 self.config.dialect,
28263 Some(crate::dialects::DialectType::Snowflake)
28264 ) {
28265 if let Some(this) = &e.this {
28266 self.generate_expression(this)?;
28267 }
28268 }
28269 self.write(")");
28270 Ok(())
28271 }
28272
28273 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
28274 self.write_keyword("CURRENT_USER");
28276 let needs_parens = e.this.is_some()
28278 || matches!(
28279 self.config.dialect,
28280 Some(DialectType::Snowflake)
28281 | Some(DialectType::Spark)
28282 | Some(DialectType::Hive)
28283 | Some(DialectType::DuckDB)
28284 | Some(DialectType::BigQuery)
28285 | Some(DialectType::MySQL)
28286 | Some(DialectType::Databricks)
28287 );
28288 if needs_parens {
28289 self.write("()");
28290 }
28291 Ok(())
28292 }
28293
28294 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
28295 if self.config.dialect == Some(DialectType::Solr) {
28297 self.generate_expression(&e.this)?;
28298 self.write(" ");
28299 self.write_keyword("OR");
28300 self.write(" ");
28301 self.generate_expression(&e.expression)?;
28302 } else if self.config.dialect == Some(DialectType::MySQL) {
28303 self.generate_mysql_concat_from_dpipe(e)?;
28304 } else {
28305 self.generate_expression(&e.this)?;
28307 self.write(" || ");
28308 self.generate_expression(&e.expression)?;
28309 }
28310 Ok(())
28311 }
28312
28313 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
28314 self.write_keyword("DATABLOCKSIZE");
28316 self.write("=");
28317 if let Some(size) = e.size {
28318 self.write(&size.to_string());
28319 if let Some(units) = &e.units {
28320 self.write_space();
28321 self.generate_expression(units)?;
28322 }
28323 } else if e.minimum.is_some() {
28324 self.write_keyword("MINIMUM");
28325 } else if e.maximum.is_some() {
28326 self.write_keyword("MAXIMUM");
28327 } else if e.default.is_some() {
28328 self.write_keyword("DEFAULT");
28329 }
28330 Ok(())
28331 }
28332
28333 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
28334 self.write_keyword("DATA_DELETION");
28336 self.write("=");
28337
28338 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
28339 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
28340
28341 if is_on {
28342 self.write_keyword("ON");
28343 if has_options {
28344 self.write("(");
28345 let mut first = true;
28346 if let Some(filter_column) = &e.filter_column {
28347 self.write_keyword("FILTER_COLUMN");
28348 self.write("=");
28349 self.generate_expression(filter_column)?;
28350 first = false;
28351 }
28352 if let Some(retention_period) = &e.retention_period {
28353 if !first {
28354 self.write(", ");
28355 }
28356 self.write_keyword("RETENTION_PERIOD");
28357 self.write("=");
28358 self.generate_expression(retention_period)?;
28359 }
28360 self.write(")");
28361 }
28362 } else {
28363 self.write_keyword("OFF");
28364 }
28365 Ok(())
28366 }
28367
28368 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
28372 use crate::dialects::DialectType;
28373 use crate::expressions::Literal;
28374
28375 match self.config.dialect {
28376 Some(DialectType::Exasol) => {
28378 self.write_keyword("TO_DATE");
28379 self.write("(");
28380 match &e.this {
28382 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
28383 let Literal::String(s) = lit.as_ref() else {
28384 unreachable!()
28385 };
28386 self.write("'");
28387 self.write(s);
28388 self.write("'");
28389 }
28390 _ => {
28391 self.generate_expression(&e.this)?;
28392 }
28393 }
28394 self.write(")");
28395 }
28396 _ => {
28398 self.write_keyword("DATE");
28399 self.write("(");
28400 self.generate_expression(&e.this)?;
28401 self.write(")");
28402 }
28403 }
28404 Ok(())
28405 }
28406
28407 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
28408 self.write_keyword("DATE_BIN");
28410 self.write("(");
28411 self.generate_expression(&e.this)?;
28412 self.write(", ");
28413 self.generate_expression(&e.expression)?;
28414 if let Some(origin) = &e.origin {
28415 self.write(", ");
28416 self.generate_expression(origin)?;
28417 }
28418 self.write(")");
28419 Ok(())
28420 }
28421
28422 fn generate_date_format_column_constraint(
28423 &mut self,
28424 e: &DateFormatColumnConstraint,
28425 ) -> Result<()> {
28426 self.write_keyword("FORMAT");
28428 self.write_space();
28429 self.generate_expression(&e.this)?;
28430 Ok(())
28431 }
28432
28433 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
28434 self.write_keyword("DATE_FROM_PARTS");
28436 self.write("(");
28437 let mut first = true;
28438 if let Some(year) = &e.year {
28439 self.generate_expression(year)?;
28440 first = false;
28441 }
28442 if let Some(month) = &e.month {
28443 if !first {
28444 self.write(", ");
28445 }
28446 self.generate_expression(month)?;
28447 first = false;
28448 }
28449 if let Some(day) = &e.day {
28450 if !first {
28451 self.write(", ");
28452 }
28453 self.generate_expression(day)?;
28454 }
28455 self.write(")");
28456 Ok(())
28457 }
28458
28459 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
28460 self.write_keyword("DATETIME");
28462 self.write("(");
28463 self.generate_expression(&e.this)?;
28464 if let Some(expr) = &e.expression {
28465 self.write(", ");
28466 self.generate_expression(expr)?;
28467 }
28468 self.write(")");
28469 Ok(())
28470 }
28471
28472 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
28473 self.write_keyword("DATETIME_ADD");
28475 self.write("(");
28476 self.generate_expression(&e.this)?;
28477 self.write(", ");
28478 self.generate_expression(&e.expression)?;
28479 if let Some(unit) = &e.unit {
28480 self.write(", ");
28481 self.write_keyword(unit);
28482 }
28483 self.write(")");
28484 Ok(())
28485 }
28486
28487 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
28488 self.write_keyword("DATETIME_DIFF");
28490 self.write("(");
28491 self.generate_expression(&e.this)?;
28492 self.write(", ");
28493 self.generate_expression(&e.expression)?;
28494 if let Some(unit) = &e.unit {
28495 self.write(", ");
28496 self.write_keyword(unit);
28497 }
28498 self.write(")");
28499 Ok(())
28500 }
28501
28502 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
28503 self.write_keyword("DATETIME_SUB");
28505 self.write("(");
28506 self.generate_expression(&e.this)?;
28507 self.write(", ");
28508 self.generate_expression(&e.expression)?;
28509 if let Some(unit) = &e.unit {
28510 self.write(", ");
28511 self.write_keyword(unit);
28512 }
28513 self.write(")");
28514 Ok(())
28515 }
28516
28517 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
28518 self.write_keyword("DATETIME_TRUNC");
28520 self.write("(");
28521 self.generate_expression(&e.this)?;
28522 self.write(", ");
28523 self.write_keyword(&e.unit);
28524 if let Some(zone) = &e.zone {
28525 self.write(", ");
28526 self.generate_expression(zone)?;
28527 }
28528 self.write(")");
28529 Ok(())
28530 }
28531
28532 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
28533 self.write_keyword("DAYNAME");
28535 self.write("(");
28536 self.generate_expression(&e.this)?;
28537 self.write(")");
28538 Ok(())
28539 }
28540
28541 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
28542 self.write_keyword("DECLARE");
28544 self.write_space();
28545 if e.replace {
28546 self.write_keyword("OR");
28547 self.write_space();
28548 self.write_keyword("REPLACE");
28549 self.write_space();
28550 }
28551 for (i, expr) in e.expressions.iter().enumerate() {
28552 if i > 0 {
28553 self.write(", ");
28554 }
28555 self.generate_expression(expr)?;
28556 }
28557 Ok(())
28558 }
28559
28560 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
28561 use crate::dialects::DialectType;
28562
28563 self.generate_expression(&e.this)?;
28565 for name in &e.additional_names {
28567 self.write(", ");
28568 self.generate_expression(name)?;
28569 }
28570 if let Some(kind) = &e.kind {
28571 self.write_space();
28572 match self.config.dialect {
28576 Some(DialectType::BigQuery) => {
28577 self.write(kind);
28578 }
28579 Some(DialectType::TSQL) => {
28580 let is_complex_table = kind.starts_with("TABLE")
28584 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
28585 if is_complex_table {
28586 self.write(kind);
28587 } else if kind == "INT" {
28588 self.write("INTEGER");
28589 } else if kind.starts_with("TABLE") {
28590 let normalized = kind
28592 .replace(" INT ", " INTEGER ")
28593 .replace(" INT,", " INTEGER,")
28594 .replace(" INT)", " INTEGER)")
28595 .replace("(INT ", "(INTEGER ");
28596 self.write(&normalized);
28597 } else {
28598 self.write(kind);
28599 }
28600 }
28601 _ => {
28602 if e.has_as {
28603 self.write_keyword("AS");
28604 self.write_space();
28605 }
28606 self.write(kind);
28607 }
28608 }
28609 }
28610 if let Some(default) = &e.default {
28611 match self.config.dialect {
28613 Some(DialectType::BigQuery) => {
28614 self.write_space();
28615 self.write_keyword("DEFAULT");
28616 self.write_space();
28617 }
28618 _ => {
28619 self.write(" = ");
28620 }
28621 }
28622 self.generate_expression(default)?;
28623 }
28624 Ok(())
28625 }
28626
28627 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
28628 self.write_keyword("DECODE");
28630 self.write("(");
28631 for (i, expr) in e.expressions.iter().enumerate() {
28632 if i > 0 {
28633 self.write(", ");
28634 }
28635 self.generate_expression(expr)?;
28636 }
28637 self.write(")");
28638 Ok(())
28639 }
28640
28641 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
28642 self.write_keyword("DECOMPRESS");
28644 self.write("(");
28645 self.generate_expression(&e.this)?;
28646 self.write(", '");
28647 self.write(&e.method);
28648 self.write("')");
28649 Ok(())
28650 }
28651
28652 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
28653 self.write_keyword("DECOMPRESS");
28655 self.write("(");
28656 self.generate_expression(&e.this)?;
28657 self.write(", '");
28658 self.write(&e.method);
28659 self.write("')");
28660 Ok(())
28661 }
28662
28663 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
28664 self.write_keyword("DECRYPT");
28666 self.write("(");
28667 self.generate_expression(&e.this)?;
28668 if let Some(passphrase) = &e.passphrase {
28669 self.write(", ");
28670 self.generate_expression(passphrase)?;
28671 }
28672 if let Some(aad) = &e.aad {
28673 self.write(", ");
28674 self.generate_expression(aad)?;
28675 }
28676 if let Some(method) = &e.encryption_method {
28677 self.write(", ");
28678 self.generate_expression(method)?;
28679 }
28680 self.write(")");
28681 Ok(())
28682 }
28683
28684 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
28685 self.write_keyword("DECRYPT_RAW");
28687 self.write("(");
28688 self.generate_expression(&e.this)?;
28689 if let Some(key) = &e.key {
28690 self.write(", ");
28691 self.generate_expression(key)?;
28692 }
28693 if let Some(iv) = &e.iv {
28694 self.write(", ");
28695 self.generate_expression(iv)?;
28696 }
28697 if let Some(aad) = &e.aad {
28698 self.write(", ");
28699 self.generate_expression(aad)?;
28700 }
28701 if let Some(method) = &e.encryption_method {
28702 self.write(", ");
28703 self.generate_expression(method)?;
28704 }
28705 self.write(")");
28706 Ok(())
28707 }
28708
28709 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
28710 self.write_keyword("DEFINER");
28712 self.write(" = ");
28713 self.generate_expression(&e.this)?;
28714 Ok(())
28715 }
28716
28717 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
28718 self.write_keyword("DETACH");
28720 if e.exists {
28721 self.write_keyword(" DATABASE IF EXISTS");
28722 }
28723 self.write_space();
28724 self.generate_expression(&e.this)?;
28725 Ok(())
28726 }
28727
28728 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
28729 let property_name = match e.this.as_ref() {
28730 Expression::Identifier(id) => id.name.as_str(),
28731 Expression::Var(v) => v.this.as_str(),
28732 _ => "DICTIONARY",
28733 };
28734 self.write_keyword(property_name);
28735 self.write("(");
28736 self.write(&e.kind);
28737 if let Some(settings) = &e.settings {
28738 self.write("(");
28739 if let Expression::Tuple(t) = settings.as_ref() {
28740 if self.config.pretty && !t.expressions.is_empty() {
28741 self.write_newline();
28742 self.indent_level += 1;
28743 for (i, pair) in t.expressions.iter().enumerate() {
28744 if i > 0 {
28745 self.write(",");
28746 self.write_newline();
28747 }
28748 self.write_indent();
28749 if let Expression::Tuple(pair_tuple) = pair {
28750 if let Some(k) = pair_tuple.expressions.first() {
28751 self.generate_expression(k)?;
28752 }
28753 if let Some(v) = pair_tuple.expressions.get(1) {
28754 self.write(" ");
28755 self.generate_expression(v)?;
28756 }
28757 } else {
28758 self.generate_expression(pair)?;
28759 }
28760 }
28761 self.indent_level -= 1;
28762 self.write_newline();
28763 self.write_indent();
28764 } else {
28765 for (i, pair) in t.expressions.iter().enumerate() {
28766 if i > 0 {
28767 self.write(" ");
28769 }
28770 if let Expression::Tuple(pair_tuple) = pair {
28771 if let Some(k) = pair_tuple.expressions.first() {
28772 self.generate_expression(k)?;
28773 }
28774 if let Some(v) = pair_tuple.expressions.get(1) {
28775 self.write(" ");
28776 self.generate_expression(v)?;
28777 }
28778 } else {
28779 self.generate_expression(pair)?;
28780 }
28781 }
28782 }
28783 } else {
28784 self.generate_expression(settings)?;
28785 }
28786 self.write(")");
28787 } else {
28788 self.write("()");
28790 }
28791 self.write(")");
28792 Ok(())
28793 }
28794
28795 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
28796 let property_name = match e.this.as_ref() {
28797 Expression::Identifier(id) => id.name.as_str(),
28798 Expression::Var(v) => v.this.as_str(),
28799 _ => "RANGE",
28800 };
28801 self.write_keyword(property_name);
28802 self.write("(");
28803 if let Some(min) = &e.min {
28804 self.write_keyword("MIN");
28805 self.write_space();
28806 self.generate_expression(min)?;
28807 }
28808 if let Some(max) = &e.max {
28809 self.write_space();
28810 self.write_keyword("MAX");
28811 self.write_space();
28812 self.generate_expression(max)?;
28813 }
28814 self.write(")");
28815 Ok(())
28816 }
28817
28818 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
28819 if e.local.is_some() {
28821 self.write_keyword("LOCAL ");
28822 }
28823 self.write_keyword("DIRECTORY");
28824 self.write_space();
28825 self.generate_expression(&e.this)?;
28826 if let Some(row_format) = &e.row_format {
28827 self.write_space();
28828 self.generate_expression(row_format)?;
28829 }
28830 Ok(())
28831 }
28832
28833 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
28834 self.write_keyword("DISTKEY");
28836 self.write("(");
28837 self.generate_expression(&e.this)?;
28838 self.write(")");
28839 Ok(())
28840 }
28841
28842 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
28843 self.write_keyword("DISTSTYLE");
28845 self.write_space();
28846 self.generate_expression(&e.this)?;
28847 Ok(())
28848 }
28849
28850 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
28851 self.write_keyword("DISTRIBUTE BY");
28853 self.write_space();
28854 for (i, expr) in e.expressions.iter().enumerate() {
28855 if i > 0 {
28856 self.write(", ");
28857 }
28858 self.generate_expression(expr)?;
28859 }
28860 Ok(())
28861 }
28862
28863 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
28864 self.write_keyword("DISTRIBUTED BY");
28866 self.write_space();
28867 self.write(&e.kind);
28868 if !e.expressions.is_empty() {
28869 self.write(" (");
28870 for (i, expr) in e.expressions.iter().enumerate() {
28871 if i > 0 {
28872 self.write(", ");
28873 }
28874 self.generate_expression(expr)?;
28875 }
28876 self.write(")");
28877 }
28878 if let Some(buckets) = &e.buckets {
28879 self.write_space();
28880 self.write_keyword("BUCKETS");
28881 self.write_space();
28882 self.generate_expression(buckets)?;
28883 }
28884 if let Some(order) = &e.order {
28885 self.write_space();
28886 self.generate_expression(order)?;
28887 }
28888 Ok(())
28889 }
28890
28891 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
28892 self.write_keyword("DOT_PRODUCT");
28894 self.write("(");
28895 self.generate_expression(&e.this)?;
28896 self.write(", ");
28897 self.generate_expression(&e.expression)?;
28898 self.write(")");
28899 Ok(())
28900 }
28901
28902 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
28903 self.write_keyword("DROP");
28905 if e.exists {
28906 self.write_keyword(" IF EXISTS ");
28907 } else {
28908 self.write_space();
28909 }
28910 for (i, expr) in e.expressions.iter().enumerate() {
28911 if i > 0 {
28912 self.write(", ");
28913 }
28914 self.generate_expression(expr)?;
28915 }
28916 Ok(())
28917 }
28918
28919 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
28920 self.write_keyword("DUPLICATE KEY");
28922 self.write(" (");
28923 for (i, expr) in e.expressions.iter().enumerate() {
28924 if i > 0 {
28925 self.write(", ");
28926 }
28927 self.generate_expression(expr)?;
28928 }
28929 self.write(")");
28930 Ok(())
28931 }
28932
28933 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
28934 self.write_keyword("ELT");
28936 self.write("(");
28937 self.generate_expression(&e.this)?;
28938 for expr in &e.expressions {
28939 self.write(", ");
28940 self.generate_expression(expr)?;
28941 }
28942 self.write(")");
28943 Ok(())
28944 }
28945
28946 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
28947 self.write_keyword("ENCODE");
28949 self.write("(");
28950 self.generate_expression(&e.this)?;
28951 if let Some(charset) = &e.charset {
28952 self.write(", ");
28953 self.generate_expression(charset)?;
28954 }
28955 self.write(")");
28956 Ok(())
28957 }
28958
28959 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
28960 if e.key.is_some() {
28962 self.write_keyword("KEY ");
28963 }
28964 self.write_keyword("ENCODE");
28965 self.write_space();
28966 self.generate_expression(&e.this)?;
28967 if !e.properties.is_empty() {
28968 self.write(" (");
28969 for (i, prop) in e.properties.iter().enumerate() {
28970 if i > 0 {
28971 self.write(", ");
28972 }
28973 self.generate_expression(prop)?;
28974 }
28975 self.write(")");
28976 }
28977 Ok(())
28978 }
28979
28980 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
28981 self.write_keyword("ENCRYPT");
28983 self.write("(");
28984 self.generate_expression(&e.this)?;
28985 if let Some(passphrase) = &e.passphrase {
28986 self.write(", ");
28987 self.generate_expression(passphrase)?;
28988 }
28989 if let Some(aad) = &e.aad {
28990 self.write(", ");
28991 self.generate_expression(aad)?;
28992 }
28993 if let Some(method) = &e.encryption_method {
28994 self.write(", ");
28995 self.generate_expression(method)?;
28996 }
28997 self.write(")");
28998 Ok(())
28999 }
29000
29001 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
29002 self.write_keyword("ENCRYPT_RAW");
29004 self.write("(");
29005 self.generate_expression(&e.this)?;
29006 if let Some(key) = &e.key {
29007 self.write(", ");
29008 self.generate_expression(key)?;
29009 }
29010 if let Some(iv) = &e.iv {
29011 self.write(", ");
29012 self.generate_expression(iv)?;
29013 }
29014 if let Some(aad) = &e.aad {
29015 self.write(", ");
29016 self.generate_expression(aad)?;
29017 }
29018 if let Some(method) = &e.encryption_method {
29019 self.write(", ");
29020 self.generate_expression(method)?;
29021 }
29022 self.write(")");
29023 Ok(())
29024 }
29025
29026 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
29027 self.write_keyword("ENGINE");
29029 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
29030 self.write("=");
29031 } else {
29032 self.write(" = ");
29033 }
29034 self.generate_expression(&e.this)?;
29035 Ok(())
29036 }
29037
29038 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
29039 self.write_keyword("ENVIRONMENT");
29041 self.write(" (");
29042 for (i, expr) in e.expressions.iter().enumerate() {
29043 if i > 0 {
29044 self.write(", ");
29045 }
29046 self.generate_expression(expr)?;
29047 }
29048 self.write(")");
29049 Ok(())
29050 }
29051
29052 fn generate_ephemeral_column_constraint(
29053 &mut self,
29054 e: &EphemeralColumnConstraint,
29055 ) -> Result<()> {
29056 self.write_keyword("EPHEMERAL");
29058 if let Some(this) = &e.this {
29059 self.write_space();
29060 self.generate_expression(this)?;
29061 }
29062 Ok(())
29063 }
29064
29065 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
29066 self.write_keyword("EQUAL_NULL");
29068 self.write("(");
29069 self.generate_expression(&e.this)?;
29070 self.write(", ");
29071 self.generate_expression(&e.expression)?;
29072 self.write(")");
29073 Ok(())
29074 }
29075
29076 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
29077 use crate::dialects::DialectType;
29078
29079 match self.config.dialect {
29081 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
29082 self.generate_expression(&e.this)?;
29083 self.write(" <-> ");
29084 self.generate_expression(&e.expression)?;
29085 }
29086 _ => {
29087 self.write_keyword("EUCLIDEAN_DISTANCE");
29089 self.write("(");
29090 self.generate_expression(&e.this)?;
29091 self.write(", ");
29092 self.generate_expression(&e.expression)?;
29093 self.write(")");
29094 }
29095 }
29096 Ok(())
29097 }
29098
29099 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
29100 self.write_keyword("EXECUTE AS");
29102 self.write_space();
29103 self.generate_expression(&e.this)?;
29104 Ok(())
29105 }
29106
29107 fn generate_export(&mut self, e: &Export) -> Result<()> {
29108 self.write_keyword("EXPORT DATA");
29110 if let Some(connection) = &e.connection {
29111 self.write_space();
29112 self.write_keyword("WITH CONNECTION");
29113 self.write_space();
29114 self.generate_expression(connection)?;
29115 }
29116 if !e.options.is_empty() {
29117 self.write_space();
29118 self.generate_options_clause(&e.options)?;
29119 }
29120 self.write_space();
29121 self.write_keyword("AS");
29122 self.write_space();
29123 self.generate_expression(&e.this)?;
29124 Ok(())
29125 }
29126
29127 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
29128 self.write_keyword("EXTERNAL");
29130 if let Some(this) = &e.this {
29131 self.write_space();
29132 self.generate_expression(this)?;
29133 }
29134 Ok(())
29135 }
29136
29137 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
29138 if e.no.is_some() {
29140 self.write_keyword("NO ");
29141 }
29142 self.write_keyword("FALLBACK");
29143 if e.protection.is_some() {
29144 self.write_keyword(" PROTECTION");
29145 }
29146 Ok(())
29147 }
29148
29149 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
29150 self.write_keyword("FARM_FINGERPRINT");
29152 self.write("(");
29153 for (i, expr) in e.expressions.iter().enumerate() {
29154 if i > 0 {
29155 self.write(", ");
29156 }
29157 self.generate_expression(expr)?;
29158 }
29159 self.write(")");
29160 Ok(())
29161 }
29162
29163 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
29164 self.write_keyword("FEATURES_AT_TIME");
29166 self.write("(");
29167 self.generate_expression(&e.this)?;
29168 if let Some(time) = &e.time {
29169 self.write(", ");
29170 self.generate_expression(time)?;
29171 }
29172 if let Some(num_rows) = &e.num_rows {
29173 self.write(", ");
29174 self.generate_expression(num_rows)?;
29175 }
29176 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
29177 self.write(", ");
29178 self.generate_expression(ignore_nulls)?;
29179 }
29180 self.write(")");
29181 Ok(())
29182 }
29183
29184 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
29185 let use_limit = !e.percent
29187 && !e.with_ties
29188 && e.count.is_some()
29189 && matches!(
29190 self.config.dialect,
29191 Some(DialectType::Spark)
29192 | Some(DialectType::Hive)
29193 | Some(DialectType::DuckDB)
29194 | Some(DialectType::SQLite)
29195 | Some(DialectType::MySQL)
29196 | Some(DialectType::BigQuery)
29197 | Some(DialectType::Databricks)
29198 | Some(DialectType::StarRocks)
29199 | Some(DialectType::Doris)
29200 | Some(DialectType::Athena)
29201 | Some(DialectType::ClickHouse)
29202 );
29203
29204 if use_limit {
29205 self.write_keyword("LIMIT");
29206 self.write_space();
29207 self.generate_expression(e.count.as_ref().unwrap())?;
29208 return Ok(());
29209 }
29210
29211 self.write_keyword("FETCH");
29213 if !e.direction.is_empty() {
29214 self.write_space();
29215 self.write_keyword(&e.direction);
29216 }
29217 if let Some(count) = &e.count {
29218 self.write_space();
29219 self.generate_expression(count)?;
29220 }
29221 if e.percent {
29223 self.write_keyword(" PERCENT");
29224 }
29225 if e.rows {
29226 self.write_keyword(" ROWS");
29227 }
29228 if e.with_ties {
29229 self.write_keyword(" WITH TIES");
29230 } else if e.rows {
29231 self.write_keyword(" ONLY");
29232 } else {
29233 self.write_keyword(" ROWS ONLY");
29234 }
29235 Ok(())
29236 }
29237
29238 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
29239 if e.hive_format.is_some() {
29243 self.write_keyword("STORED AS");
29245 self.write_space();
29246 if let Some(this) = &e.this {
29247 if let Expression::Identifier(id) = this.as_ref() {
29249 self.write_keyword(&id.name.to_ascii_uppercase());
29250 } else {
29251 self.generate_expression(this)?;
29252 }
29253 }
29254 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
29255 self.write_keyword("STORED AS");
29257 self.write_space();
29258 if let Some(this) = &e.this {
29259 if let Expression::Identifier(id) = this.as_ref() {
29260 self.write_keyword(&id.name.to_ascii_uppercase());
29261 } else {
29262 self.generate_expression(this)?;
29263 }
29264 }
29265 } else if matches!(
29266 self.config.dialect,
29267 Some(DialectType::Spark) | Some(DialectType::Databricks)
29268 ) {
29269 self.write_keyword("USING");
29271 self.write_space();
29272 if let Some(this) = &e.this {
29273 self.generate_expression(this)?;
29274 }
29275 } else {
29276 self.write_keyword("FILE_FORMAT");
29278 self.write(" = ");
29279 if let Some(this) = &e.this {
29280 self.generate_expression(this)?;
29281 } else if !e.expressions.is_empty() {
29282 self.write("(");
29283 for (i, expr) in e.expressions.iter().enumerate() {
29284 if i > 0 {
29285 self.write(", ");
29286 }
29287 self.generate_expression(expr)?;
29288 }
29289 self.write(")");
29290 }
29291 }
29292 Ok(())
29293 }
29294
29295 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
29296 self.generate_expression(&e.this)?;
29298 self.write_space();
29299 self.write_keyword("FILTER");
29300 self.write("(");
29301 self.write_keyword("WHERE");
29302 self.write_space();
29303 self.generate_expression(&e.expression)?;
29304 self.write(")");
29305 Ok(())
29306 }
29307
29308 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
29309 self.write_keyword("FLOAT64");
29311 self.write("(");
29312 self.generate_expression(&e.this)?;
29313 if let Some(expr) = &e.expression {
29314 self.write(", ");
29315 self.generate_expression(expr)?;
29316 }
29317 self.write(")");
29318 Ok(())
29319 }
29320
29321 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
29322 self.write_keyword("FOR");
29324 self.write_space();
29325 self.generate_expression(&e.this)?;
29326 self.write_space();
29327 self.write_keyword("DO");
29328 self.write_space();
29329 self.generate_expression(&e.expression)?;
29330 Ok(())
29331 }
29332
29333 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
29334 self.write_keyword("FOREIGN KEY");
29336 if !e.expressions.is_empty() {
29337 self.write(" (");
29338 for (i, expr) in e.expressions.iter().enumerate() {
29339 if i > 0 {
29340 self.write(", ");
29341 }
29342 self.generate_expression(expr)?;
29343 }
29344 self.write(")");
29345 }
29346 if let Some(reference) = &e.reference {
29347 self.write_space();
29348 self.generate_expression(reference)?;
29349 }
29350 if let Some(delete) = &e.delete {
29351 self.write_space();
29352 self.write_keyword("ON DELETE");
29353 self.write_space();
29354 self.generate_expression(delete)?;
29355 }
29356 if let Some(update) = &e.update {
29357 self.write_space();
29358 self.write_keyword("ON UPDATE");
29359 self.write_space();
29360 self.generate_expression(update)?;
29361 }
29362 if !e.options.is_empty() {
29363 self.write_space();
29364 for (i, opt) in e.options.iter().enumerate() {
29365 if i > 0 {
29366 self.write_space();
29367 }
29368 self.generate_expression(opt)?;
29369 }
29370 }
29371 Ok(())
29372 }
29373
29374 fn generate_format(&mut self, e: &Format) -> Result<()> {
29375 self.write_keyword("FORMAT");
29377 self.write("(");
29378 self.generate_expression(&e.this)?;
29379 for expr in &e.expressions {
29380 self.write(", ");
29381 self.generate_expression(expr)?;
29382 }
29383 self.write(")");
29384 Ok(())
29385 }
29386
29387 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
29388 self.generate_expression(&e.this)?;
29390 self.write(" (");
29391 self.write_keyword("FORMAT");
29392 self.write(" '");
29393 self.write(&e.format);
29394 self.write("')");
29395 Ok(())
29396 }
29397
29398 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
29399 self.write_keyword("FREESPACE");
29401 self.write("=");
29402 self.generate_expression(&e.this)?;
29403 if e.percent.is_some() {
29404 self.write_keyword(" PERCENT");
29405 }
29406 Ok(())
29407 }
29408
29409 fn generate_from(&mut self, e: &From) -> Result<()> {
29410 self.write_keyword("FROM");
29412 self.write_space();
29413
29414 use crate::dialects::DialectType;
29418 let has_tablesample = e
29419 .expressions
29420 .iter()
29421 .any(|expr| matches!(expr, Expression::TableSample(_)));
29422 let is_cross_join_dialect = matches!(
29423 self.config.dialect,
29424 Some(DialectType::BigQuery)
29425 | Some(DialectType::Hive)
29426 | Some(DialectType::Spark)
29427 | Some(DialectType::Databricks)
29428 | Some(DialectType::SQLite)
29429 | Some(DialectType::ClickHouse)
29430 );
29431 let source_is_same_as_target2 = self.config.source_dialect.is_some()
29432 && self.config.source_dialect == self.config.dialect;
29433 let source_is_cross_join_dialect2 = matches!(
29434 self.config.source_dialect,
29435 Some(DialectType::BigQuery)
29436 | Some(DialectType::Hive)
29437 | Some(DialectType::Spark)
29438 | Some(DialectType::Databricks)
29439 | Some(DialectType::SQLite)
29440 | Some(DialectType::ClickHouse)
29441 );
29442 let use_cross_join = !has_tablesample
29443 && is_cross_join_dialect
29444 && (source_is_same_as_target2
29445 || source_is_cross_join_dialect2
29446 || self.config.source_dialect.is_none());
29447
29448 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
29450
29451 for (i, expr) in e.expressions.iter().enumerate() {
29452 if i > 0 {
29453 if use_cross_join {
29454 self.write(" CROSS JOIN ");
29455 } else {
29456 self.write(", ");
29457 }
29458 }
29459 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
29460 self.write("(");
29461 self.generate_expression(expr)?;
29462 self.write(")");
29463 } else {
29464 self.generate_expression(expr)?;
29465 }
29466 let leading = Self::extract_table_leading_comments(expr);
29469 for comment in &leading {
29470 self.write_space();
29471 self.write_formatted_comment(comment);
29472 }
29473 }
29474 Ok(())
29475 }
29476
29477 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
29479 match expr {
29480 Expression::Table(t) => t.leading_comments.clone(),
29481 Expression::Pivot(p) => {
29482 if let Expression::Table(t) = &p.this {
29483 t.leading_comments.clone()
29484 } else {
29485 Vec::new()
29486 }
29487 }
29488 _ => Vec::new(),
29489 }
29490 }
29491
29492 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
29493 self.write_keyword("FROM_BASE");
29495 self.write("(");
29496 self.generate_expression(&e.this)?;
29497 self.write(", ");
29498 self.generate_expression(&e.expression)?;
29499 self.write(")");
29500 Ok(())
29501 }
29502
29503 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
29504 self.generate_expression(&e.this)?;
29506 if let Some(zone) = &e.zone {
29507 self.write_space();
29508 self.write_keyword("AT TIME ZONE");
29509 self.write_space();
29510 self.generate_expression(zone)?;
29511 self.write_space();
29512 self.write_keyword("AT TIME ZONE");
29513 self.write(" 'UTC'");
29514 }
29515 Ok(())
29516 }
29517
29518 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
29519 self.write_keyword("GAP_FILL");
29521 self.write("(");
29522 self.generate_expression(&e.this)?;
29523 if let Some(ts_column) = &e.ts_column {
29524 self.write(", ");
29525 self.generate_expression(ts_column)?;
29526 }
29527 if let Some(bucket_width) = &e.bucket_width {
29528 self.write(", ");
29529 self.generate_expression(bucket_width)?;
29530 }
29531 if let Some(partitioning_columns) = &e.partitioning_columns {
29532 self.write(", ");
29533 self.generate_expression(partitioning_columns)?;
29534 }
29535 if let Some(value_columns) = &e.value_columns {
29536 self.write(", ");
29537 self.generate_expression(value_columns)?;
29538 }
29539 self.write(")");
29540 Ok(())
29541 }
29542
29543 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
29544 self.write_keyword("GENERATE_DATE_ARRAY");
29546 self.write("(");
29547 let mut first = true;
29548 if let Some(start) = &e.start {
29549 self.generate_expression(start)?;
29550 first = false;
29551 }
29552 if let Some(end) = &e.end {
29553 if !first {
29554 self.write(", ");
29555 }
29556 self.generate_expression(end)?;
29557 first = false;
29558 }
29559 if let Some(step) = &e.step {
29560 if !first {
29561 self.write(", ");
29562 }
29563 self.generate_expression(step)?;
29564 }
29565 self.write(")");
29566 Ok(())
29567 }
29568
29569 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
29570 self.write_keyword("ML.GENERATE_EMBEDDING");
29572 self.write("(");
29573 self.generate_expression(&e.this)?;
29574 self.write(", ");
29575 self.generate_expression(&e.expression)?;
29576 if let Some(params) = &e.params_struct {
29577 self.write(", ");
29578 self.generate_expression(params)?;
29579 }
29580 self.write(")");
29581 Ok(())
29582 }
29583
29584 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
29585 let fn_name = match self.config.dialect {
29587 Some(DialectType::Presto)
29588 | Some(DialectType::Trino)
29589 | Some(DialectType::Athena)
29590 | Some(DialectType::Spark)
29591 | Some(DialectType::Databricks)
29592 | Some(DialectType::Hive) => "SEQUENCE",
29593 _ => "GENERATE_SERIES",
29594 };
29595 self.write_keyword(fn_name);
29596 self.write("(");
29597 let mut first = true;
29598 if let Some(start) = &e.start {
29599 self.generate_expression(start)?;
29600 first = false;
29601 }
29602 if let Some(end) = &e.end {
29603 if !first {
29604 self.write(", ");
29605 }
29606 self.generate_expression(end)?;
29607 first = false;
29608 }
29609 if let Some(step) = &e.step {
29610 if !first {
29611 self.write(", ");
29612 }
29613 if matches!(
29616 self.config.dialect,
29617 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
29618 ) {
29619 if let Some(converted) = self.convert_week_interval_to_day(step) {
29620 self.generate_expression(&converted)?;
29621 } else {
29622 self.generate_expression(step)?;
29623 }
29624 } else {
29625 self.generate_expression(step)?;
29626 }
29627 }
29628 self.write(")");
29629 Ok(())
29630 }
29631
29632 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
29635 use crate::expressions::*;
29636 if let Expression::Interval(ref iv) = expr {
29637 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
29639 unit: IntervalUnit::Week,
29640 ..
29641 }) = &iv.unit
29642 {
29643 let count = match &iv.this {
29645 Some(Expression::Literal(lit)) => match lit.as_ref() {
29646 Literal::String(s) | Literal::Number(s) => s.clone(),
29647 _ => return None,
29648 },
29649 _ => return None,
29650 };
29651 (true, count)
29652 } else if iv.unit.is_none() {
29653 if let Some(Expression::Literal(lit)) = &iv.this {
29655 if let Literal::String(s) = lit.as_ref() {
29656 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
29657 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
29658 (true, parts[0].to_string())
29659 } else {
29660 (false, String::new())
29661 }
29662 } else {
29663 (false, String::new())
29664 }
29665 } else {
29666 (false, String::new())
29667 }
29668 } else {
29669 (false, String::new())
29670 };
29671
29672 if is_week {
29673 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
29675 let day_interval = Expression::Interval(Box::new(Interval {
29676 this: Some(Expression::Literal(Box::new(Literal::String(
29677 "7".to_string(),
29678 )))),
29679 unit: Some(IntervalUnitSpec::Simple {
29680 unit: IntervalUnit::Day,
29681 use_plural: false,
29682 }),
29683 }));
29684 let mul = Expression::Mul(Box::new(BinaryOp {
29685 left: count_expr,
29686 right: day_interval,
29687 left_comments: vec![],
29688 operator_comments: vec![],
29689 trailing_comments: vec![],
29690 inferred_type: None,
29691 }));
29692 return Some(Expression::Paren(Box::new(Paren {
29693 this: mul,
29694 trailing_comments: vec![],
29695 })));
29696 }
29697 }
29698 None
29699 }
29700
29701 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
29702 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
29704 self.write("(");
29705 let mut first = true;
29706 if let Some(start) = &e.start {
29707 self.generate_expression(start)?;
29708 first = false;
29709 }
29710 if let Some(end) = &e.end {
29711 if !first {
29712 self.write(", ");
29713 }
29714 self.generate_expression(end)?;
29715 first = false;
29716 }
29717 if let Some(step) = &e.step {
29718 if !first {
29719 self.write(", ");
29720 }
29721 self.generate_expression(step)?;
29722 }
29723 self.write(")");
29724 Ok(())
29725 }
29726
29727 fn generate_generated_as_identity_column_constraint(
29728 &mut self,
29729 e: &GeneratedAsIdentityColumnConstraint,
29730 ) -> Result<()> {
29731 use crate::dialects::DialectType;
29732
29733 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29735 self.write_keyword("AUTOINCREMENT");
29736 if let Some(start) = &e.start {
29737 self.write_keyword(" START ");
29738 self.generate_expression(start)?;
29739 }
29740 if let Some(increment) = &e.increment {
29741 self.write_keyword(" INCREMENT ");
29742 self.generate_expression(increment)?;
29743 }
29744 return Ok(());
29745 }
29746
29747 self.write_keyword("GENERATED");
29749 if let Some(this) = &e.this {
29750 if let Expression::Boolean(b) = this.as_ref() {
29752 if b.value {
29753 self.write_keyword(" ALWAYS");
29754 } else {
29755 self.write_keyword(" BY DEFAULT");
29756 if e.on_null.is_some() {
29757 self.write_keyword(" ON NULL");
29758 }
29759 }
29760 } else {
29761 self.write_keyword(" ALWAYS");
29762 }
29763 }
29764 self.write_keyword(" AS IDENTITY");
29765 let has_options = e.start.is_some()
29767 || e.increment.is_some()
29768 || e.minvalue.is_some()
29769 || e.maxvalue.is_some();
29770 if has_options {
29771 self.write(" (");
29772 let mut first = true;
29773 if let Some(start) = &e.start {
29774 self.write_keyword("START WITH ");
29775 self.generate_expression(start)?;
29776 first = false;
29777 }
29778 if let Some(increment) = &e.increment {
29779 if !first {
29780 self.write(" ");
29781 }
29782 self.write_keyword("INCREMENT BY ");
29783 self.generate_expression(increment)?;
29784 first = false;
29785 }
29786 if let Some(minvalue) = &e.minvalue {
29787 if !first {
29788 self.write(" ");
29789 }
29790 self.write_keyword("MINVALUE ");
29791 self.generate_expression(minvalue)?;
29792 first = false;
29793 }
29794 if let Some(maxvalue) = &e.maxvalue {
29795 if !first {
29796 self.write(" ");
29797 }
29798 self.write_keyword("MAXVALUE ");
29799 self.generate_expression(maxvalue)?;
29800 }
29801 self.write(")");
29802 }
29803 Ok(())
29804 }
29805
29806 fn generate_generated_as_row_column_constraint(
29807 &mut self,
29808 e: &GeneratedAsRowColumnConstraint,
29809 ) -> Result<()> {
29810 self.write_keyword("GENERATED ALWAYS AS ROW ");
29812 if e.start.is_some() {
29813 self.write_keyword("START");
29814 } else {
29815 self.write_keyword("END");
29816 }
29817 if e.hidden.is_some() {
29818 self.write_keyword(" HIDDEN");
29819 }
29820 Ok(())
29821 }
29822
29823 fn generate_get(&mut self, e: &Get) -> Result<()> {
29824 self.write_keyword("GET");
29826 self.write_space();
29827 self.generate_expression(&e.this)?;
29828 if let Some(target) = &e.target {
29829 self.write_space();
29830 self.generate_expression(target)?;
29831 }
29832 for prop in &e.properties {
29833 self.write_space();
29834 self.generate_expression(prop)?;
29835 }
29836 Ok(())
29837 }
29838
29839 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
29840 self.generate_expression(&e.this)?;
29842 self.write("[");
29843 self.generate_expression(&e.expression)?;
29844 self.write("]");
29845 Ok(())
29846 }
29847
29848 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
29849 self.write_keyword("GETBIT");
29851 self.write("(");
29852 self.generate_expression(&e.this)?;
29853 self.write(", ");
29854 self.generate_expression(&e.expression)?;
29855 self.write(")");
29856 Ok(())
29857 }
29858
29859 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
29860 if e.is_role {
29862 self.write_keyword("ROLE");
29863 self.write_space();
29864 } else if e.is_group {
29865 self.write_keyword("GROUP");
29866 self.write_space();
29867 } else if e.is_share {
29868 self.write_keyword("SHARE");
29869 self.write_space();
29870 }
29871 self.write(&e.name.name);
29872 Ok(())
29873 }
29874
29875 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
29876 self.generate_expression(&e.this)?;
29878 if !e.expressions.is_empty() {
29879 self.write("(");
29880 for (i, expr) in e.expressions.iter().enumerate() {
29881 if i > 0 {
29882 self.write(", ");
29883 }
29884 self.generate_expression(expr)?;
29885 }
29886 self.write(")");
29887 }
29888 Ok(())
29889 }
29890
29891 fn generate_group(&mut self, e: &Group) -> Result<()> {
29892 self.write_keyword("GROUP BY");
29894 match e.all {
29896 Some(true) => {
29897 self.write_space();
29898 self.write_keyword("ALL");
29899 }
29900 Some(false) => {
29901 self.write_space();
29902 self.write_keyword("DISTINCT");
29903 }
29904 None => {}
29905 }
29906 if !e.expressions.is_empty() {
29907 self.write_space();
29908 for (i, expr) in e.expressions.iter().enumerate() {
29909 if i > 0 {
29910 self.write(", ");
29911 }
29912 self.generate_expression(expr)?;
29913 }
29914 }
29915 if let Some(cube) = &e.cube {
29917 if !e.expressions.is_empty() {
29918 self.write(", ");
29919 } else {
29920 self.write_space();
29921 }
29922 self.generate_expression(cube)?;
29923 }
29924 if let Some(rollup) = &e.rollup {
29925 if !e.expressions.is_empty() || e.cube.is_some() {
29926 self.write(", ");
29927 } else {
29928 self.write_space();
29929 }
29930 self.generate_expression(rollup)?;
29931 }
29932 if let Some(grouping_sets) = &e.grouping_sets {
29933 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
29934 self.write(", ");
29935 } else {
29936 self.write_space();
29937 }
29938 self.generate_expression(grouping_sets)?;
29939 }
29940 if let Some(totals) = &e.totals {
29941 self.write_space();
29942 self.write_keyword("WITH TOTALS");
29943 self.generate_expression(totals)?;
29944 }
29945 Ok(())
29946 }
29947
29948 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
29949 self.write_keyword("GROUP BY");
29951 match e.all {
29953 Some(true) => {
29954 self.write_space();
29955 self.write_keyword("ALL");
29956 }
29957 Some(false) => {
29958 self.write_space();
29959 self.write_keyword("DISTINCT");
29960 }
29961 None => {}
29962 }
29963
29964 let mut trailing_cube = false;
29967 let mut trailing_rollup = false;
29968 let mut regular_expressions: Vec<&Expression> = Vec::new();
29969
29970 for expr in &e.expressions {
29971 match expr {
29972 Expression::Cube(c) if c.expressions.is_empty() => {
29973 trailing_cube = true;
29974 }
29975 Expression::Rollup(r) if r.expressions.is_empty() => {
29976 trailing_rollup = true;
29977 }
29978 _ => {
29979 regular_expressions.push(expr);
29980 }
29981 }
29982 }
29983
29984 if self.config.pretty {
29986 self.write_newline();
29987 self.indent_level += 1;
29988 for (i, expr) in regular_expressions.iter().enumerate() {
29989 if i > 0 {
29990 self.write(",");
29991 self.write_newline();
29992 }
29993 self.write_indent();
29994 self.generate_expression(expr)?;
29995 }
29996 self.indent_level -= 1;
29997 } else {
29998 self.write_space();
29999 for (i, expr) in regular_expressions.iter().enumerate() {
30000 if i > 0 {
30001 self.write(", ");
30002 }
30003 self.generate_expression(expr)?;
30004 }
30005 }
30006
30007 if trailing_cube {
30009 self.write_space();
30010 self.write_keyword("WITH CUBE");
30011 } else if trailing_rollup {
30012 self.write_space();
30013 self.write_keyword("WITH ROLLUP");
30014 }
30015
30016 if e.totals {
30018 self.write_space();
30019 self.write_keyword("WITH TOTALS");
30020 }
30021
30022 Ok(())
30023 }
30024
30025 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
30026 self.write_keyword("GROUPING");
30028 self.write("(");
30029 for (i, expr) in e.expressions.iter().enumerate() {
30030 if i > 0 {
30031 self.write(", ");
30032 }
30033 self.generate_expression(expr)?;
30034 }
30035 self.write(")");
30036 Ok(())
30037 }
30038
30039 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
30040 self.write_keyword("GROUPING_ID");
30042 self.write("(");
30043 for (i, expr) in e.expressions.iter().enumerate() {
30044 if i > 0 {
30045 self.write(", ");
30046 }
30047 self.generate_expression(expr)?;
30048 }
30049 self.write(")");
30050 Ok(())
30051 }
30052
30053 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
30054 self.write_keyword("GROUPING SETS");
30056 self.write(" (");
30057 for (i, expr) in e.expressions.iter().enumerate() {
30058 if i > 0 {
30059 self.write(", ");
30060 }
30061 self.generate_expression(expr)?;
30062 }
30063 self.write(")");
30064 Ok(())
30065 }
30066
30067 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
30068 self.write_keyword("HASH_AGG");
30070 self.write("(");
30071 self.generate_expression(&e.this)?;
30072 for expr in &e.expressions {
30073 self.write(", ");
30074 self.generate_expression(expr)?;
30075 }
30076 self.write(")");
30077 Ok(())
30078 }
30079
30080 fn generate_having(&mut self, e: &Having) -> Result<()> {
30081 self.write_keyword("HAVING");
30083 self.write_space();
30084 self.generate_expression(&e.this)?;
30085 Ok(())
30086 }
30087
30088 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
30089 self.generate_expression(&e.this)?;
30091 self.write_space();
30092 self.write_keyword("HAVING");
30093 self.write_space();
30094 if e.max.is_some() {
30095 self.write_keyword("MAX");
30096 } else {
30097 self.write_keyword("MIN");
30098 }
30099 self.write_space();
30100 self.generate_expression(&e.expression)?;
30101 Ok(())
30102 }
30103
30104 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
30105 use crate::dialects::DialectType;
30106 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
30108 if let Expression::Literal(ref lit) = *e.this {
30110 if let Literal::String(ref s) = lit.as_ref() {
30111 return self.generate_string_literal(s);
30112 }
30113 }
30114 }
30115 if matches!(
30117 self.config.dialect,
30118 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
30119 ) {
30120 self.write("$");
30121 if let Some(tag) = &e.tag {
30122 self.generate_expression(tag)?;
30123 }
30124 self.write("$");
30125 self.generate_expression(&e.this)?;
30126 self.write("$");
30127 if let Some(tag) = &e.tag {
30128 self.generate_expression(tag)?;
30129 }
30130 self.write("$");
30131 return Ok(());
30132 }
30133 self.write("$");
30135 if let Some(tag) = &e.tag {
30136 self.generate_expression(tag)?;
30137 }
30138 self.write("$");
30139 self.generate_expression(&e.this)?;
30140 self.write("$");
30141 if let Some(tag) = &e.tag {
30142 self.generate_expression(tag)?;
30143 }
30144 self.write("$");
30145 Ok(())
30146 }
30147
30148 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
30149 self.write_keyword("HEX_ENCODE");
30151 self.write("(");
30152 self.generate_expression(&e.this)?;
30153 self.write(")");
30154 Ok(())
30155 }
30156
30157 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
30158 match e.this.as_ref() {
30161 Expression::Identifier(id) => self.write(&id.name),
30162 other => self.generate_expression(other)?,
30163 }
30164 self.write(" (");
30165 self.write(&e.kind);
30166 self.write(" => ");
30167 self.generate_expression(&e.expression)?;
30168 self.write(")");
30169 Ok(())
30170 }
30171
30172 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
30173 self.write_keyword("HLL");
30175 self.write("(");
30176 self.generate_expression(&e.this)?;
30177 for expr in &e.expressions {
30178 self.write(", ");
30179 self.generate_expression(expr)?;
30180 }
30181 self.write(")");
30182 Ok(())
30183 }
30184
30185 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
30186 if e.input_.is_some() && e.output.is_some() {
30188 self.write_keyword("IN OUT");
30189 } else if e.input_.is_some() {
30190 self.write_keyword("IN");
30191 } else if e.output.is_some() {
30192 self.write_keyword("OUT");
30193 }
30194 Ok(())
30195 }
30196
30197 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
30198 self.write_keyword("INCLUDE");
30200 self.write_space();
30201 self.generate_expression(&e.this)?;
30202 if let Some(column_def) = &e.column_def {
30203 self.write_space();
30204 self.generate_expression(column_def)?;
30205 }
30206 if let Some(alias) = &e.alias {
30207 self.write_space();
30208 self.write_keyword("AS");
30209 self.write_space();
30210 self.write(alias);
30211 }
30212 Ok(())
30213 }
30214
30215 fn generate_index(&mut self, e: &Index) -> Result<()> {
30216 if e.unique {
30218 self.write_keyword("UNIQUE");
30219 self.write_space();
30220 }
30221 if e.primary.is_some() {
30222 self.write_keyword("PRIMARY");
30223 self.write_space();
30224 }
30225 if e.amp.is_some() {
30226 self.write_keyword("AMP");
30227 self.write_space();
30228 }
30229 if e.table.is_none() {
30230 self.write_keyword("INDEX");
30231 self.write_space();
30232 }
30233 if let Some(name) = &e.this {
30234 self.generate_expression(name)?;
30235 self.write_space();
30236 }
30237 if let Some(table) = &e.table {
30238 self.write_keyword("ON");
30239 self.write_space();
30240 self.generate_expression(table)?;
30241 }
30242 if !e.params.is_empty() {
30243 self.write("(");
30244 for (i, param) in e.params.iter().enumerate() {
30245 if i > 0 {
30246 self.write(", ");
30247 }
30248 self.generate_expression(param)?;
30249 }
30250 self.write(")");
30251 }
30252 Ok(())
30253 }
30254
30255 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
30256 if let Some(kind) = &e.kind {
30258 self.write(kind);
30259 self.write_space();
30260 }
30261 self.write_keyword("INDEX");
30262 if let Some(this) = &e.this {
30263 self.write_space();
30264 self.generate_expression(this)?;
30265 }
30266 if let Some(index_type) = &e.index_type {
30267 self.write_space();
30268 self.write_keyword("USING");
30269 self.write_space();
30270 self.generate_expression(index_type)?;
30271 }
30272 if !e.expressions.is_empty() {
30273 self.write(" (");
30274 for (i, expr) in e.expressions.iter().enumerate() {
30275 if i > 0 {
30276 self.write(", ");
30277 }
30278 self.generate_expression(expr)?;
30279 }
30280 self.write(")");
30281 }
30282 for opt in &e.options {
30283 self.write_space();
30284 self.generate_expression(opt)?;
30285 }
30286 Ok(())
30287 }
30288
30289 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
30290 if let Some(key_block_size) = &e.key_block_size {
30292 self.write_keyword("KEY_BLOCK_SIZE");
30293 self.write(" = ");
30294 self.generate_expression(key_block_size)?;
30295 } else if let Some(using) = &e.using {
30296 self.write_keyword("USING");
30297 self.write_space();
30298 self.generate_expression(using)?;
30299 } else if let Some(parser) = &e.parser {
30300 self.write_keyword("WITH PARSER");
30301 self.write_space();
30302 self.generate_expression(parser)?;
30303 } else if let Some(comment) = &e.comment {
30304 self.write_keyword("COMMENT");
30305 self.write_space();
30306 self.generate_expression(comment)?;
30307 } else if let Some(visible) = &e.visible {
30308 self.generate_expression(visible)?;
30309 } else if let Some(engine_attr) = &e.engine_attr {
30310 self.write_keyword("ENGINE_ATTRIBUTE");
30311 self.write(" = ");
30312 self.generate_expression(engine_attr)?;
30313 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
30314 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
30315 self.write(" = ");
30316 self.generate_expression(secondary_engine_attr)?;
30317 }
30318 Ok(())
30319 }
30320
30321 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
30322 if let Some(using) = &e.using {
30324 self.write_keyword("USING");
30325 self.write_space();
30326 self.generate_expression(using)?;
30327 }
30328 if !e.columns.is_empty() {
30329 self.write("(");
30330 for (i, col) in e.columns.iter().enumerate() {
30331 if i > 0 {
30332 self.write(", ");
30333 }
30334 self.generate_expression(col)?;
30335 }
30336 self.write(")");
30337 }
30338 if let Some(partition_by) = &e.partition_by {
30339 self.write_space();
30340 self.write_keyword("PARTITION BY");
30341 self.write_space();
30342 self.generate_expression(partition_by)?;
30343 }
30344 if let Some(where_) = &e.where_ {
30345 self.write_space();
30346 self.generate_expression(where_)?;
30347 }
30348 if let Some(include) = &e.include {
30349 self.write_space();
30350 self.write_keyword("INCLUDE");
30351 self.write(" (");
30352 self.generate_expression(include)?;
30353 self.write(")");
30354 }
30355 if let Some(with_storage) = &e.with_storage {
30356 self.write_space();
30357 self.write_keyword("WITH");
30358 self.write(" (");
30359 self.generate_expression(with_storage)?;
30360 self.write(")");
30361 }
30362 if let Some(tablespace) = &e.tablespace {
30363 self.write_space();
30364 self.write_keyword("USING INDEX TABLESPACE");
30365 self.write_space();
30366 self.generate_expression(tablespace)?;
30367 }
30368 Ok(())
30369 }
30370
30371 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
30372 if let Expression::Identifier(id) = &*e.this {
30376 self.write_keyword(&id.name);
30377 } else {
30378 self.generate_expression(&e.this)?;
30379 }
30380 self.write_space();
30381 self.write_keyword("INDEX");
30382 if let Some(target) = &e.target {
30383 self.write_space();
30384 self.write_keyword("FOR");
30385 self.write_space();
30386 if let Expression::Identifier(id) = &**target {
30387 self.write_keyword(&id.name);
30388 } else {
30389 self.generate_expression(target)?;
30390 }
30391 }
30392 self.write(" (");
30394 for (i, expr) in e.expressions.iter().enumerate() {
30395 if i > 0 {
30396 self.write(", ");
30397 }
30398 self.generate_expression(expr)?;
30399 }
30400 self.write(")");
30401 Ok(())
30402 }
30403
30404 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
30405 self.write_keyword("INHERITS");
30407 self.write(" (");
30408 for (i, expr) in e.expressions.iter().enumerate() {
30409 if i > 0 {
30410 self.write(", ");
30411 }
30412 self.generate_expression(expr)?;
30413 }
30414 self.write(")");
30415 Ok(())
30416 }
30417
30418 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
30419 self.write_keyword("INPUT");
30421 self.write("(");
30422 self.generate_expression(&e.this)?;
30423 self.write(")");
30424 Ok(())
30425 }
30426
30427 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
30428 if let Some(input_format) = &e.input_format {
30430 self.write_keyword("INPUTFORMAT");
30431 self.write_space();
30432 self.generate_expression(input_format)?;
30433 }
30434 if let Some(output_format) = &e.output_format {
30435 if e.input_format.is_some() {
30436 self.write(" ");
30437 }
30438 self.write_keyword("OUTPUTFORMAT");
30439 self.write_space();
30440 self.generate_expression(output_format)?;
30441 }
30442 Ok(())
30443 }
30444
30445 fn generate_install(&mut self, e: &Install) -> Result<()> {
30446 if e.force.is_some() {
30448 self.write_keyword("FORCE");
30449 self.write_space();
30450 }
30451 self.write_keyword("INSTALL");
30452 self.write_space();
30453 self.generate_expression(&e.this)?;
30454 if let Some(from) = &e.from_ {
30455 self.write_space();
30456 self.write_keyword("FROM");
30457 self.write_space();
30458 self.generate_expression(from)?;
30459 }
30460 Ok(())
30461 }
30462
30463 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
30464 self.write_keyword("INTERVAL");
30466 self.write_space();
30467 self.generate_expression(&e.expression)?;
30469 if let Some(unit) = &e.unit {
30470 self.write_space();
30471 self.write(unit);
30472 }
30473 Ok(())
30474 }
30475
30476 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
30477 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
30479 self.write_space();
30480 self.write_keyword("TO");
30481 self.write_space();
30482 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
30483 Ok(())
30484 }
30485
30486 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
30487 self.write_keyword("INTO");
30489 if e.temporary {
30490 self.write_keyword(" TEMPORARY");
30491 }
30492 if e.unlogged.is_some() {
30493 self.write_keyword(" UNLOGGED");
30494 }
30495 if let Some(this) = &e.this {
30496 self.write_space();
30497 self.generate_expression(this)?;
30498 }
30499 if !e.expressions.is_empty() {
30500 self.write(" (");
30501 for (i, expr) in e.expressions.iter().enumerate() {
30502 if i > 0 {
30503 self.write(", ");
30504 }
30505 self.generate_expression(expr)?;
30506 }
30507 self.write(")");
30508 }
30509 Ok(())
30510 }
30511
30512 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
30513 self.generate_expression(&e.this)?;
30515 self.write_space();
30516 self.generate_expression(&e.expression)?;
30517 Ok(())
30518 }
30519
30520 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
30521 self.write_keyword("WITH");
30523 if e.no.is_some() {
30524 self.write_keyword(" NO");
30525 }
30526 if e.concurrent.is_some() {
30527 self.write_keyword(" CONCURRENT");
30528 }
30529 self.write_keyword(" ISOLATED LOADING");
30530 if let Some(target) = &e.target {
30531 self.write_space();
30532 self.generate_expression(target)?;
30533 }
30534 Ok(())
30535 }
30536
30537 fn generate_json(&mut self, e: &JSON) -> Result<()> {
30538 self.write_keyword("JSON");
30540 if let Some(this) = &e.this {
30541 self.write_space();
30542 self.generate_expression(this)?;
30543 }
30544 if let Some(with_) = &e.with_ {
30545 if let Expression::Boolean(b) = with_.as_ref() {
30547 if b.value {
30548 self.write_keyword(" WITH");
30549 } else {
30550 self.write_keyword(" WITHOUT");
30551 }
30552 }
30553 }
30554 if e.unique {
30555 self.write_keyword(" UNIQUE KEYS");
30556 }
30557 Ok(())
30558 }
30559
30560 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
30561 self.write_keyword("JSON_ARRAY");
30563 self.write("(");
30564 for (i, expr) in e.expressions.iter().enumerate() {
30565 if i > 0 {
30566 self.write(", ");
30567 }
30568 self.generate_expression(expr)?;
30569 }
30570 if let Some(null_handling) = &e.null_handling {
30571 self.write_space();
30572 self.generate_expression(null_handling)?;
30573 }
30574 if let Some(return_type) = &e.return_type {
30575 self.write_space();
30576 self.write_keyword("RETURNING");
30577 self.write_space();
30578 self.generate_expression(return_type)?;
30579 }
30580 if e.strict.is_some() {
30581 self.write_space();
30582 self.write_keyword("STRICT");
30583 }
30584 self.write(")");
30585 Ok(())
30586 }
30587
30588 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
30589 self.write_keyword("JSON_ARRAYAGG");
30591 self.write("(");
30592 self.generate_expression(&e.this)?;
30593 if let Some(order) = &e.order {
30594 self.write_space();
30595 if let Expression::OrderBy(ob) = order.as_ref() {
30597 self.write_keyword("ORDER BY");
30598 self.write_space();
30599 for (i, ord) in ob.expressions.iter().enumerate() {
30600 if i > 0 {
30601 self.write(", ");
30602 }
30603 self.generate_ordered(ord)?;
30604 }
30605 } else {
30606 self.generate_expression(order)?;
30608 }
30609 }
30610 if let Some(null_handling) = &e.null_handling {
30611 self.write_space();
30612 self.generate_expression(null_handling)?;
30613 }
30614 if let Some(return_type) = &e.return_type {
30615 self.write_space();
30616 self.write_keyword("RETURNING");
30617 self.write_space();
30618 self.generate_expression(return_type)?;
30619 }
30620 if e.strict.is_some() {
30621 self.write_space();
30622 self.write_keyword("STRICT");
30623 }
30624 self.write(")");
30625 Ok(())
30626 }
30627
30628 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
30629 self.write_keyword("JSON_OBJECTAGG");
30631 self.write("(");
30632 for (i, expr) in e.expressions.iter().enumerate() {
30633 if i > 0 {
30634 self.write(", ");
30635 }
30636 self.generate_expression(expr)?;
30637 }
30638 if let Some(null_handling) = &e.null_handling {
30639 self.write_space();
30640 self.generate_expression(null_handling)?;
30641 }
30642 if let Some(unique_keys) = &e.unique_keys {
30643 self.write_space();
30644 if let Expression::Boolean(b) = unique_keys.as_ref() {
30645 if b.value {
30646 self.write_keyword("WITH UNIQUE KEYS");
30647 } else {
30648 self.write_keyword("WITHOUT UNIQUE KEYS");
30649 }
30650 }
30651 }
30652 if let Some(return_type) = &e.return_type {
30653 self.write_space();
30654 self.write_keyword("RETURNING");
30655 self.write_space();
30656 self.generate_expression(return_type)?;
30657 }
30658 self.write(")");
30659 Ok(())
30660 }
30661
30662 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
30663 self.write_keyword("JSON_ARRAY_APPEND");
30665 self.write("(");
30666 self.generate_expression(&e.this)?;
30667 for expr in &e.expressions {
30668 self.write(", ");
30669 self.generate_expression(expr)?;
30670 }
30671 self.write(")");
30672 Ok(())
30673 }
30674
30675 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
30676 self.write_keyword("JSON_ARRAY_CONTAINS");
30678 self.write("(");
30679 self.generate_expression(&e.this)?;
30680 self.write(", ");
30681 self.generate_expression(&e.expression)?;
30682 self.write(")");
30683 Ok(())
30684 }
30685
30686 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
30687 self.write_keyword("JSON_ARRAY_INSERT");
30689 self.write("(");
30690 self.generate_expression(&e.this)?;
30691 for expr in &e.expressions {
30692 self.write(", ");
30693 self.generate_expression(expr)?;
30694 }
30695 self.write(")");
30696 Ok(())
30697 }
30698
30699 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
30700 self.write_keyword("JSONB_EXISTS");
30702 self.write("(");
30703 self.generate_expression(&e.this)?;
30704 if let Some(path) = &e.path {
30705 self.write(", ");
30706 self.generate_expression(path)?;
30707 }
30708 self.write(")");
30709 Ok(())
30710 }
30711
30712 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
30713 self.write_keyword("JSONB_EXTRACT_SCALAR");
30715 self.write("(");
30716 self.generate_expression(&e.this)?;
30717 self.write(", ");
30718 self.generate_expression(&e.expression)?;
30719 self.write(")");
30720 Ok(())
30721 }
30722
30723 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
30724 self.write_keyword("JSONB_OBJECT_AGG");
30726 self.write("(");
30727 self.generate_expression(&e.this)?;
30728 self.write(", ");
30729 self.generate_expression(&e.expression)?;
30730 self.write(")");
30731 Ok(())
30732 }
30733
30734 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
30735 if let Some(nested_schema) = &e.nested_schema {
30737 self.write_keyword("NESTED");
30738 if let Some(path) = &e.path {
30739 self.write_space();
30740 self.write_keyword("PATH");
30741 self.write_space();
30742 self.generate_expression(path)?;
30743 }
30744 self.write_space();
30745 self.generate_expression(nested_schema)?;
30746 } else {
30747 if let Some(this) = &e.this {
30748 self.generate_expression(this)?;
30749 }
30750 if let Some(kind) = &e.kind {
30751 self.write_space();
30752 self.write(kind);
30753 }
30754 if e.format_json {
30755 self.write_space();
30756 self.write_keyword("FORMAT JSON");
30757 }
30758 if let Some(path) = &e.path {
30759 self.write_space();
30760 self.write_keyword("PATH");
30761 self.write_space();
30762 self.generate_expression(path)?;
30763 }
30764 if e.ordinality.is_some() {
30765 self.write_keyword(" FOR ORDINALITY");
30766 }
30767 }
30768 Ok(())
30769 }
30770
30771 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
30772 self.write_keyword("JSON_EXISTS");
30774 self.write("(");
30775 self.generate_expression(&e.this)?;
30776 if let Some(path) = &e.path {
30777 self.write(", ");
30778 self.generate_expression(path)?;
30779 }
30780 if let Some(passing) = &e.passing {
30781 self.write_space();
30782 self.write_keyword("PASSING");
30783 self.write_space();
30784 self.generate_expression(passing)?;
30785 }
30786 if let Some(on_condition) = &e.on_condition {
30787 self.write_space();
30788 self.generate_expression(on_condition)?;
30789 }
30790 self.write(")");
30791 Ok(())
30792 }
30793
30794 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
30795 self.generate_expression(&e.this)?;
30796 self.write(".:");
30797 if Self::data_type_has_nested_expressions(&e.to) {
30801 let saved = std::mem::take(&mut self.output);
30803 self.generate_data_type(&e.to)?;
30804 let type_sql = std::mem::replace(&mut self.output, saved);
30805 self.write("\"");
30806 self.write(&type_sql);
30807 self.write("\"");
30808 } else {
30809 self.generate_data_type(&e.to)?;
30810 }
30811 Ok(())
30812 }
30813
30814 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
30817 matches!(
30818 dt,
30819 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
30820 )
30821 }
30822
30823 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
30824 self.write_keyword("JSON_EXTRACT_ARRAY");
30826 self.write("(");
30827 self.generate_expression(&e.this)?;
30828 if let Some(expr) = &e.expression {
30829 self.write(", ");
30830 self.generate_expression(expr)?;
30831 }
30832 self.write(")");
30833 Ok(())
30834 }
30835
30836 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
30837 if let Some(option) = &e.option {
30839 self.generate_expression(option)?;
30840 self.write_space();
30841 }
30842 self.write_keyword("QUOTES");
30843 if e.scalar.is_some() {
30844 self.write_keyword(" SCALAR_ONLY");
30845 }
30846 Ok(())
30847 }
30848
30849 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
30850 self.write_keyword("JSON_EXTRACT_SCALAR");
30852 self.write("(");
30853 self.generate_expression(&e.this)?;
30854 self.write(", ");
30855 self.generate_expression(&e.expression)?;
30856 self.write(")");
30857 Ok(())
30858 }
30859
30860 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
30861 if e.variant_extract.is_some() {
30865 use crate::dialects::DialectType;
30866 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
30867 self.generate_expression(&e.this)?;
30871 self.write(":");
30872 match e.expression.as_ref() {
30873 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
30874 let Literal::String(s) = lit.as_ref() else {
30875 unreachable!()
30876 };
30877 self.write_databricks_json_path(s);
30878 }
30879 _ => {
30880 self.generate_expression(&e.expression)?;
30882 }
30883 }
30884 } else {
30885 self.write_keyword("GET_PATH");
30887 self.write("(");
30888 self.generate_expression(&e.this)?;
30889 self.write(", ");
30890 self.generate_expression(&e.expression)?;
30891 self.write(")");
30892 }
30893 } else {
30894 self.write_keyword("JSON_EXTRACT");
30895 self.write("(");
30896 self.generate_expression(&e.this)?;
30897 self.write(", ");
30898 self.generate_expression(&e.expression)?;
30899 for expr in &e.expressions {
30900 self.write(", ");
30901 self.generate_expression(expr)?;
30902 }
30903 self.write(")");
30904 }
30905 Ok(())
30906 }
30907
30908 fn write_databricks_json_path(&mut self, path: &str) {
30912 if path.starts_with("[\"") || path.starts_with("['") {
30915 self.write(path);
30916 return;
30917 }
30918 let mut first = true;
30922 for segment in path.split('.') {
30923 if !first {
30924 self.write(".");
30925 }
30926 first = false;
30927 if let Some(bracket_pos) = segment.find('[') {
30929 let key = &segment[..bracket_pos];
30930 let subscript = &segment[bracket_pos..];
30931 if key.is_empty() {
30932 self.write(segment);
30934 } else if Self::is_safe_json_path_key(key) {
30935 self.write(key);
30936 self.write(subscript);
30937 } else {
30938 self.write("[\"");
30939 self.write(key);
30940 self.write("\"]");
30941 self.write(subscript);
30942 }
30943 } else if Self::is_safe_json_path_key(segment) {
30944 self.write(segment);
30945 } else {
30946 self.write("[\"");
30947 self.write(segment);
30948 self.write("\"]");
30949 }
30950 }
30951 }
30952
30953 fn is_safe_json_path_key(key: &str) -> bool {
30956 if key.is_empty() {
30957 return false;
30958 }
30959 let mut chars = key.chars();
30960 let first = chars.next().unwrap();
30961 if first != '_' && !first.is_ascii_alphabetic() {
30962 return false;
30963 }
30964 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
30965 }
30966
30967 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
30968 if let Some(this) = &e.this {
30971 self.generate_expression(this)?;
30972 self.write_space();
30973 }
30974 self.write_keyword("FORMAT JSON");
30975 Ok(())
30976 }
30977
30978 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
30979 self.generate_expression(&e.this)?;
30981 self.write(": ");
30982 self.generate_expression(&e.expression)?;
30983 Ok(())
30984 }
30985
30986 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
30987 self.write_keyword("JSON_KEYS");
30989 self.write("(");
30990 self.generate_expression(&e.this)?;
30991 if let Some(expr) = &e.expression {
30992 self.write(", ");
30993 self.generate_expression(expr)?;
30994 }
30995 for expr in &e.expressions {
30996 self.write(", ");
30997 self.generate_expression(expr)?;
30998 }
30999 self.write(")");
31000 Ok(())
31001 }
31002
31003 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
31004 self.write_keyword("JSON_KEYS");
31006 self.write("(");
31007 self.generate_expression(&e.this)?;
31008 if let Some(expr) = &e.expression {
31009 self.write(", ");
31010 self.generate_expression(expr)?;
31011 }
31012 self.write(")");
31013 Ok(())
31014 }
31015
31016 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
31017 let mut path_str = String::new();
31020 for expr in &e.expressions {
31021 match expr {
31022 Expression::JSONPathRoot(_) => {
31023 path_str.push('$');
31024 }
31025 Expression::JSONPathKey(k) => {
31026 if let Expression::Literal(lit) = k.this.as_ref() {
31028 if let crate::expressions::Literal::String(s) = lit.as_ref() {
31029 path_str.push('.');
31030 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
31032 if needs_quoting {
31033 path_str.push('"');
31034 path_str.push_str(s);
31035 path_str.push('"');
31036 } else {
31037 path_str.push_str(s);
31038 }
31039 }
31040 }
31041 }
31042 Expression::JSONPathSubscript(s) => {
31043 if let Expression::Literal(lit) = s.this.as_ref() {
31045 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
31046 path_str.push('[');
31047 path_str.push_str(n);
31048 path_str.push(']');
31049 }
31050 }
31051 }
31052 _ => {
31053 let mut temp_gen = Self::with_arc_config(self.config.clone());
31055 temp_gen.generate_expression(expr)?;
31056 path_str.push_str(&temp_gen.output);
31057 }
31058 }
31059 }
31060 self.write("'");
31062 self.write(&path_str);
31063 self.write("'");
31064 Ok(())
31065 }
31066
31067 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
31068 self.write("?(");
31070 self.generate_expression(&e.this)?;
31071 self.write(")");
31072 Ok(())
31073 }
31074
31075 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
31076 self.write(".");
31078 self.generate_expression(&e.this)?;
31079 Ok(())
31080 }
31081
31082 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
31083 self.write("..");
31085 if let Some(this) = &e.this {
31086 self.generate_expression(this)?;
31087 }
31088 Ok(())
31089 }
31090
31091 fn generate_json_path_root(&mut self) -> Result<()> {
31092 self.write("$");
31094 Ok(())
31095 }
31096
31097 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
31098 self.write("(");
31100 self.generate_expression(&e.this)?;
31101 self.write(")");
31102 Ok(())
31103 }
31104
31105 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
31106 self.generate_expression(&e.this)?;
31108 Ok(())
31109 }
31110
31111 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
31112 self.write("[");
31114 if let Some(start) = &e.start {
31115 self.generate_expression(start)?;
31116 }
31117 self.write(":");
31118 if let Some(end) = &e.end {
31119 self.generate_expression(end)?;
31120 }
31121 if let Some(step) = &e.step {
31122 self.write(":");
31123 self.generate_expression(step)?;
31124 }
31125 self.write("]");
31126 Ok(())
31127 }
31128
31129 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
31130 self.write("[");
31132 self.generate_expression(&e.this)?;
31133 self.write("]");
31134 Ok(())
31135 }
31136
31137 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
31138 self.write("[");
31140 for (i, expr) in e.expressions.iter().enumerate() {
31141 if i > 0 {
31142 self.write(", ");
31143 }
31144 self.generate_expression(expr)?;
31145 }
31146 self.write("]");
31147 Ok(())
31148 }
31149
31150 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
31151 self.write_keyword("JSON_REMOVE");
31153 self.write("(");
31154 self.generate_expression(&e.this)?;
31155 for expr in &e.expressions {
31156 self.write(", ");
31157 self.generate_expression(expr)?;
31158 }
31159 self.write(")");
31160 Ok(())
31161 }
31162
31163 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
31164 self.write_keyword("COLUMNS");
31167 self.write("(");
31168
31169 if self.config.pretty && !e.expressions.is_empty() {
31170 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
31172 for expr in &e.expressions {
31173 let mut temp_gen = Generator::with_arc_config(self.config.clone());
31174 temp_gen.generate_expression(expr)?;
31175 expr_strings.push(temp_gen.output);
31176 }
31177
31178 if self.too_wide(&expr_strings) {
31180 self.write_newline();
31182 self.indent_level += 1;
31183 for (i, expr_str) in expr_strings.iter().enumerate() {
31184 if i > 0 {
31185 self.write(",");
31186 self.write_newline();
31187 }
31188 self.write_indent();
31189 self.write(expr_str);
31190 }
31191 self.write_newline();
31192 self.indent_level -= 1;
31193 self.write_indent();
31194 } else {
31195 for (i, expr_str) in expr_strings.iter().enumerate() {
31197 if i > 0 {
31198 self.write(", ");
31199 }
31200 self.write(expr_str);
31201 }
31202 }
31203 } else {
31204 for (i, expr) in e.expressions.iter().enumerate() {
31206 if i > 0 {
31207 self.write(", ");
31208 }
31209 self.generate_expression(expr)?;
31210 }
31211 }
31212 self.write(")");
31213 Ok(())
31214 }
31215
31216 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
31217 self.write_keyword("JSON_SET");
31219 self.write("(");
31220 self.generate_expression(&e.this)?;
31221 for expr in &e.expressions {
31222 self.write(", ");
31223 self.generate_expression(expr)?;
31224 }
31225 self.write(")");
31226 Ok(())
31227 }
31228
31229 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
31230 self.write_keyword("JSON_STRIP_NULLS");
31232 self.write("(");
31233 self.generate_expression(&e.this)?;
31234 if let Some(expr) = &e.expression {
31235 self.write(", ");
31236 self.generate_expression(expr)?;
31237 }
31238 self.write(")");
31239 Ok(())
31240 }
31241
31242 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
31243 self.write_keyword("JSON_TABLE");
31245 self.write("(");
31246 self.generate_expression(&e.this)?;
31247 if let Some(path) = &e.path {
31248 self.write(", ");
31249 self.generate_expression(path)?;
31250 }
31251 if let Some(error_handling) = &e.error_handling {
31252 self.write_space();
31253 self.generate_expression(error_handling)?;
31254 }
31255 if let Some(empty_handling) = &e.empty_handling {
31256 self.write_space();
31257 self.generate_expression(empty_handling)?;
31258 }
31259 if let Some(schema) = &e.schema {
31260 self.write_space();
31261 self.generate_expression(schema)?;
31262 }
31263 self.write(")");
31264 Ok(())
31265 }
31266
31267 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
31268 self.write_keyword("JSON_TYPE");
31270 self.write("(");
31271 self.generate_expression(&e.this)?;
31272 self.write(")");
31273 Ok(())
31274 }
31275
31276 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
31277 self.write_keyword("JSON_VALUE");
31279 self.write("(");
31280 self.generate_expression(&e.this)?;
31281 if let Some(path) = &e.path {
31282 self.write(", ");
31283 self.generate_expression(path)?;
31284 }
31285 if let Some(returning) = &e.returning {
31286 self.write_space();
31287 self.write_keyword("RETURNING");
31288 self.write_space();
31289 self.generate_expression(returning)?;
31290 }
31291 if let Some(on_condition) = &e.on_condition {
31292 self.write_space();
31293 self.generate_expression(on_condition)?;
31294 }
31295 self.write(")");
31296 Ok(())
31297 }
31298
31299 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
31300 self.write_keyword("JSON_VALUE_ARRAY");
31302 self.write("(");
31303 self.generate_expression(&e.this)?;
31304 self.write(")");
31305 Ok(())
31306 }
31307
31308 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
31309 self.write_keyword("JAROWINKLER_SIMILARITY");
31311 self.write("(");
31312 self.generate_expression(&e.this)?;
31313 self.write(", ");
31314 self.generate_expression(&e.expression)?;
31315 self.write(")");
31316 Ok(())
31317 }
31318
31319 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
31320 self.generate_expression(&e.this)?;
31322 self.write("(");
31323 for (i, expr) in e.expressions.iter().enumerate() {
31324 if i > 0 {
31325 self.write(", ");
31326 }
31327 self.generate_expression(expr)?;
31328 }
31329 self.write(")");
31330 Ok(())
31331 }
31332
31333 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
31334 if e.no.is_some() {
31336 self.write_keyword("NO ");
31337 }
31338 if let Some(local) = &e.local {
31339 self.generate_expression(local)?;
31340 self.write_space();
31341 }
31342 if e.dual.is_some() {
31343 self.write_keyword("DUAL ");
31344 }
31345 if e.before.is_some() {
31346 self.write_keyword("BEFORE ");
31347 }
31348 if e.after.is_some() {
31349 self.write_keyword("AFTER ");
31350 }
31351 self.write_keyword("JOURNAL");
31352 Ok(())
31353 }
31354
31355 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
31356 self.write_keyword("LANGUAGE");
31358 self.write_space();
31359 self.generate_expression(&e.this)?;
31360 Ok(())
31361 }
31362
31363 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
31364 if e.view.is_some() {
31366 self.write_keyword("LATERAL VIEW");
31368 if e.outer.is_some() {
31369 self.write_space();
31370 self.write_keyword("OUTER");
31371 }
31372 self.write_space();
31373 self.generate_expression(&e.this)?;
31374 if let Some(alias) = &e.alias {
31375 self.write_space();
31376 self.write(alias);
31377 }
31378 } else {
31379 self.write_keyword("LATERAL");
31381 self.write_space();
31382 self.generate_expression(&e.this)?;
31383 if e.ordinality.is_some() {
31384 self.write_space();
31385 self.write_keyword("WITH ORDINALITY");
31386 }
31387 if let Some(alias) = &e.alias {
31388 self.write_space();
31389 self.write_keyword("AS");
31390 self.write_space();
31391 self.write(alias);
31392 if !e.column_aliases.is_empty() {
31393 self.write("(");
31394 for (i, col) in e.column_aliases.iter().enumerate() {
31395 if i > 0 {
31396 self.write(", ");
31397 }
31398 self.write(col);
31399 }
31400 self.write(")");
31401 }
31402 }
31403 }
31404 Ok(())
31405 }
31406
31407 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
31408 self.write_keyword("LIKE");
31410 self.write_space();
31411 self.generate_expression(&e.this)?;
31412 for expr in &e.expressions {
31413 self.write_space();
31414 self.generate_expression(expr)?;
31415 }
31416 Ok(())
31417 }
31418
31419 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
31420 self.write_keyword("LIMIT");
31421 self.write_space();
31422 self.write_limit_expr(&e.this)?;
31423 if e.percent {
31424 self.write_space();
31425 self.write_keyword("PERCENT");
31426 }
31427 for comment in &e.comments {
31429 self.write(" ");
31430 self.write_formatted_comment(comment);
31431 }
31432 Ok(())
31433 }
31434
31435 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
31436 if e.percent.is_some() {
31438 self.write_keyword(" PERCENT");
31439 }
31440 if e.rows.is_some() {
31441 self.write_keyword(" ROWS");
31442 }
31443 if e.with_ties.is_some() {
31444 self.write_keyword(" WITH TIES");
31445 } else if e.rows.is_some() {
31446 self.write_keyword(" ONLY");
31447 }
31448 Ok(())
31449 }
31450
31451 fn generate_list(&mut self, e: &List) -> Result<()> {
31452 use crate::dialects::DialectType;
31453 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
31454
31455 if e.expressions.len() == 1 {
31457 if let Expression::Select(_) = &e.expressions[0] {
31458 self.write_keyword("LIST");
31459 self.write("(");
31460 self.generate_expression(&e.expressions[0])?;
31461 self.write(")");
31462 return Ok(());
31463 }
31464 }
31465
31466 if is_materialize {
31468 self.write_keyword("LIST");
31469 self.write("[");
31470 for (i, expr) in e.expressions.iter().enumerate() {
31471 if i > 0 {
31472 self.write(", ");
31473 }
31474 self.generate_expression(expr)?;
31475 }
31476 self.write("]");
31477 } else {
31478 self.write_keyword("LIST");
31480 self.write("(");
31481 for (i, expr) in e.expressions.iter().enumerate() {
31482 if i > 0 {
31483 self.write(", ");
31484 }
31485 self.generate_expression(expr)?;
31486 }
31487 self.write(")");
31488 }
31489 Ok(())
31490 }
31491
31492 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
31493 if let Expression::Select(_) = &*e.this {
31495 self.write_keyword("MAP");
31496 self.write("(");
31497 self.generate_expression(&e.this)?;
31498 self.write(")");
31499 return Ok(());
31500 }
31501
31502 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
31503
31504 self.write_keyword("MAP");
31506 if is_duckdb {
31507 self.write(" {");
31508 } else {
31509 self.write("[");
31510 }
31511 if let Expression::Struct(s) = &*e.this {
31512 for (i, (_, expr)) in s.fields.iter().enumerate() {
31513 if i > 0 {
31514 self.write(", ");
31515 }
31516 if let Expression::PropertyEQ(op) = expr {
31517 self.generate_expression(&op.left)?;
31518 if is_duckdb {
31519 self.write(": ");
31520 } else {
31521 self.write(" => ");
31522 }
31523 self.generate_expression(&op.right)?;
31524 } else {
31525 self.generate_expression(expr)?;
31526 }
31527 }
31528 }
31529 if is_duckdb {
31530 self.write("}");
31531 } else {
31532 self.write("]");
31533 }
31534 Ok(())
31535 }
31536
31537 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
31538 self.write_keyword("LOCALTIME");
31540 if let Some(precision) = &e.this {
31541 self.write("(");
31542 self.generate_expression(precision)?;
31543 self.write(")");
31544 }
31545 Ok(())
31546 }
31547
31548 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
31549 self.write_keyword("LOCALTIMESTAMP");
31551 if let Some(precision) = &e.this {
31552 self.write("(");
31553 self.generate_expression(precision)?;
31554 self.write(")");
31555 }
31556 Ok(())
31557 }
31558
31559 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
31560 self.write_keyword("LOCATION");
31562 self.write_space();
31563 self.generate_expression(&e.this)?;
31564 Ok(())
31565 }
31566
31567 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
31568 if e.update.is_some() {
31570 if e.key.is_some() {
31571 self.write_keyword("FOR NO KEY UPDATE");
31572 } else {
31573 self.write_keyword("FOR UPDATE");
31574 }
31575 } else {
31576 if e.key.is_some() {
31577 self.write_keyword("FOR KEY SHARE");
31578 } else {
31579 self.write_keyword("FOR SHARE");
31580 }
31581 }
31582 if !e.expressions.is_empty() {
31583 self.write_keyword(" OF ");
31584 for (i, expr) in e.expressions.iter().enumerate() {
31585 if i > 0 {
31586 self.write(", ");
31587 }
31588 self.generate_expression(expr)?;
31589 }
31590 }
31591 if let Some(wait) = &e.wait {
31596 match wait.as_ref() {
31597 Expression::Boolean(b) => {
31598 if b.value {
31599 self.write_keyword(" NOWAIT");
31600 } else {
31601 self.write_keyword(" SKIP LOCKED");
31602 }
31603 }
31604 _ => {
31605 self.write_keyword(" WAIT ");
31607 self.generate_expression(wait)?;
31608 }
31609 }
31610 }
31611 Ok(())
31612 }
31613
31614 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
31615 self.write_keyword("LOCK");
31617 self.write_space();
31618 self.generate_expression(&e.this)?;
31619 Ok(())
31620 }
31621
31622 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
31623 self.write_keyword("LOCKING");
31625 self.write_space();
31626 self.write(&e.kind);
31627 if let Some(this) = &e.this {
31628 self.write_space();
31629 self.generate_expression(this)?;
31630 }
31631 if let Some(for_or_in) = &e.for_or_in {
31632 self.write_space();
31633 self.generate_expression(for_or_in)?;
31634 }
31635 if let Some(lock_type) = &e.lock_type {
31636 self.write_space();
31637 self.generate_expression(lock_type)?;
31638 }
31639 if e.override_.is_some() {
31640 self.write_keyword(" OVERRIDE");
31641 }
31642 Ok(())
31643 }
31644
31645 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
31646 self.generate_expression(&e.this)?;
31648 self.write_space();
31649 self.generate_expression(&e.expression)?;
31650 Ok(())
31651 }
31652
31653 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
31654 if e.no.is_some() {
31656 self.write_keyword("NO ");
31657 }
31658 self.write_keyword("LOG");
31659 Ok(())
31660 }
31661
31662 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
31663 self.write_keyword("MD5");
31665 self.write("(");
31666 self.generate_expression(&e.this)?;
31667 for expr in &e.expressions {
31668 self.write(", ");
31669 self.generate_expression(expr)?;
31670 }
31671 self.write(")");
31672 Ok(())
31673 }
31674
31675 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
31676 self.write_keyword("ML.FORECAST");
31678 self.write("(");
31679 self.generate_expression(&e.this)?;
31680 if let Some(expression) = &e.expression {
31681 self.write(", ");
31682 self.generate_expression(expression)?;
31683 }
31684 if let Some(params) = &e.params_struct {
31685 self.write(", ");
31686 self.generate_expression(params)?;
31687 }
31688 self.write(")");
31689 Ok(())
31690 }
31691
31692 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
31693 self.write_keyword("ML.TRANSLATE");
31695 self.write("(");
31696 self.generate_expression(&e.this)?;
31697 self.write(", ");
31698 self.generate_expression(&e.expression)?;
31699 if let Some(params) = &e.params_struct {
31700 self.write(", ");
31701 self.generate_expression(params)?;
31702 }
31703 self.write(")");
31704 Ok(())
31705 }
31706
31707 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
31708 self.write_keyword("MAKE_INTERVAL");
31710 self.write("(");
31711 let mut first = true;
31712 if let Some(year) = &e.year {
31713 self.write("years => ");
31714 self.generate_expression(year)?;
31715 first = false;
31716 }
31717 if let Some(month) = &e.month {
31718 if !first {
31719 self.write(", ");
31720 }
31721 self.write("months => ");
31722 self.generate_expression(month)?;
31723 first = false;
31724 }
31725 if let Some(week) = &e.week {
31726 if !first {
31727 self.write(", ");
31728 }
31729 self.write("weeks => ");
31730 self.generate_expression(week)?;
31731 first = false;
31732 }
31733 if let Some(day) = &e.day {
31734 if !first {
31735 self.write(", ");
31736 }
31737 self.write("days => ");
31738 self.generate_expression(day)?;
31739 first = false;
31740 }
31741 if let Some(hour) = &e.hour {
31742 if !first {
31743 self.write(", ");
31744 }
31745 self.write("hours => ");
31746 self.generate_expression(hour)?;
31747 first = false;
31748 }
31749 if let Some(minute) = &e.minute {
31750 if !first {
31751 self.write(", ");
31752 }
31753 self.write("mins => ");
31754 self.generate_expression(minute)?;
31755 first = false;
31756 }
31757 if let Some(second) = &e.second {
31758 if !first {
31759 self.write(", ");
31760 }
31761 self.write("secs => ");
31762 self.generate_expression(second)?;
31763 }
31764 self.write(")");
31765 Ok(())
31766 }
31767
31768 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
31769 self.write_keyword("MANHATTAN_DISTANCE");
31771 self.write("(");
31772 self.generate_expression(&e.this)?;
31773 self.write(", ");
31774 self.generate_expression(&e.expression)?;
31775 self.write(")");
31776 Ok(())
31777 }
31778
31779 fn generate_map(&mut self, e: &Map) -> Result<()> {
31780 self.write_keyword("MAP");
31782 self.write("(");
31783 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
31784 if i > 0 {
31785 self.write(", ");
31786 }
31787 self.generate_expression(key)?;
31788 self.write(", ");
31789 self.generate_expression(value)?;
31790 }
31791 self.write(")");
31792 Ok(())
31793 }
31794
31795 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
31796 self.write_keyword("MAP_CAT");
31798 self.write("(");
31799 self.generate_expression(&e.this)?;
31800 self.write(", ");
31801 self.generate_expression(&e.expression)?;
31802 self.write(")");
31803 Ok(())
31804 }
31805
31806 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
31807 self.write_keyword("MAP_DELETE");
31809 self.write("(");
31810 self.generate_expression(&e.this)?;
31811 for expr in &e.expressions {
31812 self.write(", ");
31813 self.generate_expression(expr)?;
31814 }
31815 self.write(")");
31816 Ok(())
31817 }
31818
31819 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
31820 self.write_keyword("MAP_INSERT");
31822 self.write("(");
31823 self.generate_expression(&e.this)?;
31824 if let Some(key) = &e.key {
31825 self.write(", ");
31826 self.generate_expression(key)?;
31827 }
31828 if let Some(value) = &e.value {
31829 self.write(", ");
31830 self.generate_expression(value)?;
31831 }
31832 if let Some(update_flag) = &e.update_flag {
31833 self.write(", ");
31834 self.generate_expression(update_flag)?;
31835 }
31836 self.write(")");
31837 Ok(())
31838 }
31839
31840 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
31841 self.write_keyword("MAP_PICK");
31843 self.write("(");
31844 self.generate_expression(&e.this)?;
31845 for expr in &e.expressions {
31846 self.write(", ");
31847 self.generate_expression(expr)?;
31848 }
31849 self.write(")");
31850 Ok(())
31851 }
31852
31853 fn generate_masking_policy_column_constraint(
31854 &mut self,
31855 e: &MaskingPolicyColumnConstraint,
31856 ) -> Result<()> {
31857 self.write_keyword("MASKING POLICY");
31859 self.write_space();
31860 self.generate_expression(&e.this)?;
31861 if !e.expressions.is_empty() {
31862 self.write_keyword(" USING");
31863 self.write(" (");
31864 for (i, expr) in e.expressions.iter().enumerate() {
31865 if i > 0 {
31866 self.write(", ");
31867 }
31868 self.generate_expression(expr)?;
31869 }
31870 self.write(")");
31871 }
31872 Ok(())
31873 }
31874
31875 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
31876 if matches!(
31877 self.config.dialect,
31878 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31879 ) {
31880 if e.expressions.len() > 1 {
31881 self.write("(");
31882 }
31883 for (i, expr) in e.expressions.iter().enumerate() {
31884 if i > 0 {
31885 self.write_keyword(" OR ");
31886 }
31887 self.generate_expression(expr)?;
31888 self.write_space();
31889 self.write("@@");
31890 self.write_space();
31891 self.generate_expression(&e.this)?;
31892 }
31893 if e.expressions.len() > 1 {
31894 self.write(")");
31895 }
31896 return Ok(());
31897 }
31898
31899 self.write_keyword("MATCH");
31901 self.write("(");
31902 for (i, expr) in e.expressions.iter().enumerate() {
31903 if i > 0 {
31904 self.write(", ");
31905 }
31906 self.generate_expression(expr)?;
31907 }
31908 self.write(")");
31909 self.write_keyword(" AGAINST");
31910 self.write("(");
31911 self.generate_expression(&e.this)?;
31912 if let Some(modifier) = &e.modifier {
31913 self.write_space();
31914 self.generate_expression(modifier)?;
31915 }
31916 self.write(")");
31917 Ok(())
31918 }
31919
31920 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
31921 if let Some(window_frame) = &e.window_frame {
31923 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
31924 self.write_space();
31925 }
31926 self.generate_expression(&e.this)?;
31927 Ok(())
31928 }
31929
31930 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
31931 self.write_keyword("MATERIALIZED");
31933 if let Some(this) = &e.this {
31934 self.write_space();
31935 self.generate_expression(this)?;
31936 }
31937 Ok(())
31938 }
31939
31940 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
31941 if let Some(with_) = &e.with_ {
31944 if let Expression::With(with_clause) = with_.as_ref() {
31945 self.generate_with(with_clause)?;
31946 self.write_space();
31947 } else {
31948 self.generate_expression(with_)?;
31949 self.write_space();
31950 }
31951 }
31952 self.write_keyword("MERGE INTO");
31953 self.write_space();
31954 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
31955 if let Expression::Alias(alias) = e.this.as_ref() {
31956 self.generate_expression(&alias.this)?;
31957 self.write_space();
31958 self.generate_identifier(&alias.alias)?;
31959 } else {
31960 self.generate_expression(&e.this)?;
31961 }
31962 } else {
31963 self.generate_expression(&e.this)?;
31964 }
31965
31966 if self.config.pretty {
31968 self.write_newline();
31969 self.write_indent();
31970 } else {
31971 self.write_space();
31972 }
31973 self.write_keyword("USING");
31974 self.write_space();
31975 self.generate_expression(&e.using)?;
31976
31977 if let Some(on) = &e.on {
31979 if self.config.pretty {
31980 self.write_newline();
31981 self.write_indent();
31982 } else {
31983 self.write_space();
31984 }
31985 self.write_keyword("ON");
31986 self.write_space();
31987 self.generate_expression(on)?;
31988 }
31989 if let Some(using_cond) = &e.using_cond {
31991 self.write_space();
31992 self.write_keyword("USING");
31993 self.write_space();
31994 self.write("(");
31995 if let Expression::Tuple(tuple) = using_cond.as_ref() {
31997 for (i, col) in tuple.expressions.iter().enumerate() {
31998 if i > 0 {
31999 self.write(", ");
32000 }
32001 self.generate_expression(col)?;
32002 }
32003 } else {
32004 self.generate_expression(using_cond)?;
32005 }
32006 self.write(")");
32007 }
32008 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
32010 if matches!(
32011 self.config.dialect,
32012 Some(crate::DialectType::PostgreSQL)
32013 | Some(crate::DialectType::Redshift)
32014 | Some(crate::DialectType::Trino)
32015 | Some(crate::DialectType::Presto)
32016 | Some(crate::DialectType::Athena)
32017 ) {
32018 let mut names = Vec::new();
32019 match e.this.as_ref() {
32020 Expression::Alias(a) => {
32021 if let Expression::Table(t) = &a.this {
32023 names.push(t.name.name.clone());
32024 } else if let Expression::Identifier(id) = &a.this {
32025 names.push(id.name.clone());
32026 }
32027 names.push(a.alias.name.clone());
32028 }
32029 Expression::Table(t) => {
32030 names.push(t.name.name.clone());
32031 }
32032 Expression::Identifier(id) => {
32033 names.push(id.name.clone());
32034 }
32035 _ => {}
32036 }
32037 self.merge_strip_qualifiers = names;
32038 }
32039
32040 if let Some(whens) = &e.whens {
32042 if self.config.pretty {
32043 self.write_newline();
32044 self.write_indent();
32045 } else {
32046 self.write_space();
32047 }
32048 self.generate_expression(whens)?;
32049 }
32050
32051 self.merge_strip_qualifiers = saved_merge_strip;
32053
32054 if let Some(returning) = &e.returning {
32056 if self.config.pretty {
32057 self.write_newline();
32058 self.write_indent();
32059 } else {
32060 self.write_space();
32061 }
32062 self.generate_expression(returning)?;
32063 }
32064 Ok(())
32065 }
32066
32067 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
32068 if e.no.is_some() {
32070 self.write_keyword("NO MERGEBLOCKRATIO");
32071 } else if e.default.is_some() {
32072 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
32073 } else {
32074 self.write_keyword("MERGEBLOCKRATIO");
32075 self.write("=");
32076 if let Some(this) = &e.this {
32077 self.generate_expression(this)?;
32078 }
32079 if e.percent.is_some() {
32080 self.write_keyword(" PERCENT");
32081 }
32082 }
32083 Ok(())
32084 }
32085
32086 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
32087 self.write_keyword("TTL");
32089 let pretty_clickhouse = self.config.pretty
32090 && matches!(
32091 self.config.dialect,
32092 Some(crate::dialects::DialectType::ClickHouse)
32093 );
32094
32095 if pretty_clickhouse {
32096 self.write_newline();
32097 self.indent_level += 1;
32098 for (i, expr) in e.expressions.iter().enumerate() {
32099 if i > 0 {
32100 self.write(",");
32101 self.write_newline();
32102 }
32103 self.write_indent();
32104 self.generate_expression(expr)?;
32105 }
32106 self.indent_level -= 1;
32107 } else {
32108 self.write_space();
32109 for (i, expr) in e.expressions.iter().enumerate() {
32110 if i > 0 {
32111 self.write(", ");
32112 }
32113 self.generate_expression(expr)?;
32114 }
32115 }
32116
32117 if let Some(where_) = &e.where_ {
32118 if pretty_clickhouse {
32119 self.write_newline();
32120 if let Expression::Where(w) = where_.as_ref() {
32121 self.write_indent();
32122 self.write_keyword("WHERE");
32123 self.write_newline();
32124 self.indent_level += 1;
32125 self.write_indent();
32126 self.generate_expression(&w.this)?;
32127 self.indent_level -= 1;
32128 } else {
32129 self.write_indent();
32130 self.generate_expression(where_)?;
32131 }
32132 } else {
32133 self.write_space();
32134 self.generate_expression(where_)?;
32135 }
32136 }
32137 if let Some(group) = &e.group {
32138 if pretty_clickhouse {
32139 self.write_newline();
32140 if let Expression::Group(g) = group.as_ref() {
32141 self.write_indent();
32142 self.write_keyword("GROUP BY");
32143 self.write_newline();
32144 self.indent_level += 1;
32145 for (i, expr) in g.expressions.iter().enumerate() {
32146 if i > 0 {
32147 self.write(",");
32148 self.write_newline();
32149 }
32150 self.write_indent();
32151 self.generate_expression(expr)?;
32152 }
32153 self.indent_level -= 1;
32154 } else {
32155 self.write_indent();
32156 self.generate_expression(group)?;
32157 }
32158 } else {
32159 self.write_space();
32160 self.generate_expression(group)?;
32161 }
32162 }
32163 if let Some(aggregates) = &e.aggregates {
32164 if pretty_clickhouse {
32165 self.write_newline();
32166 self.write_indent();
32167 self.write_keyword("SET");
32168 self.write_newline();
32169 self.indent_level += 1;
32170 if let Expression::Tuple(t) = aggregates.as_ref() {
32171 for (i, agg) in t.expressions.iter().enumerate() {
32172 if i > 0 {
32173 self.write(",");
32174 self.write_newline();
32175 }
32176 self.write_indent();
32177 self.generate_expression(agg)?;
32178 }
32179 } else {
32180 self.write_indent();
32181 self.generate_expression(aggregates)?;
32182 }
32183 self.indent_level -= 1;
32184 } else {
32185 self.write_space();
32186 self.write_keyword("SET");
32187 self.write_space();
32188 if let Expression::Tuple(t) = aggregates.as_ref() {
32189 for (i, agg) in t.expressions.iter().enumerate() {
32190 if i > 0 {
32191 self.write(", ");
32192 }
32193 self.generate_expression(agg)?;
32194 }
32195 } else {
32196 self.generate_expression(aggregates)?;
32197 }
32198 }
32199 }
32200 Ok(())
32201 }
32202
32203 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
32204 self.generate_expression(&e.this)?;
32206 if e.delete.is_some() {
32207 self.write_keyword(" DELETE");
32208 }
32209 if let Some(recompress) = &e.recompress {
32210 self.write_keyword(" RECOMPRESS ");
32211 self.generate_expression(recompress)?;
32212 }
32213 if let Some(to_disk) = &e.to_disk {
32214 self.write_keyword(" TO DISK ");
32215 self.generate_expression(to_disk)?;
32216 }
32217 if let Some(to_volume) = &e.to_volume {
32218 self.write_keyword(" TO VOLUME ");
32219 self.generate_expression(to_volume)?;
32220 }
32221 Ok(())
32222 }
32223
32224 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
32225 self.write_keyword("MINHASH");
32227 self.write("(");
32228 self.generate_expression(&e.this)?;
32229 for expr in &e.expressions {
32230 self.write(", ");
32231 self.generate_expression(expr)?;
32232 }
32233 self.write(")");
32234 Ok(())
32235 }
32236
32237 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
32238 self.generate_expression(&e.this)?;
32240 self.write("!");
32241 self.generate_expression(&e.expression)?;
32242 Ok(())
32243 }
32244
32245 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
32246 self.write_keyword("MONTHNAME");
32248 self.write("(");
32249 self.generate_expression(&e.this)?;
32250 self.write(")");
32251 Ok(())
32252 }
32253
32254 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
32255 for comment in &e.leading_comments {
32257 self.write_formatted_comment(comment);
32258 if self.config.pretty {
32259 self.write_newline();
32260 self.write_indent();
32261 } else {
32262 self.write_space();
32263 }
32264 }
32265 self.write_keyword("INSERT");
32267 if e.overwrite {
32268 self.write_space();
32269 self.write_keyword("OVERWRITE");
32270 }
32271 self.write_space();
32272 self.write(&e.kind);
32273 if self.config.pretty {
32274 self.indent_level += 1;
32275 for expr in &e.expressions {
32276 self.write_newline();
32277 self.write_indent();
32278 self.generate_expression(expr)?;
32279 }
32280 self.indent_level -= 1;
32281 } else {
32282 for expr in &e.expressions {
32283 self.write_space();
32284 self.generate_expression(expr)?;
32285 }
32286 }
32287 if let Some(source) = &e.source {
32288 if self.config.pretty {
32289 self.write_newline();
32290 self.write_indent();
32291 } else {
32292 self.write_space();
32293 }
32294 self.generate_expression(source)?;
32295 }
32296 Ok(())
32297 }
32298
32299 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
32300 self.write_keyword("NEXT VALUE FOR");
32302 self.write_space();
32303 self.generate_expression(&e.this)?;
32304 if let Some(order) = &e.order {
32305 self.write_space();
32306 self.write_keyword("OVER");
32307 self.write(" (");
32308 self.generate_expression(order)?;
32309 self.write(")");
32310 }
32311 Ok(())
32312 }
32313
32314 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
32315 self.write_keyword("NORMAL");
32317 self.write("(");
32318 self.generate_expression(&e.this)?;
32319 if let Some(stddev) = &e.stddev {
32320 self.write(", ");
32321 self.generate_expression(stddev)?;
32322 }
32323 if let Some(gen) = &e.gen {
32324 self.write(", ");
32325 self.generate_expression(gen)?;
32326 }
32327 self.write(")");
32328 Ok(())
32329 }
32330
32331 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
32332 if e.is_casefold.is_some() {
32334 self.write_keyword("NORMALIZE_AND_CASEFOLD");
32335 } else {
32336 self.write_keyword("NORMALIZE");
32337 }
32338 self.write("(");
32339 self.generate_expression(&e.this)?;
32340 if let Some(form) = &e.form {
32341 self.write(", ");
32342 self.generate_expression(form)?;
32343 }
32344 self.write(")");
32345 Ok(())
32346 }
32347
32348 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
32349 if e.allow_null.is_none() {
32351 self.write_keyword("NOT ");
32352 }
32353 self.write_keyword("NULL");
32354 Ok(())
32355 }
32356
32357 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
32358 self.write_keyword("NULLIF");
32360 self.write("(");
32361 self.generate_expression(&e.this)?;
32362 self.write(", ");
32363 self.generate_expression(&e.expression)?;
32364 self.write(")");
32365 Ok(())
32366 }
32367
32368 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
32369 self.write_keyword("FORMAT");
32371 self.write("(");
32372 self.generate_expression(&e.this)?;
32373 self.write(", '");
32374 self.write(&e.format);
32375 self.write("'");
32376 if let Some(culture) = &e.culture {
32377 self.write(", ");
32378 self.generate_expression(culture)?;
32379 }
32380 self.write(")");
32381 Ok(())
32382 }
32383
32384 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
32385 self.write_keyword("OBJECT_AGG");
32387 self.write("(");
32388 self.generate_expression(&e.this)?;
32389 self.write(", ");
32390 self.generate_expression(&e.expression)?;
32391 self.write(")");
32392 Ok(())
32393 }
32394
32395 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
32396 self.generate_expression(&e.this)?;
32398 Ok(())
32399 }
32400
32401 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
32402 self.write_keyword("OBJECT_INSERT");
32404 self.write("(");
32405 self.generate_expression(&e.this)?;
32406 if let Some(key) = &e.key {
32407 self.write(", ");
32408 self.generate_expression(key)?;
32409 }
32410 if let Some(value) = &e.value {
32411 self.write(", ");
32412 self.generate_expression(value)?;
32413 }
32414 if let Some(update_flag) = &e.update_flag {
32415 self.write(", ");
32416 self.generate_expression(update_flag)?;
32417 }
32418 self.write(")");
32419 Ok(())
32420 }
32421
32422 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
32423 self.write_keyword("OFFSET");
32425 self.write_space();
32426 self.generate_expression(&e.this)?;
32427 if e.rows == Some(true)
32429 && matches!(
32430 self.config.dialect,
32431 Some(crate::dialects::DialectType::TSQL)
32432 | Some(crate::dialects::DialectType::Oracle)
32433 )
32434 {
32435 self.write_space();
32436 self.write_keyword("ROWS");
32437 }
32438 Ok(())
32439 }
32440
32441 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
32442 self.write_keyword("QUALIFY");
32444 self.write_space();
32445 self.generate_expression(&e.this)?;
32446 Ok(())
32447 }
32448
32449 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
32450 self.write_keyword("ON CLUSTER");
32452 self.write_space();
32453 self.generate_expression(&e.this)?;
32454 Ok(())
32455 }
32456
32457 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
32458 self.write_keyword("ON COMMIT");
32460 if e.delete.is_some() {
32461 self.write_keyword(" DELETE ROWS");
32462 } else {
32463 self.write_keyword(" PRESERVE ROWS");
32464 }
32465 Ok(())
32466 }
32467
32468 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
32469 if let Some(empty) = &e.empty {
32471 self.generate_expression(empty)?;
32472 self.write_keyword(" ON EMPTY");
32473 }
32474 if let Some(error) = &e.error {
32475 if e.empty.is_some() {
32476 self.write_space();
32477 }
32478 self.generate_expression(error)?;
32479 self.write_keyword(" ON ERROR");
32480 }
32481 if let Some(null) = &e.null {
32482 if e.empty.is_some() || e.error.is_some() {
32483 self.write_space();
32484 }
32485 self.generate_expression(null)?;
32486 self.write_keyword(" ON NULL");
32487 }
32488 Ok(())
32489 }
32490
32491 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
32492 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
32494 return Ok(());
32495 }
32496 if e.duplicate.is_some() {
32498 self.write_keyword("ON DUPLICATE KEY UPDATE");
32500 for (i, expr) in e.expressions.iter().enumerate() {
32501 if i > 0 {
32502 self.write(",");
32503 }
32504 self.write_space();
32505 self.generate_expression(expr)?;
32506 }
32507 return Ok(());
32508 } else {
32509 self.write_keyword("ON CONFLICT");
32510 }
32511 if let Some(constraint) = &e.constraint {
32512 self.write_keyword(" ON CONSTRAINT ");
32513 self.generate_expression(constraint)?;
32514 }
32515 if let Some(conflict_keys) = &e.conflict_keys {
32516 if let Expression::Tuple(t) = conflict_keys.as_ref() {
32518 self.write("(");
32519 for (i, expr) in t.expressions.iter().enumerate() {
32520 if i > 0 {
32521 self.write(", ");
32522 }
32523 self.generate_expression(expr)?;
32524 }
32525 self.write(")");
32526 } else {
32527 self.write("(");
32528 self.generate_expression(conflict_keys)?;
32529 self.write(")");
32530 }
32531 }
32532 if let Some(index_predicate) = &e.index_predicate {
32533 self.write_keyword(" WHERE ");
32534 self.generate_expression(index_predicate)?;
32535 }
32536 if let Some(action) = &e.action {
32537 if let Expression::Identifier(id) = action.as_ref() {
32539 if id.name.eq_ignore_ascii_case("NOTHING") {
32540 self.write_keyword(" DO NOTHING");
32541 } else {
32542 self.write_keyword(" DO ");
32543 self.generate_expression(action)?;
32544 }
32545 } else if let Expression::Tuple(t) = action.as_ref() {
32546 self.write_keyword(" DO UPDATE SET ");
32548 for (i, expr) in t.expressions.iter().enumerate() {
32549 if i > 0 {
32550 self.write(", ");
32551 }
32552 self.generate_expression(expr)?;
32553 }
32554 } else {
32555 self.write_keyword(" DO ");
32556 self.generate_expression(action)?;
32557 }
32558 }
32559 if let Some(where_) = &e.where_ {
32561 self.write_keyword(" WHERE ");
32562 self.generate_expression(where_)?;
32563 }
32564 Ok(())
32565 }
32566
32567 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
32568 self.write_keyword("ON");
32570 self.write_space();
32571 self.generate_expression(&e.this)?;
32572 Ok(())
32573 }
32574
32575 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
32576 self.generate_expression(&e.this)?;
32578 self.write_space();
32579 self.generate_expression(&e.expression)?;
32580 Ok(())
32581 }
32582
32583 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
32584 self.write_keyword("OPENJSON");
32586 self.write("(");
32587 self.generate_expression(&e.this)?;
32588 if let Some(path) = &e.path {
32589 self.write(", ");
32590 self.generate_expression(path)?;
32591 }
32592 self.write(")");
32593 if !e.expressions.is_empty() {
32594 self.write_keyword(" WITH");
32595 if self.config.pretty {
32596 self.write(" (\n");
32597 self.indent_level += 2;
32598 for (i, expr) in e.expressions.iter().enumerate() {
32599 if i > 0 {
32600 self.write(",\n");
32601 }
32602 self.write_indent();
32603 self.generate_expression(expr)?;
32604 }
32605 self.write("\n");
32606 self.indent_level -= 2;
32607 self.write(")");
32608 } else {
32609 self.write(" (");
32610 for (i, expr) in e.expressions.iter().enumerate() {
32611 if i > 0 {
32612 self.write(", ");
32613 }
32614 self.generate_expression(expr)?;
32615 }
32616 self.write(")");
32617 }
32618 }
32619 Ok(())
32620 }
32621
32622 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
32623 self.generate_expression(&e.this)?;
32625 self.write_space();
32626 if let Some(ref dt) = e.data_type {
32628 self.generate_data_type(dt)?;
32629 } else if !e.kind.is_empty() {
32630 self.write(&e.kind);
32631 }
32632 if let Some(path) = &e.path {
32633 self.write_space();
32634 self.generate_expression(path)?;
32635 }
32636 if e.as_json.is_some() {
32637 self.write_keyword(" AS JSON");
32638 }
32639 Ok(())
32640 }
32641
32642 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
32643 self.generate_expression(&e.this)?;
32645 self.write_space();
32646 if let Some(op) = &e.operator {
32647 self.write_keyword("OPERATOR");
32648 self.write("(");
32649 self.generate_expression(op)?;
32650 self.write(")");
32651 }
32652 for comment in &e.comments {
32654 self.write_space();
32655 self.write_formatted_comment(comment);
32656 }
32657 self.write_space();
32658 self.generate_expression(&e.expression)?;
32659 Ok(())
32660 }
32661
32662 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
32663 self.write_keyword("ORDER BY");
32665 let pretty_clickhouse_single_paren = self.config.pretty
32666 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
32667 && e.expressions.len() == 1
32668 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
32669 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
32670 && e.expressions.len() == 1
32671 && matches!(e.expressions[0].this, Expression::Tuple(_))
32672 && !e.expressions[0].desc
32673 && e.expressions[0].nulls_first.is_none();
32674
32675 if pretty_clickhouse_single_paren {
32676 self.write_space();
32677 if let Expression::Paren(p) = &e.expressions[0].this {
32678 self.write("(");
32679 self.write_newline();
32680 self.indent_level += 1;
32681 self.write_indent();
32682 self.generate_expression(&p.this)?;
32683 self.indent_level -= 1;
32684 self.write_newline();
32685 self.write(")");
32686 }
32687 return Ok(());
32688 }
32689
32690 if clickhouse_single_tuple {
32691 self.write_space();
32692 if let Expression::Tuple(t) = &e.expressions[0].this {
32693 self.write("(");
32694 for (i, expr) in t.expressions.iter().enumerate() {
32695 if i > 0 {
32696 self.write(", ");
32697 }
32698 self.generate_expression(expr)?;
32699 }
32700 self.write(")");
32701 }
32702 return Ok(());
32703 }
32704
32705 self.write_space();
32706 for (i, ordered) in e.expressions.iter().enumerate() {
32707 if i > 0 {
32708 self.write(", ");
32709 }
32710 self.generate_expression(&ordered.this)?;
32711 if ordered.desc {
32712 self.write_space();
32713 self.write_keyword("DESC");
32714 } else if ordered.explicit_asc {
32715 self.write_space();
32716 self.write_keyword("ASC");
32717 }
32718 if let Some(nulls_first) = ordered.nulls_first {
32719 let skip_nulls_last =
32721 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
32722 if !skip_nulls_last {
32723 self.write_space();
32724 self.write_keyword("NULLS");
32725 self.write_space();
32726 if nulls_first {
32727 self.write_keyword("FIRST");
32728 } else {
32729 self.write_keyword("LAST");
32730 }
32731 }
32732 }
32733 }
32734 Ok(())
32735 }
32736
32737 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
32738 self.write_keyword("OUTPUT");
32740 self.write("(");
32741 if self.config.pretty {
32742 self.indent_level += 1;
32743 self.write_newline();
32744 self.write_indent();
32745 self.generate_expression(&e.this)?;
32746 self.indent_level -= 1;
32747 self.write_newline();
32748 } else {
32749 self.generate_expression(&e.this)?;
32750 }
32751 self.write(")");
32752 Ok(())
32753 }
32754
32755 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
32756 self.write_keyword("TRUNCATE");
32758 if let Some(this) = &e.this {
32759 self.write_space();
32760 self.generate_expression(this)?;
32761 }
32762 if e.with_count.is_some() {
32763 self.write_keyword(" WITH COUNT");
32764 } else {
32765 self.write_keyword(" WITHOUT COUNT");
32766 }
32767 Ok(())
32768 }
32769
32770 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
32771 self.generate_expression(&e.this)?;
32773 self.write("(");
32774 for (i, expr) in e.expressions.iter().enumerate() {
32775 if i > 0 {
32776 self.write(", ");
32777 }
32778 self.generate_expression(expr)?;
32779 }
32780 self.write(")(");
32781 for (i, param) in e.params.iter().enumerate() {
32782 if i > 0 {
32783 self.write(", ");
32784 }
32785 self.generate_expression(param)?;
32786 }
32787 self.write(")");
32788 Ok(())
32789 }
32790
32791 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
32792 self.write_keyword("PARSE_DATETIME");
32794 self.write("(");
32795 if let Some(format) = &e.format {
32796 self.write("'");
32797 self.write(format);
32798 self.write("', ");
32799 }
32800 self.generate_expression(&e.this)?;
32801 if let Some(zone) = &e.zone {
32802 self.write(", ");
32803 self.generate_expression(zone)?;
32804 }
32805 self.write(")");
32806 Ok(())
32807 }
32808
32809 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
32810 self.write_keyword("PARSE_IP");
32812 self.write("(");
32813 self.generate_expression(&e.this)?;
32814 if let Some(type_) = &e.type_ {
32815 self.write(", ");
32816 self.generate_expression(type_)?;
32817 }
32818 if let Some(permissive) = &e.permissive {
32819 self.write(", ");
32820 self.generate_expression(permissive)?;
32821 }
32822 self.write(")");
32823 Ok(())
32824 }
32825
32826 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
32827 self.write_keyword("PARSE_JSON");
32829 self.write("(");
32830 self.generate_expression(&e.this)?;
32831 if let Some(expression) = &e.expression {
32832 self.write(", ");
32833 self.generate_expression(expression)?;
32834 }
32835 self.write(")");
32836 Ok(())
32837 }
32838
32839 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
32840 self.write_keyword("PARSE_TIME");
32842 self.write("(");
32843 self.write(&format!("'{}'", e.format));
32844 self.write(", ");
32845 self.generate_expression(&e.this)?;
32846 self.write(")");
32847 Ok(())
32848 }
32849
32850 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
32851 self.write_keyword("PARSE_URL");
32853 self.write("(");
32854 self.generate_expression(&e.this)?;
32855 if let Some(part) = &e.part_to_extract {
32856 self.write(", ");
32857 self.generate_expression(part)?;
32858 }
32859 if let Some(key) = &e.key {
32860 self.write(", ");
32861 self.generate_expression(key)?;
32862 }
32863 if let Some(permissive) = &e.permissive {
32864 self.write(", ");
32865 self.generate_expression(permissive)?;
32866 }
32867 self.write(")");
32868 Ok(())
32869 }
32870
32871 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
32872 if e.subpartition {
32874 self.write_keyword("SUBPARTITION");
32875 } else {
32876 self.write_keyword("PARTITION");
32877 }
32878 self.write("(");
32879 for (i, expr) in e.expressions.iter().enumerate() {
32880 if i > 0 {
32881 self.write(", ");
32882 }
32883 self.generate_expression(expr)?;
32884 }
32885 self.write(")");
32886 Ok(())
32887 }
32888
32889 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
32890 if let Some(this) = &e.this {
32892 if let Some(expression) = &e.expression {
32893 self.write_keyword("WITH");
32895 self.write(" (");
32896 self.write_keyword("MODULUS");
32897 self.write_space();
32898 self.generate_expression(this)?;
32899 self.write(", ");
32900 self.write_keyword("REMAINDER");
32901 self.write_space();
32902 self.generate_expression(expression)?;
32903 self.write(")");
32904 } else {
32905 self.write_keyword("IN");
32907 self.write(" (");
32908 self.generate_partition_bound_values(this)?;
32909 self.write(")");
32910 }
32911 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
32912 self.write_keyword("FROM");
32914 self.write(" (");
32915 self.generate_partition_bound_values(from)?;
32916 self.write(") ");
32917 self.write_keyword("TO");
32918 self.write(" (");
32919 self.generate_partition_bound_values(to)?;
32920 self.write(")");
32921 }
32922 Ok(())
32923 }
32924
32925 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
32928 if let Expression::Tuple(t) = expr {
32929 for (i, e) in t.expressions.iter().enumerate() {
32930 if i > 0 {
32931 self.write(", ");
32932 }
32933 self.generate_expression(e)?;
32934 }
32935 Ok(())
32936 } else {
32937 self.generate_expression(expr)
32938 }
32939 }
32940
32941 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
32942 self.write_keyword("PARTITION BY LIST");
32944 if let Some(partition_exprs) = &e.partition_expressions {
32945 self.write(" (");
32946 self.generate_doris_partition_expressions(partition_exprs)?;
32948 self.write(")");
32949 }
32950 if let Some(create_exprs) = &e.create_expressions {
32951 self.write(" (");
32952 self.generate_doris_partition_definitions(create_exprs)?;
32954 self.write(")");
32955 }
32956 Ok(())
32957 }
32958
32959 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
32960 self.write_keyword("PARTITION BY RANGE");
32962 if let Some(partition_exprs) = &e.partition_expressions {
32963 self.write(" (");
32964 self.generate_doris_partition_expressions(partition_exprs)?;
32966 self.write(")");
32967 }
32968 if let Some(create_exprs) = &e.create_expressions {
32969 self.write(" (");
32970 self.generate_doris_partition_definitions(create_exprs)?;
32972 self.write(")");
32973 }
32974 Ok(())
32975 }
32976
32977 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
32979 if let Expression::Tuple(t) = expr {
32980 for (i, e) in t.expressions.iter().enumerate() {
32981 if i > 0 {
32982 self.write(", ");
32983 }
32984 self.generate_expression(e)?;
32985 }
32986 } else {
32987 self.generate_expression(expr)?;
32988 }
32989 Ok(())
32990 }
32991
32992 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
32994 match expr {
32995 Expression::Tuple(t) => {
32996 for (i, part) in t.expressions.iter().enumerate() {
32998 if i > 0 {
32999 self.write(", ");
33000 }
33001 if let Expression::Partition(p) = part {
33003 for (j, inner) in p.expressions.iter().enumerate() {
33004 if j > 0 {
33005 self.write(", ");
33006 }
33007 self.generate_expression(inner)?;
33008 }
33009 } else {
33010 self.generate_expression(part)?;
33011 }
33012 }
33013 }
33014 Expression::PartitionByRangePropertyDynamic(_) => {
33015 self.generate_expression(expr)?;
33017 }
33018 _ => {
33019 self.generate_expression(expr)?;
33020 }
33021 }
33022 Ok(())
33023 }
33024
33025 fn generate_partition_by_range_property_dynamic(
33026 &mut self,
33027 e: &PartitionByRangePropertyDynamic,
33028 ) -> Result<()> {
33029 if e.use_start_end {
33030 if let Some(start) = &e.start {
33032 self.write_keyword("START");
33033 self.write(" (");
33034 self.generate_expression(start)?;
33035 self.write(")");
33036 }
33037 if let Some(end) = &e.end {
33038 self.write_space();
33039 self.write_keyword("END");
33040 self.write(" (");
33041 self.generate_expression(end)?;
33042 self.write(")");
33043 }
33044 if let Some(every) = &e.every {
33045 self.write_space();
33046 self.write_keyword("EVERY");
33047 self.write(" (");
33048 self.generate_doris_interval(every)?;
33050 self.write(")");
33051 }
33052 } else {
33053 if let Some(start) = &e.start {
33055 self.write_keyword("FROM");
33056 self.write(" (");
33057 self.generate_expression(start)?;
33058 self.write(")");
33059 }
33060 if let Some(end) = &e.end {
33061 self.write_space();
33062 self.write_keyword("TO");
33063 self.write(" (");
33064 self.generate_expression(end)?;
33065 self.write(")");
33066 }
33067 if let Some(every) = &e.every {
33068 self.write_space();
33069 self.generate_doris_interval(every)?;
33071 }
33072 }
33073 Ok(())
33074 }
33075
33076 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
33078 if let Expression::Interval(interval) = expr {
33079 self.write_keyword("INTERVAL");
33080 if let Some(ref value) = interval.this {
33081 self.write_space();
33082 match value {
33086 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()) => {
33087 if let Literal::String(s) = lit.as_ref() {
33088 self.write(s);
33089 }
33090 }
33091 _ => {
33092 self.generate_expression(value)?;
33093 }
33094 }
33095 }
33096 if let Some(ref unit_spec) = interval.unit {
33097 self.write_space();
33098 self.write_interval_unit_spec(unit_spec)?;
33099 }
33100 Ok(())
33101 } else {
33102 self.generate_expression(expr)
33103 }
33104 }
33105
33106 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
33107 self.write_keyword("TRUNCATE");
33109 self.write("(");
33110 self.generate_expression(&e.expression)?;
33111 self.write(", ");
33112 self.generate_expression(&e.this)?;
33113 self.write(")");
33114 Ok(())
33115 }
33116
33117 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
33118 self.write_keyword("PARTITION");
33120 self.write_space();
33121 self.generate_expression(&e.this)?;
33122 self.write_space();
33123 self.write_keyword("VALUES IN");
33124 self.write(" (");
33125 for (i, expr) in e.expressions.iter().enumerate() {
33126 if i > 0 {
33127 self.write(", ");
33128 }
33129 self.generate_expression(expr)?;
33130 }
33131 self.write(")");
33132 Ok(())
33133 }
33134
33135 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
33136 if e.expressions.is_empty() && e.expression.is_some() {
33139 self.generate_expression(&e.this)?;
33141 self.write_space();
33142 self.write_keyword("TO");
33143 self.write_space();
33144 self.generate_expression(e.expression.as_ref().unwrap())?;
33145 return Ok(());
33146 }
33147
33148 self.write_keyword("PARTITION");
33150 self.write_space();
33151 self.generate_expression(&e.this)?;
33152 self.write_space();
33153
33154 if e.expressions.len() == 1 {
33156 self.write_keyword("VALUES LESS THAN");
33158 self.write(" (");
33159 self.generate_expression(&e.expressions[0])?;
33160 self.write(")");
33161 } else if !e.expressions.is_empty() {
33162 self.write_keyword("VALUES");
33164 self.write(" [");
33165 for (i, expr) in e.expressions.iter().enumerate() {
33166 if i > 0 {
33167 self.write(", ");
33168 }
33169 if let Expression::Tuple(t) = expr {
33171 self.write("(");
33172 for (j, inner) in t.expressions.iter().enumerate() {
33173 if j > 0 {
33174 self.write(", ");
33175 }
33176 self.generate_expression(inner)?;
33177 }
33178 self.write(")");
33179 } else {
33180 self.write("(");
33181 self.generate_expression(expr)?;
33182 self.write(")");
33183 }
33184 }
33185 self.write(")");
33186 }
33187 Ok(())
33188 }
33189
33190 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
33191 self.write_keyword("BUCKET");
33193 self.write("(");
33194 self.generate_expression(&e.this)?;
33195 self.write(", ");
33196 self.generate_expression(&e.expression)?;
33197 self.write(")");
33198 Ok(())
33199 }
33200
33201 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
33202 self.write_keyword("PARTITION BY");
33204 self.write_space();
33205 for (i, expr) in e.expressions.iter().enumerate() {
33206 if i > 0 {
33207 self.write(", ");
33208 }
33209 self.generate_expression(expr)?;
33210 }
33211 Ok(())
33212 }
33213
33214 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
33215 if matches!(
33217 self.config.dialect,
33218 Some(crate::dialects::DialectType::Teradata)
33219 | Some(crate::dialects::DialectType::ClickHouse)
33220 ) {
33221 self.write_keyword("PARTITION BY");
33222 } else {
33223 self.write_keyword("PARTITIONED BY");
33224 }
33225 self.write_space();
33226 if self.config.pretty {
33228 if let Expression::Tuple(ref tuple) = *e.this {
33229 self.write("(");
33230 self.write_newline();
33231 self.indent_level += 1;
33232 for (i, expr) in tuple.expressions.iter().enumerate() {
33233 if i > 0 {
33234 self.write(",");
33235 self.write_newline();
33236 }
33237 self.write_indent();
33238 self.generate_expression(expr)?;
33239 }
33240 self.indent_level -= 1;
33241 self.write_newline();
33242 self.write(")");
33243 } else {
33244 self.generate_expression(&e.this)?;
33245 }
33246 } else {
33247 self.generate_expression(&e.this)?;
33248 }
33249 Ok(())
33250 }
33251
33252 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
33253 self.write_keyword("PARTITION OF");
33255 self.write_space();
33256 self.generate_expression(&e.this)?;
33257 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
33259 self.write_space();
33260 self.write_keyword("FOR VALUES");
33261 self.write_space();
33262 self.generate_expression(&e.expression)?;
33263 } else {
33264 self.write_space();
33265 self.write_keyword("DEFAULT");
33266 }
33267 Ok(())
33268 }
33269
33270 fn generate_period_for_system_time_constraint(
33271 &mut self,
33272 e: &PeriodForSystemTimeConstraint,
33273 ) -> Result<()> {
33274 self.write_keyword("PERIOD FOR SYSTEM_TIME");
33276 self.write(" (");
33277 self.generate_expression(&e.this)?;
33278 self.write(", ");
33279 self.generate_expression(&e.expression)?;
33280 self.write(")");
33281 Ok(())
33282 }
33283
33284 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
33285 self.generate_expression(&e.this)?;
33288 self.write_space();
33289 self.write_keyword("AS");
33290 self.write_space();
33291 if self.config.unpivot_aliases_are_identifiers {
33293 match &e.alias {
33294 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
33295 let Literal::String(s) = lit.as_ref() else {
33296 unreachable!()
33297 };
33298 self.generate_identifier(&Identifier::new(s.clone()))?;
33300 }
33301 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
33302 let Literal::Number(n) = lit.as_ref() else {
33303 unreachable!()
33304 };
33305 let mut id = Identifier::new(n.clone());
33307 id.quoted = true;
33308 self.generate_identifier(&id)?;
33309 }
33310 other => {
33311 self.generate_expression(other)?;
33312 }
33313 }
33314 } else {
33315 self.generate_expression(&e.alias)?;
33316 }
33317 Ok(())
33318 }
33319
33320 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
33321 self.write_keyword("ANY");
33323 if let Some(this) = &e.this {
33324 self.write_space();
33325 self.generate_expression(this)?;
33326 }
33327 Ok(())
33328 }
33329
33330 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
33331 self.write_keyword("ML.PREDICT");
33333 self.write("(");
33334 self.write_keyword("MODEL");
33335 self.write_space();
33336 self.generate_expression(&e.this)?;
33337 self.write(", ");
33338 self.generate_expression(&e.expression)?;
33339 if let Some(params) = &e.params_struct {
33340 self.write(", ");
33341 self.generate_expression(params)?;
33342 }
33343 self.write(")");
33344 Ok(())
33345 }
33346
33347 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
33348 self.write_keyword("PREVIOUS_DAY");
33350 self.write("(");
33351 self.generate_expression(&e.this)?;
33352 self.write(", ");
33353 self.generate_expression(&e.expression)?;
33354 self.write(")");
33355 Ok(())
33356 }
33357
33358 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
33359 self.write_keyword("PRIMARY KEY");
33361 if let Some(name) = &e.this {
33362 self.write_space();
33363 self.generate_expression(name)?;
33364 }
33365 if !e.expressions.is_empty() {
33366 self.write(" (");
33367 for (i, expr) in e.expressions.iter().enumerate() {
33368 if i > 0 {
33369 self.write(", ");
33370 }
33371 self.generate_expression(expr)?;
33372 }
33373 self.write(")");
33374 }
33375 if let Some(include) = &e.include {
33376 self.write_space();
33377 self.generate_expression(include)?;
33378 }
33379 if !e.options.is_empty() {
33380 self.write_space();
33381 for (i, opt) in e.options.iter().enumerate() {
33382 if i > 0 {
33383 self.write_space();
33384 }
33385 self.generate_expression(opt)?;
33386 }
33387 }
33388 Ok(())
33389 }
33390
33391 fn generate_primary_key_column_constraint(
33392 &mut self,
33393 _e: &PrimaryKeyColumnConstraint,
33394 ) -> Result<()> {
33395 self.write_keyword("PRIMARY KEY");
33397 Ok(())
33398 }
33399
33400 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
33401 self.write_keyword("PATH");
33403 self.write_space();
33404 self.generate_expression(&e.this)?;
33405 Ok(())
33406 }
33407
33408 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
33409 self.write_keyword("PROJECTION");
33411 self.write_space();
33412 self.generate_expression(&e.this)?;
33413 self.write(" (");
33414 self.generate_expression(&e.expression)?;
33415 self.write(")");
33416 Ok(())
33417 }
33418
33419 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
33420 for (i, prop) in e.expressions.iter().enumerate() {
33422 if i > 0 {
33423 self.write(", ");
33424 }
33425 self.generate_expression(prop)?;
33426 }
33427 Ok(())
33428 }
33429
33430 fn generate_property(&mut self, e: &Property) -> Result<()> {
33431 self.generate_expression(&e.this)?;
33433 if let Some(value) = &e.value {
33434 self.write("=");
33435 self.generate_expression(value)?;
33436 }
33437 Ok(())
33438 }
33439
33440 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
33441 self.write_keyword("OPTIONS");
33442 if e.entries.is_empty() {
33443 self.write(" ()");
33444 return Ok(());
33445 }
33446
33447 if self.config.pretty {
33448 self.write(" (");
33449 self.write_newline();
33450 self.indent_level += 1;
33451 for (i, entry) in e.entries.iter().enumerate() {
33452 if i > 0 {
33453 self.write(",");
33454 self.write_newline();
33455 }
33456 self.write_indent();
33457 self.generate_identifier(&entry.key)?;
33458 self.write("=");
33459 self.generate_expression(&entry.value)?;
33460 }
33461 self.indent_level -= 1;
33462 self.write_newline();
33463 self.write(")");
33464 } else {
33465 self.write(" (");
33466 for (i, entry) in e.entries.iter().enumerate() {
33467 if i > 0 {
33468 self.write(", ");
33469 }
33470 self.generate_identifier(&entry.key)?;
33471 self.write("=");
33472 self.generate_expression(&entry.value)?;
33473 }
33474 self.write(")");
33475 }
33476 Ok(())
33477 }
33478
33479 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
33481 self.write_keyword("OPTIONS");
33482 self.write(" (");
33483 for (i, opt) in options.iter().enumerate() {
33484 if i > 0 {
33485 self.write(", ");
33486 }
33487 self.generate_option_expression(opt)?;
33488 }
33489 self.write(")");
33490 Ok(())
33491 }
33492
33493 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
33495 self.write_keyword("PROPERTIES");
33496 self.write(" (");
33497 for (i, prop) in properties.iter().enumerate() {
33498 if i > 0 {
33499 self.write(", ");
33500 }
33501 self.generate_option_expression(prop)?;
33502 }
33503 self.write(")");
33504 Ok(())
33505 }
33506
33507 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
33509 self.write_keyword("ENVIRONMENT");
33510 self.write(" (");
33511 for (i, env_item) in environment.iter().enumerate() {
33512 if i > 0 {
33513 self.write(", ");
33514 }
33515 self.generate_environment_expression(env_item)?;
33516 }
33517 self.write(")");
33518 Ok(())
33519 }
33520
33521 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
33523 match expr {
33524 Expression::Eq(eq) => {
33525 self.generate_expression(&eq.left)?;
33527 self.write(" = ");
33528 self.generate_expression(&eq.right)?;
33529 Ok(())
33530 }
33531 _ => self.generate_expression(expr),
33532 }
33533 }
33534
33535 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
33537 self.write_keyword("TBLPROPERTIES");
33538 if self.config.pretty {
33539 self.write(" (");
33540 self.write_newline();
33541 self.indent_level += 1;
33542 for (i, opt) in options.iter().enumerate() {
33543 if i > 0 {
33544 self.write(",");
33545 self.write_newline();
33546 }
33547 self.write_indent();
33548 self.generate_option_expression(opt)?;
33549 }
33550 self.indent_level -= 1;
33551 self.write_newline();
33552 self.write(")");
33553 } else {
33554 self.write(" (");
33555 for (i, opt) in options.iter().enumerate() {
33556 if i > 0 {
33557 self.write(", ");
33558 }
33559 self.generate_option_expression(opt)?;
33560 }
33561 self.write(")");
33562 }
33563 Ok(())
33564 }
33565
33566 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
33568 match expr {
33569 Expression::Eq(eq) => {
33570 self.generate_expression(&eq.left)?;
33572 self.write("=");
33573 self.generate_expression(&eq.right)?;
33574 Ok(())
33575 }
33576 _ => self.generate_expression(expr),
33577 }
33578 }
33579
33580 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
33581 self.generate_expression(&e.this)?;
33583 Ok(())
33584 }
33585
33586 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
33587 self.write_keyword("PUT");
33589 self.write_space();
33590
33591 if e.source_quoted {
33593 self.write("'");
33594 self.write(&e.source);
33595 self.write("'");
33596 } else {
33597 self.write(&e.source);
33598 }
33599
33600 self.write_space();
33601
33602 if let Expression::Literal(lit) = &e.target {
33604 if let Literal::String(s) = lit.as_ref() {
33605 self.write(s);
33606 }
33607 } else {
33608 self.generate_expression(&e.target)?;
33609 }
33610
33611 for param in &e.params {
33613 self.write_space();
33614 self.write(¶m.name);
33615 if let Some(ref value) = param.value {
33616 self.write("=");
33617 self.generate_expression(value)?;
33618 }
33619 }
33620
33621 Ok(())
33622 }
33623
33624 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
33625 self.write_keyword("QUANTILE");
33627 self.write("(");
33628 self.generate_expression(&e.this)?;
33629 if let Some(quantile) = &e.quantile {
33630 self.write(", ");
33631 self.generate_expression(quantile)?;
33632 }
33633 self.write(")");
33634 Ok(())
33635 }
33636
33637 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
33638 if matches!(
33640 self.config.dialect,
33641 Some(crate::dialects::DialectType::Teradata)
33642 ) {
33643 self.write_keyword("SET");
33644 self.write_space();
33645 }
33646 self.write_keyword("QUERY_BAND");
33647 self.write(" = ");
33648 self.generate_expression(&e.this)?;
33649 if e.update.is_some() {
33650 self.write_space();
33651 self.write_keyword("UPDATE");
33652 }
33653 if let Some(scope) = &e.scope {
33654 self.write_space();
33655 self.write_keyword("FOR");
33656 self.write_space();
33657 self.generate_expression(scope)?;
33658 }
33659 Ok(())
33660 }
33661
33662 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
33663 self.generate_expression(&e.this)?;
33665 if let Some(expression) = &e.expression {
33666 self.write(" = ");
33667 self.generate_expression(expression)?;
33668 }
33669 Ok(())
33670 }
33671
33672 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
33673 self.write_keyword("TRANSFORM");
33675 self.write("(");
33676 for (i, expr) in e.expressions.iter().enumerate() {
33677 if i > 0 {
33678 self.write(", ");
33679 }
33680 self.generate_expression(expr)?;
33681 }
33682 self.write(")");
33683 if let Some(row_format_before) = &e.row_format_before {
33684 self.write_space();
33685 self.generate_expression(row_format_before)?;
33686 }
33687 if let Some(record_writer) = &e.record_writer {
33688 self.write_space();
33689 self.write_keyword("RECORDWRITER");
33690 self.write_space();
33691 self.generate_expression(record_writer)?;
33692 }
33693 if let Some(command_script) = &e.command_script {
33694 self.write_space();
33695 self.write_keyword("USING");
33696 self.write_space();
33697 self.generate_expression(command_script)?;
33698 }
33699 if let Some(schema) = &e.schema {
33700 self.write_space();
33701 self.write_keyword("AS");
33702 self.write_space();
33703 self.generate_expression(schema)?;
33704 }
33705 if let Some(row_format_after) = &e.row_format_after {
33706 self.write_space();
33707 self.generate_expression(row_format_after)?;
33708 }
33709 if let Some(record_reader) = &e.record_reader {
33710 self.write_space();
33711 self.write_keyword("RECORDREADER");
33712 self.write_space();
33713 self.generate_expression(record_reader)?;
33714 }
33715 Ok(())
33716 }
33717
33718 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
33719 self.write_keyword("RANDN");
33721 self.write("(");
33722 if let Some(this) = &e.this {
33723 self.generate_expression(this)?;
33724 }
33725 self.write(")");
33726 Ok(())
33727 }
33728
33729 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
33730 self.write_keyword("RANDSTR");
33732 self.write("(");
33733 self.generate_expression(&e.this)?;
33734 if let Some(generator) = &e.generator {
33735 self.write(", ");
33736 self.generate_expression(generator)?;
33737 }
33738 self.write(")");
33739 Ok(())
33740 }
33741
33742 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
33743 self.write_keyword("RANGE_BUCKET");
33745 self.write("(");
33746 self.generate_expression(&e.this)?;
33747 self.write(", ");
33748 self.generate_expression(&e.expression)?;
33749 self.write(")");
33750 Ok(())
33751 }
33752
33753 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
33754 self.write_keyword("RANGE_N");
33756 self.write("(");
33757 self.generate_expression(&e.this)?;
33758 self.write_space();
33759 self.write_keyword("BETWEEN");
33760 self.write_space();
33761 for (i, expr) in e.expressions.iter().enumerate() {
33762 if i > 0 {
33763 self.write(", ");
33764 }
33765 self.generate_expression(expr)?;
33766 }
33767 if let Some(each) = &e.each {
33768 self.write_space();
33769 self.write_keyword("EACH");
33770 self.write_space();
33771 self.generate_expression(each)?;
33772 }
33773 self.write(")");
33774 Ok(())
33775 }
33776
33777 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
33778 self.write_keyword("READ_CSV");
33780 self.write("(");
33781 self.generate_expression(&e.this)?;
33782 for expr in &e.expressions {
33783 self.write(", ");
33784 self.generate_expression(expr)?;
33785 }
33786 self.write(")");
33787 Ok(())
33788 }
33789
33790 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
33791 self.write_keyword("READ_PARQUET");
33793 self.write("(");
33794 for (i, expr) in e.expressions.iter().enumerate() {
33795 if i > 0 {
33796 self.write(", ");
33797 }
33798 self.generate_expression(expr)?;
33799 }
33800 self.write(")");
33801 Ok(())
33802 }
33803
33804 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
33805 if e.kind == "CYCLE" {
33808 self.write_keyword("CYCLE");
33809 } else {
33810 self.write_keyword("SEARCH");
33811 self.write_space();
33812 self.write(&e.kind);
33813 self.write_space();
33814 self.write_keyword("FIRST BY");
33815 }
33816 self.write_space();
33817 self.generate_expression(&e.this)?;
33818 self.write_space();
33819 self.write_keyword("SET");
33820 self.write_space();
33821 self.generate_expression(&e.expression)?;
33822 if let Some(using) = &e.using {
33823 self.write_space();
33824 self.write_keyword("USING");
33825 self.write_space();
33826 self.generate_expression(using)?;
33827 }
33828 Ok(())
33829 }
33830
33831 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
33832 self.write_keyword("REDUCE");
33834 self.write("(");
33835 self.generate_expression(&e.this)?;
33836 if let Some(initial) = &e.initial {
33837 self.write(", ");
33838 self.generate_expression(initial)?;
33839 }
33840 if let Some(merge) = &e.merge {
33841 self.write(", ");
33842 self.generate_expression(merge)?;
33843 }
33844 if let Some(finish) = &e.finish {
33845 self.write(", ");
33846 self.generate_expression(finish)?;
33847 }
33848 self.write(")");
33849 Ok(())
33850 }
33851
33852 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
33853 self.write_keyword("REFERENCES");
33855 self.write_space();
33856 self.generate_expression(&e.this)?;
33857 if !e.expressions.is_empty() {
33858 self.write(" (");
33859 for (i, expr) in e.expressions.iter().enumerate() {
33860 if i > 0 {
33861 self.write(", ");
33862 }
33863 self.generate_expression(expr)?;
33864 }
33865 self.write(")");
33866 }
33867 for opt in &e.options {
33868 self.write_space();
33869 self.generate_expression(opt)?;
33870 }
33871 Ok(())
33872 }
33873
33874 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
33875 self.write_keyword("REFRESH");
33877 if !e.kind.is_empty() {
33878 self.write_space();
33879 self.write_keyword(&e.kind);
33880 }
33881 self.write_space();
33882 self.generate_expression(&e.this)?;
33883 Ok(())
33884 }
33885
33886 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
33887 self.write_keyword("REFRESH");
33889 self.write_space();
33890 self.write_keyword(&e.method);
33891
33892 if let Some(ref kind) = e.kind {
33893 self.write_space();
33894 self.write_keyword("ON");
33895 self.write_space();
33896 self.write_keyword(kind);
33897
33898 if let Some(ref every) = e.every {
33900 self.write_space();
33901 self.write_keyword("EVERY");
33902 self.write_space();
33903 self.generate_expression(every)?;
33904 if let Some(ref unit) = e.unit {
33905 self.write_space();
33906 self.write_keyword(unit);
33907 }
33908 }
33909
33910 if let Some(ref starts) = e.starts {
33912 self.write_space();
33913 self.write_keyword("STARTS");
33914 self.write_space();
33915 self.generate_expression(starts)?;
33916 }
33917 }
33918 Ok(())
33919 }
33920
33921 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
33922 self.write_keyword("REGEXP_COUNT");
33924 self.write("(");
33925 self.generate_expression(&e.this)?;
33926 self.write(", ");
33927 self.generate_expression(&e.expression)?;
33928 if let Some(position) = &e.position {
33929 self.write(", ");
33930 self.generate_expression(position)?;
33931 }
33932 if let Some(parameters) = &e.parameters {
33933 self.write(", ");
33934 self.generate_expression(parameters)?;
33935 }
33936 self.write(")");
33937 Ok(())
33938 }
33939
33940 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
33941 self.write_keyword("REGEXP_EXTRACT_ALL");
33943 self.write("(");
33944 self.generate_expression(&e.this)?;
33945 self.write(", ");
33946 self.generate_expression(&e.expression)?;
33947 if let Some(group) = &e.group {
33948 self.write(", ");
33949 self.generate_expression(group)?;
33950 }
33951 self.write(")");
33952 Ok(())
33953 }
33954
33955 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
33956 self.write_keyword("REGEXP_FULL_MATCH");
33958 self.write("(");
33959 self.generate_expression(&e.this)?;
33960 self.write(", ");
33961 self.generate_expression(&e.expression)?;
33962 self.write(")");
33963 Ok(())
33964 }
33965
33966 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
33967 use crate::dialects::DialectType;
33968 if matches!(
33970 self.config.dialect,
33971 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
33972 ) && e.flag.is_none()
33973 {
33974 self.generate_expression(&e.this)?;
33975 self.write(" ~* ");
33976 self.generate_expression(&e.expression)?;
33977 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33978 self.write_keyword("REGEXP_LIKE");
33980 self.write("(");
33981 self.generate_expression(&e.this)?;
33982 self.write(", ");
33983 self.generate_expression(&e.expression)?;
33984 self.write(", ");
33985 if let Some(flag) = &e.flag {
33986 self.generate_expression(flag)?;
33987 } else {
33988 self.write("'i'");
33989 }
33990 self.write(")");
33991 } else {
33992 self.generate_expression(&e.this)?;
33994 self.write_space();
33995 self.write_keyword("REGEXP_ILIKE");
33996 self.write_space();
33997 self.generate_expression(&e.expression)?;
33998 if let Some(flag) = &e.flag {
33999 self.write(", ");
34000 self.generate_expression(flag)?;
34001 }
34002 }
34003 Ok(())
34004 }
34005
34006 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
34007 self.write_keyword("REGEXP_INSTR");
34009 self.write("(");
34010 self.generate_expression(&e.this)?;
34011 self.write(", ");
34012 self.generate_expression(&e.expression)?;
34013 if let Some(position) = &e.position {
34014 self.write(", ");
34015 self.generate_expression(position)?;
34016 }
34017 if let Some(occurrence) = &e.occurrence {
34018 self.write(", ");
34019 self.generate_expression(occurrence)?;
34020 }
34021 if let Some(option) = &e.option {
34022 self.write(", ");
34023 self.generate_expression(option)?;
34024 }
34025 if let Some(parameters) = &e.parameters {
34026 self.write(", ");
34027 self.generate_expression(parameters)?;
34028 }
34029 if let Some(group) = &e.group {
34030 self.write(", ");
34031 self.generate_expression(group)?;
34032 }
34033 self.write(")");
34034 Ok(())
34035 }
34036
34037 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
34038 self.write_keyword("REGEXP_SPLIT");
34040 self.write("(");
34041 self.generate_expression(&e.this)?;
34042 self.write(", ");
34043 self.generate_expression(&e.expression)?;
34044 if let Some(limit) = &e.limit {
34045 self.write(", ");
34046 self.generate_expression(limit)?;
34047 }
34048 self.write(")");
34049 Ok(())
34050 }
34051
34052 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
34053 self.write_keyword("REGR_AVGX");
34055 self.write("(");
34056 self.generate_expression(&e.this)?;
34057 self.write(", ");
34058 self.generate_expression(&e.expression)?;
34059 self.write(")");
34060 Ok(())
34061 }
34062
34063 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
34064 self.write_keyword("REGR_AVGY");
34066 self.write("(");
34067 self.generate_expression(&e.this)?;
34068 self.write(", ");
34069 self.generate_expression(&e.expression)?;
34070 self.write(")");
34071 Ok(())
34072 }
34073
34074 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
34075 self.write_keyword("REGR_COUNT");
34077 self.write("(");
34078 self.generate_expression(&e.this)?;
34079 self.write(", ");
34080 self.generate_expression(&e.expression)?;
34081 self.write(")");
34082 Ok(())
34083 }
34084
34085 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
34086 self.write_keyword("REGR_INTERCEPT");
34088 self.write("(");
34089 self.generate_expression(&e.this)?;
34090 self.write(", ");
34091 self.generate_expression(&e.expression)?;
34092 self.write(")");
34093 Ok(())
34094 }
34095
34096 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
34097 self.write_keyword("REGR_R2");
34099 self.write("(");
34100 self.generate_expression(&e.this)?;
34101 self.write(", ");
34102 self.generate_expression(&e.expression)?;
34103 self.write(")");
34104 Ok(())
34105 }
34106
34107 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
34108 self.write_keyword("REGR_SLOPE");
34110 self.write("(");
34111 self.generate_expression(&e.this)?;
34112 self.write(", ");
34113 self.generate_expression(&e.expression)?;
34114 self.write(")");
34115 Ok(())
34116 }
34117
34118 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
34119 self.write_keyword("REGR_SXX");
34121 self.write("(");
34122 self.generate_expression(&e.this)?;
34123 self.write(", ");
34124 self.generate_expression(&e.expression)?;
34125 self.write(")");
34126 Ok(())
34127 }
34128
34129 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
34130 self.write_keyword("REGR_SXY");
34132 self.write("(");
34133 self.generate_expression(&e.this)?;
34134 self.write(", ");
34135 self.generate_expression(&e.expression)?;
34136 self.write(")");
34137 Ok(())
34138 }
34139
34140 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
34141 self.write_keyword("REGR_SYY");
34143 self.write("(");
34144 self.generate_expression(&e.this)?;
34145 self.write(", ");
34146 self.generate_expression(&e.expression)?;
34147 self.write(")");
34148 Ok(())
34149 }
34150
34151 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
34152 self.write_keyword("REGR_VALX");
34154 self.write("(");
34155 self.generate_expression(&e.this)?;
34156 self.write(", ");
34157 self.generate_expression(&e.expression)?;
34158 self.write(")");
34159 Ok(())
34160 }
34161
34162 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
34163 self.write_keyword("REGR_VALY");
34165 self.write("(");
34166 self.generate_expression(&e.this)?;
34167 self.write(", ");
34168 self.generate_expression(&e.expression)?;
34169 self.write(")");
34170 Ok(())
34171 }
34172
34173 fn generate_remote_with_connection_model_property(
34174 &mut self,
34175 e: &RemoteWithConnectionModelProperty,
34176 ) -> Result<()> {
34177 self.write_keyword("REMOTE WITH CONNECTION");
34179 self.write_space();
34180 self.generate_expression(&e.this)?;
34181 Ok(())
34182 }
34183
34184 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
34185 self.write_keyword("RENAME COLUMN");
34187 if e.exists {
34188 self.write_space();
34189 self.write_keyword("IF EXISTS");
34190 }
34191 self.write_space();
34192 self.generate_expression(&e.this)?;
34193 if let Some(to) = &e.to {
34194 self.write_space();
34195 self.write_keyword("TO");
34196 self.write_space();
34197 self.generate_expression(to)?;
34198 }
34199 Ok(())
34200 }
34201
34202 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
34203 self.write_keyword("REPLACE PARTITION");
34205 self.write_space();
34206 self.generate_expression(&e.expression)?;
34207 if let Some(source) = &e.source {
34208 self.write_space();
34209 self.write_keyword("FROM");
34210 self.write_space();
34211 self.generate_expression(source)?;
34212 }
34213 Ok(())
34214 }
34215
34216 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
34217 let keyword = match self.config.dialect {
34220 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
34221 _ => "RETURNING",
34222 };
34223 self.write_keyword(keyword);
34224 self.write_space();
34225 for (i, expr) in e.expressions.iter().enumerate() {
34226 if i > 0 {
34227 self.write(", ");
34228 }
34229 self.generate_expression(expr)?;
34230 }
34231 if let Some(into) = &e.into {
34232 self.write_space();
34233 self.write_keyword("INTO");
34234 self.write_space();
34235 self.generate_expression(into)?;
34236 }
34237 Ok(())
34238 }
34239
34240 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
34241 self.write_space();
34243 self.write_keyword("OUTPUT");
34244 self.write_space();
34245 for (i, expr) in output.columns.iter().enumerate() {
34246 if i > 0 {
34247 self.write(", ");
34248 }
34249 self.generate_expression(expr)?;
34250 }
34251 if let Some(into_table) = &output.into_table {
34252 self.write_space();
34253 self.write_keyword("INTO");
34254 self.write_space();
34255 self.generate_expression(into_table)?;
34256 }
34257 Ok(())
34258 }
34259
34260 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
34261 self.write_keyword("RETURNS");
34263 if e.is_table.is_some() {
34264 self.write_space();
34265 self.write_keyword("TABLE");
34266 }
34267 if let Some(table) = &e.table {
34268 self.write_space();
34269 self.generate_expression(table)?;
34270 } else if let Some(this) = &e.this {
34271 self.write_space();
34272 self.generate_expression(this)?;
34273 }
34274 if e.null.is_some() {
34275 self.write_space();
34276 self.write_keyword("NULL ON NULL INPUT");
34277 }
34278 Ok(())
34279 }
34280
34281 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
34282 self.write_keyword("ROLLBACK");
34284
34285 if e.this.is_none()
34287 && matches!(
34288 self.config.dialect,
34289 Some(DialectType::TSQL) | Some(DialectType::Fabric)
34290 )
34291 {
34292 self.write_space();
34293 self.write_keyword("TRANSACTION");
34294 }
34295
34296 if let Some(this) = &e.this {
34298 let is_transaction_marker = matches!(
34300 this.as_ref(),
34301 Expression::Identifier(id) if id.name == "TRANSACTION"
34302 );
34303
34304 self.write_space();
34305 self.write_keyword("TRANSACTION");
34306
34307 if !is_transaction_marker {
34309 self.write_space();
34310 self.generate_expression(this)?;
34311 }
34312 }
34313
34314 if let Some(savepoint) = &e.savepoint {
34316 self.write_space();
34317 self.write_keyword("TO");
34318 self.write_space();
34319 self.generate_expression(savepoint)?;
34320 }
34321 Ok(())
34322 }
34323
34324 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
34325 if e.expressions.is_empty() {
34327 self.write_keyword("WITH ROLLUP");
34328 } else {
34329 self.write_keyword("ROLLUP");
34330 self.write("(");
34331 for (i, expr) in e.expressions.iter().enumerate() {
34332 if i > 0 {
34333 self.write(", ");
34334 }
34335 self.generate_expression(expr)?;
34336 }
34337 self.write(")");
34338 }
34339 Ok(())
34340 }
34341
34342 fn generate_row_format_delimited_property(
34343 &mut self,
34344 e: &RowFormatDelimitedProperty,
34345 ) -> Result<()> {
34346 self.write_keyword("ROW FORMAT DELIMITED");
34348 if let Some(fields) = &e.fields {
34349 self.write_space();
34350 self.write_keyword("FIELDS TERMINATED BY");
34351 self.write_space();
34352 self.generate_expression(fields)?;
34353 }
34354 if let Some(escaped) = &e.escaped {
34355 self.write_space();
34356 self.write_keyword("ESCAPED BY");
34357 self.write_space();
34358 self.generate_expression(escaped)?;
34359 }
34360 if let Some(items) = &e.collection_items {
34361 self.write_space();
34362 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
34363 self.write_space();
34364 self.generate_expression(items)?;
34365 }
34366 if let Some(keys) = &e.map_keys {
34367 self.write_space();
34368 self.write_keyword("MAP KEYS TERMINATED BY");
34369 self.write_space();
34370 self.generate_expression(keys)?;
34371 }
34372 if let Some(lines) = &e.lines {
34373 self.write_space();
34374 self.write_keyword("LINES TERMINATED BY");
34375 self.write_space();
34376 self.generate_expression(lines)?;
34377 }
34378 if let Some(null) = &e.null {
34379 self.write_space();
34380 self.write_keyword("NULL DEFINED AS");
34381 self.write_space();
34382 self.generate_expression(null)?;
34383 }
34384 if let Some(serde) = &e.serde {
34385 self.write_space();
34386 self.generate_expression(serde)?;
34387 }
34388 Ok(())
34389 }
34390
34391 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
34392 self.write_keyword("ROW FORMAT");
34394 self.write_space();
34395 self.generate_expression(&e.this)?;
34396 Ok(())
34397 }
34398
34399 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
34400 self.write_keyword("ROW FORMAT SERDE");
34402 self.write_space();
34403 self.generate_expression(&e.this)?;
34404 if let Some(props) = &e.serde_properties {
34405 self.write_space();
34406 self.generate_expression(props)?;
34408 }
34409 Ok(())
34410 }
34411
34412 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
34413 self.write_keyword("SHA2");
34415 self.write("(");
34416 self.generate_expression(&e.this)?;
34417 if let Some(length) = e.length {
34418 self.write(", ");
34419 self.write(&length.to_string());
34420 }
34421 self.write(")");
34422 Ok(())
34423 }
34424
34425 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
34426 self.write_keyword("SHA2_DIGEST");
34428 self.write("(");
34429 self.generate_expression(&e.this)?;
34430 if let Some(length) = e.length {
34431 self.write(", ");
34432 self.write(&length.to_string());
34433 }
34434 self.write(")");
34435 Ok(())
34436 }
34437
34438 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
34439 let name = if matches!(
34440 self.config.dialect,
34441 Some(crate::dialects::DialectType::Spark)
34442 | Some(crate::dialects::DialectType::Databricks)
34443 ) {
34444 "TRY_ADD"
34445 } else {
34446 "SAFE_ADD"
34447 };
34448 self.write_keyword(name);
34449 self.write("(");
34450 self.generate_expression(&e.this)?;
34451 self.write(", ");
34452 self.generate_expression(&e.expression)?;
34453 self.write(")");
34454 Ok(())
34455 }
34456
34457 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
34458 self.write_keyword("SAFE_DIVIDE");
34460 self.write("(");
34461 self.generate_expression(&e.this)?;
34462 self.write(", ");
34463 self.generate_expression(&e.expression)?;
34464 self.write(")");
34465 Ok(())
34466 }
34467
34468 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
34469 let name = if matches!(
34470 self.config.dialect,
34471 Some(crate::dialects::DialectType::Spark)
34472 | Some(crate::dialects::DialectType::Databricks)
34473 ) {
34474 "TRY_MULTIPLY"
34475 } else {
34476 "SAFE_MULTIPLY"
34477 };
34478 self.write_keyword(name);
34479 self.write("(");
34480 self.generate_expression(&e.this)?;
34481 self.write(", ");
34482 self.generate_expression(&e.expression)?;
34483 self.write(")");
34484 Ok(())
34485 }
34486
34487 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
34488 let name = if matches!(
34489 self.config.dialect,
34490 Some(crate::dialects::DialectType::Spark)
34491 | Some(crate::dialects::DialectType::Databricks)
34492 ) {
34493 "TRY_SUBTRACT"
34494 } else {
34495 "SAFE_SUBTRACT"
34496 };
34497 self.write_keyword(name);
34498 self.write("(");
34499 self.generate_expression(&e.this)?;
34500 self.write(", ");
34501 self.generate_expression(&e.expression)?;
34502 self.write(")");
34503 Ok(())
34504 }
34505
34506 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
34509 if matches!(sample.method, SampleMethod::Bucket) {
34511 self.write(" (");
34512 self.write_keyword("BUCKET");
34513 self.write_space();
34514 if let Some(ref num) = sample.bucket_numerator {
34515 self.generate_expression(num)?;
34516 }
34517 self.write_space();
34518 self.write_keyword("OUT OF");
34519 self.write_space();
34520 if let Some(ref denom) = sample.bucket_denominator {
34521 self.generate_expression(denom)?;
34522 }
34523 if let Some(ref field) = sample.bucket_field {
34524 self.write_space();
34525 self.write_keyword("ON");
34526 self.write_space();
34527 self.generate_expression(field)?;
34528 }
34529 self.write(")");
34530 return Ok(());
34531 }
34532
34533 let is_snowflake = matches!(
34535 self.config.dialect,
34536 Some(crate::dialects::DialectType::Snowflake)
34537 );
34538 let is_postgres = matches!(
34539 self.config.dialect,
34540 Some(crate::dialects::DialectType::PostgreSQL)
34541 | Some(crate::dialects::DialectType::Redshift)
34542 );
34543 let is_databricks = matches!(
34545 self.config.dialect,
34546 Some(crate::dialects::DialectType::Databricks)
34547 );
34548 let is_spark = matches!(
34549 self.config.dialect,
34550 Some(crate::dialects::DialectType::Spark)
34551 );
34552 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
34553 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
34555 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
34556 self.write_space();
34557 if !sample.explicit_method && (is_snowflake || force_method) {
34558 self.write_keyword("BERNOULLI");
34560 } else {
34561 match sample.method {
34562 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
34563 SampleMethod::System => self.write_keyword("SYSTEM"),
34564 SampleMethod::Block => self.write_keyword("BLOCK"),
34565 SampleMethod::Row => self.write_keyword("ROW"),
34566 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
34567 SampleMethod::Percent => self.write_keyword("SYSTEM"),
34568 SampleMethod::Bucket => {} }
34570 }
34571 }
34572
34573 let emit_size_no_parens = !self.config.tablesample_requires_parens;
34575 if emit_size_no_parens {
34576 self.write_space();
34577 match &sample.size {
34578 Expression::Tuple(tuple) => {
34579 for (i, expr) in tuple.expressions.iter().enumerate() {
34580 if i > 0 {
34581 self.write(", ");
34582 }
34583 self.generate_expression(expr)?;
34584 }
34585 }
34586 expr => self.generate_expression(expr)?,
34587 }
34588 } else {
34589 self.write(" (");
34590 self.generate_expression(&sample.size)?;
34591 }
34592
34593 let is_rows_method = matches!(
34595 sample.method,
34596 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
34597 );
34598 let is_percent = matches!(
34599 sample.method,
34600 SampleMethod::Percent
34601 | SampleMethod::System
34602 | SampleMethod::Bernoulli
34603 | SampleMethod::Block
34604 );
34605
34606 let is_presto = matches!(
34610 self.config.dialect,
34611 Some(crate::dialects::DialectType::Presto)
34612 | Some(crate::dialects::DialectType::Trino)
34613 | Some(crate::dialects::DialectType::Athena)
34614 );
34615 let should_output_unit = if is_databricks || is_spark {
34616 is_percent || is_rows_method || sample.unit_after_size
34618 } else if is_snowflake || is_postgres || is_presto {
34619 sample.unit_after_size
34620 } else {
34621 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
34622 };
34623
34624 if should_output_unit {
34625 self.write_space();
34626 if sample.is_percent {
34627 self.write_keyword("PERCENT");
34628 } else if is_rows_method && !sample.unit_after_size {
34629 self.write_keyword("ROWS");
34630 } else if sample.unit_after_size {
34631 match sample.method {
34632 SampleMethod::Percent
34633 | SampleMethod::System
34634 | SampleMethod::Bernoulli
34635 | SampleMethod::Block => {
34636 self.write_keyword("PERCENT");
34637 }
34638 SampleMethod::Row | SampleMethod::Reservoir => {
34639 self.write_keyword("ROWS");
34640 }
34641 _ => self.write_keyword("ROWS"),
34642 }
34643 } else {
34644 self.write_keyword("PERCENT");
34645 }
34646 }
34647
34648 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34649 if let Some(ref offset) = sample.offset {
34650 self.write_space();
34651 self.write_keyword("OFFSET");
34652 self.write_space();
34653 self.generate_expression(offset)?;
34654 }
34655 }
34656 if !emit_size_no_parens {
34657 self.write(")");
34658 }
34659
34660 Ok(())
34661 }
34662
34663 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
34664 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34666 self.write_keyword("SAMPLE BY");
34667 } else {
34668 self.write_keyword("SAMPLE");
34669 }
34670 self.write_space();
34671 self.generate_expression(&e.this)?;
34672 Ok(())
34673 }
34674
34675 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
34676 if let Some(this) = &e.this {
34678 self.generate_expression(this)?;
34679 }
34680 if !e.expressions.is_empty() {
34681 if e.this.is_some() {
34683 self.write_space();
34684 }
34685 self.write("(");
34686 for (i, expr) in e.expressions.iter().enumerate() {
34687 if i > 0 {
34688 self.write(", ");
34689 }
34690 self.generate_expression(expr)?;
34691 }
34692 self.write(")");
34693 }
34694 Ok(())
34695 }
34696
34697 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
34698 self.write_keyword("COMMENT");
34700 self.write_space();
34701 self.generate_expression(&e.this)?;
34702 Ok(())
34703 }
34704
34705 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
34706 if let Some(this) = &e.this {
34708 self.generate_expression(this)?;
34709 self.write("::");
34710 }
34711 self.generate_expression(&e.expression)?;
34712 Ok(())
34713 }
34714
34715 fn generate_search(&mut self, e: &Search) -> Result<()> {
34716 self.write_keyword("SEARCH");
34718 self.write("(");
34719 self.generate_expression(&e.this)?;
34720 self.write(", ");
34721 self.generate_expression(&e.expression)?;
34722 if let Some(json_scope) = &e.json_scope {
34723 self.write(", ");
34724 self.generate_expression(json_scope)?;
34725 }
34726 if let Some(analyzer) = &e.analyzer {
34727 self.write(", ");
34728 self.generate_expression(analyzer)?;
34729 }
34730 if let Some(analyzer_options) = &e.analyzer_options {
34731 self.write(", ");
34732 self.generate_expression(analyzer_options)?;
34733 }
34734 if let Some(search_mode) = &e.search_mode {
34735 self.write(", ");
34736 self.generate_expression(search_mode)?;
34737 }
34738 self.write(")");
34739 Ok(())
34740 }
34741
34742 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
34743 self.write_keyword("SEARCH_IP");
34745 self.write("(");
34746 self.generate_expression(&e.this)?;
34747 self.write(", ");
34748 self.generate_expression(&e.expression)?;
34749 self.write(")");
34750 Ok(())
34751 }
34752
34753 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
34754 self.write_keyword("SECURITY");
34756 self.write_space();
34757 self.generate_expression(&e.this)?;
34758 Ok(())
34759 }
34760
34761 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
34762 self.write("SEMANTIC_VIEW(");
34764
34765 if self.config.pretty {
34766 self.write_newline();
34768 self.indent_level += 1;
34769 self.write_indent();
34770 self.generate_expression(&e.this)?;
34771
34772 if let Some(metrics) = &e.metrics {
34773 self.write_newline();
34774 self.write_indent();
34775 self.write_keyword("METRICS");
34776 self.write_space();
34777 self.generate_semantic_view_tuple(metrics)?;
34778 }
34779 if let Some(dimensions) = &e.dimensions {
34780 self.write_newline();
34781 self.write_indent();
34782 self.write_keyword("DIMENSIONS");
34783 self.write_space();
34784 self.generate_semantic_view_tuple(dimensions)?;
34785 }
34786 if let Some(facts) = &e.facts {
34787 self.write_newline();
34788 self.write_indent();
34789 self.write_keyword("FACTS");
34790 self.write_space();
34791 self.generate_semantic_view_tuple(facts)?;
34792 }
34793 if let Some(where_) = &e.where_ {
34794 self.write_newline();
34795 self.write_indent();
34796 self.write_keyword("WHERE");
34797 self.write_space();
34798 self.generate_expression(where_)?;
34799 }
34800 self.write_newline();
34801 self.indent_level -= 1;
34802 self.write_indent();
34803 } else {
34804 self.generate_expression(&e.this)?;
34806 if let Some(metrics) = &e.metrics {
34807 self.write_space();
34808 self.write_keyword("METRICS");
34809 self.write_space();
34810 self.generate_semantic_view_tuple(metrics)?;
34811 }
34812 if let Some(dimensions) = &e.dimensions {
34813 self.write_space();
34814 self.write_keyword("DIMENSIONS");
34815 self.write_space();
34816 self.generate_semantic_view_tuple(dimensions)?;
34817 }
34818 if let Some(facts) = &e.facts {
34819 self.write_space();
34820 self.write_keyword("FACTS");
34821 self.write_space();
34822 self.generate_semantic_view_tuple(facts)?;
34823 }
34824 if let Some(where_) = &e.where_ {
34825 self.write_space();
34826 self.write_keyword("WHERE");
34827 self.write_space();
34828 self.generate_expression(where_)?;
34829 }
34830 }
34831 self.write(")");
34832 Ok(())
34833 }
34834
34835 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
34837 if let Expression::Tuple(t) = expr {
34838 for (i, e) in t.expressions.iter().enumerate() {
34839 if i > 0 {
34840 self.write(", ");
34841 }
34842 self.generate_expression(e)?;
34843 }
34844 } else {
34845 self.generate_expression(expr)?;
34846 }
34847 Ok(())
34848 }
34849
34850 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
34851 if let Some(start) = &e.start {
34853 self.write_keyword("START WITH");
34854 self.write_space();
34855 self.generate_expression(start)?;
34856 }
34857 if let Some(increment) = &e.increment {
34858 self.write_space();
34859 self.write_keyword("INCREMENT BY");
34860 self.write_space();
34861 self.generate_expression(increment)?;
34862 }
34863 if let Some(minvalue) = &e.minvalue {
34864 self.write_space();
34865 self.write_keyword("MINVALUE");
34866 self.write_space();
34867 self.generate_expression(minvalue)?;
34868 }
34869 if let Some(maxvalue) = &e.maxvalue {
34870 self.write_space();
34871 self.write_keyword("MAXVALUE");
34872 self.write_space();
34873 self.generate_expression(maxvalue)?;
34874 }
34875 if let Some(cache) = &e.cache {
34876 self.write_space();
34877 self.write_keyword("CACHE");
34878 self.write_space();
34879 self.generate_expression(cache)?;
34880 }
34881 if let Some(owned) = &e.owned {
34882 self.write_space();
34883 self.write_keyword("OWNED BY");
34884 self.write_space();
34885 self.generate_expression(owned)?;
34886 }
34887 for opt in &e.options {
34888 self.write_space();
34889 self.generate_expression(opt)?;
34890 }
34891 Ok(())
34892 }
34893
34894 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
34895 if e.with_.is_some() {
34897 self.write_keyword("WITH");
34898 self.write_space();
34899 }
34900 self.write_keyword("SERDEPROPERTIES");
34901 self.write(" (");
34902 for (i, expr) in e.expressions.iter().enumerate() {
34903 if i > 0 {
34904 self.write(", ");
34905 }
34906 match expr {
34908 Expression::Eq(eq) => {
34909 self.generate_expression(&eq.left)?;
34910 self.write("=");
34911 self.generate_expression(&eq.right)?;
34912 }
34913 _ => self.generate_expression(expr)?,
34914 }
34915 }
34916 self.write(")");
34917 Ok(())
34918 }
34919
34920 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
34921 self.write("@@");
34923 if let Some(kind) = &e.kind {
34924 self.write(kind);
34925 self.write(".");
34926 }
34927 self.generate_expression(&e.this)?;
34928 Ok(())
34929 }
34930
34931 fn generate_set(&mut self, e: &Set) -> Result<()> {
34932 if e.unset.is_some() {
34934 self.write_keyword("UNSET");
34935 } else {
34936 self.write_keyword("SET");
34937 }
34938 if e.tag.is_some() {
34939 self.write_space();
34940 self.write_keyword("TAG");
34941 }
34942 if !e.expressions.is_empty() {
34943 self.write_space();
34944 for (i, expr) in e.expressions.iter().enumerate() {
34945 if i > 0 {
34946 self.write(", ");
34947 }
34948 self.generate_expression(expr)?;
34949 }
34950 }
34951 Ok(())
34952 }
34953
34954 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
34955 self.write_keyword("SET");
34957 self.write_space();
34958 self.generate_expression(&e.this)?;
34959 Ok(())
34960 }
34961
34962 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
34963 if let Some(kind) = &e.kind {
34965 self.write_keyword(kind);
34966 self.write_space();
34967 }
34968 self.generate_expression(&e.name)?;
34969 self.write(" = ");
34970 self.generate_expression(&e.value)?;
34971 Ok(())
34972 }
34973
34974 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
34975 if let Some(with_) = &e.with_ {
34977 self.generate_expression(with_)?;
34978 self.write_space();
34979 }
34980 self.generate_expression(&e.this)?;
34981 self.write_space();
34982 if let Some(kind) = &e.kind {
34984 self.write_keyword(kind);
34985 }
34986 if e.distinct {
34987 self.write_space();
34988 self.write_keyword("DISTINCT");
34989 } else {
34990 self.write_space();
34991 self.write_keyword("ALL");
34992 }
34993 if e.by_name.is_some() {
34994 self.write_space();
34995 self.write_keyword("BY NAME");
34996 }
34997 self.write_space();
34998 self.generate_expression(&e.expression)?;
34999 Ok(())
35000 }
35001
35002 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
35003 if e.multi.is_some() {
35005 self.write_keyword("MULTISET");
35006 } else {
35007 self.write_keyword("SET");
35008 }
35009 Ok(())
35010 }
35011
35012 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
35013 self.write_keyword("SETTINGS");
35015 if self.config.pretty && e.expressions.len() > 1 {
35016 self.indent_level += 1;
35018 for (i, expr) in e.expressions.iter().enumerate() {
35019 if i > 0 {
35020 self.write(",");
35021 }
35022 self.write_newline();
35023 self.write_indent();
35024 self.generate_expression(expr)?;
35025 }
35026 self.indent_level -= 1;
35027 } else {
35028 self.write_space();
35029 for (i, expr) in e.expressions.iter().enumerate() {
35030 if i > 0 {
35031 self.write(", ");
35032 }
35033 self.generate_expression(expr)?;
35034 }
35035 }
35036 Ok(())
35037 }
35038
35039 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
35040 self.write_keyword("SHARING");
35042 if let Some(this) = &e.this {
35043 self.write(" = ");
35044 self.generate_expression(this)?;
35045 }
35046 Ok(())
35047 }
35048
35049 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
35050 if let Some(begin) = &e.this {
35052 self.generate_expression(begin)?;
35053 }
35054 self.write(":");
35055 if let Some(end) = &e.expression {
35056 self.generate_expression(end)?;
35057 }
35058 if let Some(step) = &e.step {
35059 self.write(":");
35060 self.generate_expression(step)?;
35061 }
35062 Ok(())
35063 }
35064
35065 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
35066 self.write_keyword("SORT_ARRAY");
35068 self.write("(");
35069 self.generate_expression(&e.this)?;
35070 if let Some(asc) = &e.asc {
35071 self.write(", ");
35072 self.generate_expression(asc)?;
35073 }
35074 self.write(")");
35075 Ok(())
35076 }
35077
35078 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
35079 self.write_keyword("SORT BY");
35081 self.write_space();
35082 for (i, expr) in e.expressions.iter().enumerate() {
35083 if i > 0 {
35084 self.write(", ");
35085 }
35086 self.generate_ordered(expr)?;
35087 }
35088 Ok(())
35089 }
35090
35091 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
35092 if e.compound.is_some() {
35094 self.write_keyword("COMPOUND");
35095 self.write_space();
35096 }
35097 self.write_keyword("SORTKEY");
35098 self.write("(");
35099 if let Expression::Tuple(t) = e.this.as_ref() {
35101 for (i, expr) in t.expressions.iter().enumerate() {
35102 if i > 0 {
35103 self.write(", ");
35104 }
35105 self.generate_expression(expr)?;
35106 }
35107 } else {
35108 self.generate_expression(&e.this)?;
35109 }
35110 self.write(")");
35111 Ok(())
35112 }
35113
35114 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
35115 self.write_keyword("SPLIT_PART");
35117 self.write("(");
35118 self.generate_expression(&e.this)?;
35119 if let Some(delimiter) = &e.delimiter {
35120 self.write(", ");
35121 self.generate_expression(delimiter)?;
35122 }
35123 if let Some(part_index) = &e.part_index {
35124 self.write(", ");
35125 self.generate_expression(part_index)?;
35126 }
35127 self.write(")");
35128 Ok(())
35129 }
35130
35131 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
35132 self.generate_expression(&e.this)?;
35134 Ok(())
35135 }
35136
35137 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
35138 self.write_keyword("SQL SECURITY");
35140 self.write_space();
35141 self.generate_expression(&e.this)?;
35142 Ok(())
35143 }
35144
35145 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
35146 self.write_keyword("ST_DISTANCE");
35148 self.write("(");
35149 self.generate_expression(&e.this)?;
35150 self.write(", ");
35151 self.generate_expression(&e.expression)?;
35152 if let Some(use_spheroid) = &e.use_spheroid {
35153 self.write(", ");
35154 self.generate_expression(use_spheroid)?;
35155 }
35156 self.write(")");
35157 Ok(())
35158 }
35159
35160 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
35161 self.write_keyword("ST_POINT");
35163 self.write("(");
35164 self.generate_expression(&e.this)?;
35165 self.write(", ");
35166 self.generate_expression(&e.expression)?;
35167 self.write(")");
35168 Ok(())
35169 }
35170
35171 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
35172 self.generate_expression(&e.this)?;
35174 Ok(())
35175 }
35176
35177 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
35178 self.write_keyword("STANDARD_HASH");
35180 self.write("(");
35181 self.generate_expression(&e.this)?;
35182 if let Some(expression) = &e.expression {
35183 self.write(", ");
35184 self.generate_expression(expression)?;
35185 }
35186 self.write(")");
35187 Ok(())
35188 }
35189
35190 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
35191 self.write_keyword("STORED BY");
35193 self.write_space();
35194 self.generate_expression(&e.this)?;
35195 Ok(())
35196 }
35197
35198 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
35199 use crate::dialects::DialectType;
35202 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35203 self.write_keyword("CHARINDEX");
35205 self.write("(");
35206 if let Some(substr) = &e.substr {
35207 self.generate_expression(substr)?;
35208 self.write(", ");
35209 }
35210 self.generate_expression(&e.this)?;
35211 if let Some(position) = &e.position {
35212 self.write(", ");
35213 self.generate_expression(position)?;
35214 }
35215 self.write(")");
35216 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
35217 self.write_keyword("POSITION");
35218 self.write("(");
35219 self.generate_expression(&e.this)?;
35220 if let Some(substr) = &e.substr {
35221 self.write(", ");
35222 self.generate_expression(substr)?;
35223 }
35224 if let Some(position) = &e.position {
35225 self.write(", ");
35226 self.generate_expression(position)?;
35227 }
35228 if let Some(occurrence) = &e.occurrence {
35229 self.write(", ");
35230 self.generate_expression(occurrence)?;
35231 }
35232 self.write(")");
35233 } else if matches!(
35234 self.config.dialect,
35235 Some(DialectType::SQLite)
35236 | Some(DialectType::Oracle)
35237 | Some(DialectType::BigQuery)
35238 | Some(DialectType::Teradata)
35239 ) {
35240 self.write_keyword("INSTR");
35241 self.write("(");
35242 self.generate_expression(&e.this)?;
35243 if let Some(substr) = &e.substr {
35244 self.write(", ");
35245 self.generate_expression(substr)?;
35246 }
35247 if let Some(position) = &e.position {
35248 self.write(", ");
35249 self.generate_expression(position)?;
35250 } else if e.occurrence.is_some() {
35251 self.write(", 1");
35254 }
35255 if let Some(occurrence) = &e.occurrence {
35256 self.write(", ");
35257 self.generate_expression(occurrence)?;
35258 }
35259 self.write(")");
35260 } else if matches!(
35261 self.config.dialect,
35262 Some(DialectType::MySQL)
35263 | Some(DialectType::SingleStore)
35264 | Some(DialectType::Doris)
35265 | Some(DialectType::StarRocks)
35266 | Some(DialectType::Hive)
35267 | Some(DialectType::Spark)
35268 | Some(DialectType::Databricks)
35269 ) {
35270 self.write_keyword("LOCATE");
35272 self.write("(");
35273 if let Some(substr) = &e.substr {
35274 self.generate_expression(substr)?;
35275 self.write(", ");
35276 }
35277 self.generate_expression(&e.this)?;
35278 if let Some(position) = &e.position {
35279 self.write(", ");
35280 self.generate_expression(position)?;
35281 }
35282 self.write(")");
35283 } else if matches!(
35284 self.config.dialect,
35285 Some(DialectType::TSQL) | Some(DialectType::Fabric)
35286 ) {
35287 self.write_keyword("CHARINDEX");
35289 self.write("(");
35290 if let Some(substr) = &e.substr {
35291 self.generate_expression(substr)?;
35292 self.write(", ");
35293 }
35294 self.generate_expression(&e.this)?;
35295 if let Some(position) = &e.position {
35296 self.write(", ");
35297 self.generate_expression(position)?;
35298 }
35299 self.write(")");
35300 } else if matches!(
35301 self.config.dialect,
35302 Some(DialectType::PostgreSQL)
35303 | Some(DialectType::Materialize)
35304 | Some(DialectType::RisingWave)
35305 | Some(DialectType::Redshift)
35306 ) {
35307 self.write_keyword("POSITION");
35309 self.write("(");
35310 if let Some(substr) = &e.substr {
35311 self.generate_expression(substr)?;
35312 self.write(" IN ");
35313 }
35314 self.generate_expression(&e.this)?;
35315 self.write(")");
35316 } else {
35317 self.write_keyword("STRPOS");
35318 self.write("(");
35319 self.generate_expression(&e.this)?;
35320 if let Some(substr) = &e.substr {
35321 self.write(", ");
35322 self.generate_expression(substr)?;
35323 }
35324 if let Some(position) = &e.position {
35325 self.write(", ");
35326 self.generate_expression(position)?;
35327 }
35328 if let Some(occurrence) = &e.occurrence {
35329 self.write(", ");
35330 self.generate_expression(occurrence)?;
35331 }
35332 self.write(")");
35333 }
35334 Ok(())
35335 }
35336
35337 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
35338 match self.config.dialect {
35339 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
35340 self.write_keyword("TO_DATE");
35342 self.write("(");
35343 self.generate_expression(&e.this)?;
35344 if let Some(format) = &e.format {
35345 self.write(", '");
35346 self.write(&Self::strftime_to_java_format(format));
35347 self.write("'");
35348 }
35349 self.write(")");
35350 }
35351 Some(DialectType::DuckDB) => {
35352 self.write_keyword("CAST");
35354 self.write("(");
35355 self.write_keyword("STRPTIME");
35356 self.write("(");
35357 self.generate_expression(&e.this)?;
35358 if let Some(format) = &e.format {
35359 self.write(", '");
35360 self.write(format);
35361 self.write("'");
35362 }
35363 self.write(")");
35364 self.write_keyword(" AS ");
35365 self.write_keyword("DATE");
35366 self.write(")");
35367 }
35368 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
35369 self.write_keyword("TO_DATE");
35371 self.write("(");
35372 self.generate_expression(&e.this)?;
35373 if let Some(format) = &e.format {
35374 self.write(", '");
35375 self.write(&Self::strftime_to_postgres_format(format));
35376 self.write("'");
35377 }
35378 self.write(")");
35379 }
35380 Some(DialectType::BigQuery) => {
35381 self.write_keyword("PARSE_DATE");
35383 self.write("(");
35384 if let Some(format) = &e.format {
35385 self.write("'");
35386 self.write(format);
35387 self.write("'");
35388 self.write(", ");
35389 }
35390 self.generate_expression(&e.this)?;
35391 self.write(")");
35392 }
35393 Some(DialectType::Teradata) => {
35394 self.write_keyword("CAST");
35396 self.write("(");
35397 self.generate_expression(&e.this)?;
35398 self.write_keyword(" AS ");
35399 self.write_keyword("DATE");
35400 if let Some(format) = &e.format {
35401 self.write_keyword(" FORMAT ");
35402 self.write("'");
35403 self.write(&Self::strftime_to_teradata_format(format));
35404 self.write("'");
35405 }
35406 self.write(")");
35407 }
35408 _ => {
35409 self.write_keyword("STR_TO_DATE");
35411 self.write("(");
35412 self.generate_expression(&e.this)?;
35413 if let Some(format) = &e.format {
35414 self.write(", '");
35415 self.write(format);
35416 self.write("'");
35417 }
35418 self.write(")");
35419 }
35420 }
35421 Ok(())
35422 }
35423
35424 fn strftime_to_teradata_format(fmt: &str) -> String {
35426 let mut result = String::with_capacity(fmt.len() * 2);
35427 let bytes = fmt.as_bytes();
35428 let len = bytes.len();
35429 let mut i = 0;
35430 while i < len {
35431 if bytes[i] == b'%' && i + 1 < len {
35432 let replacement = match bytes[i + 1] {
35433 b'Y' => "YYYY",
35434 b'y' => "YY",
35435 b'm' => "MM",
35436 b'B' => "MMMM",
35437 b'b' => "MMM",
35438 b'd' => "DD",
35439 b'j' => "DDD",
35440 b'H' => "HH",
35441 b'M' => "MI",
35442 b'S' => "SS",
35443 b'f' => "SSSSSS",
35444 b'A' => "EEEE",
35445 b'a' => "EEE",
35446 _ => {
35447 result.push('%');
35448 i += 1;
35449 continue;
35450 }
35451 };
35452 result.push_str(replacement);
35453 i += 2;
35454 } else {
35455 result.push(bytes[i] as char);
35456 i += 1;
35457 }
35458 }
35459 result
35460 }
35461
35462 pub fn strftime_to_java_format_static(fmt: &str) -> String {
35465 Self::strftime_to_java_format(fmt)
35466 }
35467
35468 fn strftime_to_java_format(fmt: &str) -> String {
35470 let mut result = String::with_capacity(fmt.len() * 2);
35471 let bytes = fmt.as_bytes();
35472 let len = bytes.len();
35473 let mut i = 0;
35474 while i < len {
35475 if bytes[i] == b'%' && i + 1 < len {
35476 if bytes[i + 1] == b'-' && i + 2 < len {
35478 let replacement = match bytes[i + 2] {
35479 b'd' => "d",
35480 b'm' => "M",
35481 b'H' => "H",
35482 b'M' => "m",
35483 b'S' => "s",
35484 _ => {
35485 result.push('%');
35486 i += 1;
35487 continue;
35488 }
35489 };
35490 result.push_str(replacement);
35491 i += 3;
35492 } else {
35493 let replacement = match bytes[i + 1] {
35494 b'Y' => "yyyy",
35495 b'y' => "yy",
35496 b'm' => "MM",
35497 b'B' => "MMMM",
35498 b'b' => "MMM",
35499 b'd' => "dd",
35500 b'j' => "DDD",
35501 b'H' => "HH",
35502 b'M' => "mm",
35503 b'S' => "ss",
35504 b'f' => "SSSSSS",
35505 b'A' => "EEEE",
35506 b'a' => "EEE",
35507 _ => {
35508 result.push('%');
35509 i += 1;
35510 continue;
35511 }
35512 };
35513 result.push_str(replacement);
35514 i += 2;
35515 }
35516 } else {
35517 result.push(bytes[i] as char);
35518 i += 1;
35519 }
35520 }
35521 result
35522 }
35523
35524 fn strftime_to_tsql_format(fmt: &str) -> String {
35527 let mut result = String::with_capacity(fmt.len() * 2);
35528 let bytes = fmt.as_bytes();
35529 let len = bytes.len();
35530 let mut i = 0;
35531 while i < len {
35532 if bytes[i] == b'%' && i + 1 < len {
35533 if bytes[i + 1] == b'-' && i + 2 < len {
35535 let replacement = match bytes[i + 2] {
35536 b'd' => "d",
35537 b'm' => "M",
35538 b'H' => "H",
35539 b'M' => "m",
35540 b'S' => "s",
35541 _ => {
35542 result.push('%');
35543 i += 1;
35544 continue;
35545 }
35546 };
35547 result.push_str(replacement);
35548 i += 3;
35549 } else {
35550 let replacement = match bytes[i + 1] {
35551 b'Y' => "yyyy",
35552 b'y' => "yy",
35553 b'm' => "MM",
35554 b'B' => "MMMM",
35555 b'b' => "MMM",
35556 b'd' => "dd",
35557 b'j' => "DDD",
35558 b'H' => "HH",
35559 b'M' => "mm",
35560 b'S' => "ss",
35561 b'f' => "ffffff",
35562 b'A' => "dddd",
35563 b'a' => "ddd",
35564 _ => {
35565 result.push('%');
35566 i += 1;
35567 continue;
35568 }
35569 };
35570 result.push_str(replacement);
35571 i += 2;
35572 }
35573 } else {
35574 result.push(bytes[i] as char);
35575 i += 1;
35576 }
35577 }
35578 result
35579 }
35580
35581 fn decompose_json_path(path: &str) -> Vec<String> {
35584 let mut parts = Vec::new();
35585 let path = if path.starts_with("$.") {
35587 &path[2..]
35588 } else if path.starts_with('$') {
35589 &path[1..]
35590 } else {
35591 path
35592 };
35593 if path.is_empty() {
35594 return parts;
35595 }
35596 let mut current = String::new();
35597 let chars: Vec<char> = path.chars().collect();
35598 let mut i = 0;
35599 while i < chars.len() {
35600 match chars[i] {
35601 '.' => {
35602 if !current.is_empty() {
35603 parts.push(current.clone());
35604 current.clear();
35605 }
35606 i += 1;
35607 }
35608 '[' => {
35609 if !current.is_empty() {
35610 parts.push(current.clone());
35611 current.clear();
35612 }
35613 i += 1;
35614 let mut bracket_content = String::new();
35616 while i < chars.len() && chars[i] != ']' {
35617 if chars[i] == '"' || chars[i] == '\'' {
35619 let quote = chars[i];
35620 i += 1;
35621 while i < chars.len() && chars[i] != quote {
35622 bracket_content.push(chars[i]);
35623 i += 1;
35624 }
35625 if i < chars.len() {
35626 i += 1;
35627 } } else {
35629 bracket_content.push(chars[i]);
35630 i += 1;
35631 }
35632 }
35633 if i < chars.len() {
35634 i += 1;
35635 } if bracket_content != "*" {
35638 parts.push(bracket_content);
35639 }
35640 }
35641 _ => {
35642 current.push(chars[i]);
35643 i += 1;
35644 }
35645 }
35646 }
35647 if !current.is_empty() {
35648 parts.push(current);
35649 }
35650 parts
35651 }
35652
35653 fn strftime_to_postgres_format(fmt: &str) -> String {
35655 let mut result = String::with_capacity(fmt.len() * 2);
35656 let bytes = fmt.as_bytes();
35657 let len = bytes.len();
35658 let mut i = 0;
35659 while i < len {
35660 if bytes[i] == b'%' && i + 1 < len {
35661 if bytes[i + 1] == b'-' && i + 2 < len {
35663 let replacement = match bytes[i + 2] {
35664 b'd' => "FMDD",
35665 b'm' => "FMMM",
35666 b'H' => "FMHH24",
35667 b'M' => "FMMI",
35668 b'S' => "FMSS",
35669 _ => {
35670 result.push('%');
35671 i += 1;
35672 continue;
35673 }
35674 };
35675 result.push_str(replacement);
35676 i += 3;
35677 } else {
35678 let replacement = match bytes[i + 1] {
35679 b'Y' => "YYYY",
35680 b'y' => "YY",
35681 b'm' => "MM",
35682 b'B' => "Month",
35683 b'b' => "Mon",
35684 b'd' => "DD",
35685 b'j' => "DDD",
35686 b'H' => "HH24",
35687 b'M' => "MI",
35688 b'S' => "SS",
35689 b'f' => "US",
35690 b'A' => "Day",
35691 b'a' => "Dy",
35692 _ => {
35693 result.push('%');
35694 i += 1;
35695 continue;
35696 }
35697 };
35698 result.push_str(replacement);
35699 i += 2;
35700 }
35701 } else {
35702 result.push(bytes[i] as char);
35703 i += 1;
35704 }
35705 }
35706 result
35707 }
35708
35709 fn strftime_to_snowflake_format(fmt: &str) -> String {
35711 let mut result = String::with_capacity(fmt.len() * 2);
35712 let bytes = fmt.as_bytes();
35713 let len = bytes.len();
35714 let mut i = 0;
35715 while i < len {
35716 if bytes[i] == b'%' && i + 1 < len {
35717 if bytes[i + 1] == b'-' && i + 2 < len {
35719 let replacement = match bytes[i + 2] {
35720 b'd' => "dd",
35721 b'm' => "mm",
35722 _ => {
35723 result.push('%');
35724 i += 1;
35725 continue;
35726 }
35727 };
35728 result.push_str(replacement);
35729 i += 3;
35730 } else {
35731 let replacement = match bytes[i + 1] {
35732 b'Y' => "yyyy",
35733 b'y' => "yy",
35734 b'm' => "mm",
35735 b'd' => "DD",
35736 b'H' => "hh24",
35737 b'M' => "mi",
35738 b'S' => "ss",
35739 b'f' => "ff",
35740 _ => {
35741 result.push('%');
35742 i += 1;
35743 continue;
35744 }
35745 };
35746 result.push_str(replacement);
35747 i += 2;
35748 }
35749 } else {
35750 result.push(bytes[i] as char);
35751 i += 1;
35752 }
35753 }
35754 result
35755 }
35756
35757 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
35758 self.write_keyword("STR_TO_MAP");
35760 self.write("(");
35761 self.generate_expression(&e.this)?;
35762 let needs_defaults = matches!(
35764 self.config.dialect,
35765 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
35766 );
35767 if let Some(pair_delim) = &e.pair_delim {
35768 self.write(", ");
35769 self.generate_expression(pair_delim)?;
35770 } else if needs_defaults {
35771 self.write(", ','");
35772 }
35773 if let Some(key_value_delim) = &e.key_value_delim {
35774 self.write(", ");
35775 self.generate_expression(key_value_delim)?;
35776 } else if needs_defaults {
35777 self.write(", ':'");
35778 }
35779 self.write(")");
35780 Ok(())
35781 }
35782
35783 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
35784 let is_strftime = e.format.contains('%');
35786 let to_strftime = |f: &str| -> String {
35788 if is_strftime {
35789 f.to_string()
35790 } else {
35791 Self::snowflake_format_to_strftime(f)
35792 }
35793 };
35794 let to_java = |f: &str| -> String {
35796 if is_strftime {
35797 Self::strftime_to_java_format(f)
35798 } else {
35799 Self::snowflake_format_to_spark(f)
35800 }
35801 };
35802 let to_pg = |f: &str| -> String {
35804 if is_strftime {
35805 Self::strftime_to_postgres_format(f)
35806 } else {
35807 Self::convert_strptime_to_postgres_format(f)
35808 }
35809 };
35810
35811 match self.config.dialect {
35812 Some(DialectType::Exasol) => {
35813 self.write_keyword("TO_DATE");
35814 self.write("(");
35815 self.generate_expression(&e.this)?;
35816 self.write(", '");
35817 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35818 self.write("'");
35819 self.write(")");
35820 }
35821 Some(DialectType::BigQuery) => {
35822 let fmt = to_strftime(&e.format);
35824 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35826 self.write_keyword("PARSE_TIMESTAMP");
35827 self.write("('");
35828 self.write(&fmt);
35829 self.write("', ");
35830 self.generate_expression(&e.this)?;
35831 self.write(")");
35832 }
35833 Some(DialectType::Hive) => {
35834 let java_fmt = to_java(&e.format);
35837 if java_fmt == "yyyy-MM-dd HH:mm:ss"
35838 || java_fmt == "yyyy-MM-dd"
35839 || e.format == "yyyy-MM-dd HH:mm:ss"
35840 || e.format == "yyyy-MM-dd"
35841 {
35842 self.write_keyword("CAST");
35843 self.write("(");
35844 self.generate_expression(&e.this)?;
35845 self.write(" ");
35846 self.write_keyword("AS TIMESTAMP");
35847 self.write(")");
35848 } else {
35849 self.write_keyword("CAST");
35851 self.write("(");
35852 self.write_keyword("FROM_UNIXTIME");
35853 self.write("(");
35854 self.write_keyword("UNIX_TIMESTAMP");
35855 self.write("(");
35856 self.generate_expression(&e.this)?;
35857 self.write(", '");
35858 self.write(&java_fmt);
35859 self.write("')");
35860 self.write(") ");
35861 self.write_keyword("AS TIMESTAMP");
35862 self.write(")");
35863 }
35864 }
35865 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35866 let java_fmt = to_java(&e.format);
35868 self.write_keyword("TO_TIMESTAMP");
35869 self.write("(");
35870 self.generate_expression(&e.this)?;
35871 self.write(", '");
35872 self.write(&java_fmt);
35873 self.write("')");
35874 }
35875 Some(DialectType::MySQL) => {
35876 let mut fmt = to_strftime(&e.format);
35878 fmt = fmt.replace("%-d", "%e");
35880 fmt = fmt.replace("%-m", "%c");
35881 fmt = fmt.replace("%H:%M:%S", "%T");
35882 self.write_keyword("STR_TO_DATE");
35883 self.write("(");
35884 self.generate_expression(&e.this)?;
35885 self.write(", '");
35886 self.write(&fmt);
35887 self.write("')");
35888 }
35889 Some(DialectType::Drill) => {
35890 let java_fmt = to_java(&e.format);
35892 let java_fmt = java_fmt.replace('T', "''T''");
35894 self.write_keyword("TO_TIMESTAMP");
35895 self.write("(");
35896 self.generate_expression(&e.this)?;
35897 self.write(", '");
35898 self.write(&java_fmt);
35899 self.write("')");
35900 }
35901 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35902 let mut fmt = to_strftime(&e.format);
35904 fmt = fmt.replace("%-d", "%e");
35906 fmt = fmt.replace("%-m", "%c");
35907 fmt = fmt.replace("%H:%M:%S", "%T");
35908 self.write_keyword("DATE_PARSE");
35909 self.write("(");
35910 self.generate_expression(&e.this)?;
35911 self.write(", '");
35912 self.write(&fmt);
35913 self.write("')");
35914 }
35915 Some(DialectType::DuckDB) => {
35916 let fmt = to_strftime(&e.format);
35918 self.write_keyword("STRPTIME");
35919 self.write("(");
35920 self.generate_expression(&e.this)?;
35921 self.write(", '");
35922 self.write(&fmt);
35923 self.write("')");
35924 }
35925 Some(DialectType::PostgreSQL)
35926 | Some(DialectType::Redshift)
35927 | Some(DialectType::Materialize) => {
35928 let pg_fmt = to_pg(&e.format);
35930 self.write_keyword("TO_TIMESTAMP");
35931 self.write("(");
35932 self.generate_expression(&e.this)?;
35933 self.write(", '");
35934 self.write(&pg_fmt);
35935 self.write("')");
35936 }
35937 Some(DialectType::Oracle) => {
35938 let pg_fmt = to_pg(&e.format);
35940 self.write_keyword("TO_TIMESTAMP");
35941 self.write("(");
35942 self.generate_expression(&e.this)?;
35943 self.write(", '");
35944 self.write(&pg_fmt);
35945 self.write("')");
35946 }
35947 Some(DialectType::Snowflake) => {
35948 self.write_keyword("TO_TIMESTAMP");
35950 self.write("(");
35951 self.generate_expression(&e.this)?;
35952 self.write(", '");
35953 self.write(&e.format);
35954 self.write("')");
35955 }
35956 _ => {
35957 self.write_keyword("STR_TO_TIME");
35959 self.write("(");
35960 self.generate_expression(&e.this)?;
35961 self.write(", '");
35962 self.write(&e.format);
35963 self.write("'");
35964 self.write(")");
35965 }
35966 }
35967 Ok(())
35968 }
35969
35970 fn snowflake_format_to_strftime(format: &str) -> String {
35972 let mut result = String::new();
35973 let chars: Vec<char> = format.chars().collect();
35974 let mut i = 0;
35975 while i < chars.len() {
35976 let remaining = &format[i..];
35977 if remaining.starts_with("yyyy") {
35978 result.push_str("%Y");
35979 i += 4;
35980 } else if remaining.starts_with("yy") {
35981 result.push_str("%y");
35982 i += 2;
35983 } else if remaining.starts_with("mmmm") {
35984 result.push_str("%B"); i += 4;
35986 } else if remaining.starts_with("mon") {
35987 result.push_str("%b"); i += 3;
35989 } else if remaining.starts_with("mm") {
35990 result.push_str("%m");
35991 i += 2;
35992 } else if remaining.starts_with("DD") {
35993 result.push_str("%d");
35994 i += 2;
35995 } else if remaining.starts_with("dy") {
35996 result.push_str("%a"); i += 2;
35998 } else if remaining.starts_with("hh24") {
35999 result.push_str("%H");
36000 i += 4;
36001 } else if remaining.starts_with("hh12") {
36002 result.push_str("%I");
36003 i += 4;
36004 } else if remaining.starts_with("hh") {
36005 result.push_str("%H");
36006 i += 2;
36007 } else if remaining.starts_with("mi") {
36008 result.push_str("%M");
36009 i += 2;
36010 } else if remaining.starts_with("ss") {
36011 result.push_str("%S");
36012 i += 2;
36013 } else if remaining.starts_with("ff") {
36014 result.push_str("%f");
36016 i += 2;
36017 while i < chars.len() && chars[i].is_ascii_digit() {
36019 i += 1;
36020 }
36021 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
36022 result.push_str("%p");
36023 i += 2;
36024 } else if remaining.starts_with("tz") {
36025 result.push_str("%Z");
36026 i += 2;
36027 } else {
36028 result.push(chars[i]);
36029 i += 1;
36030 }
36031 }
36032 result
36033 }
36034
36035 fn snowflake_format_to_spark(format: &str) -> String {
36037 let mut result = String::new();
36038 let chars: Vec<char> = format.chars().collect();
36039 let mut i = 0;
36040 while i < chars.len() {
36041 let remaining = &format[i..];
36042 if remaining.starts_with("yyyy") {
36043 result.push_str("yyyy");
36044 i += 4;
36045 } else if remaining.starts_with("yy") {
36046 result.push_str("yy");
36047 i += 2;
36048 } else if remaining.starts_with("mmmm") {
36049 result.push_str("MMMM"); i += 4;
36051 } else if remaining.starts_with("mon") {
36052 result.push_str("MMM"); i += 3;
36054 } else if remaining.starts_with("mm") {
36055 result.push_str("MM");
36056 i += 2;
36057 } else if remaining.starts_with("DD") {
36058 result.push_str("dd");
36059 i += 2;
36060 } else if remaining.starts_with("dy") {
36061 result.push_str("EEE"); i += 2;
36063 } else if remaining.starts_with("hh24") {
36064 result.push_str("HH");
36065 i += 4;
36066 } else if remaining.starts_with("hh12") {
36067 result.push_str("hh");
36068 i += 4;
36069 } else if remaining.starts_with("hh") {
36070 result.push_str("HH");
36071 i += 2;
36072 } else if remaining.starts_with("mi") {
36073 result.push_str("mm");
36074 i += 2;
36075 } else if remaining.starts_with("ss") {
36076 result.push_str("ss");
36077 i += 2;
36078 } else if remaining.starts_with("ff") {
36079 result.push_str("SSS"); i += 2;
36081 while i < chars.len() && chars[i].is_ascii_digit() {
36083 i += 1;
36084 }
36085 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
36086 result.push_str("a");
36087 i += 2;
36088 } else if remaining.starts_with("tz") {
36089 result.push_str("z");
36090 i += 2;
36091 } else {
36092 result.push(chars[i]);
36093 i += 1;
36094 }
36095 }
36096 result
36097 }
36098
36099 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
36100 match self.config.dialect {
36101 Some(DialectType::DuckDB) => {
36102 self.write_keyword("EPOCH");
36104 self.write("(");
36105 self.write_keyword("STRPTIME");
36106 self.write("(");
36107 if let Some(this) = &e.this {
36108 self.generate_expression(this)?;
36109 }
36110 if let Some(format) = &e.format {
36111 self.write(", '");
36112 self.write(format);
36113 self.write("'");
36114 }
36115 self.write("))");
36116 }
36117 Some(DialectType::Hive) => {
36118 self.write_keyword("UNIX_TIMESTAMP");
36120 self.write("(");
36121 if let Some(this) = &e.this {
36122 self.generate_expression(this)?;
36123 }
36124 if let Some(format) = &e.format {
36125 let java_fmt = Self::strftime_to_java_format(format);
36126 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
36127 self.write(", '");
36128 self.write(&java_fmt);
36129 self.write("'");
36130 }
36131 }
36132 self.write(")");
36133 }
36134 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36135 self.write_keyword("UNIX_TIMESTAMP");
36137 self.write("(");
36138 if let Some(this) = &e.this {
36139 self.generate_expression(this)?;
36140 }
36141 if let Some(format) = &e.format {
36142 self.write(", '");
36143 self.write(format);
36144 self.write("'");
36145 }
36146 self.write(")");
36147 }
36148 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36149 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
36152 let java_fmt = Self::strftime_to_java_format(c_fmt);
36153 self.write_keyword("TO_UNIXTIME");
36154 self.write("(");
36155 self.write_keyword("COALESCE");
36156 self.write("(");
36157 self.write_keyword("TRY");
36158 self.write("(");
36159 self.write_keyword("DATE_PARSE");
36160 self.write("(");
36161 self.write_keyword("CAST");
36162 self.write("(");
36163 if let Some(this) = &e.this {
36164 self.generate_expression(this)?;
36165 }
36166 self.write(" ");
36167 self.write_keyword("AS VARCHAR");
36168 self.write("), '");
36169 self.write(c_fmt);
36170 self.write("')), ");
36171 self.write_keyword("PARSE_DATETIME");
36172 self.write("(");
36173 self.write_keyword("DATE_FORMAT");
36174 self.write("(");
36175 self.write_keyword("CAST");
36176 self.write("(");
36177 if let Some(this) = &e.this {
36178 self.generate_expression(this)?;
36179 }
36180 self.write(" ");
36181 self.write_keyword("AS TIMESTAMP");
36182 self.write("), '");
36183 self.write(c_fmt);
36184 self.write("'), '");
36185 self.write(&java_fmt);
36186 self.write("')))");
36187 }
36188 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36189 self.write_keyword("UNIX_TIMESTAMP");
36191 self.write("(");
36192 if let Some(this) = &e.this {
36193 self.generate_expression(this)?;
36194 }
36195 if let Some(format) = &e.format {
36196 let java_fmt = Self::strftime_to_java_format(format);
36197 self.write(", '");
36198 self.write(&java_fmt);
36199 self.write("'");
36200 }
36201 self.write(")");
36202 }
36203 _ => {
36204 self.write_keyword("STR_TO_UNIX");
36206 self.write("(");
36207 if let Some(this) = &e.this {
36208 self.generate_expression(this)?;
36209 }
36210 if let Some(format) = &e.format {
36211 self.write(", '");
36212 self.write(format);
36213 self.write("'");
36214 }
36215 self.write(")");
36216 }
36217 }
36218 Ok(())
36219 }
36220
36221 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
36222 self.write_keyword("STRING_TO_ARRAY");
36224 self.write("(");
36225 self.generate_expression(&e.this)?;
36226 if let Some(expression) = &e.expression {
36227 self.write(", ");
36228 self.generate_expression(expression)?;
36229 }
36230 if let Some(null_val) = &e.null {
36231 self.write(", ");
36232 self.generate_expression(null_val)?;
36233 }
36234 self.write(")");
36235 Ok(())
36236 }
36237
36238 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
36239 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36240 self.write_keyword("OBJECT_CONSTRUCT");
36242 self.write("(");
36243 for (i, (name, expr)) in e.fields.iter().enumerate() {
36244 if i > 0 {
36245 self.write(", ");
36246 }
36247 if let Some(name) = name {
36248 self.write("'");
36249 self.write(name);
36250 self.write("'");
36251 self.write(", ");
36252 } else {
36253 self.write("'_");
36254 self.write(&i.to_string());
36255 self.write("'");
36256 self.write(", ");
36257 }
36258 self.generate_expression(expr)?;
36259 }
36260 self.write(")");
36261 } else if self.config.struct_curly_brace_notation {
36262 self.write("{");
36264 for (i, (name, expr)) in e.fields.iter().enumerate() {
36265 if i > 0 {
36266 self.write(", ");
36267 }
36268 if let Some(name) = name {
36269 self.write("'");
36271 self.write(name);
36272 self.write("'");
36273 self.write(": ");
36274 } else {
36275 self.write("'_");
36277 self.write(&i.to_string());
36278 self.write("'");
36279 self.write(": ");
36280 }
36281 self.generate_expression(expr)?;
36282 }
36283 self.write("}");
36284 } else {
36285 let value_as_name = matches!(
36289 self.config.dialect,
36290 Some(DialectType::BigQuery)
36291 | Some(DialectType::Spark)
36292 | Some(DialectType::Databricks)
36293 | Some(DialectType::Hive)
36294 );
36295 self.write_keyword("STRUCT");
36296 self.write("(");
36297 for (i, (name, expr)) in e.fields.iter().enumerate() {
36298 if i > 0 {
36299 self.write(", ");
36300 }
36301 if let Some(name) = name {
36302 if value_as_name {
36303 self.generate_expression(expr)?;
36305 self.write_space();
36306 self.write_keyword("AS");
36307 self.write_space();
36308 let needs_quoting = name.contains(' ') || name.contains('-');
36310 if needs_quoting {
36311 if matches!(
36312 self.config.dialect,
36313 Some(DialectType::Spark)
36314 | Some(DialectType::Databricks)
36315 | Some(DialectType::Hive)
36316 ) {
36317 self.write("`");
36318 self.write(name);
36319 self.write("`");
36320 } else {
36321 self.write(name);
36322 }
36323 } else {
36324 self.write(name);
36325 }
36326 } else {
36327 self.write(name);
36329 self.write_space();
36330 self.write_keyword("AS");
36331 self.write_space();
36332 self.generate_expression(expr)?;
36333 }
36334 } else {
36335 self.generate_expression(expr)?;
36336 }
36337 }
36338 self.write(")");
36339 }
36340 Ok(())
36341 }
36342
36343 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
36344 self.write_keyword("STUFF");
36346 self.write("(");
36347 self.generate_expression(&e.this)?;
36348 if let Some(start) = &e.start {
36349 self.write(", ");
36350 self.generate_expression(start)?;
36351 }
36352 if let Some(length) = e.length {
36353 self.write(", ");
36354 self.write(&length.to_string());
36355 }
36356 self.write(", ");
36357 self.generate_expression(&e.expression)?;
36358 self.write(")");
36359 Ok(())
36360 }
36361
36362 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
36363 self.write_keyword("SUBSTRING_INDEX");
36365 self.write("(");
36366 self.generate_expression(&e.this)?;
36367 if let Some(delimiter) = &e.delimiter {
36368 self.write(", ");
36369 self.generate_expression(delimiter)?;
36370 }
36371 if let Some(count) = &e.count {
36372 self.write(", ");
36373 self.generate_expression(count)?;
36374 }
36375 self.write(")");
36376 Ok(())
36377 }
36378
36379 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
36380 self.write_keyword("SUMMARIZE");
36382 if e.table.is_some() {
36383 self.write_space();
36384 self.write_keyword("TABLE");
36385 }
36386 self.write_space();
36387 self.generate_expression(&e.this)?;
36388 Ok(())
36389 }
36390
36391 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
36392 self.write_keyword("SYSTIMESTAMP");
36394 Ok(())
36395 }
36396
36397 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
36398 if let Some(this) = &e.this {
36400 self.generate_expression(this)?;
36401 }
36402 if !e.columns.is_empty() {
36403 self.write("(");
36404 for (i, col) in e.columns.iter().enumerate() {
36405 if i > 0 {
36406 self.write(", ");
36407 }
36408 self.generate_expression(col)?;
36409 }
36410 self.write(")");
36411 }
36412 Ok(())
36413 }
36414
36415 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
36416 self.write_keyword("TABLE");
36418 self.write("(");
36419 self.generate_expression(&e.this)?;
36420 self.write(")");
36421 if let Some(alias) = &e.alias {
36422 self.write_space();
36423 self.write_keyword("AS");
36424 self.write_space();
36425 self.write(alias);
36426 }
36427 Ok(())
36428 }
36429
36430 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
36431 self.write_keyword("ROWS FROM");
36433 self.write(" (");
36434 for (i, expr) in e.expressions.iter().enumerate() {
36435 if i > 0 {
36436 self.write(", ");
36437 }
36438 match expr {
36442 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
36443 self.generate_expression(&tuple.expressions[0])?;
36445 self.write_space();
36446 self.write_keyword("AS");
36447 self.write_space();
36448 self.generate_expression(&tuple.expressions[1])?;
36449 }
36450 _ => {
36451 self.generate_expression(expr)?;
36452 }
36453 }
36454 }
36455 self.write(")");
36456 if e.ordinality {
36457 self.write_space();
36458 self.write_keyword("WITH ORDINALITY");
36459 }
36460 if let Some(alias) = &e.alias {
36461 self.write_space();
36462 self.write_keyword("AS");
36463 self.write_space();
36464 self.generate_expression(alias)?;
36465 }
36466 Ok(())
36467 }
36468
36469 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
36470 use crate::dialects::DialectType;
36471
36472 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
36474 if self.config.alias_post_tablesample {
36476 if let Expression::Subquery(ref s) = **this {
36478 if let Some(ref alias) = s.alias {
36479 let mut subquery_no_alias = (**s).clone();
36481 subquery_no_alias.alias = None;
36482 subquery_no_alias.column_aliases = Vec::new();
36483 self.generate_expression(&Expression::Subquery(Box::new(
36484 subquery_no_alias,
36485 )))?;
36486 self.write_space();
36487 self.write_keyword(self.config.tablesample_keywords);
36488 self.generate_sample_body(sample)?;
36489 if let Some(ref seed) = sample.seed {
36490 self.write_space();
36491 let use_seed = sample.use_seed_keyword
36492 && !matches!(
36493 self.config.dialect,
36494 Some(crate::dialects::DialectType::Databricks)
36495 | Some(crate::dialects::DialectType::Spark)
36496 );
36497 if use_seed {
36498 self.write_keyword("SEED");
36499 } else {
36500 self.write_keyword("REPEATABLE");
36501 }
36502 self.write(" (");
36503 self.generate_expression(seed)?;
36504 self.write(")");
36505 }
36506 self.write_space();
36507 self.write_keyword("AS");
36508 self.write_space();
36509 self.generate_identifier(alias)?;
36510 return Ok(());
36511 }
36512 } else if let Expression::Alias(ref a) = **this {
36513 self.generate_expression(&a.this)?;
36515 self.write_space();
36516 self.write_keyword(self.config.tablesample_keywords);
36517 self.generate_sample_body(sample)?;
36518 if let Some(ref seed) = sample.seed {
36519 self.write_space();
36520 let use_seed = sample.use_seed_keyword
36521 && !matches!(
36522 self.config.dialect,
36523 Some(crate::dialects::DialectType::Databricks)
36524 | Some(crate::dialects::DialectType::Spark)
36525 );
36526 if use_seed {
36527 self.write_keyword("SEED");
36528 } else {
36529 self.write_keyword("REPEATABLE");
36530 }
36531 self.write(" (");
36532 self.generate_expression(seed)?;
36533 self.write(")");
36534 }
36535 self.write_space();
36537 self.write_keyword("AS");
36538 self.write_space();
36539 self.generate_identifier(&a.alias)?;
36540 return Ok(());
36541 }
36542 }
36543 self.generate_expression(this)?;
36545 self.write_space();
36546 self.write_keyword(self.config.tablesample_keywords);
36547 self.generate_sample_body(sample)?;
36548 if let Some(ref seed) = sample.seed {
36550 self.write_space();
36551 let use_seed = sample.use_seed_keyword
36553 && !matches!(
36554 self.config.dialect,
36555 Some(crate::dialects::DialectType::Databricks)
36556 | Some(crate::dialects::DialectType::Spark)
36557 );
36558 if use_seed {
36559 self.write_keyword("SEED");
36560 } else {
36561 self.write_keyword("REPEATABLE");
36562 }
36563 self.write(" (");
36564 self.generate_expression(seed)?;
36565 self.write(")");
36566 }
36567 return Ok(());
36568 }
36569
36570 self.write_keyword(self.config.tablesample_keywords);
36572 if let Some(method) = &e.method {
36573 self.write_space();
36574 self.write_keyword(method);
36575 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36576 self.write_space();
36578 self.write_keyword("BERNOULLI");
36579 }
36580 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
36581 self.write_space();
36582 self.write_keyword("BUCKET");
36583 self.write_space();
36584 self.generate_expression(numerator)?;
36585 self.write_space();
36586 self.write_keyword("OUT OF");
36587 self.write_space();
36588 self.generate_expression(denominator)?;
36589 if let Some(field) = &e.bucket_field {
36590 self.write_space();
36591 self.write_keyword("ON");
36592 self.write_space();
36593 self.generate_expression(field)?;
36594 }
36595 } else if !e.expressions.is_empty() {
36596 self.write(" (");
36597 for (i, expr) in e.expressions.iter().enumerate() {
36598 if i > 0 {
36599 self.write(", ");
36600 }
36601 self.generate_expression(expr)?;
36602 }
36603 self.write(")");
36604 } else if let Some(percent) = &e.percent {
36605 self.write(" (");
36606 self.generate_expression(percent)?;
36607 self.write_space();
36608 self.write_keyword("PERCENT");
36609 self.write(")");
36610 }
36611 Ok(())
36612 }
36613
36614 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
36615 if let Some(prefix) = &e.prefix {
36617 self.generate_expression(prefix)?;
36618 }
36619 if let Some(this) = &e.this {
36620 self.generate_expression(this)?;
36621 }
36622 if let Some(postfix) = &e.postfix {
36623 self.generate_expression(postfix)?;
36624 }
36625 Ok(())
36626 }
36627
36628 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
36629 self.write_keyword("TAG");
36631 self.write(" (");
36632 for (i, expr) in e.expressions.iter().enumerate() {
36633 if i > 0 {
36634 self.write(", ");
36635 }
36636 self.generate_expression(expr)?;
36637 }
36638 self.write(")");
36639 Ok(())
36640 }
36641
36642 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
36643 if let Some(this) = &e.this {
36645 self.generate_expression(this)?;
36646 self.write_space();
36647 }
36648 self.write_keyword("TEMPORARY");
36649 Ok(())
36650 }
36651
36652 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
36655 self.write_keyword("TIME");
36657 self.write("(");
36658 self.generate_expression(&e.this)?;
36659 self.write(")");
36660 Ok(())
36661 }
36662
36663 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
36664 self.write_keyword("TIME_ADD");
36666 self.write("(");
36667 self.generate_expression(&e.this)?;
36668 self.write(", ");
36669 self.generate_expression(&e.expression)?;
36670 if let Some(unit) = &e.unit {
36671 self.write(", ");
36672 self.write_keyword(unit);
36673 }
36674 self.write(")");
36675 Ok(())
36676 }
36677
36678 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
36679 self.write_keyword("TIME_DIFF");
36681 self.write("(");
36682 self.generate_expression(&e.this)?;
36683 self.write(", ");
36684 self.generate_expression(&e.expression)?;
36685 if let Some(unit) = &e.unit {
36686 self.write(", ");
36687 self.write_keyword(unit);
36688 }
36689 self.write(")");
36690 Ok(())
36691 }
36692
36693 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
36694 self.write_keyword("TIME_FROM_PARTS");
36696 self.write("(");
36697 let mut first = true;
36698 if let Some(hour) = &e.hour {
36699 self.generate_expression(hour)?;
36700 first = false;
36701 }
36702 if let Some(minute) = &e.min {
36703 if !first {
36704 self.write(", ");
36705 }
36706 self.generate_expression(minute)?;
36707 first = false;
36708 }
36709 if let Some(second) = &e.sec {
36710 if !first {
36711 self.write(", ");
36712 }
36713 self.generate_expression(second)?;
36714 first = false;
36715 }
36716 if let Some(ns) = &e.nano {
36717 if !first {
36718 self.write(", ");
36719 }
36720 self.generate_expression(ns)?;
36721 }
36722 self.write(")");
36723 Ok(())
36724 }
36725
36726 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
36727 self.write_keyword("TIME_SLICE");
36729 self.write("(");
36730 self.generate_expression(&e.this)?;
36731 self.write(", ");
36732 self.generate_expression(&e.expression)?;
36733 self.write(", ");
36734 self.write_keyword(&e.unit);
36735 self.write(")");
36736 Ok(())
36737 }
36738
36739 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
36740 self.write_keyword("TIME_STR_TO_TIME");
36742 self.write("(");
36743 self.generate_expression(&e.this)?;
36744 self.write(")");
36745 Ok(())
36746 }
36747
36748 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
36749 self.write_keyword("TIME_SUB");
36751 self.write("(");
36752 self.generate_expression(&e.this)?;
36753 self.write(", ");
36754 self.generate_expression(&e.expression)?;
36755 if let Some(unit) = &e.unit {
36756 self.write(", ");
36757 self.write_keyword(unit);
36758 }
36759 self.write(")");
36760 Ok(())
36761 }
36762
36763 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
36764 match self.config.dialect {
36765 Some(DialectType::Exasol) => {
36766 self.write_keyword("TO_CHAR");
36768 self.write("(");
36769 self.generate_expression(&e.this)?;
36770 self.write(", '");
36771 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
36772 self.write("'");
36773 self.write(")");
36774 }
36775 Some(DialectType::PostgreSQL)
36776 | Some(DialectType::Redshift)
36777 | Some(DialectType::Materialize) => {
36778 self.write_keyword("TO_CHAR");
36780 self.write("(");
36781 self.generate_expression(&e.this)?;
36782 self.write(", '");
36783 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36784 self.write("'");
36785 self.write(")");
36786 }
36787 Some(DialectType::Oracle) => {
36788 self.write_keyword("TO_CHAR");
36790 self.write("(");
36791 self.generate_expression(&e.this)?;
36792 self.write(", '");
36793 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36794 self.write("'");
36795 self.write(")");
36796 }
36797 Some(DialectType::Drill) => {
36798 self.write_keyword("TO_CHAR");
36800 self.write("(");
36801 self.generate_expression(&e.this)?;
36802 self.write(", '");
36803 self.write(&Self::strftime_to_java_format(&e.format));
36804 self.write("'");
36805 self.write(")");
36806 }
36807 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
36808 self.write_keyword("FORMAT");
36810 self.write("(");
36811 self.generate_expression(&e.this)?;
36812 self.write(", '");
36813 self.write(&Self::strftime_to_tsql_format(&e.format));
36814 self.write("'");
36815 self.write(")");
36816 }
36817 Some(DialectType::DuckDB) => {
36818 self.write_keyword("STRFTIME");
36820 self.write("(");
36821 self.generate_expression(&e.this)?;
36822 self.write(", '");
36823 self.write(&e.format);
36824 self.write("'");
36825 self.write(")");
36826 }
36827 Some(DialectType::BigQuery) => {
36828 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
36831 self.write_keyword("FORMAT_DATE");
36832 self.write("('");
36833 self.write(&fmt);
36834 self.write("', ");
36835 self.generate_expression(&e.this)?;
36836 self.write(")");
36837 }
36838 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36839 self.write_keyword("DATE_FORMAT");
36841 self.write("(");
36842 self.generate_expression(&e.this)?;
36843 self.write(", '");
36844 self.write(&Self::strftime_to_java_format(&e.format));
36845 self.write("'");
36846 self.write(")");
36847 }
36848 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
36849 self.write_keyword("DATE_FORMAT");
36851 self.write("(");
36852 self.generate_expression(&e.this)?;
36853 self.write(", '");
36854 self.write(&e.format);
36855 self.write("'");
36856 self.write(")");
36857 }
36858 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36859 self.write_keyword("DATE_FORMAT");
36861 self.write("(");
36862 self.generate_expression(&e.this)?;
36863 self.write(", '");
36864 self.write(&e.format);
36865 self.write("'");
36866 self.write(")");
36867 }
36868 _ => {
36869 self.write_keyword("TIME_TO_STR");
36871 self.write("(");
36872 self.generate_expression(&e.this)?;
36873 self.write(", '");
36874 self.write(&e.format);
36875 self.write("'");
36876 self.write(")");
36877 }
36878 }
36879 Ok(())
36880 }
36881
36882 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36883 match self.config.dialect {
36884 Some(DialectType::DuckDB) => {
36885 self.write_keyword("EPOCH");
36887 self.write("(");
36888 self.generate_expression(&e.this)?;
36889 self.write(")");
36890 }
36891 Some(DialectType::Hive)
36892 | Some(DialectType::Spark)
36893 | Some(DialectType::Databricks)
36894 | Some(DialectType::Doris)
36895 | Some(DialectType::StarRocks)
36896 | Some(DialectType::Drill) => {
36897 self.write_keyword("UNIX_TIMESTAMP");
36899 self.write("(");
36900 self.generate_expression(&e.this)?;
36901 self.write(")");
36902 }
36903 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36904 self.write_keyword("TO_UNIXTIME");
36906 self.write("(");
36907 self.generate_expression(&e.this)?;
36908 self.write(")");
36909 }
36910 _ => {
36911 self.write_keyword("TIME_TO_UNIX");
36913 self.write("(");
36914 self.generate_expression(&e.this)?;
36915 self.write(")");
36916 }
36917 }
36918 Ok(())
36919 }
36920
36921 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36922 match self.config.dialect {
36923 Some(DialectType::Hive) => {
36924 self.write_keyword("TO_DATE");
36926 self.write("(");
36927 self.generate_expression(&e.this)?;
36928 self.write(")");
36929 }
36930 _ => {
36931 self.write_keyword("TIME_STR_TO_DATE");
36933 self.write("(");
36934 self.generate_expression(&e.this)?;
36935 self.write(")");
36936 }
36937 }
36938 Ok(())
36939 }
36940
36941 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
36942 self.write_keyword("TIME_TRUNC");
36944 self.write("(");
36945 self.generate_expression(&e.this)?;
36946 self.write(", ");
36947 self.write_keyword(&e.unit);
36948 self.write(")");
36949 Ok(())
36950 }
36951
36952 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
36953 if let Some(unit) = &e.unit {
36955 self.write_keyword(unit);
36956 }
36957 Ok(())
36958 }
36959
36960 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
36964 use crate::dialects::DialectType;
36965 use crate::expressions::Literal;
36966
36967 match self.config.dialect {
36968 Some(DialectType::Exasol) => {
36970 self.write_keyword("TO_TIMESTAMP");
36971 self.write("(");
36972 if let Some(this) = &e.this {
36974 match this.as_ref() {
36975 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36976 let Literal::String(s) = lit.as_ref() else {
36977 unreachable!()
36978 };
36979 self.write("'");
36980 self.write(s);
36981 self.write("'");
36982 }
36983 _ => {
36984 self.generate_expression(this)?;
36985 }
36986 }
36987 }
36988 self.write(")");
36989 }
36990 _ => {
36992 self.write_keyword("TIMESTAMP");
36993 self.write("(");
36994 if let Some(this) = &e.this {
36995 self.generate_expression(this)?;
36996 }
36997 if let Some(zone) = &e.zone {
36998 self.write(", ");
36999 self.generate_expression(zone)?;
37000 }
37001 self.write(")");
37002 }
37003 }
37004 Ok(())
37005 }
37006
37007 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
37008 self.write_keyword("TIMESTAMP_ADD");
37010 self.write("(");
37011 self.generate_expression(&e.this)?;
37012 self.write(", ");
37013 self.generate_expression(&e.expression)?;
37014 if let Some(unit) = &e.unit {
37015 self.write(", ");
37016 self.write_keyword(unit);
37017 }
37018 self.write(")");
37019 Ok(())
37020 }
37021
37022 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
37023 self.write_keyword("TIMESTAMP_DIFF");
37025 self.write("(");
37026 self.generate_expression(&e.this)?;
37027 self.write(", ");
37028 self.generate_expression(&e.expression)?;
37029 if let Some(unit) = &e.unit {
37030 self.write(", ");
37031 self.write_keyword(unit);
37032 }
37033 self.write(")");
37034 Ok(())
37035 }
37036
37037 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
37038 self.write_keyword("TIMESTAMP_FROM_PARTS");
37040 self.write("(");
37041 if let Some(this) = &e.this {
37042 self.generate_expression(this)?;
37043 }
37044 if let Some(expression) = &e.expression {
37045 self.write(", ");
37046 self.generate_expression(expression)?;
37047 }
37048 if let Some(zone) = &e.zone {
37049 self.write(", ");
37050 self.generate_expression(zone)?;
37051 }
37052 if let Some(milli) = &e.milli {
37053 self.write(", ");
37054 self.generate_expression(milli)?;
37055 }
37056 self.write(")");
37057 Ok(())
37058 }
37059
37060 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
37061 self.write_keyword("TIMESTAMP_SUB");
37063 self.write("(");
37064 self.generate_expression(&e.this)?;
37065 self.write(", ");
37066 self.write_keyword("INTERVAL");
37067 self.write_space();
37068 self.generate_expression(&e.expression)?;
37069 if let Some(unit) = &e.unit {
37070 self.write_space();
37071 self.write_keyword(unit);
37072 }
37073 self.write(")");
37074 Ok(())
37075 }
37076
37077 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
37078 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
37080 self.write("(");
37081 if let Some(zone) = &e.zone {
37082 self.generate_expression(zone)?;
37083 }
37084 self.write(")");
37085 Ok(())
37086 }
37087
37088 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
37089 self.write_keyword("TO_BINARY");
37091 self.write("(");
37092 self.generate_expression(&e.this)?;
37093 if let Some(format) = &e.format {
37094 self.write(", '");
37095 self.write(format);
37096 self.write("'");
37097 }
37098 self.write(")");
37099 Ok(())
37100 }
37101
37102 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
37103 self.write_keyword("TO_BOOLEAN");
37105 self.write("(");
37106 self.generate_expression(&e.this)?;
37107 self.write(")");
37108 Ok(())
37109 }
37110
37111 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
37112 self.write_keyword("TO_CHAR");
37114 self.write("(");
37115 self.generate_expression(&e.this)?;
37116 if let Some(format) = &e.format {
37117 self.write(", '");
37118 self.write(format);
37119 self.write("'");
37120 }
37121 if let Some(nlsparam) = &e.nlsparam {
37122 self.write(", ");
37123 self.generate_expression(nlsparam)?;
37124 }
37125 self.write(")");
37126 Ok(())
37127 }
37128
37129 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
37130 self.write_keyword("TO_DECFLOAT");
37132 self.write("(");
37133 self.generate_expression(&e.this)?;
37134 if let Some(format) = &e.format {
37135 self.write(", '");
37136 self.write(format);
37137 self.write("'");
37138 }
37139 self.write(")");
37140 Ok(())
37141 }
37142
37143 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
37144 self.write_keyword("TO_DOUBLE");
37146 self.write("(");
37147 self.generate_expression(&e.this)?;
37148 if let Some(format) = &e.format {
37149 self.write(", '");
37150 self.write(format);
37151 self.write("'");
37152 }
37153 self.write(")");
37154 Ok(())
37155 }
37156
37157 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
37158 self.write_keyword("TO_FILE");
37160 self.write("(");
37161 self.generate_expression(&e.this)?;
37162 if let Some(path) = &e.path {
37163 self.write(", ");
37164 self.generate_expression(path)?;
37165 }
37166 self.write(")");
37167 Ok(())
37168 }
37169
37170 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
37171 let is_safe = e.safe.is_some();
37174 if is_safe {
37175 self.write_keyword("TRY_TO_NUMBER");
37176 } else {
37177 self.write_keyword("TO_NUMBER");
37178 }
37179 self.write("(");
37180 self.generate_expression(&e.this)?;
37181 let precision_is_snowflake_default = e.precision.is_none()
37182 || matches!(
37183 e.precision.as_deref(),
37184 Some(Expression::Literal(lit))
37185 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
37186 );
37187 let is_snowflake_default_precision =
37188 matches!(self.config.dialect, Some(DialectType::Snowflake))
37189 && e.nlsparam.is_none()
37190 && e.scale.is_none()
37191 && matches!(
37192 e.format.as_deref(),
37193 Some(Expression::Literal(lit))
37194 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
37195 )
37196 && precision_is_snowflake_default;
37197
37198 if !is_snowflake_default_precision {
37199 if let Some(format) = &e.format {
37200 self.write(", ");
37201 self.generate_expression(format)?;
37202 }
37203 if let Some(nlsparam) = &e.nlsparam {
37204 self.write(", ");
37205 self.generate_expression(nlsparam)?;
37206 }
37207 if let Some(precision) = &e.precision {
37208 self.write(", ");
37209 self.generate_expression(precision)?;
37210 }
37211 if let Some(scale) = &e.scale {
37212 self.write(", ");
37213 self.generate_expression(scale)?;
37214 }
37215 }
37216 self.write(")");
37217 Ok(())
37218 }
37219
37220 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
37221 self.write_keyword("TO_TABLE");
37223 self.write_space();
37224 self.generate_expression(&e.this)?;
37225 Ok(())
37226 }
37227
37228 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
37229 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
37231 Expression::Identifier(id) => id.name.clone(),
37232 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
37233 let Literal::String(s) = lit.as_ref() else {
37234 unreachable!()
37235 };
37236 s.clone()
37237 }
37238 _ => String::new(),
37239 });
37240
37241 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
37242 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
37243 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
37244 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
37245 });
37246
37247 let use_start_transaction = matches!(
37249 self.config.dialect,
37250 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
37251 );
37252 let strip_transaction = matches!(
37254 self.config.dialect,
37255 Some(DialectType::Snowflake)
37256 | Some(DialectType::PostgreSQL)
37257 | Some(DialectType::Redshift)
37258 | Some(DialectType::MySQL)
37259 | Some(DialectType::Hive)
37260 | Some(DialectType::Spark)
37261 | Some(DialectType::Databricks)
37262 | Some(DialectType::DuckDB)
37263 | Some(DialectType::Oracle)
37264 | Some(DialectType::Doris)
37265 | Some(DialectType::StarRocks)
37266 | Some(DialectType::Materialize)
37267 | Some(DialectType::ClickHouse)
37268 );
37269
37270 if is_start || use_start_transaction {
37271 self.write_keyword("START TRANSACTION");
37273 if let Some(modes) = &e.modes {
37274 self.write_space();
37275 self.generate_expression(modes)?;
37276 }
37277 } else {
37278 self.write_keyword("BEGIN");
37280
37281 let is_kind = e.this.as_ref().map_or(false, |t| {
37283 if let Expression::Identifier(id) = t.as_ref() {
37284 id.name.eq_ignore_ascii_case("DEFERRED")
37285 || id.name.eq_ignore_ascii_case("IMMEDIATE")
37286 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
37287 } else {
37288 false
37289 }
37290 });
37291
37292 if is_kind {
37294 if let Some(this) = &e.this {
37295 self.write_space();
37296 if let Expression::Identifier(id) = this.as_ref() {
37297 self.write_keyword(&id.name);
37298 }
37299 }
37300 }
37301
37302 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
37304 self.write_space();
37305 self.write_keyword("TRANSACTION");
37306 }
37307
37308 if !is_kind {
37310 if let Some(this) = &e.this {
37311 self.write_space();
37312 self.generate_expression(this)?;
37313 }
37314 }
37315
37316 if has_with_mark {
37318 self.write_space();
37319 self.write_keyword("WITH MARK");
37320 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
37321 if let Literal::String(desc) = lit.as_ref() {
37322 if !desc.is_empty() {
37323 self.write_space();
37324 self.write(&format!("'{}'", desc));
37325 }
37326 }
37327 }
37328 }
37329
37330 if let Some(modes) = &e.modes {
37332 self.write_space();
37333 self.generate_expression(modes)?;
37334 }
37335 }
37336 Ok(())
37337 }
37338
37339 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
37340 self.write_keyword("TRANSFORM");
37342 self.write("(");
37343 self.generate_expression(&e.this)?;
37344 self.write(", ");
37345 self.generate_expression(&e.expression)?;
37346 self.write(")");
37347 Ok(())
37348 }
37349
37350 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
37351 self.write_keyword("TRANSFORM");
37353 self.write("(");
37354 if self.config.pretty && !e.expressions.is_empty() {
37355 self.indent_level += 1;
37356 for (i, expr) in e.expressions.iter().enumerate() {
37357 if i > 0 {
37358 self.write(",");
37359 }
37360 self.write_newline();
37361 self.write_indent();
37362 self.generate_expression(expr)?;
37363 }
37364 self.indent_level -= 1;
37365 self.write_newline();
37366 self.write(")");
37367 } else {
37368 for (i, expr) in e.expressions.iter().enumerate() {
37369 if i > 0 {
37370 self.write(", ");
37371 }
37372 self.generate_expression(expr)?;
37373 }
37374 self.write(")");
37375 }
37376 Ok(())
37377 }
37378
37379 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
37380 use crate::dialects::DialectType;
37381 if let Some(this) = &e.this {
37383 self.generate_expression(this)?;
37384 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
37385 self.write_space();
37386 }
37387 }
37388 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
37389 self.write_keyword("TRANSIENT");
37390 }
37391 Ok(())
37392 }
37393
37394 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
37395 self.write_keyword("TRANSLATE");
37397 self.write("(");
37398 self.generate_expression(&e.this)?;
37399 if let Some(from) = &e.from_ {
37400 self.write(", ");
37401 self.generate_expression(from)?;
37402 }
37403 if let Some(to) = &e.to {
37404 self.write(", ");
37405 self.generate_expression(to)?;
37406 }
37407 self.write(")");
37408 Ok(())
37409 }
37410
37411 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
37412 self.write_keyword("TRANSLATE");
37414 self.write("(");
37415 self.generate_expression(&e.this)?;
37416 self.write_space();
37417 self.write_keyword("USING");
37418 self.write_space();
37419 self.generate_expression(&e.expression)?;
37420 if e.with_error.is_some() {
37421 self.write_space();
37422 self.write_keyword("WITH ERROR");
37423 }
37424 self.write(")");
37425 Ok(())
37426 }
37427
37428 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
37429 self.write_keyword("TRUNCATE TABLE");
37431 self.write_space();
37432 for (i, expr) in e.expressions.iter().enumerate() {
37433 if i > 0 {
37434 self.write(", ");
37435 }
37436 self.generate_expression(expr)?;
37437 }
37438 Ok(())
37439 }
37440
37441 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
37442 self.write_keyword("TRY_BASE64_DECODE_BINARY");
37444 self.write("(");
37445 self.generate_expression(&e.this)?;
37446 if let Some(alphabet) = &e.alphabet {
37447 self.write(", ");
37448 self.generate_expression(alphabet)?;
37449 }
37450 self.write(")");
37451 Ok(())
37452 }
37453
37454 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
37455 self.write_keyword("TRY_BASE64_DECODE_STRING");
37457 self.write("(");
37458 self.generate_expression(&e.this)?;
37459 if let Some(alphabet) = &e.alphabet {
37460 self.write(", ");
37461 self.generate_expression(alphabet)?;
37462 }
37463 self.write(")");
37464 Ok(())
37465 }
37466
37467 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
37468 self.write_keyword("TRY_TO_DECFLOAT");
37470 self.write("(");
37471 self.generate_expression(&e.this)?;
37472 if let Some(format) = &e.format {
37473 self.write(", '");
37474 self.write(format);
37475 self.write("'");
37476 }
37477 self.write(")");
37478 Ok(())
37479 }
37480
37481 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
37482 self.write_keyword("TS_OR_DS_ADD");
37484 self.write("(");
37485 self.generate_expression(&e.this)?;
37486 self.write(", ");
37487 self.generate_expression(&e.expression)?;
37488 if let Some(unit) = &e.unit {
37489 self.write(", ");
37490 self.write_keyword(unit);
37491 }
37492 if let Some(return_type) = &e.return_type {
37493 self.write(", ");
37494 self.generate_expression(return_type)?;
37495 }
37496 self.write(")");
37497 Ok(())
37498 }
37499
37500 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
37501 self.write_keyword("TS_OR_DS_DIFF");
37503 self.write("(");
37504 self.generate_expression(&e.this)?;
37505 self.write(", ");
37506 self.generate_expression(&e.expression)?;
37507 if let Some(unit) = &e.unit {
37508 self.write(", ");
37509 self.write_keyword(unit);
37510 }
37511 self.write(")");
37512 Ok(())
37513 }
37514
37515 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
37516 let default_time_format = "%Y-%m-%d %H:%M:%S";
37517 let default_date_format = "%Y-%m-%d";
37518 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
37519 f != default_time_format && f != default_date_format
37520 });
37521
37522 if has_non_default_format {
37523 let fmt = e.format.as_ref().unwrap();
37525 match self.config.dialect {
37526 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
37527 let str_to_time = crate::expressions::StrToTime {
37530 this: Box::new((*e.this).clone()),
37531 format: fmt.clone(),
37532 zone: None,
37533 safe: None,
37534 target_type: None,
37535 };
37536 self.generate_str_to_time(&str_to_time)?;
37537 }
37538 Some(DialectType::Hive)
37539 | Some(DialectType::Spark)
37540 | Some(DialectType::Databricks) => {
37541 self.write_keyword("TO_DATE");
37543 self.write("(");
37544 self.generate_expression(&e.this)?;
37545 self.write(", '");
37546 self.write(&Self::strftime_to_java_format(fmt));
37547 self.write("')");
37548 }
37549 Some(DialectType::Snowflake) => {
37550 self.write_keyword("TO_DATE");
37552 self.write("(");
37553 self.generate_expression(&e.this)?;
37554 self.write(", '");
37555 self.write(&Self::strftime_to_snowflake_format(fmt));
37556 self.write("')");
37557 }
37558 Some(DialectType::Doris) => {
37559 self.write_keyword("TO_DATE");
37561 self.write("(");
37562 self.generate_expression(&e.this)?;
37563 self.write(")");
37564 }
37565 _ => {
37566 self.write_keyword("CAST");
37568 self.write("(");
37569 let str_to_time = crate::expressions::StrToTime {
37570 this: Box::new((*e.this).clone()),
37571 format: fmt.clone(),
37572 zone: None,
37573 safe: None,
37574 target_type: None,
37575 };
37576 self.generate_str_to_time(&str_to_time)?;
37577 self.write_keyword(" AS ");
37578 self.write_keyword("DATE");
37579 self.write(")");
37580 }
37581 }
37582 } else {
37583 match self.config.dialect {
37585 Some(DialectType::MySQL)
37586 | Some(DialectType::SQLite)
37587 | Some(DialectType::StarRocks) => {
37588 self.write_keyword("DATE");
37590 self.write("(");
37591 self.generate_expression(&e.this)?;
37592 self.write(")");
37593 }
37594 Some(DialectType::Hive)
37595 | Some(DialectType::Spark)
37596 | Some(DialectType::Databricks)
37597 | Some(DialectType::Snowflake)
37598 | Some(DialectType::Doris) => {
37599 self.write_keyword("TO_DATE");
37601 self.write("(");
37602 self.generate_expression(&e.this)?;
37603 self.write(")");
37604 }
37605 Some(DialectType::Presto)
37606 | Some(DialectType::Trino)
37607 | Some(DialectType::Athena) => {
37608 self.write_keyword("CAST");
37610 self.write("(");
37611 self.write_keyword("CAST");
37612 self.write("(");
37613 self.generate_expression(&e.this)?;
37614 self.write_keyword(" AS ");
37615 self.write_keyword("TIMESTAMP");
37616 self.write(")");
37617 self.write_keyword(" AS ");
37618 self.write_keyword("DATE");
37619 self.write(")");
37620 }
37621 Some(DialectType::ClickHouse) => {
37622 self.write_keyword("CAST");
37624 self.write("(");
37625 self.generate_expression(&e.this)?;
37626 self.write_keyword(" AS ");
37627 self.write("Nullable(DATE)");
37628 self.write(")");
37629 }
37630 _ => {
37631 self.write_keyword("CAST");
37633 self.write("(");
37634 self.generate_expression(&e.this)?;
37635 self.write_keyword(" AS ");
37636 self.write_keyword("DATE");
37637 self.write(")");
37638 }
37639 }
37640 }
37641 Ok(())
37642 }
37643
37644 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
37645 self.write_keyword("TS_OR_DS_TO_TIME");
37647 self.write("(");
37648 self.generate_expression(&e.this)?;
37649 if let Some(format) = &e.format {
37650 self.write(", '");
37651 self.write(format);
37652 self.write("'");
37653 }
37654 self.write(")");
37655 Ok(())
37656 }
37657
37658 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
37659 self.write_keyword("UNHEX");
37661 self.write("(");
37662 self.generate_expression(&e.this)?;
37663 if let Some(expression) = &e.expression {
37664 self.write(", ");
37665 self.generate_expression(expression)?;
37666 }
37667 self.write(")");
37668 Ok(())
37669 }
37670
37671 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
37672 self.write("U&");
37674 self.generate_expression(&e.this)?;
37675 if let Some(escape) = &e.escape {
37676 self.write_space();
37677 self.write_keyword("UESCAPE");
37678 self.write_space();
37679 self.generate_expression(escape)?;
37680 }
37681 Ok(())
37682 }
37683
37684 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
37685 self.write_keyword("UNIFORM");
37687 self.write("(");
37688 self.generate_expression(&e.this)?;
37689 self.write(", ");
37690 self.generate_expression(&e.expression)?;
37691 if let Some(gen) = &e.gen {
37692 self.write(", ");
37693 self.generate_expression(gen)?;
37694 }
37695 if let Some(seed) = &e.seed {
37696 self.write(", ");
37697 self.generate_expression(seed)?;
37698 }
37699 self.write(")");
37700 Ok(())
37701 }
37702
37703 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
37704 self.write_keyword("UNIQUE");
37706 if e.nulls.is_some() {
37708 self.write(" NULLS NOT DISTINCT");
37709 }
37710 if let Some(this) = &e.this {
37711 self.write_space();
37712 self.generate_expression(this)?;
37713 }
37714 if let Some(index_type) = &e.index_type {
37715 self.write(" USING ");
37716 self.generate_expression(index_type)?;
37717 }
37718 if let Some(on_conflict) = &e.on_conflict {
37719 self.write_space();
37720 self.generate_expression(on_conflict)?;
37721 }
37722 for opt in &e.options {
37723 self.write_space();
37724 self.generate_expression(opt)?;
37725 }
37726 Ok(())
37727 }
37728
37729 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
37730 self.write_keyword("UNIQUE KEY");
37732 self.write(" (");
37733 for (i, expr) in e.expressions.iter().enumerate() {
37734 if i > 0 {
37735 self.write(", ");
37736 }
37737 self.generate_expression(expr)?;
37738 }
37739 self.write(")");
37740 Ok(())
37741 }
37742
37743 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
37744 self.write_keyword("ROLLUP");
37746 self.write(" (");
37747 for (i, index) in e.expressions.iter().enumerate() {
37748 if i > 0 {
37749 self.write(", ");
37750 }
37751 self.generate_identifier(&index.name)?;
37752 self.write("(");
37753 for (j, col) in index.expressions.iter().enumerate() {
37754 if j > 0 {
37755 self.write(", ");
37756 }
37757 self.generate_identifier(col)?;
37758 }
37759 self.write(")");
37760 }
37761 self.write(")");
37762 Ok(())
37763 }
37764
37765 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
37766 match self.config.dialect {
37767 Some(DialectType::DuckDB) => {
37768 self.write_keyword("STRFTIME");
37770 self.write("(");
37771 self.write_keyword("TO_TIMESTAMP");
37772 self.write("(");
37773 self.generate_expression(&e.this)?;
37774 self.write("), '");
37775 if let Some(format) = &e.format {
37776 self.write(format);
37777 }
37778 self.write("')");
37779 }
37780 Some(DialectType::Hive) => {
37781 self.write_keyword("FROM_UNIXTIME");
37783 self.write("(");
37784 self.generate_expression(&e.this)?;
37785 if let Some(format) = &e.format {
37786 if format != "yyyy-MM-dd HH:mm:ss" {
37787 self.write(", '");
37788 self.write(format);
37789 self.write("'");
37790 }
37791 }
37792 self.write(")");
37793 }
37794 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37795 self.write_keyword("DATE_FORMAT");
37797 self.write("(");
37798 self.write_keyword("FROM_UNIXTIME");
37799 self.write("(");
37800 self.generate_expression(&e.this)?;
37801 self.write("), '");
37802 if let Some(format) = &e.format {
37803 self.write(format);
37804 }
37805 self.write("')");
37806 }
37807 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37808 self.write_keyword("FROM_UNIXTIME");
37810 self.write("(");
37811 self.generate_expression(&e.this)?;
37812 if let Some(format) = &e.format {
37813 self.write(", '");
37814 self.write(format);
37815 self.write("'");
37816 }
37817 self.write(")");
37818 }
37819 _ => {
37820 self.write_keyword("UNIX_TO_STR");
37822 self.write("(");
37823 self.generate_expression(&e.this)?;
37824 if let Some(format) = &e.format {
37825 self.write(", '");
37826 self.write(format);
37827 self.write("'");
37828 }
37829 self.write(")");
37830 }
37831 }
37832 Ok(())
37833 }
37834
37835 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
37836 use crate::dialects::DialectType;
37837 let scale = e.scale.unwrap_or(0); match self.config.dialect {
37840 Some(DialectType::Snowflake) => {
37841 self.write_keyword("TO_TIMESTAMP");
37843 self.write("(");
37844 self.generate_expression(&e.this)?;
37845 if let Some(s) = e.scale {
37846 if s > 0 {
37847 self.write(", ");
37848 self.write(&s.to_string());
37849 }
37850 }
37851 self.write(")");
37852 }
37853 Some(DialectType::BigQuery) => {
37854 match scale {
37857 0 => {
37858 self.write_keyword("TIMESTAMP_SECONDS");
37859 self.write("(");
37860 self.generate_expression(&e.this)?;
37861 self.write(")");
37862 }
37863 3 => {
37864 self.write_keyword("TIMESTAMP_MILLIS");
37865 self.write("(");
37866 self.generate_expression(&e.this)?;
37867 self.write(")");
37868 }
37869 6 => {
37870 self.write_keyword("TIMESTAMP_MICROS");
37871 self.write("(");
37872 self.generate_expression(&e.this)?;
37873 self.write(")");
37874 }
37875 _ => {
37876 self.write_keyword("TIMESTAMP_SECONDS");
37878 self.write("(CAST(");
37879 self.generate_expression(&e.this)?;
37880 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
37881 }
37882 }
37883 }
37884 Some(DialectType::Spark) => {
37885 match scale {
37890 0 => {
37891 self.write_keyword("CAST");
37892 self.write("(");
37893 self.write_keyword("FROM_UNIXTIME");
37894 self.write("(");
37895 self.generate_expression(&e.this)?;
37896 self.write(") ");
37897 self.write_keyword("AS TIMESTAMP");
37898 self.write(")");
37899 }
37900 3 => {
37901 self.write_keyword("TIMESTAMP_MILLIS");
37902 self.write("(");
37903 self.generate_expression(&e.this)?;
37904 self.write(")");
37905 }
37906 6 => {
37907 self.write_keyword("TIMESTAMP_MICROS");
37908 self.write("(");
37909 self.generate_expression(&e.this)?;
37910 self.write(")");
37911 }
37912 _ => {
37913 self.write_keyword("TIMESTAMP_SECONDS");
37914 self.write("(");
37915 self.generate_expression(&e.this)?;
37916 self.write(&format!(" / POWER(10, {}))", scale));
37917 }
37918 }
37919 }
37920 Some(DialectType::Databricks) => {
37921 match scale {
37925 0 => {
37926 self.write_keyword("CAST");
37927 self.write("(");
37928 self.write_keyword("FROM_UNIXTIME");
37929 self.write("(");
37930 self.generate_expression(&e.this)?;
37931 self.write(") ");
37932 self.write_keyword("AS TIMESTAMP");
37933 self.write(")");
37934 }
37935 3 => {
37936 self.write_keyword("TIMESTAMP_MILLIS");
37937 self.write("(");
37938 self.generate_expression(&e.this)?;
37939 self.write(")");
37940 }
37941 6 => {
37942 self.write_keyword("TIMESTAMP_MICROS");
37943 self.write("(");
37944 self.generate_expression(&e.this)?;
37945 self.write(")");
37946 }
37947 _ => {
37948 self.write_keyword("TIMESTAMP_SECONDS");
37949 self.write("(");
37950 self.generate_expression(&e.this)?;
37951 self.write(&format!(" / POWER(10, {}))", scale));
37952 }
37953 }
37954 }
37955 Some(DialectType::Hive) => {
37956 if scale == 0 {
37958 self.write_keyword("FROM_UNIXTIME");
37959 self.write("(");
37960 self.generate_expression(&e.this)?;
37961 self.write(")");
37962 } else {
37963 self.write_keyword("FROM_UNIXTIME");
37964 self.write("(");
37965 self.generate_expression(&e.this)?;
37966 self.write(&format!(" / POWER(10, {})", scale));
37967 self.write(")");
37968 }
37969 }
37970 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37971 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("(CAST(");
37981 self.generate_expression(&e.this)?;
37982 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
37983 }
37984 }
37985 Some(DialectType::DuckDB) => {
37986 match scale {
37990 0 => {
37991 self.write_keyword("TO_TIMESTAMP");
37992 self.write("(");
37993 self.generate_expression(&e.this)?;
37994 self.write(")");
37995 }
37996 3 => {
37997 self.write_keyword("EPOCH_MS");
37998 self.write("(");
37999 self.generate_expression(&e.this)?;
38000 self.write(")");
38001 }
38002 6 => {
38003 self.write_keyword("MAKE_TIMESTAMP");
38004 self.write("(");
38005 self.generate_expression(&e.this)?;
38006 self.write(")");
38007 }
38008 _ => {
38009 self.write_keyword("TO_TIMESTAMP");
38010 self.write("(");
38011 self.generate_expression(&e.this)?;
38012 self.write(&format!(" / POWER(10, {}))", scale));
38013 self.write_keyword(" AT TIME ZONE");
38014 self.write(" 'UTC'");
38015 }
38016 }
38017 }
38018 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
38019 self.write_keyword("FROM_UNIXTIME");
38021 self.write("(");
38022 self.generate_expression(&e.this)?;
38023 self.write(")");
38024 }
38025 Some(DialectType::Oracle) => {
38026 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
38028 self.generate_expression(&e.this)?;
38029 self.write(" / 86400)");
38030 }
38031 Some(DialectType::Redshift) => {
38032 self.write("(TIMESTAMP 'epoch' + ");
38035 if scale == 0 {
38036 self.generate_expression(&e.this)?;
38037 } else {
38038 self.write("(");
38039 self.generate_expression(&e.this)?;
38040 self.write(&format!(" / POWER(10, {}))", scale));
38041 }
38042 self.write(" * INTERVAL '1 SECOND')");
38043 }
38044 Some(DialectType::Exasol) => {
38045 self.write_keyword("FROM_POSIX_TIME");
38047 self.write("(");
38048 self.generate_expression(&e.this)?;
38049 self.write(")");
38050 }
38051 _ => {
38052 self.write_keyword("TO_TIMESTAMP");
38054 self.write("(");
38055 self.generate_expression(&e.this)?;
38056 if let Some(s) = e.scale {
38057 self.write(", ");
38058 self.write(&s.to_string());
38059 }
38060 self.write(")");
38061 }
38062 }
38063 Ok(())
38064 }
38065
38066 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
38067 if !matches!(&*e.this, Expression::Null(_)) {
38069 self.write_keyword("NAME");
38070 self.write_space();
38071 self.generate_expression(&e.this)?;
38072 }
38073 if !e.expressions.is_empty() {
38074 self.write_space();
38075 self.write_keyword("VALUE");
38076 self.write_space();
38077 for (i, expr) in e.expressions.iter().enumerate() {
38078 if i > 0 {
38079 self.write(", ");
38080 }
38081 self.generate_expression(expr)?;
38082 }
38083 }
38084 Ok(())
38085 }
38086
38087 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
38088 if e.wrapped.is_some() {
38090 self.write("(");
38091 }
38092 self.generate_expression(&e.this)?;
38093 if e.wrapped.is_some() {
38094 self.write(")");
38095 }
38096 self.write("(");
38097 for (i, expr) in e.expressions.iter().enumerate() {
38098 if i > 0 {
38099 self.write(", ");
38100 }
38101 self.generate_expression(expr)?;
38102 }
38103 self.write(")");
38104 Ok(())
38105 }
38106
38107 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
38108 self.write_keyword("USING TEMPLATE");
38110 self.write_space();
38111 self.generate_expression(&e.this)?;
38112 Ok(())
38113 }
38114
38115 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
38116 self.write_keyword("UTC_TIME");
38118 Ok(())
38119 }
38120
38121 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
38122 if matches!(
38123 self.config.dialect,
38124 Some(crate::dialects::DialectType::ClickHouse)
38125 ) {
38126 self.write_keyword("CURRENT_TIMESTAMP");
38127 self.write("('UTC')");
38128 } else {
38129 self.write_keyword("UTC_TIMESTAMP");
38130 }
38131 Ok(())
38132 }
38133
38134 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
38135 use crate::dialects::DialectType;
38136 let func_name = match self.config.dialect {
38138 Some(DialectType::Snowflake) => "UUID_STRING",
38139 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
38140 Some(DialectType::BigQuery) => "GENERATE_UUID",
38141 _ => {
38142 if let Some(name) = &e.name {
38143 name.as_str()
38144 } else {
38145 "UUID"
38146 }
38147 }
38148 };
38149 self.write_keyword(func_name);
38150 self.write("(");
38151 if let Some(this) = &e.this {
38152 self.generate_expression(this)?;
38153 }
38154 self.write(")");
38155 Ok(())
38156 }
38157
38158 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
38159 self.write_keyword("MAP");
38161 self.write("(");
38162 let mut first = true;
38163 for (k, v) in e.keys.iter().zip(e.values.iter()) {
38164 if !first {
38165 self.write(", ");
38166 }
38167 self.generate_expression(k)?;
38168 self.write(", ");
38169 self.generate_expression(v)?;
38170 first = false;
38171 }
38172 self.write(")");
38173 Ok(())
38174 }
38175
38176 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
38177 self.write_keyword("VECTOR_SEARCH");
38179 self.write("(");
38180 self.generate_expression(&e.this)?;
38181 if let Some(col) = &e.column_to_search {
38182 self.write(", ");
38183 self.generate_expression(col)?;
38184 }
38185 if let Some(query_table) = &e.query_table {
38186 self.write(", ");
38187 self.generate_expression(query_table)?;
38188 }
38189 if let Some(query_col) = &e.query_column_to_search {
38190 self.write(", ");
38191 self.generate_expression(query_col)?;
38192 }
38193 if let Some(top_k) = &e.top_k {
38194 self.write(", ");
38195 self.generate_expression(top_k)?;
38196 }
38197 if let Some(dist_type) = &e.distance_type {
38198 self.write(", ");
38199 self.generate_expression(dist_type)?;
38200 }
38201 self.write(")");
38202 Ok(())
38203 }
38204
38205 fn generate_version(&mut self, e: &Version) -> Result<()> {
38206 use crate::dialects::DialectType;
38212 let skip_for = matches!(
38213 self.config.dialect,
38214 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
38215 );
38216 if !skip_for {
38217 self.write_keyword("FOR");
38218 self.write_space();
38219 }
38220 match e.this.as_ref() {
38222 Expression::Identifier(ident) => {
38223 self.write_keyword(&ident.name);
38224 }
38225 _ => {
38226 self.generate_expression(&e.this)?;
38227 }
38228 }
38229 self.write_space();
38230 self.write_keyword(&e.kind);
38231 if let Some(expression) = &e.expression {
38232 self.write_space();
38233 self.generate_expression(expression)?;
38234 }
38235 Ok(())
38236 }
38237
38238 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
38239 self.generate_expression(&e.this)?;
38241 Ok(())
38242 }
38243
38244 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
38245 if e.this.is_some() {
38247 self.write_keyword("NOT VOLATILE");
38248 } else {
38249 self.write_keyword("VOLATILE");
38250 }
38251 Ok(())
38252 }
38253
38254 fn generate_watermark_column_constraint(
38255 &mut self,
38256 e: &WatermarkColumnConstraint,
38257 ) -> Result<()> {
38258 self.write_keyword("WATERMARK FOR");
38260 self.write_space();
38261 self.generate_expression(&e.this)?;
38262 self.write_space();
38263 self.write_keyword("AS");
38264 self.write_space();
38265 self.generate_expression(&e.expression)?;
38266 Ok(())
38267 }
38268
38269 fn generate_week(&mut self, e: &Week) -> Result<()> {
38270 self.write_keyword("WEEK");
38272 self.write("(");
38273 self.generate_expression(&e.this)?;
38274 if let Some(mode) = &e.mode {
38275 self.write(", ");
38276 self.generate_expression(mode)?;
38277 }
38278 self.write(")");
38279 Ok(())
38280 }
38281
38282 fn generate_when(&mut self, e: &When) -> Result<()> {
38283 self.write_keyword("WHEN");
38287 self.write_space();
38288
38289 if let Some(matched) = &e.matched {
38291 match matched.as_ref() {
38293 Expression::Boolean(b) if b.value => {
38294 self.write_keyword("MATCHED");
38295 }
38296 _ => {
38297 self.write_keyword("NOT MATCHED");
38298 }
38299 }
38300 } else {
38301 self.write_keyword("NOT MATCHED");
38302 }
38303
38304 if self.config.matched_by_source {
38309 if let Some(source) = &e.source {
38310 if let Expression::Boolean(b) = source.as_ref() {
38311 if b.value {
38312 self.write_space();
38314 self.write_keyword("BY SOURCE");
38315 }
38316 } else {
38318 self.write_space();
38320 self.write_keyword("BY SOURCE");
38321 }
38322 }
38323 }
38324
38325 if let Some(condition) = &e.condition {
38327 self.write_space();
38328 self.write_keyword("AND");
38329 self.write_space();
38330 self.generate_expression(condition)?;
38331 }
38332
38333 self.write_space();
38334 self.write_keyword("THEN");
38335 self.write_space();
38336
38337 self.generate_merge_action(&e.then)?;
38340
38341 Ok(())
38342 }
38343
38344 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
38345 match action {
38346 Expression::Tuple(tuple) => {
38347 let elements = &tuple.expressions;
38348 if elements.is_empty() {
38349 return self.generate_expression(action);
38350 }
38351 match &elements[0] {
38353 Expression::Var(v) if v.this == "INSERT" => {
38354 self.write_keyword("INSERT");
38355 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
38357 self.write(" *");
38358 if let Some(Expression::Where(w)) = elements.get(2) {
38359 self.write_space();
38360 self.generate_where(w)?;
38361 }
38362 } else {
38363 let mut values_idx = 1;
38364 if elements.len() > 1 {
38366 if let Expression::Tuple(cols) = &elements[1] {
38367 if elements.len() > 2 {
38369 self.write(" (");
38371 for (i, col) in cols.expressions.iter().enumerate() {
38372 if i > 0 {
38373 self.write(", ");
38374 }
38375 if !self.merge_strip_qualifiers.is_empty() {
38377 let stripped = self.strip_merge_qualifier(col);
38378 self.generate_expression(&stripped)?;
38379 } else {
38380 self.generate_expression(col)?;
38381 }
38382 }
38383 self.write(")");
38384 values_idx = 2;
38385 } else {
38386 values_idx = 1;
38388 }
38389 }
38390 }
38391 let mut next_idx = values_idx;
38392 if values_idx < elements.len()
38394 && !matches!(&elements[values_idx], Expression::Where(_))
38395 {
38396 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
38398 if !is_row {
38399 self.write_space();
38400 self.write_keyword("VALUES");
38401 }
38402 self.write(" ");
38403 if let Expression::Tuple(vals) = &elements[values_idx] {
38404 self.write("(");
38405 for (i, val) in vals.expressions.iter().enumerate() {
38406 if i > 0 {
38407 self.write(", ");
38408 }
38409 self.generate_expression(val)?;
38410 }
38411 self.write(")");
38412 } else {
38413 self.generate_expression(&elements[values_idx])?;
38414 }
38415 next_idx += 1;
38416 }
38417 if let Some(Expression::Where(w)) = elements.get(next_idx) {
38418 self.write_space();
38419 self.generate_where(w)?;
38420 }
38421 } }
38423 Expression::Var(v) if v.this == "UPDATE" => {
38424 self.write_keyword("UPDATE");
38425 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
38427 self.write(" *");
38428 if let Some(Expression::Where(w)) = elements.get(2) {
38429 self.write_space();
38430 self.generate_where(w)?;
38431 }
38432 } else if elements.len() > 1 {
38433 self.write_space();
38434 self.write_keyword("SET");
38435 if self.config.pretty {
38437 self.write_newline();
38438 self.indent_level += 1;
38439 self.write_indent();
38440 } else {
38441 self.write_space();
38442 }
38443 if let Expression::Tuple(assignments) = &elements[1] {
38444 for (i, assignment) in assignments.expressions.iter().enumerate() {
38445 if i > 0 {
38446 if self.config.pretty {
38447 self.write(",");
38448 self.write_newline();
38449 self.write_indent();
38450 } else {
38451 self.write(", ");
38452 }
38453 }
38454 if !self.merge_strip_qualifiers.is_empty() {
38456 self.generate_merge_set_assignment(assignment)?;
38457 } else {
38458 self.generate_expression(assignment)?;
38459 }
38460 }
38461 } else {
38462 self.generate_expression(&elements[1])?;
38463 }
38464 if self.config.pretty {
38465 self.indent_level -= 1;
38466 }
38467 if let Some(Expression::Where(w)) = elements.get(2) {
38468 self.write_space();
38469 self.generate_where(w)?;
38470 }
38471 }
38472 }
38473 Expression::Var(v) if v.this == "DELETE" => {
38474 self.write_keyword("DELETE");
38475 if let Some(Expression::Where(w)) = elements.get(1) {
38476 self.write_space();
38477 self.generate_where(w)?;
38478 }
38479 }
38480 _ => {
38481 self.generate_expression(action)?;
38483 }
38484 }
38485 }
38486 Expression::Var(v)
38487 if v.this == "INSERT"
38488 || v.this == "UPDATE"
38489 || v.this == "DELETE"
38490 || v.this == "DO NOTHING" =>
38491 {
38492 self.write_keyword(&v.this);
38493 }
38494 _ => {
38495 self.generate_expression(action)?;
38496 }
38497 }
38498 Ok(())
38499 }
38500
38501 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
38503 match assignment {
38504 Expression::Eq(eq) => {
38505 let stripped_left = self.strip_merge_qualifier(&eq.left);
38507 self.generate_expression(&stripped_left)?;
38508 self.write(" = ");
38509 self.generate_expression(&eq.right)?;
38510 Ok(())
38511 }
38512 other => self.generate_expression(other),
38513 }
38514 }
38515
38516 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
38518 match expr {
38519 Expression::Column(col) => {
38520 if let Some(ref table_ident) = col.table {
38521 if self
38522 .merge_strip_qualifiers
38523 .iter()
38524 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
38525 {
38526 let mut col = col.clone();
38528 col.table = None;
38529 return Expression::Column(col);
38530 }
38531 }
38532 expr.clone()
38533 }
38534 Expression::Dot(dot) => {
38535 if let Expression::Identifier(id) = &dot.this {
38537 if self
38538 .merge_strip_qualifiers
38539 .iter()
38540 .any(|n| n.eq_ignore_ascii_case(&id.name))
38541 {
38542 return Expression::Identifier(dot.field.clone());
38543 }
38544 }
38545 expr.clone()
38546 }
38547 _ => expr.clone(),
38548 }
38549 }
38550
38551 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
38552 for (i, expr) in e.expressions.iter().enumerate() {
38554 if i > 0 {
38555 if self.config.pretty {
38557 self.write_newline();
38558 self.write_indent();
38559 } else {
38560 self.write_space();
38561 }
38562 }
38563 self.generate_expression(expr)?;
38564 }
38565 Ok(())
38566 }
38567
38568 fn generate_where(&mut self, e: &Where) -> Result<()> {
38569 self.write_keyword("WHERE");
38571 self.write_space();
38572 self.generate_expression(&e.this)?;
38573 Ok(())
38574 }
38575
38576 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
38577 self.write_keyword("WIDTH_BUCKET");
38579 self.write("(");
38580 self.generate_expression(&e.this)?;
38581 if let Some(min_value) = &e.min_value {
38582 self.write(", ");
38583 self.generate_expression(min_value)?;
38584 }
38585 if let Some(max_value) = &e.max_value {
38586 self.write(", ");
38587 self.generate_expression(max_value)?;
38588 }
38589 if let Some(num_buckets) = &e.num_buckets {
38590 self.write(", ");
38591 self.generate_expression(num_buckets)?;
38592 }
38593 self.write(")");
38594 Ok(())
38595 }
38596
38597 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
38598 self.generate_window_spec(e)
38600 }
38601
38602 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
38603 let mut has_content = false;
38605
38606 if !e.partition_by.is_empty() {
38608 self.write_keyword("PARTITION BY");
38609 self.write_space();
38610 for (i, expr) in e.partition_by.iter().enumerate() {
38611 if i > 0 {
38612 self.write(", ");
38613 }
38614 self.generate_expression(expr)?;
38615 }
38616 has_content = true;
38617 }
38618
38619 if !e.order_by.is_empty() {
38621 if has_content {
38622 self.write_space();
38623 }
38624 self.write_keyword("ORDER BY");
38625 self.write_space();
38626 for (i, ordered) in e.order_by.iter().enumerate() {
38627 if i > 0 {
38628 self.write(", ");
38629 }
38630 self.generate_expression(&ordered.this)?;
38631 if ordered.desc {
38632 self.write_space();
38633 self.write_keyword("DESC");
38634 } else if ordered.explicit_asc {
38635 self.write_space();
38636 self.write_keyword("ASC");
38637 }
38638 if let Some(nulls_first) = ordered.nulls_first {
38639 self.write_space();
38640 self.write_keyword("NULLS");
38641 self.write_space();
38642 if nulls_first {
38643 self.write_keyword("FIRST");
38644 } else {
38645 self.write_keyword("LAST");
38646 }
38647 }
38648 }
38649 has_content = true;
38650 }
38651
38652 if let Some(frame) = &e.frame {
38654 if has_content {
38655 self.write_space();
38656 }
38657 self.generate_window_frame(frame)?;
38658 }
38659
38660 Ok(())
38661 }
38662
38663 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
38664 self.write_keyword("WITH");
38666 self.write_space();
38667 if e.no.is_some() {
38668 self.write_keyword("NO");
38669 self.write_space();
38670 }
38671 self.write_keyword("DATA");
38672
38673 if let Some(statistics) = &e.statistics {
38675 self.write_space();
38676 self.write_keyword("AND");
38677 self.write_space();
38678 match statistics.as_ref() {
38680 Expression::Boolean(b) if !b.value => {
38681 self.write_keyword("NO");
38682 self.write_space();
38683 }
38684 _ => {}
38685 }
38686 self.write_keyword("STATISTICS");
38687 }
38688 Ok(())
38689 }
38690
38691 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
38692 self.write_keyword("WITH FILL");
38694
38695 if let Some(from_) = &e.from_ {
38696 self.write_space();
38697 self.write_keyword("FROM");
38698 self.write_space();
38699 self.generate_expression(from_)?;
38700 }
38701
38702 if let Some(to) = &e.to {
38703 self.write_space();
38704 self.write_keyword("TO");
38705 self.write_space();
38706 self.generate_expression(to)?;
38707 }
38708
38709 if let Some(step) = &e.step {
38710 self.write_space();
38711 self.write_keyword("STEP");
38712 self.write_space();
38713 self.generate_expression(step)?;
38714 }
38715
38716 if let Some(staleness) = &e.staleness {
38717 self.write_space();
38718 self.write_keyword("STALENESS");
38719 self.write_space();
38720 self.generate_expression(staleness)?;
38721 }
38722
38723 if let Some(interpolate) = &e.interpolate {
38724 self.write_space();
38725 self.write_keyword("INTERPOLATE");
38726 self.write(" (");
38727 self.generate_interpolate_item(interpolate)?;
38729 self.write(")");
38730 }
38731
38732 Ok(())
38733 }
38734
38735 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
38737 match expr {
38738 Expression::Alias(alias) => {
38739 self.generate_identifier(&alias.alias)?;
38741 self.write_space();
38742 self.write_keyword("AS");
38743 self.write_space();
38744 self.generate_expression(&alias.this)?;
38745 }
38746 Expression::Tuple(tuple) => {
38747 for (i, item) in tuple.expressions.iter().enumerate() {
38748 if i > 0 {
38749 self.write(", ");
38750 }
38751 self.generate_interpolate_item(item)?;
38752 }
38753 }
38754 other => {
38755 self.generate_expression(other)?;
38756 }
38757 }
38758 Ok(())
38759 }
38760
38761 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
38762 self.write_keyword("WITH JOURNAL TABLE");
38764 self.write("=");
38765 self.generate_expression(&e.this)?;
38766 Ok(())
38767 }
38768
38769 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
38770 self.generate_expression(&e.this)?;
38772 self.write_space();
38773 self.write_keyword("WITH");
38774 self.write_space();
38775 self.write_keyword(&e.op);
38776 Ok(())
38777 }
38778
38779 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
38780 self.write_keyword("WITH");
38782 self.write_space();
38783 for (i, expr) in e.expressions.iter().enumerate() {
38784 if i > 0 {
38785 self.write(", ");
38786 }
38787 self.generate_expression(expr)?;
38788 }
38789 Ok(())
38790 }
38791
38792 fn generate_with_schema_binding_property(
38793 &mut self,
38794 e: &WithSchemaBindingProperty,
38795 ) -> Result<()> {
38796 self.write_keyword("WITH");
38798 self.write_space();
38799 self.generate_expression(&e.this)?;
38800 Ok(())
38801 }
38802
38803 fn generate_with_system_versioning_property(
38804 &mut self,
38805 e: &WithSystemVersioningProperty,
38806 ) -> Result<()> {
38807 let mut parts = Vec::new();
38813
38814 if let Some(this) = &e.this {
38815 let mut s = String::from("HISTORY_TABLE=");
38817 let mut gen = Generator::new();
38818 gen.generate_expression(this)?;
38819 s.push_str(&gen.output);
38820 parts.push(s);
38821 }
38822
38823 if let Some(data_consistency) = &e.data_consistency {
38824 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
38825 let mut gen = Generator::new();
38826 gen.generate_expression(data_consistency)?;
38827 s.push_str(&gen.output);
38828 parts.push(s);
38829 }
38830
38831 if let Some(retention_period) = &e.retention_period {
38832 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
38833 let mut gen = Generator::new();
38834 gen.generate_expression(retention_period)?;
38835 s.push_str(&gen.output);
38836 parts.push(s);
38837 }
38838
38839 self.write_keyword("SYSTEM_VERSIONING");
38840 self.write("=");
38841
38842 if !parts.is_empty() {
38843 self.write_keyword("ON");
38844 self.write("(");
38845 self.write(&parts.join(", "));
38846 self.write(")");
38847 } else if e.on.is_some() {
38848 self.write_keyword("ON");
38849 } else {
38850 self.write_keyword("OFF");
38851 }
38852
38853 if e.with_.is_some() {
38855 let inner = self.output.clone();
38856 self.output.clear();
38857 self.write("WITH(");
38858 self.write(&inner);
38859 self.write(")");
38860 }
38861
38862 Ok(())
38863 }
38864
38865 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
38866 self.write_keyword("WITH");
38868 self.write(" (");
38869 for (i, expr) in e.expressions.iter().enumerate() {
38870 if i > 0 {
38871 self.write(", ");
38872 }
38873 self.generate_expression(expr)?;
38874 }
38875 self.write(")");
38876 Ok(())
38877 }
38878
38879 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
38880 self.write_keyword("XMLELEMENT");
38883 self.write("(");
38884
38885 if e.evalname.is_some() {
38886 self.write_keyword("EVALNAME");
38887 } else {
38888 self.write_keyword("NAME");
38889 }
38890 self.write_space();
38891 self.generate_expression(&e.this)?;
38892
38893 for expr in &e.expressions {
38894 self.write(", ");
38895 self.generate_expression(expr)?;
38896 }
38897 self.write(")");
38898 Ok(())
38899 }
38900
38901 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
38902 self.write_keyword("XMLGET");
38904 self.write("(");
38905 self.generate_expression(&e.this)?;
38906 self.write(", ");
38907 self.generate_expression(&e.expression)?;
38908 if let Some(instance) = &e.instance {
38909 self.write(", ");
38910 self.generate_expression(instance)?;
38911 }
38912 self.write(")");
38913 Ok(())
38914 }
38915
38916 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
38917 self.generate_expression(&e.this)?;
38919 if let Some(expression) = &e.expression {
38920 self.write("(");
38921 self.generate_expression(expression)?;
38922 self.write(")");
38923 }
38924 Ok(())
38925 }
38926
38927 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
38928 self.write_keyword("XMLTABLE");
38930 self.write("(");
38931
38932 if self.config.pretty {
38933 self.indent_level += 1;
38934 self.write_newline();
38935 self.write_indent();
38936 self.generate_expression(&e.this)?;
38937
38938 if let Some(passing) = &e.passing {
38939 self.write_newline();
38940 self.write_indent();
38941 self.write_keyword("PASSING");
38942 if let Expression::Tuple(tuple) = passing.as_ref() {
38943 for expr in &tuple.expressions {
38944 self.write_newline();
38945 self.indent_level += 1;
38946 self.write_indent();
38947 self.generate_expression(expr)?;
38948 self.indent_level -= 1;
38949 }
38950 } else {
38951 self.write_newline();
38952 self.indent_level += 1;
38953 self.write_indent();
38954 self.generate_expression(passing)?;
38955 self.indent_level -= 1;
38956 }
38957 }
38958
38959 if e.by_ref.is_some() {
38960 self.write_newline();
38961 self.write_indent();
38962 self.write_keyword("RETURNING SEQUENCE BY REF");
38963 }
38964
38965 if !e.columns.is_empty() {
38966 self.write_newline();
38967 self.write_indent();
38968 self.write_keyword("COLUMNS");
38969 for (i, col) in e.columns.iter().enumerate() {
38970 self.write_newline();
38971 self.indent_level += 1;
38972 self.write_indent();
38973 self.generate_expression(col)?;
38974 self.indent_level -= 1;
38975 if i < e.columns.len() - 1 {
38976 self.write(",");
38977 }
38978 }
38979 }
38980
38981 self.indent_level -= 1;
38982 self.write_newline();
38983 self.write_indent();
38984 self.write(")");
38985 return Ok(());
38986 }
38987
38988 if let Some(namespaces) = &e.namespaces {
38990 self.write_keyword("XMLNAMESPACES");
38991 self.write("(");
38992 if let Expression::Tuple(tuple) = namespaces.as_ref() {
38994 for (i, expr) in tuple.expressions.iter().enumerate() {
38995 if i > 0 {
38996 self.write(", ");
38997 }
38998 if !matches!(expr, Expression::Alias(_)) {
39001 self.write_keyword("DEFAULT");
39002 self.write_space();
39003 }
39004 self.generate_expression(expr)?;
39005 }
39006 } else {
39007 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
39009 self.write_keyword("DEFAULT");
39010 self.write_space();
39011 }
39012 self.generate_expression(namespaces)?;
39013 }
39014 self.write("), ");
39015 }
39016
39017 self.generate_expression(&e.this)?;
39019
39020 if let Some(passing) = &e.passing {
39022 self.write_space();
39023 self.write_keyword("PASSING");
39024 self.write_space();
39025 if let Expression::Tuple(tuple) = passing.as_ref() {
39027 for (i, expr) in tuple.expressions.iter().enumerate() {
39028 if i > 0 {
39029 self.write(", ");
39030 }
39031 self.generate_expression(expr)?;
39032 }
39033 } else {
39034 self.generate_expression(passing)?;
39035 }
39036 }
39037
39038 if e.by_ref.is_some() {
39040 self.write_space();
39041 self.write_keyword("RETURNING SEQUENCE BY REF");
39042 }
39043
39044 if !e.columns.is_empty() {
39046 self.write_space();
39047 self.write_keyword("COLUMNS");
39048 self.write_space();
39049 for (i, col) in e.columns.iter().enumerate() {
39050 if i > 0 {
39051 self.write(", ");
39052 }
39053 self.generate_expression(col)?;
39054 }
39055 }
39056
39057 self.write(")");
39058 Ok(())
39059 }
39060
39061 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
39062 if let Some(this) = &e.this {
39065 self.generate_expression(this)?;
39066 if let Some(expression) = &e.expression {
39067 self.write_space();
39068 self.write_keyword("XOR");
39069 self.write_space();
39070 self.generate_expression(expression)?;
39071 }
39072 }
39073
39074 for (i, expr) in e.expressions.iter().enumerate() {
39076 if i > 0 || e.this.is_some() {
39077 self.write_space();
39078 self.write_keyword("XOR");
39079 self.write_space();
39080 }
39081 self.generate_expression(expr)?;
39082 }
39083 Ok(())
39084 }
39085
39086 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
39087 self.write_keyword("ZIPF");
39089 self.write("(");
39090 self.generate_expression(&e.this)?;
39091 if let Some(elementcount) = &e.elementcount {
39092 self.write(", ");
39093 self.generate_expression(elementcount)?;
39094 }
39095 if let Some(gen) = &e.gen {
39096 self.write(", ");
39097 self.generate_expression(gen)?;
39098 }
39099 self.write(")");
39100 Ok(())
39101 }
39102}
39103
39104impl Default for Generator {
39105 fn default() -> Self {
39106 Self::new()
39107 }
39108}
39109
39110#[cfg(test)]
39111mod tests {
39112 use super::*;
39113 use crate::parser::Parser;
39114
39115 fn roundtrip(sql: &str) -> String {
39116 let ast = Parser::parse_sql(sql).unwrap();
39117 Generator::sql(&ast[0]).unwrap()
39118 }
39119
39120 #[test]
39121 fn test_simple_select() {
39122 let result = roundtrip("SELECT 1");
39123 assert_eq!(result, "SELECT 1");
39124 }
39125
39126 #[test]
39127 fn test_select_from() {
39128 let result = roundtrip("SELECT a, b FROM t");
39129 assert_eq!(result, "SELECT a, b FROM t");
39130 }
39131
39132 #[test]
39133 fn test_select_where() {
39134 let result = roundtrip("SELECT * FROM t WHERE x = 1");
39135 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
39136 }
39137
39138 #[test]
39139 fn test_select_join() {
39140 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
39141 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
39142 }
39143
39144 #[test]
39145 fn test_insert() {
39146 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
39147 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
39148 }
39149
39150 #[test]
39151 fn test_pretty_print() {
39152 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
39153 let result = Generator::pretty_sql(&ast[0]).unwrap();
39154 assert!(result.contains('\n'));
39155 }
39156
39157 #[test]
39158 fn test_window_function() {
39159 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
39160 assert_eq!(
39161 result,
39162 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
39163 );
39164 }
39165
39166 #[test]
39167 fn test_window_function_with_frame() {
39168 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
39169 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
39170 }
39171
39172 #[test]
39173 fn test_aggregate_with_filter() {
39174 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
39175 assert_eq!(
39176 result,
39177 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
39178 );
39179 }
39180
39181 #[test]
39182 fn test_subscript() {
39183 let result = roundtrip("SELECT arr[0]");
39184 assert_eq!(result, "SELECT arr[0]");
39185 }
39186
39187 #[test]
39189 fn test_create_table() {
39190 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
39191 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
39192 }
39193
39194 #[test]
39195 fn test_create_table_with_constraints() {
39196 let result = roundtrip(
39197 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
39198 );
39199 assert_eq!(
39200 result,
39201 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
39202 );
39203 }
39204
39205 #[test]
39206 fn test_create_table_if_not_exists() {
39207 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
39208 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
39209 }
39210
39211 #[test]
39212 fn test_drop_table() {
39213 let result = roundtrip("DROP TABLE users");
39214 assert_eq!(result, "DROP TABLE users");
39215 }
39216
39217 #[test]
39218 fn test_drop_table_if_exists_cascade() {
39219 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
39220 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
39221 }
39222
39223 #[test]
39224 fn test_alter_table_add_column() {
39225 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
39226 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
39227 }
39228
39229 #[test]
39230 fn test_alter_table_drop_column() {
39231 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
39232 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
39233 }
39234
39235 #[test]
39236 fn test_create_index() {
39237 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
39238 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
39239 }
39240
39241 #[test]
39242 fn test_create_unique_index() {
39243 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
39244 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
39245 }
39246
39247 #[test]
39248 fn test_drop_index() {
39249 let result = roundtrip("DROP INDEX idx_name");
39250 assert_eq!(result, "DROP INDEX idx_name");
39251
39252 let result = roundtrip(r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#);
39253 assert_eq!(
39254 result,
39255 r#"DROP INDEX IF EXISTS "idx_tokenKey__pb_users_auth_""#
39256 );
39257
39258 let result = roundtrip(r#"DROP INDEX "public"."IdxMixed""#);
39259 assert_eq!(result, r#"DROP INDEX "public"."IdxMixed""#);
39260 }
39261
39262 #[test]
39263 fn test_create_view() {
39264 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
39265 assert_eq!(
39266 result,
39267 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
39268 );
39269 }
39270
39271 #[test]
39272 fn test_drop_view() {
39273 let result = roundtrip("DROP VIEW active_users");
39274 assert_eq!(result, "DROP VIEW active_users");
39275 }
39276
39277 #[test]
39278 fn test_truncate() {
39279 let result = roundtrip("TRUNCATE TABLE users");
39280 assert_eq!(result, "TRUNCATE TABLE users");
39281 }
39282
39283 #[test]
39284 fn test_string_literal_escaping_default() {
39285 let result = roundtrip("SELECT 'hello'");
39287 assert_eq!(result, "SELECT 'hello'");
39288
39289 let result = roundtrip("SELECT 'it''s a test'");
39291 assert_eq!(result, "SELECT 'it''s a test'");
39292 }
39293
39294 #[test]
39295 fn test_not_in_style_prefix_default_generic() {
39296 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
39297 assert_eq!(
39298 result,
39299 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
39300 );
39301 }
39302
39303 #[test]
39304 fn test_not_in_style_infix_generic_override() {
39305 let ast =
39306 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
39307 .unwrap();
39308 let config = GeneratorConfig {
39309 not_in_style: NotInStyle::Infix,
39310 ..Default::default()
39311 };
39312 let mut gen = Generator::with_config(config);
39313 let result = gen.generate(&ast[0]).unwrap();
39314 assert_eq!(
39315 result,
39316 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
39317 );
39318 }
39319
39320 #[test]
39321 fn test_string_literal_escaping_mysql() {
39322 use crate::dialects::DialectType;
39323
39324 let config = GeneratorConfig {
39325 dialect: Some(DialectType::MySQL),
39326 ..Default::default()
39327 };
39328
39329 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39330 let mut gen = Generator::with_config(config.clone());
39331 let result = gen.generate(&ast[0]).unwrap();
39332 assert_eq!(result, "SELECT 'hello'");
39333
39334 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39336 let mut gen = Generator::with_config(config.clone());
39337 let result = gen.generate(&ast[0]).unwrap();
39338 assert_eq!(result, "SELECT 'it''s'");
39339 }
39340
39341 #[test]
39342 fn test_string_literal_escaping_postgres() {
39343 use crate::dialects::DialectType;
39344
39345 let config = GeneratorConfig {
39346 dialect: Some(DialectType::PostgreSQL),
39347 ..Default::default()
39348 };
39349
39350 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39351 let mut gen = Generator::with_config(config.clone());
39352 let result = gen.generate(&ast[0]).unwrap();
39353 assert_eq!(result, "SELECT 'hello'");
39354
39355 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39357 let mut gen = Generator::with_config(config.clone());
39358 let result = gen.generate(&ast[0]).unwrap();
39359 assert_eq!(result, "SELECT 'it''s'");
39360 }
39361
39362 #[test]
39363 fn test_string_literal_escaping_bigquery() {
39364 use crate::dialects::DialectType;
39365
39366 let config = GeneratorConfig {
39367 dialect: Some(DialectType::BigQuery),
39368 ..Default::default()
39369 };
39370
39371 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
39372 let mut gen = Generator::with_config(config.clone());
39373 let result = gen.generate(&ast[0]).unwrap();
39374 assert_eq!(result, "SELECT 'hello'");
39375
39376 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
39378 let mut gen = Generator::with_config(config.clone());
39379 let result = gen.generate(&ast[0]).unwrap();
39380 assert_eq!(result, "SELECT 'it\\'s'");
39381 }
39382
39383 #[test]
39384 fn test_generate_deep_and_chain_without_stack_growth() {
39385 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
39386 Expression::column("c0"),
39387 Expression::number(0),
39388 )));
39389
39390 for i in 1..2500 {
39391 let predicate = Expression::Eq(Box::new(BinaryOp::new(
39392 Expression::column(format!("c{i}")),
39393 Expression::number(i as i64),
39394 )));
39395 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
39396 }
39397
39398 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
39399 assert!(sql.contains("c2499 = 2499"), "{}", sql);
39400 }
39401
39402 #[test]
39403 fn test_generate_deep_or_chain_without_stack_growth() {
39404 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
39405 Expression::column("c0"),
39406 Expression::number(0),
39407 )));
39408
39409 for i in 1..2500 {
39410 let predicate = Expression::Eq(Box::new(BinaryOp::new(
39411 Expression::column(format!("c{i}")),
39412 Expression::number(i as i64),
39413 )));
39414 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
39415 }
39416
39417 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
39418 assert!(sql.contains("c2499 = 2499"), "{}", sql);
39419 }
39420}