1use std::borrow::Cow;
14use std::sync::Arc;
15
16use crate::error::Result;
17use crate::expressions::*;
18use crate::DialectType;
19
20pub struct Generator {
45 config: Arc<GeneratorConfig>,
46 output: String,
47 unsupported_messages: Vec<String>,
48 indent_level: usize,
49 athena_hive_context: bool,
52 sqlite_inline_pk_columns: std::collections::HashSet<String>,
54 merge_strip_qualifiers: Vec<String>,
56 clickhouse_nullable_depth: i32,
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Default)]
69pub enum NormalizeFunctions {
70 #[default]
72 Upper,
73 Lower,
75 None,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Default)]
81pub enum LimitFetchStyle {
82 #[default]
84 Limit,
85 Top,
87 FetchFirst,
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
93pub enum NotInStyle {
94 #[default]
96 Prefix,
97 Infix,
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
103pub enum UnsupportedLevel {
104 Ignore,
106 #[default]
108 Warn,
109 Raise,
111 Immediate,
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
116enum ConnectorOperator {
117 And,
118 Or,
119}
120
121impl ConnectorOperator {
122 fn keyword(self) -> &'static str {
123 match self {
124 Self::And => "AND",
125 Self::Or => "OR",
126 }
127 }
128}
129
130#[derive(Debug, Clone, Copy, PartialEq)]
132pub struct IdentifierQuoteStyle {
133 pub start: char,
135 pub end: char,
137}
138
139impl Default for IdentifierQuoteStyle {
140 fn default() -> Self {
141 Self {
142 start: '"',
143 end: '"',
144 }
145 }
146}
147
148impl IdentifierQuoteStyle {
149 pub const DOUBLE_QUOTE: Self = Self {
151 start: '"',
152 end: '"',
153 };
154 pub const BACKTICK: Self = Self {
156 start: '`',
157 end: '`',
158 };
159 pub const BRACKET: Self = Self {
161 start: '[',
162 end: ']',
163 };
164}
165
166#[derive(Debug, Clone)]
188pub struct GeneratorConfig {
189 pub pretty: bool,
192 pub indent: &'static str,
194 pub max_text_width: usize,
196 pub identifier_quote: char,
198 pub identifier_quote_style: IdentifierQuoteStyle,
200 pub uppercase_keywords: bool,
202 pub normalize_identifiers: bool,
204 pub dialect: Option<crate::dialects::DialectType>,
206 pub source_dialect: Option<crate::dialects::DialectType>,
208 pub unsupported_level: UnsupportedLevel,
210 pub max_unsupported: usize,
212 pub normalize_functions: NormalizeFunctions,
214 pub string_escape: char,
216 pub case_sensitive_identifiers: bool,
218 pub identifiers_can_start_with_digit: bool,
220 pub always_quote_identifiers: bool,
223 pub not_in_style: NotInStyle,
225
226 pub null_ordering_supported: bool,
230 pub ignore_nulls_in_func: bool,
233 pub nvl2_supported: bool,
235
236 pub limit_fetch_style: LimitFetchStyle,
239 pub limit_is_top: bool,
241 pub limit_only_literals: bool,
243
244 pub single_string_interval: bool,
247 pub interval_allows_plural_form: bool,
249
250 pub cte_recursive_keyword_required: bool,
253
254 pub values_as_table: bool,
257 pub wrap_derived_values: bool,
259
260 pub tablesample_seed_keyword: &'static str,
263 pub tablesample_requires_parens: bool,
265 pub tablesample_size_is_rows: bool,
267 pub tablesample_keywords: &'static str,
269 pub tablesample_with_method: bool,
271 pub alias_post_tablesample: bool,
273
274 pub aggregate_filter_supported: bool,
277 pub multi_arg_distinct: bool,
279 pub quantified_no_paren_space: bool,
281 pub supports_median: bool,
283
284 pub supports_select_into: bool,
287 pub locking_reads_supported: bool,
289
290 pub rename_table_with_db: bool,
293 pub semi_anti_join_with_side: bool,
295 pub supports_table_alias_columns: bool,
297 pub join_hints: bool,
299 pub table_hints: bool,
301 pub query_hints: bool,
303 pub query_hint_sep: &'static str,
305 pub supports_column_join_marks: bool,
307
308 pub index_using_no_space: bool,
312 pub supports_unlogged_tables: bool,
314 pub supports_create_table_like: bool,
316 pub like_property_inside_schema: bool,
318 pub alter_table_include_column_keyword: bool,
320 pub supports_table_copy: bool,
322 pub alter_set_type: &'static str,
324 pub alter_set_wrapped: bool,
326
327 pub tz_to_with_time_zone: bool,
330 pub supports_convert_timezone: bool,
332
333 pub json_type_required_for_extraction: bool,
336 pub json_path_bracketed_key_supported: bool,
338 pub json_path_single_quote_escape: bool,
340 pub quote_json_path: bool,
342 pub json_key_value_pair_sep: &'static str,
344
345 pub copy_params_are_wrapped: bool,
348 pub copy_params_eq_required: bool,
350 pub copy_has_into_keyword: bool,
352
353 pub supports_window_exclude: bool,
356 pub unnest_with_ordinality: bool,
358 pub lowercase_window_frame_keywords: bool,
361 pub normalize_window_frame_between: bool,
364
365 pub array_concat_is_var_len: bool,
368 pub array_size_dim_required: Option<bool>,
371 pub can_implement_array_any: bool,
373 pub array_size_name: &'static str,
375
376 pub supports_between_flags: bool,
379
380 pub is_bool_allowed: bool,
383 pub ensure_bools: bool,
385
386 pub extract_allows_quotes: bool,
389 pub normalize_extract_date_parts: bool,
391
392 pub try_supported: bool,
395 pub supports_uescape: bool,
397 pub supports_to_number: bool,
399 pub supports_single_arg_concat: bool,
401 pub last_day_supports_date_part: bool,
403 pub supports_exploding_projections: bool,
405 pub supports_unix_seconds: bool,
407 pub supports_like_quantifiers: bool,
409 pub supports_decode_case: bool,
411 pub set_op_modifiers: bool,
413 pub update_statement_supports_from: bool,
415
416 pub collate_is_func: bool,
419
420 pub duplicate_key_update_with_set: bool,
423 pub insert_overwrite: &'static str,
425
426 pub returning_end: bool,
429
430 pub matched_by_source: bool,
433
434 pub create_function_return_as: bool,
437 pub parameter_default_equals: bool,
439
440 pub computed_column_with_type: bool,
443
444 pub unpivot_aliases_are_identifiers: bool,
447
448 pub star_except: &'static str,
451
452 pub hex_func: &'static str,
455
456 pub with_properties_prefix: &'static str,
459
460 pub pad_fill_pattern_is_required: bool,
463
464 pub index_on: &'static str,
467
468 pub groupings_sep: &'static str,
471
472 pub struct_delimiter: (&'static str, &'static str),
475 pub struct_curly_brace_notation: bool,
477 pub array_bracket_only: bool,
479 pub struct_field_sep: &'static str,
481
482 pub except_intersect_support_all_clause: bool,
485
486 pub parameter_token: &'static str,
489 pub named_placeholder_token: &'static str,
491
492 pub data_type_specifiers_allowed: bool,
495
496 pub schema_comment_with_eq: bool,
500}
501
502impl Default for GeneratorConfig {
503 fn default() -> Self {
504 Self {
505 pretty: false,
507 indent: " ",
508 max_text_width: 80,
509 identifier_quote: '"',
510 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
511 uppercase_keywords: true,
512 normalize_identifiers: false,
513 dialect: None,
514 source_dialect: None,
515 unsupported_level: UnsupportedLevel::Warn,
516 max_unsupported: 3,
517 normalize_functions: NormalizeFunctions::Upper,
518 string_escape: '\'',
519 case_sensitive_identifiers: false,
520 identifiers_can_start_with_digit: false,
521 always_quote_identifiers: false,
522 not_in_style: NotInStyle::Prefix,
523
524 null_ordering_supported: true,
526 ignore_nulls_in_func: false,
527 nvl2_supported: true,
528
529 limit_fetch_style: LimitFetchStyle::Limit,
531 limit_is_top: false,
532 limit_only_literals: false,
533
534 single_string_interval: false,
536 interval_allows_plural_form: true,
537
538 cte_recursive_keyword_required: true,
540
541 values_as_table: true,
543 wrap_derived_values: true,
544
545 tablesample_seed_keyword: "SEED",
547 tablesample_requires_parens: true,
548 tablesample_size_is_rows: true,
549 tablesample_keywords: "TABLESAMPLE",
550 tablesample_with_method: true,
551 alias_post_tablesample: false,
552
553 aggregate_filter_supported: true,
555 multi_arg_distinct: true,
556 quantified_no_paren_space: false,
557 supports_median: true,
558
559 supports_select_into: false,
561 locking_reads_supported: true,
562
563 rename_table_with_db: true,
565 semi_anti_join_with_side: true,
566 supports_table_alias_columns: true,
567 join_hints: true,
568 table_hints: true,
569 query_hints: true,
570 query_hint_sep: ", ",
571 supports_column_join_marks: false,
572
573 index_using_no_space: false,
575 supports_unlogged_tables: false,
576 supports_create_table_like: true,
577 like_property_inside_schema: false,
578 alter_table_include_column_keyword: true,
579 supports_table_copy: true,
580 alter_set_type: "SET DATA TYPE",
581 alter_set_wrapped: false,
582
583 tz_to_with_time_zone: false,
585 supports_convert_timezone: false,
586
587 json_type_required_for_extraction: false,
589 json_path_bracketed_key_supported: true,
590 json_path_single_quote_escape: false,
591 quote_json_path: true,
592 json_key_value_pair_sep: ":",
593
594 copy_params_are_wrapped: true,
596 copy_params_eq_required: false,
597 copy_has_into_keyword: true,
598
599 supports_window_exclude: false,
601 unnest_with_ordinality: true,
602 lowercase_window_frame_keywords: false,
603 normalize_window_frame_between: false,
604
605 array_concat_is_var_len: true,
607 array_size_dim_required: None,
608 can_implement_array_any: false,
609 array_size_name: "ARRAY_LENGTH",
610
611 supports_between_flags: false,
613
614 is_bool_allowed: true,
616 ensure_bools: false,
617
618 extract_allows_quotes: true,
620 normalize_extract_date_parts: false,
621
622 try_supported: true,
624 supports_uescape: true,
625 supports_to_number: true,
626 supports_single_arg_concat: true,
627 last_day_supports_date_part: true,
628 supports_exploding_projections: true,
629 supports_unix_seconds: false,
630 supports_like_quantifiers: true,
631 supports_decode_case: true,
632 set_op_modifiers: true,
633 update_statement_supports_from: true,
634
635 collate_is_func: false,
637
638 duplicate_key_update_with_set: true,
640 insert_overwrite: " OVERWRITE TABLE",
641
642 returning_end: true,
644
645 matched_by_source: true,
647
648 create_function_return_as: true,
650 parameter_default_equals: false,
651
652 computed_column_with_type: true,
654
655 unpivot_aliases_are_identifiers: true,
657
658 star_except: "EXCEPT",
660
661 hex_func: "HEX",
663
664 with_properties_prefix: "WITH",
666
667 pad_fill_pattern_is_required: false,
669
670 index_on: "ON",
672
673 groupings_sep: ",",
675
676 struct_delimiter: ("<", ">"),
678 struct_curly_brace_notation: false,
679 array_bracket_only: false,
680 struct_field_sep: " ",
681
682 except_intersect_support_all_clause: true,
684
685 parameter_token: "@",
687 named_placeholder_token: ":",
688
689 data_type_specifiers_allowed: false,
691
692 schema_comment_with_eq: true,
694 }
695 }
696}
697
698mod reserved_keywords {
701 use std::collections::HashSet;
702 use std::sync::LazyLock;
703
704 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
706 [
707 "all",
708 "alter",
709 "and",
710 "any",
711 "array",
712 "as",
713 "asc",
714 "at",
715 "authorization",
716 "begin",
717 "between",
718 "both",
719 "by",
720 "case",
721 "cast",
722 "check",
723 "collate",
724 "column",
725 "commit",
726 "constraint",
727 "create",
728 "cross",
729 "cube",
730 "current",
731 "current_date",
732 "current_time",
733 "current_timestamp",
734 "current_user",
735 "default",
736 "delete",
737 "desc",
738 "distinct",
739 "drop",
740 "else",
741 "end",
742 "escape",
743 "except",
744 "execute",
745 "exists",
746 "external",
747 "false",
748 "fetch",
749 "filter",
750 "for",
751 "foreign",
752 "from",
753 "full",
754 "function",
755 "grant",
756 "group",
757 "grouping",
758 "having",
759 "if",
760 "in",
761 "index",
762 "inner",
763 "insert",
764 "intersect",
765 "interval",
766 "into",
767 "is",
768 "join",
769 "key",
770 "leading",
771 "left",
772 "like",
773 "limit",
774 "local",
775 "localtime",
776 "localtimestamp",
777 "match",
778 "merge",
779 "natural",
780 "no",
781 "not",
782 "null",
783 "of",
784 "offset",
785 "on",
786 "only",
787 "or",
788 "order",
789 "outer",
790 "over",
791 "partition",
792 "primary",
793 "procedure",
794 "range",
795 "references",
796 "right",
797 "rollback",
798 "rollup",
799 "row",
800 "rows",
801 "select",
802 "session_user",
803 "set",
804 "some",
805 "table",
806 "tablesample",
807 "then",
808 "to",
809 "trailing",
810 "true",
811 "truncate",
812 "union",
813 "unique",
814 "unknown",
815 "update",
816 "user",
817 "using",
818 "values",
819 "view",
820 "when",
821 "where",
822 "window",
823 "with",
824 ]
825 .into_iter()
826 .collect()
827 });
828
829 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
832 let mut set = SQL_RESERVED.clone();
833 set.extend([
834 "assert_rows_modified",
835 "at",
836 "contains",
837 "cube",
838 "current",
839 "define",
840 "enum",
841 "escape",
842 "exclude",
843 "following",
844 "for",
845 "groups",
846 "hash",
847 "ignore",
848 "lateral",
849 "lookup",
850 "new",
851 "no",
852 "nulls",
853 "of",
854 "over",
855 "preceding",
856 "proto",
857 "qualify",
858 "recursive",
859 "respect",
860 "struct",
861 "tablesample",
862 "treat",
863 "unbounded",
864 "unnest",
865 "window",
866 "within",
867 ]);
868 set.remove("grant");
870 set.remove("key");
871 set.remove("index");
872 set.remove("offset");
873 set.remove("values");
874 set.remove("table");
875 set
876 });
877
878 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
880 let mut set = SQL_RESERVED.clone();
881 set.extend([
882 "accessible",
883 "add",
884 "analyze",
885 "asensitive",
886 "before",
887 "bigint",
888 "binary",
889 "blob",
890 "call",
891 "cascade",
892 "change",
893 "char",
894 "character",
895 "condition",
896 "continue",
897 "convert",
898 "current_date",
899 "current_time",
900 "current_timestamp",
901 "current_user",
902 "cursor",
903 "database",
904 "databases",
905 "day_hour",
906 "day_microsecond",
907 "day_minute",
908 "day_second",
909 "dec",
910 "decimal",
911 "declare",
912 "delayed",
913 "describe",
914 "deterministic",
915 "distinctrow",
916 "div",
917 "double",
918 "dual",
919 "each",
920 "elseif",
921 "enclosed",
922 "escaped",
923 "exit",
924 "explain",
925 "float",
926 "float4",
927 "float8",
928 "force",
929 "get",
930 "high_priority",
931 "hour_microsecond",
932 "hour_minute",
933 "hour_second",
934 "ignore",
935 "infile",
936 "inout",
937 "insensitive",
938 "int",
939 "int1",
940 "int2",
941 "int3",
942 "int4",
943 "int8",
944 "integer",
945 "iterate",
946 "keys",
947 "kill",
948 "leave",
949 "linear",
950 "lines",
951 "load",
952 "lock",
953 "long",
954 "longblob",
955 "longtext",
956 "loop",
957 "low_priority",
958 "master_ssl_verify_server_cert",
959 "maxvalue",
960 "mediumblob",
961 "mediumint",
962 "mediumtext",
963 "middleint",
964 "minute_microsecond",
965 "minute_second",
966 "mod",
967 "modifies",
968 "no_write_to_binlog",
969 "numeric",
970 "optimize",
971 "option",
972 "optionally",
973 "out",
974 "outfile",
975 "precision",
976 "purge",
977 "read",
978 "reads",
979 "real",
980 "regexp",
981 "release",
982 "rename",
983 "repeat",
984 "replace",
985 "require",
986 "resignal",
987 "restrict",
988 "return",
989 "revoke",
990 "rlike",
991 "schema",
992 "schemas",
993 "second_microsecond",
994 "sensitive",
995 "separator",
996 "show",
997 "signal",
998 "smallint",
999 "spatial",
1000 "specific",
1001 "sql",
1002 "sql_big_result",
1003 "sql_calc_found_rows",
1004 "sql_small_result",
1005 "sqlexception",
1006 "sqlstate",
1007 "sqlwarning",
1008 "ssl",
1009 "starting",
1010 "straight_join",
1011 "terminated",
1012 "text",
1013 "tinyblob",
1014 "tinyint",
1015 "tinytext",
1016 "trigger",
1017 "undo",
1018 "unlock",
1019 "unsigned",
1020 "usage",
1021 "utc_date",
1022 "utc_time",
1023 "utc_timestamp",
1024 "varbinary",
1025 "varchar",
1026 "varcharacter",
1027 "varying",
1028 "while",
1029 "write",
1030 "xor",
1031 "year_month",
1032 "zerofill",
1033 ]);
1034 set.remove("table");
1035 set
1036 });
1037
1038 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1041 let mut set = MYSQL_RESERVED.clone();
1042 set.extend([
1043 "aggregate",
1044 "anti",
1045 "array",
1046 "backend",
1047 "backup",
1048 "begin",
1049 "bitmap",
1050 "boolean",
1051 "broker",
1052 "buckets",
1053 "cached",
1054 "cancel",
1055 "cast",
1056 "catalog",
1057 "charset",
1058 "cluster",
1059 "collation",
1060 "columns",
1061 "comment",
1062 "commit",
1063 "config",
1064 "connection",
1065 "count",
1066 "current",
1067 "data",
1068 "date",
1069 "datetime",
1070 "day",
1071 "deferred",
1072 "distributed",
1073 "dynamic",
1074 "enable",
1075 "end",
1076 "events",
1077 "export",
1078 "external",
1079 "fields",
1080 "first",
1081 "follower",
1082 "format",
1083 "free",
1084 "frontend",
1085 "full",
1086 "functions",
1087 "global",
1088 "grants",
1089 "hash",
1090 "help",
1091 "hour",
1092 "install",
1093 "intermediate",
1094 "json",
1095 "label",
1096 "last",
1097 "less",
1098 "level",
1099 "link",
1100 "local",
1101 "location",
1102 "max",
1103 "merge",
1104 "min",
1105 "minute",
1106 "modify",
1107 "month",
1108 "name",
1109 "names",
1110 "negative",
1111 "nulls",
1112 "observer",
1113 "offset",
1114 "only",
1115 "open",
1116 "overwrite",
1117 "password",
1118 "path",
1119 "plan",
1120 "plugin",
1121 "plugins",
1122 "policy",
1123 "process",
1124 "properties",
1125 "property",
1126 "query",
1127 "quota",
1128 "recover",
1129 "refresh",
1130 "repair",
1131 "replica",
1132 "repository",
1133 "resource",
1134 "restore",
1135 "resume",
1136 "role",
1137 "roles",
1138 "rollback",
1139 "rollup",
1140 "routine",
1141 "sample",
1142 "second",
1143 "semi",
1144 "session",
1145 "signed",
1146 "snapshot",
1147 "start",
1148 "stats",
1149 "status",
1150 "stop",
1151 "stream",
1152 "string",
1153 "sum",
1154 "tables",
1155 "tablet",
1156 "temporary",
1157 "text",
1158 "timestamp",
1159 "transaction",
1160 "trash",
1161 "trim",
1162 "truncate",
1163 "type",
1164 "user",
1165 "value",
1166 "variables",
1167 "verbose",
1168 "version",
1169 "view",
1170 "warnings",
1171 "week",
1172 "work",
1173 "year",
1174 ]);
1175 set
1176 });
1177
1178 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1180 let mut set = SQL_RESERVED.clone();
1181 set.extend([
1182 "analyse",
1183 "analyze",
1184 "asymmetric",
1185 "binary",
1186 "collation",
1187 "concurrently",
1188 "current_catalog",
1189 "current_role",
1190 "current_schema",
1191 "deferrable",
1192 "do",
1193 "freeze",
1194 "ilike",
1195 "initially",
1196 "isnull",
1197 "lateral",
1198 "notnull",
1199 "placing",
1200 "returning",
1201 "similar",
1202 "symmetric",
1203 "variadic",
1204 "verbose",
1205 ]);
1206 set.remove("default");
1208 set.remove("interval");
1209 set.remove("match");
1210 set.remove("offset");
1211 set.remove("table");
1212 set
1213 });
1214
1215 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1219 [
1220 "aes128",
1221 "aes256",
1222 "all",
1223 "allowoverwrite",
1224 "analyse",
1225 "analyze",
1226 "and",
1227 "any",
1228 "array",
1229 "as",
1230 "asc",
1231 "authorization",
1232 "az64",
1233 "backup",
1234 "between",
1235 "binary",
1236 "blanksasnull",
1237 "both",
1238 "bytedict",
1239 "bzip2",
1240 "case",
1241 "cast",
1242 "check",
1243 "collate",
1244 "column",
1245 "constraint",
1246 "create",
1247 "credentials",
1248 "cross",
1249 "current_date",
1250 "current_time",
1251 "current_timestamp",
1252 "current_user",
1253 "current_user_id",
1254 "default",
1255 "deferrable",
1256 "deflate",
1257 "defrag",
1258 "delta",
1259 "delta32k",
1260 "desc",
1261 "disable",
1262 "distinct",
1263 "do",
1264 "else",
1265 "emptyasnull",
1266 "enable",
1267 "encode",
1268 "encrypt",
1269 "encryption",
1270 "end",
1271 "except",
1272 "explicit",
1273 "false",
1274 "for",
1275 "foreign",
1276 "freeze",
1277 "from",
1278 "full",
1279 "globaldict256",
1280 "globaldict64k",
1281 "grant",
1282 "group",
1283 "gzip",
1284 "having",
1285 "identity",
1286 "ignore",
1287 "ilike",
1288 "in",
1289 "initially",
1290 "inner",
1291 "intersect",
1292 "interval",
1293 "into",
1294 "is",
1295 "isnull",
1296 "join",
1297 "leading",
1298 "left",
1299 "like",
1300 "limit",
1301 "localtime",
1302 "localtimestamp",
1303 "lun",
1304 "luns",
1305 "lzo",
1306 "lzop",
1307 "minus",
1308 "mostly16",
1309 "mostly32",
1310 "mostly8",
1311 "natural",
1312 "new",
1313 "not",
1314 "notnull",
1315 "null",
1316 "nulls",
1317 "off",
1318 "offline",
1319 "offset",
1320 "oid",
1321 "old",
1322 "on",
1323 "only",
1324 "open",
1325 "or",
1326 "order",
1327 "outer",
1328 "overlaps",
1329 "parallel",
1330 "partition",
1331 "percent",
1332 "permissions",
1333 "pivot",
1334 "placing",
1335 "primary",
1336 "raw",
1337 "readratio",
1338 "recover",
1339 "references",
1340 "rejectlog",
1341 "resort",
1342 "respect",
1343 "restore",
1344 "right",
1345 "select",
1346 "session_user",
1347 "similar",
1348 "snapshot",
1349 "some",
1350 "sysdate",
1351 "system",
1352 "table",
1353 "tag",
1354 "tdes",
1355 "text255",
1356 "text32k",
1357 "then",
1358 "timestamp",
1359 "to",
1360 "top",
1361 "trailing",
1362 "true",
1363 "truncatecolumns",
1364 "type",
1365 "union",
1366 "unique",
1367 "unnest",
1368 "unpivot",
1369 "user",
1370 "using",
1371 "verbose",
1372 "wallet",
1373 "when",
1374 "where",
1375 "with",
1376 "without",
1377 ]
1378 .into_iter()
1379 .collect()
1380 });
1381
1382 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1384 let mut set = POSTGRES_RESERVED.clone();
1385 set.extend([
1386 "anti",
1387 "asof",
1388 "columns",
1389 "describe",
1390 "groups",
1391 "macro",
1392 "pivot",
1393 "pivot_longer",
1394 "pivot_wider",
1395 "qualify",
1396 "replace",
1397 "respect",
1398 "semi",
1399 "show",
1400 "table",
1401 "unpivot",
1402 ]);
1403 set.remove("at");
1404 set.remove("key");
1405 set.remove("range");
1406 set.remove("row");
1407 set.remove("values");
1408 set
1409 });
1410
1411 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1413 let mut set = SQL_RESERVED.clone();
1414 set.extend([
1415 "alter",
1416 "and",
1417 "as",
1418 "between",
1419 "by",
1420 "case",
1421 "cast",
1422 "constraint",
1423 "create",
1424 "cross",
1425 "cube",
1426 "current_catalog",
1427 "current_date",
1428 "current_path",
1429 "current_role",
1430 "current_schema",
1431 "current_time",
1432 "current_timestamp",
1433 "current_user",
1434 "deallocate",
1435 "delete",
1436 "describe",
1437 "distinct",
1438 "drop",
1439 "else",
1440 "end",
1441 "escape",
1442 "except",
1443 "execute",
1444 "exists",
1445 "extract",
1446 "false",
1447 "for",
1448 "from",
1449 "full",
1450 "group",
1451 "grouping",
1452 "having",
1453 "in",
1454 "inner",
1455 "insert",
1456 "intersect",
1457 "into",
1458 "is",
1459 "join",
1460 "json_array",
1461 "json_exists",
1462 "json_object",
1463 "json_query",
1464 "json_table",
1465 "json_value",
1466 "left",
1467 "like",
1468 "listagg",
1469 "localtime",
1470 "localtimestamp",
1471 "natural",
1472 "normalize",
1473 "not",
1474 "null",
1475 "on",
1476 "or",
1477 "order",
1478 "outer",
1479 "prepare",
1480 "recursive",
1481 "right",
1482 "rollup",
1483 "select",
1484 "skip",
1485 "table",
1486 "then",
1487 "trim",
1488 "true",
1489 "uescape",
1490 "union",
1491 "unnest",
1492 "using",
1493 "values",
1494 "when",
1495 "where",
1496 "with",
1497 ]);
1498 set.remove("key");
1500 set
1501 });
1502
1503 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1506 [
1507 "add",
1508 "all",
1509 "alter",
1510 "analyze",
1511 "and",
1512 "array",
1513 "as",
1514 "asc",
1515 "between",
1516 "bigint",
1517 "bitmap",
1518 "both",
1519 "by",
1520 "case",
1521 "char",
1522 "character",
1523 "check",
1524 "collate",
1525 "column",
1526 "compaction",
1527 "convert",
1528 "create",
1529 "cross",
1530 "cube",
1531 "current_date",
1532 "current_role",
1533 "current_time",
1534 "current_timestamp",
1535 "current_user",
1536 "database",
1537 "databases",
1538 "decimal",
1539 "decimalv2",
1540 "decimal32",
1541 "decimal64",
1542 "decimal128",
1543 "default",
1544 "deferred",
1545 "delete",
1546 "dense_rank",
1547 "desc",
1548 "describe",
1549 "distinct",
1550 "double",
1551 "drop",
1552 "dual",
1553 "else",
1554 "except",
1555 "exists",
1556 "explain",
1557 "false",
1558 "first_value",
1559 "float",
1560 "for",
1561 "force",
1562 "from",
1563 "full",
1564 "function",
1565 "grant",
1566 "group",
1567 "grouping",
1568 "grouping_id",
1569 "groups",
1570 "having",
1571 "hll",
1572 "host",
1573 "if",
1574 "ignore",
1575 "immediate",
1576 "in",
1577 "index",
1578 "infile",
1579 "inner",
1580 "insert",
1581 "int",
1582 "integer",
1583 "intersect",
1584 "into",
1585 "is",
1586 "join",
1587 "json",
1588 "key",
1589 "keys",
1590 "kill",
1591 "lag",
1592 "largeint",
1593 "last_value",
1594 "lateral",
1595 "lead",
1596 "left",
1597 "like",
1598 "limit",
1599 "load",
1600 "localtime",
1601 "localtimestamp",
1602 "maxvalue",
1603 "minus",
1604 "mod",
1605 "not",
1606 "ntile",
1607 "null",
1608 "on",
1609 "or",
1610 "order",
1611 "outer",
1612 "outfile",
1613 "over",
1614 "partition",
1615 "percentile",
1616 "primary",
1617 "procedure",
1618 "qualify",
1619 "range",
1620 "rank",
1621 "read",
1622 "regexp",
1623 "release",
1624 "rename",
1625 "replace",
1626 "revoke",
1627 "right",
1628 "rlike",
1629 "row",
1630 "row_number",
1631 "rows",
1632 "schema",
1633 "schemas",
1634 "select",
1635 "set",
1636 "set_var",
1637 "show",
1638 "smallint",
1639 "system",
1640 "table",
1641 "terminated",
1642 "text",
1643 "then",
1644 "tinyint",
1645 "to",
1646 "true",
1647 "union",
1648 "unique",
1649 "unsigned",
1650 "update",
1651 "use",
1652 "using",
1653 "values",
1654 "varchar",
1655 "when",
1656 "where",
1657 "with",
1658 ]
1659 .into_iter()
1660 .collect()
1661 });
1662
1663 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1666 let mut set = MYSQL_RESERVED.clone();
1667 set.extend([
1668 "abs",
1671 "account",
1672 "acos",
1673 "adddate",
1674 "addtime",
1675 "admin",
1676 "aes_decrypt",
1677 "aes_encrypt",
1678 "aggregate",
1679 "aggregates",
1680 "aggregator",
1681 "anti_join",
1682 "any_value",
1683 "approx_count_distinct",
1684 "approx_percentile",
1685 "arrange",
1686 "arrangement",
1687 "asin",
1688 "atan",
1689 "atan2",
1690 "attach",
1691 "autostats",
1692 "avro",
1693 "background",
1694 "backup",
1695 "batch",
1696 "batches",
1697 "boot_strapping",
1698 "ceil",
1699 "ceiling",
1700 "coercibility",
1701 "columnar",
1702 "columnstore",
1703 "compile",
1704 "concurrent",
1705 "connection_id",
1706 "cos",
1707 "cot",
1708 "current_security_groups",
1709 "current_security_roles",
1710 "dayname",
1711 "dayofmonth",
1712 "dayofweek",
1713 "dayofyear",
1714 "degrees",
1715 "dot_product",
1716 "dump",
1717 "durability",
1718 "earliest",
1719 "echo",
1720 "election",
1721 "euclidean_distance",
1722 "exp",
1723 "extractor",
1724 "extractors",
1725 "floor",
1726 "foreground",
1727 "found_rows",
1728 "from_base64",
1729 "from_days",
1730 "from_unixtime",
1731 "fs",
1732 "fulltext",
1733 "gc",
1734 "gcs",
1735 "geography",
1736 "geography_area",
1737 "geography_contains",
1738 "geography_distance",
1739 "geography_intersects",
1740 "geography_latitude",
1741 "geography_length",
1742 "geography_longitude",
1743 "geographypoint",
1744 "geography_point",
1745 "geography_within_distance",
1746 "geometry",
1747 "geometry_area",
1748 "geometry_contains",
1749 "geometry_distance",
1750 "geometry_filter",
1751 "geometry_intersects",
1752 "geometry_length",
1753 "geometrypoint",
1754 "geometry_point",
1755 "geometry_within_distance",
1756 "geometry_x",
1757 "geometry_y",
1758 "greatest",
1759 "groups",
1760 "group_concat",
1761 "gzip",
1762 "hdfs",
1763 "hex",
1764 "highlight",
1765 "ifnull",
1766 "ilike",
1767 "inet_aton",
1768 "inet_ntoa",
1769 "inet6_aton",
1770 "inet6_ntoa",
1771 "initcap",
1772 "instr",
1773 "interpreter_mode",
1774 "isnull",
1775 "json",
1776 "json_agg",
1777 "json_array_contains_double",
1778 "json_array_contains_json",
1779 "json_array_contains_string",
1780 "json_delete_key",
1781 "json_extract_double",
1782 "json_extract_json",
1783 "json_extract_string",
1784 "json_extract_bigint",
1785 "json_get_type",
1786 "json_length",
1787 "json_set_double",
1788 "json_set_json",
1789 "json_set_string",
1790 "kafka",
1791 "lag",
1792 "last_day",
1793 "last_insert_id",
1794 "latest",
1795 "lcase",
1796 "lead",
1797 "leaf",
1798 "least",
1799 "leaves",
1800 "length",
1801 "license",
1802 "links",
1803 "llvm",
1804 "ln",
1805 "load",
1806 "locate",
1807 "log",
1808 "log10",
1809 "log2",
1810 "lpad",
1811 "lz4",
1812 "management",
1813 "match",
1814 "mbc",
1815 "md5",
1816 "median",
1817 "memsql",
1818 "memsql_deserialize",
1819 "memsql_serialize",
1820 "metadata",
1821 "microsecond",
1822 "minute",
1823 "model",
1824 "monthname",
1825 "months_between",
1826 "mpl",
1827 "namespace",
1828 "node",
1829 "noparam",
1830 "now",
1831 "nth_value",
1832 "ntile",
1833 "nullcols",
1834 "nullif",
1835 "object",
1836 "octet_length",
1837 "offsets",
1838 "online",
1839 "optimizer",
1840 "orphan",
1841 "parquet",
1842 "partitions",
1843 "pause",
1844 "percentile_cont",
1845 "percentile_disc",
1846 "periodic",
1847 "persisted",
1848 "pi",
1849 "pipeline",
1850 "pipelines",
1851 "plancache",
1852 "plugins",
1853 "pool",
1854 "pools",
1855 "pow",
1856 "power",
1857 "process",
1858 "processlist",
1859 "profile",
1860 "profiles",
1861 "quarter",
1862 "queries",
1863 "query",
1864 "radians",
1865 "rand",
1866 "record",
1867 "reduce",
1868 "redundancy",
1869 "regexp_match",
1870 "regexp_substr",
1871 "remote",
1872 "replication",
1873 "resource",
1874 "resource_pool",
1875 "restore",
1876 "retry",
1877 "role",
1878 "roles",
1879 "round",
1880 "rpad",
1881 "rtrim",
1882 "running",
1883 "s3",
1884 "scalar",
1885 "sec_to_time",
1886 "second",
1887 "security_lists_intersect",
1888 "semi_join",
1889 "sha",
1890 "sha1",
1891 "sha2",
1892 "shard",
1893 "sharded",
1894 "sharded_id",
1895 "sigmoid",
1896 "sign",
1897 "sin",
1898 "skip",
1899 "sleep",
1900 "snapshot",
1901 "soname",
1902 "sparse",
1903 "spatial_check_index",
1904 "split",
1905 "sqrt",
1906 "standalone",
1907 "std",
1908 "stddev",
1909 "stddev_pop",
1910 "stddev_samp",
1911 "stop",
1912 "str_to_date",
1913 "subdate",
1914 "substr",
1915 "substring_index",
1916 "success",
1917 "synchronize",
1918 "table_checksum",
1919 "tan",
1920 "task",
1921 "timediff",
1922 "time_bucket",
1923 "time_format",
1924 "time_to_sec",
1925 "timestampadd",
1926 "timestampdiff",
1927 "to_base64",
1928 "to_char",
1929 "to_date",
1930 "to_days",
1931 "to_json",
1932 "to_number",
1933 "to_seconds",
1934 "to_timestamp",
1935 "tracelogs",
1936 "transform",
1937 "trim",
1938 "trunc",
1939 "truncate",
1940 "ucase",
1941 "unhex",
1942 "unix_timestamp",
1943 "utc_date",
1944 "utc_time",
1945 "utc_timestamp",
1946 "vacuum",
1947 "variance",
1948 "var_pop",
1949 "var_samp",
1950 "vector_sub",
1951 "voting",
1952 "week",
1953 "weekday",
1954 "weekofyear",
1955 "workload",
1956 "year",
1957 ]);
1958 set.remove("all");
1960 set
1961 });
1962
1963 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1967 [
1969 "abort",
1970 "action",
1971 "add",
1972 "after",
1973 "all",
1974 "alter",
1975 "always",
1976 "analyze",
1977 "and",
1978 "as",
1979 "asc",
1980 "attach",
1981 "autoincrement",
1982 "before",
1983 "begin",
1984 "between",
1985 "by",
1986 "cascade",
1987 "case",
1988 "cast",
1989 "check",
1990 "collate",
1991 "column",
1992 "commit",
1993 "conflict",
1994 "constraint",
1995 "create",
1996 "cross",
1997 "current",
1998 "current_date",
1999 "current_time",
2000 "current_timestamp",
2001 "database",
2002 "default",
2003 "deferrable",
2004 "deferred",
2005 "delete",
2006 "desc",
2007 "detach",
2008 "distinct",
2009 "do",
2010 "drop",
2011 "each",
2012 "else",
2013 "end",
2014 "escape",
2015 "except",
2016 "exclude",
2017 "exclusive",
2018 "exists",
2019 "explain",
2020 "fail",
2021 "filter",
2022 "first",
2023 "following",
2024 "for",
2025 "foreign",
2026 "from",
2027 "full",
2028 "generated",
2029 "glob",
2030 "group",
2031 "groups",
2032 "having",
2033 "if",
2034 "ignore",
2035 "immediate",
2036 "in",
2037 "index",
2038 "indexed",
2039 "initially",
2040 "inner",
2041 "insert",
2042 "instead",
2043 "intersect",
2044 "into",
2045 "is",
2046 "isnull",
2047 "join",
2048 "key",
2049 "last",
2050 "left",
2051 "like",
2052 "limit",
2053 "natural",
2054 "no",
2055 "not",
2056 "nothing",
2057 "notnull",
2058 "null",
2059 "nulls",
2060 "of",
2061 "offset",
2062 "on",
2063 "or",
2064 "order",
2065 "others",
2066 "outer",
2067 "partition",
2068 "plan",
2069 "pragma",
2070 "preceding",
2071 "primary",
2072 "query",
2073 "raise",
2074 "range",
2075 "recursive",
2076 "references",
2077 "regexp",
2078 "reindex",
2079 "release",
2080 "rename",
2081 "replace",
2082 "restrict",
2083 "returning",
2084 "right",
2085 "rollback",
2086 "row",
2087 "rows",
2088 "savepoint",
2089 "select",
2090 "set",
2091 "table",
2092 "temp",
2093 "temporary",
2094 "then",
2095 "ties",
2096 "to",
2097 "transaction",
2098 "trigger",
2099 "unbounded",
2100 "union",
2101 "unique",
2102 "update",
2103 "using",
2104 "vacuum",
2105 "values",
2106 "view",
2107 "virtual",
2108 "when",
2109 "where",
2110 "window",
2111 "with",
2112 "without",
2113 ]
2114 .into_iter()
2115 .collect()
2116 });
2117}
2118
2119impl Generator {
2120 pub fn new() -> Self {
2126 Self::with_config(GeneratorConfig::default())
2127 }
2128
2129 pub fn with_config(config: GeneratorConfig) -> Self {
2134 Self::with_arc_config(Arc::new(config))
2135 }
2136
2137 pub(crate) fn with_arc_config(config: Arc<GeneratorConfig>) -> Self {
2142 Self {
2143 config,
2144 output: String::new(),
2145 unsupported_messages: Vec::new(),
2146 indent_level: 0,
2147 athena_hive_context: false,
2148 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2149 merge_strip_qualifiers: Vec::new(),
2150 clickhouse_nullable_depth: 0,
2151 }
2152 }
2153
2154 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2158 match expr {
2159 Expression::Select(mut select) => {
2160 select.expressions = select
2162 .expressions
2163 .into_iter()
2164 .map(|e| Self::add_alias_to_expression(e))
2165 .collect();
2166
2167 if let Some(ref mut from) = select.from {
2169 from.expressions = from
2170 .expressions
2171 .iter()
2172 .cloned()
2173 .map(|e| Self::add_column_aliases_to_query(e))
2174 .collect();
2175 }
2176
2177 Expression::Select(select)
2178 }
2179 Expression::Subquery(mut sq) => {
2180 sq.this = Self::add_column_aliases_to_query(sq.this);
2181 Expression::Subquery(sq)
2182 }
2183 Expression::Paren(mut p) => {
2184 p.this = Self::add_column_aliases_to_query(p.this);
2185 Expression::Paren(p)
2186 }
2187 other => other,
2189 }
2190 }
2191
2192 fn add_alias_to_expression(expr: Expression) -> Expression {
2195 use crate::expressions::Alias;
2196
2197 match &expr {
2198 Expression::Alias(_) => expr,
2200
2201 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2203 this: expr.clone(),
2204 alias: col.name.clone(),
2205 column_aliases: Vec::new(),
2206 pre_alias_comments: Vec::new(),
2207 trailing_comments: Vec::new(),
2208 inferred_type: None,
2209 })),
2210
2211 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2213 this: expr.clone(),
2214 alias: ident.clone(),
2215 column_aliases: Vec::new(),
2216 pre_alias_comments: Vec::new(),
2217 trailing_comments: Vec::new(),
2218 inferred_type: None,
2219 })),
2220
2221 Expression::Subquery(sq) => {
2223 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2224 if sq.alias.is_some() {
2226 processed
2227 } else {
2228 processed
2230 }
2231 }
2232
2233 Expression::Star(_) => expr,
2235
2236 _ => expr,
2239 }
2240 }
2241
2242 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2246 match expr {
2247 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
2248 let Literal::Number(n) = lit.as_ref() else {
2249 unreachable!()
2250 };
2251 n.parse::<i64>().ok()
2252 }
2253 Expression::Add(op) => {
2254 let left = Self::try_evaluate_constant(&op.left)?;
2255 let right = Self::try_evaluate_constant(&op.right)?;
2256 Some(left + right)
2257 }
2258 Expression::Sub(op) => {
2259 let left = Self::try_evaluate_constant(&op.left)?;
2260 let right = Self::try_evaluate_constant(&op.right)?;
2261 Some(left - right)
2262 }
2263 Expression::Mul(op) => {
2264 let left = Self::try_evaluate_constant(&op.left)?;
2265 let right = Self::try_evaluate_constant(&op.right)?;
2266 Some(left * right)
2267 }
2268 Expression::Div(op) => {
2269 let left = Self::try_evaluate_constant(&op.left)?;
2270 let right = Self::try_evaluate_constant(&op.right)?;
2271 if right != 0 {
2272 Some(left / right)
2273 } else {
2274 None
2275 }
2276 }
2277 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2278 _ => None,
2279 }
2280 }
2281
2282 fn is_reserved_keyword(&self, name: &str) -> bool {
2284 use crate::dialects::DialectType;
2285 let mut buf = [0u8; 128];
2286 let lower_ref: &str = if name.len() <= 128 {
2287 for (i, b) in name.bytes().enumerate() {
2288 buf[i] = b.to_ascii_lowercase();
2289 }
2290 std::str::from_utf8(&buf[..name.len()]).unwrap_or(name)
2292 } else {
2293 return false;
2294 };
2295
2296 match self.config.dialect {
2297 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2298 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2299 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2300 }
2301 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2302 Some(DialectType::SingleStore) => {
2303 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2304 }
2305 Some(DialectType::StarRocks) => {
2306 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2307 }
2308 Some(DialectType::PostgreSQL)
2309 | Some(DialectType::CockroachDB)
2310 | Some(DialectType::Materialize)
2311 | Some(DialectType::RisingWave) => {
2312 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2313 }
2314 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2315 Some(DialectType::Snowflake) => false,
2318 Some(DialectType::ClickHouse) => false,
2320 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2321 Some(DialectType::Teradata) => false,
2323 Some(DialectType::TSQL)
2325 | Some(DialectType::Fabric)
2326 | Some(DialectType::Oracle)
2327 | Some(DialectType::Spark)
2328 | Some(DialectType::Databricks)
2329 | Some(DialectType::Hive)
2330 | Some(DialectType::Solr) => false,
2331 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2332 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2333 }
2334 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2335 Some(DialectType::Generic) | None => false,
2337 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2339 }
2340 }
2341
2342 fn normalize_func_name<'a>(&self, name: &'a str) -> Cow<'a, str> {
2344 match self.config.normalize_functions {
2345 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
2346 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
2347 NormalizeFunctions::None => Cow::Borrowed(name),
2348 }
2349 }
2350
2351 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2360 self.output.clear();
2361 self.unsupported_messages.clear();
2362 self.generate_expression(expr)?;
2363 if self.config.unsupported_level == UnsupportedLevel::Raise
2364 && !self.unsupported_messages.is_empty()
2365 {
2366 return Err(crate::error::Error::generate(
2367 self.format_unsupported_messages(),
2368 ));
2369 }
2370 Ok(std::mem::take(&mut self.output))
2371 }
2372
2373 pub fn unsupported_messages(&self) -> &[String] {
2375 &self.unsupported_messages
2376 }
2377
2378 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2379 let message = message.into();
2380 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2381 return Err(crate::error::Error::generate(message));
2382 }
2383 self.unsupported_messages.push(message);
2384 Ok(())
2385 }
2386
2387 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2388 self.unsupported(message.to_string())?;
2389 self.write("/* ");
2390 self.write(message);
2391 self.write(" */");
2392 Ok(())
2393 }
2394
2395 fn format_unsupported_messages(&self) -> String {
2396 let limit = self.config.max_unsupported.max(1);
2397 if self.unsupported_messages.len() <= limit {
2398 return self.unsupported_messages.join("; ");
2399 }
2400
2401 let mut messages = self
2402 .unsupported_messages
2403 .iter()
2404 .take(limit)
2405 .cloned()
2406 .collect::<Vec<_>>();
2407 messages.push(format!(
2408 "... and {} more",
2409 self.unsupported_messages.len() - limit
2410 ));
2411 messages.join("; ")
2412 }
2413
2414 pub fn sql(expr: &Expression) -> Result<String> {
2420 let mut gen = Generator::new();
2421 gen.generate(expr)
2422 }
2423
2424 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2429 let config = GeneratorConfig {
2430 pretty: true,
2431 ..Default::default()
2432 };
2433 let mut gen = Generator::with_config(config);
2434 let mut sql = gen.generate(expr)?;
2435 if !sql.ends_with(';') {
2437 sql.push(';');
2438 }
2439 Ok(sql)
2440 }
2441
2442 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2443 #[cfg(feature = "stacker")]
2444 {
2445 let red_zone = if cfg!(debug_assertions) {
2446 4 * 1024 * 1024
2447 } else {
2448 1024 * 1024
2449 };
2450 stacker::maybe_grow(red_zone, 8 * 1024 * 1024, || {
2451 self.generate_expression_inner(expr)
2452 })
2453 }
2454 #[cfg(not(feature = "stacker"))]
2455 {
2456 self.generate_expression_inner(expr)
2457 }
2458 }
2459
2460 fn generate_expression_inner(&mut self, expr: &Expression) -> Result<()> {
2461 match expr {
2462 Expression::Select(select) => self.generate_select(select),
2463 Expression::Union(union) => self.generate_union(union),
2464 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2465 Expression::Except(except) => self.generate_except(except),
2466 Expression::Insert(insert) => self.generate_insert(insert),
2467 Expression::Update(update) => self.generate_update(update),
2468 Expression::Delete(delete) => self.generate_delete(delete),
2469 Expression::Literal(lit) => self.generate_literal(lit),
2470 Expression::Boolean(b) => self.generate_boolean(b),
2471 Expression::Null(_) => {
2472 self.write_keyword("NULL");
2473 Ok(())
2474 }
2475 Expression::Identifier(id) => self.generate_identifier(id),
2476 Expression::Column(col) => self.generate_column(col),
2477 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2478 Expression::Connect(c) => self.generate_connect_expr(c),
2479 Expression::Prior(p) => self.generate_prior(p),
2480 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2481 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2482 Expression::Table(table) => self.generate_table(table),
2483 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2484 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2485 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2486 Expression::Star(star) => self.generate_star(star),
2487 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2488 Expression::Alias(alias) => self.generate_alias(alias),
2489 Expression::Cast(cast) => self.generate_cast(cast),
2490 Expression::Collation(coll) => self.generate_collation(coll),
2491 Expression::Case(case) => self.generate_case(case),
2492 Expression::Function(func) => self.generate_function(func),
2493 Expression::FunctionEmits(fe) => self.generate_function_emits(fe),
2494 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2495 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2496 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2497 Expression::Interval(interval) => self.generate_interval(interval),
2498
2499 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2501 Expression::Substring(f) => self.generate_substring(f),
2502 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2503 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2504 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2505 Expression::Trim(f) => self.generate_trim(f),
2506 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2507 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2508 Expression::Replace(f) => self.generate_replace(f),
2509 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2510 Expression::Left(f) => self.generate_left_right("LEFT", f),
2511 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2512 Expression::Repeat(f) => self.generate_repeat(f),
2513 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2514 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2515 Expression::Split(f) => self.generate_split(f),
2516 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2517 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2518 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2519 Expression::Overlay(f) => self.generate_overlay(f),
2520
2521 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2523 Expression::Round(f) => self.generate_round(f),
2524 Expression::Floor(f) => self.generate_floor(f),
2525 Expression::Ceil(f) => self.generate_ceil(f),
2526 Expression::Power(f) => self.generate_power(f),
2527 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2528 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2529 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2530 Expression::Log(f) => self.generate_log(f),
2531 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2532 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2533 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2534 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2535
2536 Expression::CurrentDate(_) => {
2538 self.write_keyword("CURRENT_DATE");
2539 Ok(())
2540 }
2541 Expression::CurrentTime(f) => self.generate_current_time(f),
2542 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2543 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2544 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2545 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2546 Expression::DateDiff(f) => self.generate_datediff(f),
2547 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2548 Expression::Extract(f) => self.generate_extract(f),
2549 Expression::ToDate(f) => self.generate_to_date(f),
2550 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2551
2552 Expression::Coalesce(f) => {
2554 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2556 self.generate_vararg_func(func_name, &f.expressions)
2557 }
2558 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2559 Expression::IfFunc(f) => self.generate_if_func(f),
2560 Expression::IfNull(f) => self.generate_ifnull(f),
2561 Expression::Nvl(f) => self.generate_nvl(f),
2562 Expression::Nvl2(f) => self.generate_nvl2(f),
2563
2564 Expression::TryCast(cast) => self.generate_try_cast(cast),
2566 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2567
2568 Expression::Count(f) => self.generate_count(f),
2570 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2571 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2572 Expression::Min(f) => self.generate_agg_func("MIN", f),
2573 Expression::Max(f) => self.generate_agg_func("MAX", f),
2574 Expression::GroupConcat(f) => self.generate_group_concat(f),
2575 Expression::StringAgg(f) => self.generate_string_agg(f),
2576 Expression::ListAgg(f) => self.generate_listagg(f),
2577 Expression::ArrayAgg(f) => {
2578 let override_name = f
2581 .name
2582 .as_ref()
2583 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2584 .map(|n| n.to_ascii_uppercase());
2585 match override_name {
2586 Some(name) => self.generate_agg_func(&name, f),
2587 None => self.generate_agg_func("ARRAY_AGG", f),
2588 }
2589 }
2590 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2591 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2592 Expression::SumIf(f) => self.generate_sum_if(f),
2593 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2594 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2595 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2596 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2597 Expression::VarPop(f) => {
2598 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2599 "VARIANCE_POP"
2600 } else {
2601 "VAR_POP"
2602 };
2603 self.generate_agg_func(name, f)
2604 }
2605 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2606 Expression::Skewness(f) => {
2607 let name = match self.config.dialect {
2608 Some(DialectType::Snowflake) => "SKEW",
2609 _ => "SKEWNESS",
2610 };
2611 self.generate_agg_func(name, f)
2612 }
2613 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2614 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2615 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2616 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2617 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2618 Expression::ApproxDistinct(f) => {
2619 match self.config.dialect {
2620 Some(DialectType::Hive)
2621 | Some(DialectType::Spark)
2622 | Some(DialectType::Databricks)
2623 | Some(DialectType::BigQuery) => {
2624 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2626 }
2627 Some(DialectType::Redshift) => {
2628 self.write_keyword("APPROXIMATE COUNT");
2630 self.write("(");
2631 self.write_keyword("DISTINCT");
2632 self.write(" ");
2633 self.generate_expression(&f.this)?;
2634 self.write(")");
2635 Ok(())
2636 }
2637 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2638 }
2639 }
2640 Expression::ApproxCountDistinct(f) => {
2641 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2642 }
2643 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2644 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2645 Expression::LogicalAnd(f) => {
2646 let name = match self.config.dialect {
2647 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2648 Some(DialectType::Spark)
2649 | Some(DialectType::Databricks)
2650 | Some(DialectType::PostgreSQL)
2651 | Some(DialectType::DuckDB)
2652 | Some(DialectType::Redshift) => "BOOL_AND",
2653 Some(DialectType::Oracle)
2654 | Some(DialectType::SQLite)
2655 | Some(DialectType::MySQL) => "MIN",
2656 _ => "BOOL_AND",
2657 };
2658 self.generate_agg_func(name, f)
2659 }
2660 Expression::LogicalOr(f) => {
2661 let name = match self.config.dialect {
2662 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2663 Some(DialectType::Spark)
2664 | Some(DialectType::Databricks)
2665 | Some(DialectType::PostgreSQL)
2666 | Some(DialectType::DuckDB)
2667 | Some(DialectType::Redshift) => "BOOL_OR",
2668 Some(DialectType::Oracle)
2669 | Some(DialectType::SQLite)
2670 | Some(DialectType::MySQL) => "MAX",
2671 _ => "BOOL_OR",
2672 };
2673 self.generate_agg_func(name, f)
2674 }
2675
2676 Expression::RowNumber(_) => {
2678 if self.config.dialect == Some(DialectType::ClickHouse) {
2679 self.write("row_number");
2680 } else {
2681 self.write_keyword("ROW_NUMBER");
2682 }
2683 self.write("()");
2684 Ok(())
2685 }
2686 Expression::Rank(r) => {
2687 self.write_keyword("RANK");
2688 self.write("(");
2689 if !r.args.is_empty() {
2691 for (i, arg) in r.args.iter().enumerate() {
2692 if i > 0 {
2693 self.write(", ");
2694 }
2695 self.generate_expression(arg)?;
2696 }
2697 } else if let Some(order_by) = &r.order_by {
2698 self.write_keyword(" ORDER BY ");
2700 for (i, ob) in order_by.iter().enumerate() {
2701 if i > 0 {
2702 self.write(", ");
2703 }
2704 self.generate_ordered(ob)?;
2705 }
2706 }
2707 self.write(")");
2708 Ok(())
2709 }
2710 Expression::DenseRank(dr) => {
2711 self.write_keyword("DENSE_RANK");
2712 self.write("(");
2713 for (i, arg) in dr.args.iter().enumerate() {
2715 if i > 0 {
2716 self.write(", ");
2717 }
2718 self.generate_expression(arg)?;
2719 }
2720 self.write(")");
2721 Ok(())
2722 }
2723 Expression::NTile(f) => self.generate_ntile(f),
2724 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2725 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2726 Expression::FirstValue(f) => {
2727 self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f)
2728 }
2729 Expression::LastValue(f) => {
2730 self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f)
2731 }
2732 Expression::NthValue(f) => self.generate_nth_value(f),
2733 Expression::PercentRank(pr) => {
2734 self.write_keyword("PERCENT_RANK");
2735 self.write("(");
2736 if !pr.args.is_empty() {
2738 for (i, arg) in pr.args.iter().enumerate() {
2739 if i > 0 {
2740 self.write(", ");
2741 }
2742 self.generate_expression(arg)?;
2743 }
2744 } else if let Some(order_by) = &pr.order_by {
2745 self.write_keyword(" ORDER BY ");
2747 for (i, ob) in order_by.iter().enumerate() {
2748 if i > 0 {
2749 self.write(", ");
2750 }
2751 self.generate_ordered(ob)?;
2752 }
2753 }
2754 self.write(")");
2755 Ok(())
2756 }
2757 Expression::CumeDist(cd) => {
2758 self.write_keyword("CUME_DIST");
2759 self.write("(");
2760 if !cd.args.is_empty() {
2762 for (i, arg) in cd.args.iter().enumerate() {
2763 if i > 0 {
2764 self.write(", ");
2765 }
2766 self.generate_expression(arg)?;
2767 }
2768 } else if let Some(order_by) = &cd.order_by {
2769 self.write_keyword(" ORDER BY ");
2771 for (i, ob) in order_by.iter().enumerate() {
2772 if i > 0 {
2773 self.write(", ");
2774 }
2775 self.generate_ordered(ob)?;
2776 }
2777 }
2778 self.write(")");
2779 Ok(())
2780 }
2781 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2782 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2783
2784 Expression::Contains(f) => {
2786 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2787 }
2788 Expression::StartsWith(f) => {
2789 let name = match self.config.dialect {
2790 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2791 _ => "STARTS_WITH",
2792 };
2793 self.generate_binary_func(name, &f.this, &f.expression)
2794 }
2795 Expression::EndsWith(f) => {
2796 let name = match self.config.dialect {
2797 Some(DialectType::Snowflake) => "ENDSWITH",
2798 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2799 Some(DialectType::ClickHouse) => "endsWith",
2800 _ => "ENDS_WITH",
2801 };
2802 self.generate_binary_func(name, &f.this, &f.expression)
2803 }
2804 Expression::Position(f) => self.generate_position(f),
2805 Expression::Initcap(f) => match self.config.dialect {
2806 Some(DialectType::Presto)
2807 | Some(DialectType::Trino)
2808 | Some(DialectType::Athena) => {
2809 self.write_keyword("REGEXP_REPLACE");
2810 self.write("(");
2811 self.generate_expression(&f.this)?;
2812 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2813 Ok(())
2814 }
2815 _ => self.generate_simple_func("INITCAP", &f.this),
2816 },
2817 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2818 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2819 Expression::CharFunc(f) => self.generate_char_func(f),
2820 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2821 Expression::Levenshtein(f) => {
2822 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2823 }
2824
2825 Expression::ModFunc(f) => self.generate_mod_func(f),
2827 Expression::Random(_) => {
2828 self.write_keyword("RANDOM");
2829 self.write("()");
2830 Ok(())
2831 }
2832 Expression::Rand(f) => self.generate_rand(f),
2833 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2834 Expression::Pi(_) => {
2835 self.write_keyword("PI");
2836 self.write("()");
2837 Ok(())
2838 }
2839 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2840 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2841 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2842 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2843 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2844 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2845 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2846 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2847 Expression::Atan2(f) => {
2848 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2849 self.generate_binary_func(name, &f.this, &f.expression)
2850 }
2851
2852 Expression::Decode(f) => self.generate_decode(f),
2854
2855 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2857 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2858 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2859 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2860 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2861 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2862 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2863 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2864 Expression::DayOfWeek(f) => {
2865 let name = match self.config.dialect {
2866 Some(DialectType::Presto)
2867 | Some(DialectType::Trino)
2868 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2869 Some(DialectType::DuckDB) => "ISODOW",
2870 _ => "DAYOFWEEK",
2871 };
2872 self.generate_simple_func(name, &f.this)
2873 }
2874 Expression::DayOfMonth(f) => {
2875 let name = match self.config.dialect {
2876 Some(DialectType::Presto)
2877 | Some(DialectType::Trino)
2878 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2879 _ => "DAYOFMONTH",
2880 };
2881 self.generate_simple_func(name, &f.this)
2882 }
2883 Expression::DayOfYear(f) => {
2884 let name = match self.config.dialect {
2885 Some(DialectType::Presto)
2886 | Some(DialectType::Trino)
2887 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2888 _ => "DAYOFYEAR",
2889 };
2890 self.generate_simple_func(name, &f.this)
2891 }
2892 Expression::WeekOfYear(f) => {
2893 let name = match self.config.dialect {
2895 Some(DialectType::Hive)
2896 | Some(DialectType::DuckDB)
2897 | Some(DialectType::Spark)
2898 | Some(DialectType::Databricks)
2899 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2900 _ => "WEEK_OF_YEAR",
2901 };
2902 self.generate_simple_func(name, &f.this)
2903 }
2904 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2905 Expression::AddMonths(f) => {
2906 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2907 }
2908 Expression::MonthsBetween(f) => {
2909 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2910 }
2911 Expression::LastDay(f) => self.generate_last_day(f),
2912 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2913 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2914 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2915 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2916 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2917 Expression::MakeDate(f) => self.generate_make_date(f),
2918 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2919 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2920
2921 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2923 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2924 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2925 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2926 Expression::ArrayContains(f) => {
2927 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2928 }
2929 Expression::ArrayPosition(f) => {
2930 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2931 }
2932 Expression::ArrayAppend(f) => {
2933 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2934 }
2935 Expression::ArrayPrepend(f) => {
2936 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2937 }
2938 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2939 Expression::ArraySort(f) => self.generate_array_sort(f),
2940 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2941 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2942 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2943 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2944 Expression::Unnest(f) => self.generate_unnest(f),
2945 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2946 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2947 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2948 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2949 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2950 Expression::ArrayCompact(f) => {
2951 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2952 self.write("LIST_FILTER(");
2954 self.generate_expression(&f.this)?;
2955 self.write(", _u -> NOT _u IS NULL)");
2956 Ok(())
2957 } else {
2958 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2959 }
2960 }
2961 Expression::ArrayIntersect(f) => {
2962 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2963 self.generate_vararg_func(func_name, &f.expressions)
2964 }
2965 Expression::ArrayUnion(f) => {
2966 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2967 }
2968 Expression::ArrayExcept(f) => {
2969 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2970 }
2971 Expression::ArrayRemove(f) => {
2972 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2973 }
2974 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2975 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2976 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2977
2978 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2980 Expression::StructExtract(f) => self.generate_struct_extract(f),
2981 Expression::NamedStruct(f) => self.generate_named_struct(f),
2982
2983 Expression::MapFunc(f) => self.generate_map_constructor(f),
2985 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2986 Expression::MapFromArrays(f) => {
2987 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2988 }
2989 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2990 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2991 Expression::MapContainsKey(f) => {
2992 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2993 }
2994 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2995 Expression::ElementAt(f) => {
2996 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
2997 }
2998 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
2999 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
3000
3001 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
3003 Expression::JsonExtractScalar(f) => {
3004 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
3005 }
3006 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
3007 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
3008 Expression::JsonObject(f) => self.generate_json_object(f),
3009 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
3010 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
3011 Expression::JsonArrayLength(f) => {
3012 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
3013 }
3014 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
3015 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
3016 Expression::ParseJson(f) => {
3017 let name = match self.config.dialect {
3018 Some(DialectType::Presto)
3019 | Some(DialectType::Trino)
3020 | Some(DialectType::Athena) => "JSON_PARSE",
3021 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
3022 self.write_keyword("CAST");
3024 self.write("(");
3025 self.generate_expression(&f.this)?;
3026 self.write_keyword(" AS ");
3027 self.write_keyword("JSON");
3028 self.write(")");
3029 return Ok(());
3030 }
3031 Some(DialectType::Hive)
3032 | Some(DialectType::Spark)
3033 | Some(DialectType::MySQL)
3034 | Some(DialectType::SingleStore)
3035 | Some(DialectType::TiDB)
3036 | Some(DialectType::TSQL) => {
3037 self.generate_expression(&f.this)?;
3039 return Ok(());
3040 }
3041 Some(DialectType::DuckDB) => "JSON",
3042 _ => "PARSE_JSON",
3043 };
3044 self.generate_simple_func(name, &f.this)
3045 }
3046 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3047 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3048 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3049 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3050 Expression::JsonMergePatch(f) => {
3051 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3052 }
3053 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3054 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3055
3056 Expression::Convert(f) => self.generate_convert(f),
3058 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3059
3060 Expression::Lambda(f) => self.generate_lambda(f),
3062 Expression::Parameter(f) => self.generate_parameter(f),
3063 Expression::Placeholder(f) => self.generate_placeholder(f),
3064 Expression::NamedArgument(f) => self.generate_named_argument(f),
3065 Expression::TableArgument(f) => self.generate_table_argument(f),
3066 Expression::SqlComment(f) => self.generate_sql_comment(f),
3067
3068 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3070 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3071 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3072 Expression::SimilarTo(f) => self.generate_similar_to(f),
3073 Expression::Any(f) => self.generate_quantified("ANY", f),
3074 Expression::All(f) => self.generate_quantified("ALL", f),
3075 Expression::Overlaps(f) => self.generate_overlaps(f),
3076
3077 Expression::BitwiseLeftShift(op) => {
3079 if matches!(
3080 self.config.dialect,
3081 Some(DialectType::Presto) | Some(DialectType::Trino)
3082 ) {
3083 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
3084 self.write("(");
3085 self.generate_expression(&op.left)?;
3086 self.write(", ");
3087 self.generate_expression(&op.right)?;
3088 self.write(")");
3089 Ok(())
3090 } else if matches!(
3091 self.config.dialect,
3092 Some(DialectType::Spark) | Some(DialectType::Databricks)
3093 ) {
3094 self.write_keyword("SHIFTLEFT");
3095 self.write("(");
3096 self.generate_expression(&op.left)?;
3097 self.write(", ");
3098 self.generate_expression(&op.right)?;
3099 self.write(")");
3100 Ok(())
3101 } else {
3102 self.generate_binary_op(op, "<<")
3103 }
3104 }
3105 Expression::BitwiseRightShift(op) => {
3106 if matches!(
3107 self.config.dialect,
3108 Some(DialectType::Presto) | Some(DialectType::Trino)
3109 ) {
3110 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
3111 self.write("(");
3112 self.generate_expression(&op.left)?;
3113 self.write(", ");
3114 self.generate_expression(&op.right)?;
3115 self.write(")");
3116 Ok(())
3117 } else if matches!(
3118 self.config.dialect,
3119 Some(DialectType::Spark) | Some(DialectType::Databricks)
3120 ) {
3121 self.write_keyword("SHIFTRIGHT");
3122 self.write("(");
3123 self.generate_expression(&op.left)?;
3124 self.write(", ");
3125 self.generate_expression(&op.right)?;
3126 self.write(")");
3127 Ok(())
3128 } else {
3129 self.generate_binary_op(op, ">>")
3130 }
3131 }
3132 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3133 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3134 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3135
3136 Expression::Subscript(s) => self.generate_subscript(s),
3138 Expression::Dot(d) => self.generate_dot_access(d),
3139 Expression::MethodCall(m) => self.generate_method_call(m),
3140 Expression::ArraySlice(s) => self.generate_array_slice(s),
3141
3142 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3143 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3144 Expression::Add(op) => self.generate_binary_op(op, "+"),
3145 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3146 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3147 Expression::Div(op) => self.generate_binary_op(op, "/"),
3148 Expression::IntDiv(f) => {
3149 use crate::dialects::DialectType;
3150 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3151 self.generate_expression(&f.this)?;
3153 self.write(" // ");
3154 self.generate_expression(&f.expression)?;
3155 Ok(())
3156 } else if matches!(
3157 self.config.dialect,
3158 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3159 ) {
3160 self.generate_expression(&f.this)?;
3162 self.write(" ");
3163 self.write_keyword("DIV");
3164 self.write(" ");
3165 self.generate_expression(&f.expression)?;
3166 Ok(())
3167 } else {
3168 self.write_keyword("DIV");
3170 self.write("(");
3171 self.generate_expression(&f.this)?;
3172 self.write(", ");
3173 self.generate_expression(&f.expression)?;
3174 self.write(")");
3175 Ok(())
3176 }
3177 }
3178 Expression::Mod(op) => {
3179 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3180 self.generate_binary_op(op, "MOD")
3181 } else {
3182 self.generate_binary_op(op, "%")
3183 }
3184 }
3185 Expression::Eq(op) => self.generate_binary_op(op, "="),
3186 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3187 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3188 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3189 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3190 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3191 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3192 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3193 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3194 Expression::Concat(op) => {
3195 if self.config.dialect == Some(DialectType::Solr) {
3197 self.generate_binary_op(op, "OR")
3198 } else if self.config.dialect == Some(DialectType::MySQL) {
3199 self.generate_mysql_concat_from_concat(op)
3200 } else {
3201 self.generate_binary_op(op, "||")
3202 }
3203 }
3204 Expression::BitwiseAnd(op) => {
3205 if matches!(
3207 self.config.dialect,
3208 Some(DialectType::Presto) | Some(DialectType::Trino)
3209 ) {
3210 self.write_keyword("BITWISE_AND");
3211 self.write("(");
3212 self.generate_expression(&op.left)?;
3213 self.write(", ");
3214 self.generate_expression(&op.right)?;
3215 self.write(")");
3216 Ok(())
3217 } else {
3218 self.generate_binary_op(op, "&")
3219 }
3220 }
3221 Expression::BitwiseOr(op) => {
3222 if matches!(
3224 self.config.dialect,
3225 Some(DialectType::Presto) | Some(DialectType::Trino)
3226 ) {
3227 self.write_keyword("BITWISE_OR");
3228 self.write("(");
3229 self.generate_expression(&op.left)?;
3230 self.write(", ");
3231 self.generate_expression(&op.right)?;
3232 self.write(")");
3233 Ok(())
3234 } else {
3235 self.generate_binary_op(op, "|")
3236 }
3237 }
3238 Expression::BitwiseXor(op) => {
3239 if matches!(
3241 self.config.dialect,
3242 Some(DialectType::Presto) | Some(DialectType::Trino)
3243 ) {
3244 self.write_keyword("BITWISE_XOR");
3245 self.write("(");
3246 self.generate_expression(&op.left)?;
3247 self.write(", ");
3248 self.generate_expression(&op.right)?;
3249 self.write(")");
3250 Ok(())
3251 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3252 self.generate_binary_op(op, "#")
3253 } else {
3254 self.generate_binary_op(op, "^")
3255 }
3256 }
3257 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3258 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3259 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3260 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3261 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3262 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3263 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3264 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3265 Expression::JSONBContains(f) => {
3266 self.generate_expression(&f.this)?;
3268 self.write_space();
3269 self.write("?");
3270 self.write_space();
3271 self.generate_expression(&f.expression)
3272 }
3273 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3274 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3275 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3276 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3277 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3278 Expression::BitwiseNot(op) => {
3279 if matches!(
3281 self.config.dialect,
3282 Some(DialectType::Presto) | Some(DialectType::Trino)
3283 ) {
3284 self.write_keyword("BITWISE_NOT");
3285 self.write("(");
3286 self.generate_expression(&op.this)?;
3287 self.write(")");
3288 Ok(())
3289 } else {
3290 self.generate_unary_op(op, "~")
3291 }
3292 }
3293 Expression::In(in_expr) => self.generate_in(in_expr),
3294 Expression::Between(between) => self.generate_between(between),
3295 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3296 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3297 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3298 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3299 Expression::Is(is_expr) => self.generate_is(is_expr),
3300 Expression::Exists(exists) => self.generate_exists(exists),
3301 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3302 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3303 Expression::Paren(paren) => {
3304 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3306
3307 if !skip_parens {
3308 self.write("(");
3309 if self.config.pretty {
3310 self.write_newline();
3311 self.indent_level += 1;
3312 self.write_indent();
3313 }
3314 }
3315 self.generate_expression(&paren.this)?;
3316 if !skip_parens {
3317 if self.config.pretty {
3318 self.write_newline();
3319 self.indent_level -= 1;
3320 self.write_indent();
3321 }
3322 self.write(")");
3323 }
3324 for comment in &paren.trailing_comments {
3326 self.write(" ");
3327 self.write_formatted_comment(comment);
3328 }
3329 Ok(())
3330 }
3331 Expression::Array(arr) => self.generate_array(arr),
3332 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3333 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3334 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3335 Expression::DataType(dt) => self.generate_data_type(dt),
3336 Expression::Raw(raw) => {
3337 self.write(&raw.sql);
3338 Ok(())
3339 }
3340 Expression::CreateTask(task) => self.generate_create_task(task),
3341 Expression::Command(cmd) => {
3342 self.write(&cmd.this);
3343 Ok(())
3344 }
3345 Expression::Kill(kill) => {
3346 self.write_keyword("KILL");
3347 if let Some(kind) = &kill.kind {
3348 self.write_space();
3349 self.write_keyword(kind);
3350 }
3351 self.write_space();
3352 self.generate_expression(&kill.this)?;
3353 Ok(())
3354 }
3355 Expression::Execute(exec) => {
3356 self.write_keyword("EXECUTE");
3357 self.write_space();
3358 self.generate_expression(&exec.this)?;
3359 for (i, param) in exec.parameters.iter().enumerate() {
3360 if i == 0 {
3361 self.write_space();
3362 } else {
3363 self.write(", ");
3364 }
3365 self.write(¶m.name);
3366 if !param.positional {
3368 self.write(" = ");
3369 self.generate_expression(¶m.value)?;
3370 }
3371 if param.output {
3372 self.write_space();
3373 self.write_keyword("OUTPUT");
3374 }
3375 }
3376 if let Some(ref suffix) = exec.suffix {
3377 self.write_space();
3378 self.write(suffix);
3379 }
3380 Ok(())
3381 }
3382 Expression::Annotated(annotated) => {
3383 self.generate_expression(&annotated.this)?;
3384 for comment in &annotated.trailing_comments {
3385 self.write(" ");
3386 self.write_formatted_comment(comment);
3387 }
3388 Ok(())
3389 }
3390
3391 Expression::CreateTable(ct) => self.generate_create_table(ct),
3393 Expression::DropTable(dt) => self.generate_drop_table(dt),
3394 Expression::Undrop(u) => self.generate_undrop(u),
3395 Expression::AlterTable(at) => self.generate_alter_table(at),
3396 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3397 Expression::DropIndex(di) => self.generate_drop_index(di),
3398 Expression::CreateView(cv) => self.generate_create_view(cv),
3399 Expression::DropView(dv) => self.generate_drop_view(dv),
3400 Expression::AlterView(av) => self.generate_alter_view(av),
3401 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3402 Expression::Truncate(tr) => self.generate_truncate(tr),
3403 Expression::Use(u) => self.generate_use(u),
3404 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3406 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3407 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3408 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3409 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3410 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3411 Expression::DropFunction(df) => self.generate_drop_function(df),
3412 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3413 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3414 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3415 Expression::CreateSynonym(cs) => {
3416 self.write_keyword("CREATE SYNONYM");
3417 self.write_space();
3418 self.generate_table(&cs.name)?;
3419 self.write_space();
3420 self.write_keyword("FOR");
3421 self.write_space();
3422 self.generate_table(&cs.target)?;
3423 Ok(())
3424 }
3425 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3426 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3427 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3428 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3429 Expression::CreateType(ct) => self.generate_create_type(ct),
3430 Expression::DropType(dt) => self.generate_drop_type(dt),
3431 Expression::Describe(d) => self.generate_describe(d),
3432 Expression::Show(s) => self.generate_show(s),
3433
3434 Expression::Cache(c) => self.generate_cache(c),
3436 Expression::Uncache(u) => self.generate_uncache(u),
3437 Expression::LoadData(l) => self.generate_load_data(l),
3438 Expression::Pragma(p) => self.generate_pragma(p),
3439 Expression::Grant(g) => self.generate_grant(g),
3440 Expression::Revoke(r) => self.generate_revoke(r),
3441 Expression::Comment(c) => self.generate_comment(c),
3442 Expression::SetStatement(s) => self.generate_set_statement(s),
3443
3444 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3446 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3447
3448 Expression::Values(values) => self.generate_values(values),
3450
3451 Expression::AIAgg(e) => self.generate_ai_agg(e),
3453 Expression::AIClassify(e) => self.generate_ai_classify(e),
3454 Expression::AddPartition(e) => self.generate_add_partition(e),
3455 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3456 Expression::Aliases(e) => self.generate_aliases(e),
3457 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3458 Expression::AlterColumn(e) => self.generate_alter_column(e),
3459 Expression::AlterSession(e) => self.generate_alter_session(e),
3460 Expression::AlterSet(e) => self.generate_alter_set(e),
3461 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3462 Expression::Analyze(e) => self.generate_analyze(e),
3463 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3464 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3465 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3466 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3467 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3468 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3469 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3470 Expression::Anonymous(e) => self.generate_anonymous(e),
3471 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3472 Expression::Apply(e) => self.generate_apply(e),
3473 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3474 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3475 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3476 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3477 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3478 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3479 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3480 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3481 Expression::ArgMax(e) => self.generate_arg_max(e),
3482 Expression::ArgMin(e) => self.generate_arg_min(e),
3483 Expression::ArrayAll(e) => self.generate_array_all(e),
3484 Expression::ArrayAny(e) => self.generate_array_any(e),
3485 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3486 Expression::ArraySum(e) => self.generate_array_sum(e),
3487 Expression::AtIndex(e) => self.generate_at_index(e),
3488 Expression::Attach(e) => self.generate_attach(e),
3489 Expression::AttachOption(e) => self.generate_attach_option(e),
3490 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3491 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3492 Expression::BackupProperty(e) => self.generate_backup_property(e),
3493 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3494 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3495 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3496 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3497 Expression::Booland(e) => self.generate_booland(e),
3498 Expression::Boolor(e) => self.generate_boolor(e),
3499 Expression::BuildProperty(e) => self.generate_build_property(e),
3500 Expression::ByteString(e) => self.generate_byte_string(e),
3501 Expression::CaseSpecificColumnConstraint(e) => {
3502 self.generate_case_specific_column_constraint(e)
3503 }
3504 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3505 Expression::Changes(e) => self.generate_changes(e),
3506 Expression::CharacterSetColumnConstraint(e) => {
3507 self.generate_character_set_column_constraint(e)
3508 }
3509 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3510 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3511 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3512 Expression::CheckJson(e) => self.generate_check_json(e),
3513 Expression::CheckXml(e) => self.generate_check_xml(e),
3514 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3515 Expression::Clone(e) => self.generate_clone(e),
3516 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3517 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3518 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3519 Expression::CollateProperty(e) => self.generate_collate_property(e),
3520 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3521 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3522 Expression::ColumnPosition(e) => self.generate_column_position(e),
3523 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3524 Expression::Columns(e) => self.generate_columns(e),
3525 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3526 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3527 Expression::Commit(e) => self.generate_commit(e),
3528 Expression::Comprehension(e) => self.generate_comprehension(e),
3529 Expression::Compress(e) => self.generate_compress(e),
3530 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3531 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3532 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3533 Expression::Constraint(e) => self.generate_constraint(e),
3534 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3535 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3536 Expression::Copy(e) => self.generate_copy(e),
3537 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3538 Expression::Corr(e) => self.generate_corr(e),
3539 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3540 Expression::CovarPop(e) => self.generate_covar_pop(e),
3541 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3542 Expression::Credentials(e) => self.generate_credentials(e),
3543 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3544 Expression::Cte(e) => self.generate_cte(e),
3545 Expression::Cube(e) => self.generate_cube(e),
3546 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3547 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3548 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3549 Expression::CurrentUser(e) => self.generate_current_user(e),
3550 Expression::DPipe(e) => self.generate_d_pipe(e),
3551 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3552 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3553 Expression::Date(e) => self.generate_date_func(e),
3554 Expression::DateBin(e) => self.generate_date_bin(e),
3555 Expression::DateFormatColumnConstraint(e) => {
3556 self.generate_date_format_column_constraint(e)
3557 }
3558 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3559 Expression::Datetime(e) => self.generate_datetime(e),
3560 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3561 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3562 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3563 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3564 Expression::Dayname(e) => self.generate_dayname(e),
3565 Expression::Declare(e) => self.generate_declare(e),
3566 Expression::DeclareItem(e) => self.generate_declare_item(e),
3567 Expression::DecodeCase(e) => self.generate_decode_case(e),
3568 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3569 Expression::DecompressString(e) => self.generate_decompress_string(e),
3570 Expression::Decrypt(e) => self.generate_decrypt(e),
3571 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3572 Expression::DefaultColumnConstraint(e) => {
3573 self.write_keyword("DEFAULT");
3574 self.write_space();
3575 self.generate_expression(&e.this)?;
3576 if let Some(ref col) = e.for_column {
3577 self.write_space();
3578 self.write_keyword("FOR");
3579 self.write_space();
3580 self.generate_identifier(col)?;
3581 }
3582 Ok(())
3583 }
3584 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3585 Expression::Detach(e) => self.generate_detach(e),
3586 Expression::DictProperty(e) => self.generate_dict_property(e),
3587 Expression::DictRange(e) => self.generate_dict_range(e),
3588 Expression::Directory(e) => self.generate_directory(e),
3589 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3590 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3591 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3592 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3593 Expression::DotProduct(e) => self.generate_dot_product(e),
3594 Expression::DropPartition(e) => self.generate_drop_partition(e),
3595 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3596 Expression::Elt(e) => self.generate_elt(e),
3597 Expression::Encode(e) => self.generate_encode(e),
3598 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3599 Expression::Encrypt(e) => self.generate_encrypt(e),
3600 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3601 Expression::EngineProperty(e) => self.generate_engine_property(e),
3602 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3603 Expression::EphemeralColumnConstraint(e) => {
3604 self.generate_ephemeral_column_constraint(e)
3605 }
3606 Expression::EqualNull(e) => self.generate_equal_null(e),
3607 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3608 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3609 Expression::Export(e) => self.generate_export(e),
3610 Expression::ExternalProperty(e) => self.generate_external_property(e),
3611 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3612 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3613 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3614 Expression::Fetch(e) => self.generate_fetch(e),
3615 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3616 Expression::Filter(e) => self.generate_filter(e),
3617 Expression::Float64(e) => self.generate_float64(e),
3618 Expression::ForIn(e) => self.generate_for_in(e),
3619 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3620 Expression::Format(e) => self.generate_format(e),
3621 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3622 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3623 Expression::From(e) => self.generate_from(e),
3624 Expression::FromBase(e) => self.generate_from_base(e),
3625 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3626 Expression::GapFill(e) => self.generate_gap_fill(e),
3627 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3628 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3629 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3630 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3631 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3632 self.generate_generated_as_identity_column_constraint(e)
3633 }
3634 Expression::GeneratedAsRowColumnConstraint(e) => {
3635 self.generate_generated_as_row_column_constraint(e)
3636 }
3637 Expression::Get(e) => self.generate_get(e),
3638 Expression::GetExtract(e) => self.generate_get_extract(e),
3639 Expression::Getbit(e) => self.generate_getbit(e),
3640 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3641 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3642 Expression::Group(e) => self.generate_group(e),
3643 Expression::GroupBy(e) => self.generate_group_by(e),
3644 Expression::Grouping(e) => self.generate_grouping(e),
3645 Expression::GroupingId(e) => self.generate_grouping_id(e),
3646 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3647 Expression::HashAgg(e) => self.generate_hash_agg(e),
3648 Expression::Having(e) => self.generate_having(e),
3649 Expression::HavingMax(e) => self.generate_having_max(e),
3650 Expression::Heredoc(e) => self.generate_heredoc(e),
3651 Expression::HexEncode(e) => self.generate_hex_encode(e),
3652 Expression::Hll(e) => self.generate_hll(e),
3653 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3654 Expression::IncludeProperty(e) => self.generate_include_property(e),
3655 Expression::Index(e) => self.generate_index(e),
3656 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3657 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3658 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3659 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3660 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3661 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3662 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3663 Expression::Install(e) => self.generate_install(e),
3664 Expression::IntervalOp(e) => self.generate_interval_op(e),
3665 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3666 Expression::IntoClause(e) => self.generate_into_clause(e),
3667 Expression::Introducer(e) => self.generate_introducer(e),
3668 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3669 Expression::JSON(e) => self.generate_json(e),
3670 Expression::JSONArray(e) => self.generate_json_array(e),
3671 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3672 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3673 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3674 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3675 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3676 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3677 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3678 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3679 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3680 Expression::JSONExists(e) => self.generate_json_exists(e),
3681 Expression::JSONCast(e) => self.generate_json_cast(e),
3682 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3683 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3684 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3685 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3686 Expression::JSONFormat(e) => self.generate_json_format(e),
3687 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3688 Expression::JSONKeys(e) => self.generate_json_keys(e),
3689 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3690 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3691 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3692 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3693 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3694 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3695 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3696 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3697 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3698 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3699 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3700 Expression::JSONRemove(e) => self.generate_json_remove(e),
3701 Expression::JSONSchema(e) => self.generate_json_schema(e),
3702 Expression::JSONSet(e) => self.generate_json_set(e),
3703 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3704 Expression::JSONTable(e) => self.generate_json_table(e),
3705 Expression::JSONType(e) => self.generate_json_type(e),
3706 Expression::JSONValue(e) => self.generate_json_value(e),
3707 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3708 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3709 Expression::JoinHint(e) => self.generate_join_hint(e),
3710 Expression::JournalProperty(e) => self.generate_journal_property(e),
3711 Expression::LanguageProperty(e) => self.generate_language_property(e),
3712 Expression::Lateral(e) => self.generate_lateral(e),
3713 Expression::LikeProperty(e) => self.generate_like_property(e),
3714 Expression::Limit(e) => self.generate_limit(e),
3715 Expression::LimitOptions(e) => self.generate_limit_options(e),
3716 Expression::List(e) => self.generate_list(e),
3717 Expression::ToMap(e) => self.generate_tomap(e),
3718 Expression::Localtime(e) => self.generate_localtime(e),
3719 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3720 Expression::LocationProperty(e) => self.generate_location_property(e),
3721 Expression::Lock(e) => self.generate_lock(e),
3722 Expression::LockProperty(e) => self.generate_lock_property(e),
3723 Expression::LockingProperty(e) => self.generate_locking_property(e),
3724 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3725 Expression::LogProperty(e) => self.generate_log_property(e),
3726 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3727 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3728 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3729 Expression::MakeInterval(e) => self.generate_make_interval(e),
3730 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3731 Expression::Map(e) => self.generate_map(e),
3732 Expression::MapCat(e) => self.generate_map_cat(e),
3733 Expression::MapDelete(e) => self.generate_map_delete(e),
3734 Expression::MapInsert(e) => self.generate_map_insert(e),
3735 Expression::MapPick(e) => self.generate_map_pick(e),
3736 Expression::MaskingPolicyColumnConstraint(e) => {
3737 self.generate_masking_policy_column_constraint(e)
3738 }
3739 Expression::MatchAgainst(e) => self.generate_match_against(e),
3740 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3741 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3742 Expression::Merge(e) => self.generate_merge(e),
3743 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3744 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3745 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3746 Expression::Minhash(e) => self.generate_minhash(e),
3747 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3748 Expression::Monthname(e) => self.generate_monthname(e),
3749 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3750 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3751 Expression::Normal(e) => self.generate_normal(e),
3752 Expression::Normalize(e) => self.generate_normalize(e),
3753 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3754 Expression::Nullif(e) => self.generate_nullif(e),
3755 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3756 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3757 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3758 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3759 Expression::Offset(e) => self.generate_offset(e),
3760 Expression::Qualify(e) => self.generate_qualify(e),
3761 Expression::OnCluster(e) => self.generate_on_cluster(e),
3762 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3763 Expression::OnCondition(e) => self.generate_on_condition(e),
3764 Expression::OnConflict(e) => self.generate_on_conflict(e),
3765 Expression::OnProperty(e) => self.generate_on_property(e),
3766 Expression::Opclass(e) => self.generate_opclass(e),
3767 Expression::OpenJSON(e) => self.generate_open_json(e),
3768 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3769 Expression::Operator(e) => self.generate_operator(e),
3770 Expression::OrderBy(e) => self.generate_order_by(e),
3771 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3772 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3773 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3774 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3775 Expression::ParseIp(e) => self.generate_parse_ip(e),
3776 Expression::ParseJSON(e) => self.generate_parse_json(e),
3777 Expression::ParseTime(e) => self.generate_parse_time(e),
3778 Expression::ParseUrl(e) => self.generate_parse_url(e),
3779 Expression::Partition(e) => self.generate_partition_expr(e),
3780 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3781 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3782 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3783 Expression::PartitionByRangePropertyDynamic(e) => {
3784 self.generate_partition_by_range_property_dynamic(e)
3785 }
3786 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3787 Expression::PartitionList(e) => self.generate_partition_list(e),
3788 Expression::PartitionRange(e) => self.generate_partition_range(e),
3789 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3790 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3791 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3792 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3793 Expression::PeriodForSystemTimeConstraint(e) => {
3794 self.generate_period_for_system_time_constraint(e)
3795 }
3796 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3797 Expression::PivotAny(e) => self.generate_pivot_any(e),
3798 Expression::Predict(e) => self.generate_predict(e),
3799 Expression::PreviousDay(e) => self.generate_previous_day(e),
3800 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3801 Expression::PrimaryKeyColumnConstraint(e) => {
3802 self.generate_primary_key_column_constraint(e)
3803 }
3804 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3805 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3806 Expression::OptionsProperty(e) => self.generate_options_property(e),
3807 Expression::Properties(e) => self.generate_properties(e),
3808 Expression::Property(e) => self.generate_property(e),
3809 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3810 Expression::Put(e) => self.generate_put(e),
3811 Expression::Quantile(e) => self.generate_quantile(e),
3812 Expression::QueryBand(e) => self.generate_query_band(e),
3813 Expression::QueryOption(e) => self.generate_query_option(e),
3814 Expression::QueryTransform(e) => self.generate_query_transform(e),
3815 Expression::Randn(e) => self.generate_randn(e),
3816 Expression::Randstr(e) => self.generate_randstr(e),
3817 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3818 Expression::RangeN(e) => self.generate_range_n(e),
3819 Expression::ReadCSV(e) => self.generate_read_csv(e),
3820 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3821 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3822 Expression::Reduce(e) => self.generate_reduce(e),
3823 Expression::Reference(e) => self.generate_reference(e),
3824 Expression::Refresh(e) => self.generate_refresh(e),
3825 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3826 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3827 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3828 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3829 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3830 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3831 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3832 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3833 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3834 Expression::RegrCount(e) => self.generate_regr_count(e),
3835 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3836 Expression::RegrR2(e) => self.generate_regr_r2(e),
3837 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3838 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3839 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3840 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3841 Expression::RegrValx(e) => self.generate_regr_valx(e),
3842 Expression::RegrValy(e) => self.generate_regr_valy(e),
3843 Expression::RemoteWithConnectionModelProperty(e) => {
3844 self.generate_remote_with_connection_model_property(e)
3845 }
3846 Expression::RenameColumn(e) => self.generate_rename_column(e),
3847 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3848 Expression::Returning(e) => self.generate_returning(e),
3849 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3850 Expression::Rollback(e) => self.generate_rollback(e),
3851 Expression::Rollup(e) => self.generate_rollup(e),
3852 Expression::RowFormatDelimitedProperty(e) => {
3853 self.generate_row_format_delimited_property(e)
3854 }
3855 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3856 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3857 Expression::SHA2(e) => self.generate_sha2(e),
3858 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3859 Expression::SafeAdd(e) => self.generate_safe_add(e),
3860 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3861 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3862 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3863 Expression::SampleProperty(e) => self.generate_sample_property(e),
3864 Expression::Schema(e) => self.generate_schema(e),
3865 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3866 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3867 Expression::Search(e) => self.generate_search(e),
3868 Expression::SearchIp(e) => self.generate_search_ip(e),
3869 Expression::SecurityProperty(e) => self.generate_security_property(e),
3870 Expression::SemanticView(e) => self.generate_semantic_view(e),
3871 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3872 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3873 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3874 Expression::Set(e) => self.generate_set(e),
3875 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3876 Expression::SetItem(e) => self.generate_set_item(e),
3877 Expression::SetOperation(e) => self.generate_set_operation(e),
3878 Expression::SetProperty(e) => self.generate_set_property(e),
3879 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3880 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3881 Expression::Slice(e) => self.generate_slice(e),
3882 Expression::SortArray(e) => self.generate_sort_array(e),
3883 Expression::SortBy(e) => self.generate_sort_by(e),
3884 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3885 Expression::SplitPart(e) => self.generate_split_part(e),
3886 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3887 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3888 Expression::StDistance(e) => self.generate_st_distance(e),
3889 Expression::StPoint(e) => self.generate_st_point(e),
3890 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3891 Expression::StandardHash(e) => self.generate_standard_hash(e),
3892 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3893 Expression::StrPosition(e) => self.generate_str_position(e),
3894 Expression::StrToDate(e) => self.generate_str_to_date(e),
3895 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3896 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3897 Expression::StrToMap(e) => self.generate_str_to_map(e),
3898 Expression::StrToTime(e) => self.generate_str_to_time(e),
3899 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3900 Expression::StringToArray(e) => self.generate_string_to_array(e),
3901 Expression::Struct(e) => self.generate_struct(e),
3902 Expression::Stuff(e) => self.generate_stuff(e),
3903 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3904 Expression::Summarize(e) => self.generate_summarize(e),
3905 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3906 Expression::TableAlias(e) => self.generate_table_alias(e),
3907 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3908 Expression::RowsFrom(e) => self.generate_rows_from(e),
3909 Expression::TableSample(e) => self.generate_table_sample(e),
3910 Expression::Tag(e) => self.generate_tag(e),
3911 Expression::Tags(e) => self.generate_tags(e),
3912 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3913 Expression::Time(e) => self.generate_time_func(e),
3914 Expression::TimeAdd(e) => self.generate_time_add(e),
3915 Expression::TimeDiff(e) => self.generate_time_diff(e),
3916 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3917 Expression::TimeSlice(e) => self.generate_time_slice(e),
3918 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3919 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3920 Expression::TimeSub(e) => self.generate_time_sub(e),
3921 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3922 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3923 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3924 Expression::TimeUnit(e) => self.generate_time_unit(e),
3925 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3926 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3927 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3928 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3929 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3930 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3931 Expression::ToBinary(e) => self.generate_to_binary(e),
3932 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3933 Expression::ToChar(e) => self.generate_to_char(e),
3934 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3935 Expression::ToDouble(e) => self.generate_to_double(e),
3936 Expression::ToFile(e) => self.generate_to_file(e),
3937 Expression::ToNumber(e) => self.generate_to_number(e),
3938 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3939 Expression::Transaction(e) => self.generate_transaction(e),
3940 Expression::Transform(e) => self.generate_transform(e),
3941 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3942 Expression::TransientProperty(e) => self.generate_transient_property(e),
3943 Expression::Translate(e) => self.generate_translate(e),
3944 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3945 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3946 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3947 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3948 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3949 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3950 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3951 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3952 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3953 Expression::Unhex(e) => self.generate_unhex(e),
3954 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3955 Expression::Uniform(e) => self.generate_uniform(e),
3956 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3957 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3958 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3959 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3960 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3961 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3962 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3963 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3964 Expression::UtcTime(e) => self.generate_utc_time(e),
3965 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3966 Expression::Uuid(e) => self.generate_uuid(e),
3967 Expression::Var(v) => {
3968 if matches!(self.config.dialect, Some(DialectType::MySQL))
3969 && v.this.len() > 2
3970 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3971 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3972 {
3973 return self.generate_identifier(&Identifier {
3974 name: v.this.clone(),
3975 quoted: true,
3976 trailing_comments: Vec::new(),
3977 span: None,
3978 });
3979 }
3980 self.write(&v.this);
3981 Ok(())
3982 }
3983 Expression::Variadic(e) => {
3984 self.write_keyword("VARIADIC");
3985 self.write_space();
3986 self.generate_expression(&e.this)?;
3987 Ok(())
3988 }
3989 Expression::VarMap(e) => self.generate_var_map(e),
3990 Expression::VectorSearch(e) => self.generate_vector_search(e),
3991 Expression::Version(e) => self.generate_version(e),
3992 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3993 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3994 Expression::WatermarkColumnConstraint(e) => {
3995 self.generate_watermark_column_constraint(e)
3996 }
3997 Expression::Week(e) => self.generate_week(e),
3998 Expression::When(e) => self.generate_when(e),
3999 Expression::Whens(e) => self.generate_whens(e),
4000 Expression::Where(e) => self.generate_where(e),
4001 Expression::WidthBucket(e) => self.generate_width_bucket(e),
4002 Expression::Window(e) => self.generate_window(e),
4003 Expression::WindowSpec(e) => self.generate_window_spec(e),
4004 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
4005 Expression::WithFill(e) => self.generate_with_fill(e),
4006 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
4007 Expression::WithOperator(e) => self.generate_with_operator(e),
4008 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
4009 Expression::WithSchemaBindingProperty(e) => {
4010 self.generate_with_schema_binding_property(e)
4011 }
4012 Expression::WithSystemVersioningProperty(e) => {
4013 self.generate_with_system_versioning_property(e)
4014 }
4015 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
4016 Expression::XMLElement(e) => self.generate_xml_element(e),
4017 Expression::XMLGet(e) => self.generate_xml_get(e),
4018 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
4019 Expression::XMLTable(e) => self.generate_xml_table(e),
4020 Expression::Xor(e) => self.generate_xor(e),
4021 Expression::Zipf(e) => self.generate_zipf(e),
4022 _ => self.write_unsupported_comment("unsupported expression"),
4023 }
4024 }
4025
4026 fn generate_select(&mut self, select: &Select) -> Result<()> {
4027 use crate::dialects::DialectType;
4028
4029 if let Some(exclude) = &select.exclude {
4033 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4034 let mut inner_select = select.clone();
4036 inner_select.exclude = None;
4037 let inner_expr = Expression::Select(Box::new(inner_select));
4038
4039 let subquery = crate::expressions::Subquery {
4041 this: inner_expr,
4042 alias: None,
4043 column_aliases: Vec::new(),
4044 order_by: None,
4045 limit: None,
4046 offset: None,
4047 distribute_by: None,
4048 sort_by: None,
4049 cluster_by: None,
4050 lateral: false,
4051 modifiers_inside: false,
4052 trailing_comments: Vec::new(),
4053 inferred_type: None,
4054 };
4055
4056 let star = Expression::Star(crate::expressions::Star {
4058 table: None,
4059 except: Some(
4060 exclude
4061 .iter()
4062 .map(|e| match e {
4063 Expression::Column(col) => col.name.clone(),
4064 Expression::Identifier(id) => id.clone(),
4065 _ => crate::expressions::Identifier::new("unknown".to_string()),
4066 })
4067 .collect(),
4068 ),
4069 replace: None,
4070 rename: None,
4071 trailing_comments: Vec::new(),
4072 span: None,
4073 });
4074
4075 let outer_select = Select {
4076 expressions: vec![star],
4077 from: Some(crate::expressions::From {
4078 expressions: vec![Expression::Subquery(Box::new(subquery))],
4079 }),
4080 ..Select::new()
4081 };
4082
4083 return self.generate_select(&outer_select);
4084 }
4085 }
4086
4087 for comment in &select.leading_comments {
4089 self.write_formatted_comment(comment);
4090 self.write(" ");
4091 }
4092
4093 if let Some(with) = &select.with {
4095 self.generate_with(with)?;
4096 if self.config.pretty {
4097 self.write_newline();
4098 self.write_indent();
4099 } else {
4100 self.write_space();
4101 }
4102 }
4103
4104 for comment in &select.post_select_comments {
4107 self.write_formatted_comment(comment);
4108 self.write(" ");
4109 }
4110
4111 self.write_keyword("SELECT");
4112
4113 if let Some(hint) = &select.hint {
4115 self.generate_hint(hint)?;
4116 }
4117
4118 let use_top_from_limit = matches!(
4122 self.config.dialect,
4123 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4124 ) && select.top.is_none()
4125 && select.limit.is_some()
4126 && select.offset.is_none(); let is_top_dialect = matches!(
4131 self.config.dialect,
4132 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4133 );
4134 let keep_top_verbatim = !is_top_dialect
4135 && select.limit.is_none()
4136 && select
4137 .top
4138 .as_ref()
4139 .map_or(false, |top| top.percent || top.with_ties);
4140
4141 if select.distinct && (is_top_dialect || select.top.is_some()) {
4142 self.write_space();
4143 self.write_keyword("DISTINCT");
4144 }
4145
4146 if is_top_dialect || keep_top_verbatim {
4147 if let Some(top) = &select.top {
4148 self.write_space();
4149 self.write_keyword("TOP");
4150 if top.parenthesized {
4151 if matches!(&top.this, Expression::Subquery(_) | Expression::Paren(_)) {
4152 self.write_space();
4153 self.generate_expression(&top.this)?;
4154 } else {
4155 self.write(" (");
4156 self.generate_expression(&top.this)?;
4157 self.write(")");
4158 }
4159 } else {
4160 self.write_space();
4161 self.generate_expression(&top.this)?;
4162 }
4163 if top.percent {
4164 self.write_space();
4165 self.write_keyword("PERCENT");
4166 }
4167 if top.with_ties {
4168 self.write_space();
4169 self.write_keyword("WITH TIES");
4170 }
4171 } else if use_top_from_limit {
4172 if let Some(limit) = &select.limit {
4174 self.write_space();
4175 self.write_keyword("TOP");
4176 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4178 if is_simple_literal {
4179 self.write_space();
4180 self.generate_expression(&limit.this)?;
4181 } else {
4182 self.write(" (");
4183 self.generate_expression(&limit.this)?;
4184 self.write(")");
4185 }
4186 }
4187 }
4188 }
4189
4190 if select.distinct && !is_top_dialect && select.top.is_none() {
4191 self.write_space();
4192 self.write_keyword("DISTINCT");
4193 }
4194
4195 if let Some(distinct_on) = &select.distinct_on {
4197 self.write_space();
4198 self.write_keyword("ON");
4199 self.write(" (");
4200 for (i, expr) in distinct_on.iter().enumerate() {
4201 if i > 0 {
4202 self.write(", ");
4203 }
4204 self.generate_expression(expr)?;
4205 }
4206 self.write(")");
4207 }
4208
4209 for modifier in &select.operation_modifiers {
4211 self.write_space();
4212 self.write_keyword(modifier);
4213 }
4214
4215 if let Some(kind) = &select.kind {
4217 self.write_space();
4218 self.write_keyword("AS");
4219 self.write_space();
4220 self.write_keyword(kind);
4221 }
4222
4223 if !select.expressions.is_empty() {
4225 if self.config.pretty {
4226 self.write_newline();
4227 self.indent_level += 1;
4228 } else {
4229 self.write_space();
4230 }
4231 }
4232
4233 for (i, expr) in select.expressions.iter().enumerate() {
4234 if i > 0 {
4235 self.write(",");
4236 if self.config.pretty {
4237 self.write_newline();
4238 } else {
4239 self.write_space();
4240 }
4241 }
4242 if self.config.pretty {
4243 self.write_indent();
4244 }
4245 self.generate_expression(expr)?;
4246 }
4247
4248 if self.config.pretty && !select.expressions.is_empty() {
4249 self.indent_level -= 1;
4250 }
4251
4252 if let Some(exclude) = &select.exclude {
4257 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4258 self.write_space();
4259 self.write_keyword("EXCLUDE");
4260 self.write(" (");
4261 for (i, col) in exclude.iter().enumerate() {
4262 if i > 0 {
4263 self.write(", ");
4264 }
4265 self.generate_expression(col)?;
4266 }
4267 self.write(")");
4268 }
4269 }
4270
4271 if let Some(into) = &select.into {
4274 if self.config.pretty {
4275 self.write_newline();
4276 self.write_indent();
4277 } else {
4278 self.write_space();
4279 }
4280 if into.bulk_collect {
4281 self.write_keyword("BULK COLLECT INTO");
4282 } else {
4283 self.write_keyword("INTO");
4284 }
4285 if into.temporary {
4286 self.write_space();
4287 self.write_keyword("TEMPORARY");
4288 }
4289 if into.unlogged {
4290 self.write_space();
4291 self.write_keyword("UNLOGGED");
4292 }
4293 self.write_space();
4294 if !into.expressions.is_empty() {
4296 for (i, expr) in into.expressions.iter().enumerate() {
4297 if i > 0 {
4298 self.write(", ");
4299 }
4300 self.generate_expression(expr)?;
4301 }
4302 } else {
4303 self.generate_expression(&into.this)?;
4304 }
4305 }
4306
4307 if let Some(from) = &select.from {
4309 if self.config.pretty {
4310 self.write_newline();
4311 self.write_indent();
4312 } else {
4313 self.write_space();
4314 }
4315 self.write_keyword("FROM");
4316 self.write_space();
4317
4318 let has_tablesample = from
4323 .expressions
4324 .iter()
4325 .any(|e| matches!(e, Expression::TableSample(_)));
4326 let is_cross_join_dialect = matches!(
4327 self.config.dialect,
4328 Some(DialectType::BigQuery)
4329 | Some(DialectType::Hive)
4330 | Some(DialectType::Spark)
4331 | Some(DialectType::Databricks)
4332 | Some(DialectType::SQLite)
4333 | Some(DialectType::ClickHouse)
4334 );
4335 let source_is_same_as_target = self.config.source_dialect.is_some()
4338 && self.config.source_dialect == self.config.dialect;
4339 let source_is_cross_join_dialect = matches!(
4340 self.config.source_dialect,
4341 Some(DialectType::BigQuery)
4342 | Some(DialectType::Hive)
4343 | Some(DialectType::Spark)
4344 | Some(DialectType::Databricks)
4345 | Some(DialectType::SQLite)
4346 | Some(DialectType::ClickHouse)
4347 );
4348 let use_cross_join = !has_tablesample
4349 && is_cross_join_dialect
4350 && (source_is_same_as_target
4351 || source_is_cross_join_dialect
4352 || self.config.source_dialect.is_none());
4353
4354 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4356
4357 for (i, expr) in from.expressions.iter().enumerate() {
4358 if i > 0 {
4359 if use_cross_join {
4360 self.write(" CROSS JOIN ");
4361 } else {
4362 self.write(", ");
4363 }
4364 }
4365 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4366 self.write("(");
4367 self.generate_expression(expr)?;
4368 self.write(")");
4369 } else {
4370 self.generate_expression(expr)?;
4371 }
4372 let leading = Self::extract_table_leading_comments(expr);
4375 for comment in &leading {
4376 self.write_space();
4377 self.write_formatted_comment(comment);
4378 }
4379 }
4380 }
4381
4382 if self.config.pretty {
4386 self.generate_joins_with_nesting(&select.joins)?;
4387 } else {
4388 for join in &select.joins {
4389 self.generate_join(join)?;
4390 }
4391 for join in select.joins.iter().rev() {
4393 if join.deferred_condition {
4394 self.generate_join_condition(join)?;
4395 }
4396 }
4397 }
4398
4399 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4401 self.generate_lateral_view(lateral_view, lv_idx)?;
4402 }
4403
4404 if let Some(prewhere) = &select.prewhere {
4406 self.write_clause_condition("PREWHERE", prewhere)?;
4407 }
4408
4409 if let Some(where_clause) = &select.where_clause {
4411 self.write_clause_condition("WHERE", &where_clause.this)?;
4412 }
4413
4414 if let Some(connect) = &select.connect {
4416 self.generate_connect(connect)?;
4417 }
4418
4419 if let Some(group_by) = &select.group_by {
4421 if self.config.pretty {
4422 for comment in &group_by.comments {
4424 self.write_newline();
4425 self.write_indent();
4426 self.write_formatted_comment(comment);
4427 }
4428 self.write_newline();
4429 self.write_indent();
4430 } else {
4431 self.write_space();
4432 for comment in &group_by.comments {
4434 self.write_formatted_comment(comment);
4435 self.write_space();
4436 }
4437 }
4438 self.write_keyword("GROUP BY");
4439 match group_by.all {
4441 Some(true) => {
4442 self.write_space();
4443 self.write_keyword("ALL");
4444 }
4445 Some(false) => {
4446 self.write_space();
4447 self.write_keyword("DISTINCT");
4448 }
4449 None => {}
4450 }
4451 if !group_by.expressions.is_empty() {
4452 let mut trailing_cube = false;
4455 let mut trailing_rollup = false;
4456 let mut plain_expressions: Vec<&Expression> = Vec::new();
4457 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4458 let mut cube_expressions: Vec<&Expression> = Vec::new();
4459 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4460
4461 for expr in &group_by.expressions {
4462 match expr {
4463 Expression::Cube(c) if c.expressions.is_empty() => {
4464 trailing_cube = true;
4465 }
4466 Expression::Rollup(r) if r.expressions.is_empty() => {
4467 trailing_rollup = true;
4468 }
4469 Expression::Function(f) if f.name == "CUBE" => {
4470 cube_expressions.push(expr);
4471 }
4472 Expression::Function(f) if f.name == "ROLLUP" => {
4473 rollup_expressions.push(expr);
4474 }
4475 Expression::Function(f) if f.name == "GROUPING SETS" => {
4476 grouping_sets_expressions.push(expr);
4477 }
4478 _ => {
4479 plain_expressions.push(expr);
4480 }
4481 }
4482 }
4483
4484 let mut regular_expressions: Vec<&Expression> = Vec::new();
4486 regular_expressions.extend(plain_expressions);
4487 regular_expressions.extend(grouping_sets_expressions);
4488 regular_expressions.extend(cube_expressions);
4489 regular_expressions.extend(rollup_expressions);
4490
4491 if self.config.pretty {
4492 self.write_newline();
4493 self.indent_level += 1;
4494 self.write_indent();
4495 } else {
4496 self.write_space();
4497 }
4498
4499 for (i, expr) in regular_expressions.iter().enumerate() {
4500 if i > 0 {
4501 if self.config.pretty {
4502 self.write(",");
4503 self.write_newline();
4504 self.write_indent();
4505 } else {
4506 self.write(", ");
4507 }
4508 }
4509 self.generate_expression(expr)?;
4510 }
4511
4512 if self.config.pretty {
4513 self.indent_level -= 1;
4514 }
4515
4516 if trailing_cube {
4518 self.write_space();
4519 self.write_keyword("WITH CUBE");
4520 } else if trailing_rollup {
4521 self.write_space();
4522 self.write_keyword("WITH ROLLUP");
4523 }
4524 }
4525
4526 if group_by.totals {
4528 self.write_space();
4529 self.write_keyword("WITH TOTALS");
4530 }
4531 }
4532
4533 if let Some(having) = &select.having {
4535 if self.config.pretty {
4536 for comment in &having.comments {
4538 self.write_newline();
4539 self.write_indent();
4540 self.write_formatted_comment(comment);
4541 }
4542 } else {
4543 for comment in &having.comments {
4544 self.write_space();
4545 self.write_formatted_comment(comment);
4546 }
4547 }
4548 self.write_clause_condition("HAVING", &having.this)?;
4549 }
4550
4551 if select.qualify_after_window {
4553 if let Some(windows) = &select.windows {
4555 self.write_window_clause(windows)?;
4556 }
4557 if let Some(qualify) = &select.qualify {
4558 self.write_clause_condition("QUALIFY", &qualify.this)?;
4559 }
4560 } else {
4561 if let Some(qualify) = &select.qualify {
4563 self.write_clause_condition("QUALIFY", &qualify.this)?;
4564 }
4565 if let Some(windows) = &select.windows {
4566 self.write_window_clause(windows)?;
4567 }
4568 }
4569
4570 if let Some(distribute_by) = &select.distribute_by {
4572 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4573 }
4574
4575 if let Some(cluster_by) = &select.cluster_by {
4577 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4578 }
4579
4580 if let Some(sort_by) = &select.sort_by {
4582 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4583 }
4584
4585 if let Some(order_by) = &select.order_by {
4587 if self.config.pretty {
4588 for comment in &order_by.comments {
4590 self.write_newline();
4591 self.write_indent();
4592 self.write_formatted_comment(comment);
4593 }
4594 } else {
4595 for comment in &order_by.comments {
4596 self.write_space();
4597 self.write_formatted_comment(comment);
4598 }
4599 }
4600 let keyword = if order_by.siblings {
4601 "ORDER SIBLINGS BY"
4602 } else {
4603 "ORDER BY"
4604 };
4605 self.write_order_clause(keyword, &order_by.expressions)?;
4606 }
4607
4608 if select.order_by.is_none()
4610 && select.fetch.is_some()
4611 && matches!(
4612 self.config.dialect,
4613 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4614 )
4615 {
4616 if self.config.pretty {
4617 self.write_newline();
4618 self.write_indent();
4619 } else {
4620 self.write_space();
4621 }
4622 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4623 }
4624
4625 let is_presto_like = matches!(
4630 self.config.dialect,
4631 Some(DialectType::Presto) | Some(DialectType::Trino)
4632 );
4633
4634 if is_presto_like && select.offset.is_some() {
4635 if let Some(offset) = &select.offset {
4637 if self.config.pretty {
4638 self.write_newline();
4639 self.write_indent();
4640 } else {
4641 self.write_space();
4642 }
4643 self.write_keyword("OFFSET");
4644 self.write_space();
4645 self.write_limit_expr(&offset.this)?;
4646 if offset.rows == Some(true) {
4647 self.write_space();
4648 self.write_keyword("ROWS");
4649 }
4650 }
4651 if let Some(limit) = &select.limit {
4652 if self.config.pretty {
4653 self.write_newline();
4654 self.write_indent();
4655 } else {
4656 self.write_space();
4657 }
4658 self.write_keyword("LIMIT");
4659 self.write_space();
4660 self.write_limit_expr(&limit.this)?;
4661 if limit.percent {
4662 self.write_space();
4663 self.write_keyword("PERCENT");
4664 }
4665 for comment in &limit.comments {
4667 self.write(" ");
4668 self.write_formatted_comment(comment);
4669 }
4670 }
4671 } else {
4672 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4674 !fetch.percent
4675 && !fetch.with_ties
4676 && fetch.count.is_some()
4677 && matches!(
4678 self.config.dialect,
4679 Some(DialectType::Spark)
4680 | Some(DialectType::Hive)
4681 | Some(DialectType::DuckDB)
4682 | Some(DialectType::SQLite)
4683 | Some(DialectType::MySQL)
4684 | Some(DialectType::BigQuery)
4685 | Some(DialectType::Databricks)
4686 | Some(DialectType::StarRocks)
4687 | Some(DialectType::Doris)
4688 | Some(DialectType::Athena)
4689 | Some(DialectType::ClickHouse)
4690 | Some(DialectType::Redshift)
4691 )
4692 });
4693
4694 if let Some(limit) = &select.limit {
4696 if !matches!(
4698 self.config.dialect,
4699 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4700 ) {
4701 if self.config.pretty {
4702 self.write_newline();
4703 self.write_indent();
4704 } else {
4705 self.write_space();
4706 }
4707 self.write_keyword("LIMIT");
4708 self.write_space();
4709 self.write_limit_expr(&limit.this)?;
4710 if limit.percent {
4711 self.write_space();
4712 self.write_keyword("PERCENT");
4713 }
4714 for comment in &limit.comments {
4716 self.write(" ");
4717 self.write_formatted_comment(comment);
4718 }
4719 }
4720 }
4721
4722 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4724 if let Some(top) = &select.top {
4725 if !top.percent && !top.with_ties {
4726 if self.config.pretty {
4727 self.write_newline();
4728 self.write_indent();
4729 } else {
4730 self.write_space();
4731 }
4732 self.write_keyword("LIMIT");
4733 self.write_space();
4734 self.generate_expression(&top.this)?;
4735 }
4736 }
4737 }
4738
4739 if fetch_as_limit && select.offset.is_some() {
4742 if let Some(fetch) = &select.fetch {
4743 if self.config.pretty {
4744 self.write_newline();
4745 self.write_indent();
4746 } else {
4747 self.write_space();
4748 }
4749 self.write_keyword("LIMIT");
4750 self.write_space();
4751 self.generate_expression(fetch.count.as_ref().unwrap())?;
4752 }
4753 }
4754
4755 if let Some(offset) = &select.offset {
4759 if self.config.pretty {
4760 self.write_newline();
4761 self.write_indent();
4762 } else {
4763 self.write_space();
4764 }
4765 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4766 self.write_keyword("OFFSET");
4768 self.write_space();
4769 self.write_limit_expr(&offset.this)?;
4770 self.write_space();
4771 self.write_keyword("ROWS");
4772 if let Some(limit) = &select.limit {
4774 self.write_space();
4775 self.write_keyword("FETCH NEXT");
4776 self.write_space();
4777 self.write_limit_expr(&limit.this)?;
4778 self.write_space();
4779 self.write_keyword("ROWS ONLY");
4780 }
4781 } else {
4782 self.write_keyword("OFFSET");
4783 self.write_space();
4784 self.write_limit_expr(&offset.this)?;
4785 if offset.rows == Some(true) {
4787 self.write_space();
4788 self.write_keyword("ROWS");
4789 }
4790 }
4791 }
4792 }
4793
4794 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4796 if let Some(limit_by) = &select.limit_by {
4797 if !limit_by.is_empty() {
4798 self.write_space();
4799 self.write_keyword("BY");
4800 self.write_space();
4801 for (i, expr) in limit_by.iter().enumerate() {
4802 if i > 0 {
4803 self.write(", ");
4804 }
4805 self.generate_expression(expr)?;
4806 }
4807 }
4808 }
4809 }
4810
4811 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4813 if let Some(settings) = &select.settings {
4814 if self.config.pretty {
4815 self.write_newline();
4816 self.write_indent();
4817 } else {
4818 self.write_space();
4819 }
4820 self.write_keyword("SETTINGS");
4821 self.write_space();
4822 for (i, expr) in settings.iter().enumerate() {
4823 if i > 0 {
4824 self.write(", ");
4825 }
4826 self.generate_expression(expr)?;
4827 }
4828 }
4829
4830 if let Some(format_expr) = &select.format {
4831 if self.config.pretty {
4832 self.write_newline();
4833 self.write_indent();
4834 } else {
4835 self.write_space();
4836 }
4837 self.write_keyword("FORMAT");
4838 self.write_space();
4839 self.generate_expression(format_expr)?;
4840 }
4841 }
4842
4843 if let Some(fetch) = &select.fetch {
4845 let fetch_already_as_limit = select.offset.is_some()
4847 && !fetch.percent
4848 && !fetch.with_ties
4849 && fetch.count.is_some()
4850 && matches!(
4851 self.config.dialect,
4852 Some(DialectType::Spark)
4853 | Some(DialectType::Hive)
4854 | Some(DialectType::DuckDB)
4855 | Some(DialectType::SQLite)
4856 | Some(DialectType::MySQL)
4857 | Some(DialectType::BigQuery)
4858 | Some(DialectType::Databricks)
4859 | Some(DialectType::StarRocks)
4860 | Some(DialectType::Doris)
4861 | Some(DialectType::Athena)
4862 | Some(DialectType::ClickHouse)
4863 | Some(DialectType::Redshift)
4864 );
4865
4866 if fetch_already_as_limit {
4867 } else {
4869 if self.config.pretty {
4870 self.write_newline();
4871 self.write_indent();
4872 } else {
4873 self.write_space();
4874 }
4875
4876 let use_limit = !fetch.percent
4878 && !fetch.with_ties
4879 && fetch.count.is_some()
4880 && matches!(
4881 self.config.dialect,
4882 Some(DialectType::Spark)
4883 | Some(DialectType::Hive)
4884 | Some(DialectType::DuckDB)
4885 | Some(DialectType::SQLite)
4886 | Some(DialectType::MySQL)
4887 | Some(DialectType::BigQuery)
4888 | Some(DialectType::Databricks)
4889 | Some(DialectType::StarRocks)
4890 | Some(DialectType::Doris)
4891 | Some(DialectType::Athena)
4892 | Some(DialectType::ClickHouse)
4893 | Some(DialectType::Redshift)
4894 );
4895
4896 if use_limit {
4897 self.write_keyword("LIMIT");
4898 self.write_space();
4899 self.generate_expression(fetch.count.as_ref().unwrap())?;
4900 } else {
4901 self.write_keyword("FETCH");
4902 self.write_space();
4903 self.write_keyword(&fetch.direction);
4904 if let Some(ref count) = fetch.count {
4905 self.write_space();
4906 self.generate_expression(count)?;
4907 }
4908 if fetch.percent {
4909 self.write_space();
4910 self.write_keyword("PERCENT");
4911 }
4912 if fetch.rows {
4913 self.write_space();
4914 self.write_keyword("ROWS");
4915 }
4916 if fetch.with_ties {
4917 self.write_space();
4918 self.write_keyword("WITH TIES");
4919 } else {
4920 self.write_space();
4921 self.write_keyword("ONLY");
4922 }
4923 }
4924 } }
4926
4927 if let Some(sample) = &select.sample {
4929 use crate::dialects::DialectType;
4930 if self.config.pretty {
4931 self.write_newline();
4932 } else {
4933 self.write_space();
4934 }
4935
4936 if sample.is_using_sample {
4937 self.write_keyword("USING SAMPLE");
4939 self.generate_sample_body(sample)?;
4940 } else {
4941 self.write_keyword("TABLESAMPLE");
4942
4943 let snowflake_bernoulli =
4945 matches!(self.config.dialect, Some(DialectType::Snowflake))
4946 && !sample.explicit_method;
4947 if snowflake_bernoulli {
4948 self.write_space();
4949 self.write_keyword("BERNOULLI");
4950 }
4951
4952 if matches!(sample.method, SampleMethod::Bucket) {
4954 self.write_space();
4955 self.write("(");
4956 self.write_keyword("BUCKET");
4957 self.write_space();
4958 if let Some(ref num) = sample.bucket_numerator {
4959 self.generate_expression(num)?;
4960 }
4961 self.write_space();
4962 self.write_keyword("OUT OF");
4963 self.write_space();
4964 if let Some(ref denom) = sample.bucket_denominator {
4965 self.generate_expression(denom)?;
4966 }
4967 if let Some(ref field) = sample.bucket_field {
4968 self.write_space();
4969 self.write_keyword("ON");
4970 self.write_space();
4971 self.generate_expression(field)?;
4972 }
4973 self.write(")");
4974 } else if sample.unit_after_size {
4975 if sample.explicit_method && sample.method_before_size {
4977 self.write_space();
4978 match sample.method {
4979 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4980 SampleMethod::System => self.write_keyword("SYSTEM"),
4981 SampleMethod::Block => self.write_keyword("BLOCK"),
4982 SampleMethod::Row => self.write_keyword("ROW"),
4983 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4984 _ => {}
4985 }
4986 }
4987 self.write(" (");
4988 self.generate_expression(&sample.size)?;
4989 self.write_space();
4990 match sample.method {
4991 SampleMethod::Percent => self.write_keyword("PERCENT"),
4992 SampleMethod::Row => self.write_keyword("ROWS"),
4993 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4994 _ => {
4995 self.write_keyword("PERCENT");
4996 }
4997 }
4998 self.write(")");
4999 } else {
5000 self.write_space();
5002 match sample.method {
5003 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5004 SampleMethod::System => self.write_keyword("SYSTEM"),
5005 SampleMethod::Block => self.write_keyword("BLOCK"),
5006 SampleMethod::Row => self.write_keyword("ROW"),
5007 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
5008 SampleMethod::Bucket => {}
5009 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5010 }
5011 self.write(" (");
5012 self.generate_expression(&sample.size)?;
5013 if matches!(sample.method, SampleMethod::Percent) {
5014 self.write_space();
5015 self.write_keyword("PERCENT");
5016 }
5017 self.write(")");
5018 }
5019 }
5020
5021 if let Some(seed) = &sample.seed {
5022 self.write_space();
5023 let use_seed = sample.use_seed_keyword
5025 && !matches!(
5026 self.config.dialect,
5027 Some(crate::dialects::DialectType::Databricks)
5028 | Some(crate::dialects::DialectType::Spark)
5029 );
5030 if use_seed {
5031 self.write_keyword("SEED");
5032 } else {
5033 self.write_keyword("REPEATABLE");
5034 }
5035 self.write(" (");
5036 self.generate_expression(seed)?;
5037 self.write(")");
5038 }
5039 }
5040
5041 if self.config.locking_reads_supported {
5044 for lock in &select.locks {
5045 if self.config.pretty {
5046 self.write_newline();
5047 self.write_indent();
5048 } else {
5049 self.write_space();
5050 }
5051 self.generate_lock(lock)?;
5052 }
5053 }
5054
5055 if !select.for_xml.is_empty() {
5057 if self.config.pretty {
5058 self.write_newline();
5059 self.write_indent();
5060 } else {
5061 self.write_space();
5062 }
5063 self.write_keyword("FOR XML");
5064 for (i, opt) in select.for_xml.iter().enumerate() {
5065 if self.config.pretty {
5066 if i > 0 {
5067 self.write(",");
5068 }
5069 self.write_newline();
5070 self.write_indent();
5071 self.write(" "); } else {
5073 if i > 0 {
5074 self.write(",");
5075 }
5076 self.write_space();
5077 }
5078 self.generate_for_xml_option(opt)?;
5079 }
5080 }
5081
5082 if !select.for_json.is_empty() {
5084 if self.config.pretty {
5085 self.write_newline();
5086 self.write_indent();
5087 } else {
5088 self.write_space();
5089 }
5090 self.write_keyword("FOR JSON");
5091 for (i, opt) in select.for_json.iter().enumerate() {
5092 if self.config.pretty {
5093 if i > 0 {
5094 self.write(",");
5095 }
5096 self.write_newline();
5097 self.write_indent();
5098 self.write(" "); } else {
5100 if i > 0 {
5101 self.write(",");
5102 }
5103 self.write_space();
5104 }
5105 self.generate_for_xml_option(opt)?;
5106 }
5107 }
5108
5109 if let Some(ref option) = select.option {
5111 if matches!(
5112 self.config.dialect,
5113 Some(crate::dialects::DialectType::TSQL)
5114 | Some(crate::dialects::DialectType::Fabric)
5115 ) {
5116 self.write_space();
5117 self.write(option);
5118 }
5119 }
5120
5121 Ok(())
5122 }
5123
5124 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5126 match opt {
5127 Expression::QueryOption(qo) => {
5128 if let Expression::Var(var) = &*qo.this {
5130 self.write(&var.this);
5131 } else {
5132 self.generate_expression(&qo.this)?;
5133 }
5134 if let Some(expr) = &qo.expression {
5136 self.write("(");
5137 self.generate_expression(expr)?;
5138 self.write(")");
5139 }
5140 }
5141 _ => {
5142 self.generate_expression(opt)?;
5143 }
5144 }
5145 Ok(())
5146 }
5147
5148 fn generate_with(&mut self, with: &With) -> Result<()> {
5149 use crate::dialects::DialectType;
5150
5151 for comment in &with.leading_comments {
5153 self.write_formatted_comment(comment);
5154 self.write(" ");
5155 }
5156 self.write_keyword("WITH");
5157 if with.recursive && self.config.cte_recursive_keyword_required {
5158 self.write_space();
5159 self.write_keyword("RECURSIVE");
5160 }
5161 self.write_space();
5162
5163 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5165
5166 for (i, cte) in with.ctes.iter().enumerate() {
5167 if i > 0 {
5168 self.write(",");
5169 if self.config.pretty {
5170 self.write_space();
5171 } else {
5172 self.write(" ");
5173 }
5174 }
5175 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5176 self.generate_expression(&cte.this)?;
5177 self.write_space();
5178 self.write_keyword("AS");
5179 self.write_space();
5180 self.generate_identifier(&cte.alias)?;
5181 continue;
5182 }
5183 self.generate_identifier(&cte.alias)?;
5184 for comment in &cte.comments {
5186 self.write_space();
5187 self.write_formatted_comment(comment);
5188 }
5189 if !cte.columns.is_empty() && !skip_cte_columns {
5190 self.write("(");
5191 for (j, col) in cte.columns.iter().enumerate() {
5192 if j > 0 {
5193 self.write(", ");
5194 }
5195 self.generate_identifier(col)?;
5196 }
5197 self.write(")");
5198 }
5199 if !cte.key_expressions.is_empty() {
5201 self.write_space();
5202 self.write_keyword("USING KEY");
5203 self.write(" (");
5204 for (i, key) in cte.key_expressions.iter().enumerate() {
5205 if i > 0 {
5206 self.write(", ");
5207 }
5208 self.generate_identifier(key)?;
5209 }
5210 self.write(")");
5211 }
5212 self.write_space();
5213 self.write_keyword("AS");
5214 if let Some(materialized) = cte.materialized {
5216 self.write_space();
5217 if materialized {
5218 self.write_keyword("MATERIALIZED");
5219 } else {
5220 self.write_keyword("NOT MATERIALIZED");
5221 }
5222 }
5223 self.write(" (");
5224 if self.config.pretty {
5225 self.write_newline();
5226 self.indent_level += 1;
5227 self.write_indent();
5228 }
5229 let wrap_values_in_select = matches!(
5232 self.config.dialect,
5233 Some(DialectType::Spark) | Some(DialectType::Databricks)
5234 ) && matches!(&cte.this, Expression::Values(_));
5235
5236 if wrap_values_in_select {
5237 self.write_keyword("SELECT");
5238 self.write(" * ");
5239 self.write_keyword("FROM");
5240 self.write_space();
5241 }
5242 self.generate_expression(&cte.this)?;
5243 if self.config.pretty {
5244 self.write_newline();
5245 self.indent_level -= 1;
5246 self.write_indent();
5247 }
5248 self.write(")");
5249 }
5250
5251 if let Some(search) = &with.search {
5253 self.write_space();
5254 self.generate_expression(search)?;
5255 }
5256
5257 Ok(())
5258 }
5259
5260 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5264 let mut i = 0;
5265 while i < joins.len() {
5266 if joins[i].deferred_condition {
5267 let parent_group = joins[i].nesting_group;
5268
5269 self.generate_join_without_condition(&joins[i])?;
5272
5273 let child_start = i + 1;
5275 let mut child_end = child_start;
5276 while child_end < joins.len()
5277 && !joins[child_end].deferred_condition
5278 && joins[child_end].nesting_group == parent_group
5279 {
5280 child_end += 1;
5281 }
5282
5283 if child_start < child_end {
5285 self.indent_level += 1;
5286 for j in child_start..child_end {
5287 self.generate_join(&joins[j])?;
5288 }
5289 self.indent_level -= 1;
5290 }
5291
5292 self.generate_join_condition(&joins[i])?;
5294
5295 i = child_end;
5296 } else {
5297 self.generate_join(&joins[i])?;
5299 i += 1;
5300 }
5301 }
5302 Ok(())
5303 }
5304
5305 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5308 let mut join_copy = join.clone();
5311 join_copy.on = None;
5312 join_copy.using = Vec::new();
5313 join_copy.deferred_condition = false;
5314 self.generate_join(&join_copy)
5315 }
5316
5317 fn generate_join(&mut self, join: &Join) -> Result<()> {
5318 if join.kind == JoinKind::Implicit {
5320 self.write(",");
5321 if self.config.pretty {
5322 self.write_newline();
5323 self.write_indent();
5324 } else {
5325 self.write_space();
5326 }
5327 self.generate_expression(&join.this)?;
5328 return Ok(());
5329 }
5330
5331 if self.config.pretty {
5332 self.write_newline();
5333 self.write_indent();
5334 } else {
5335 self.write_space();
5336 }
5337
5338 let hint_str = if self.config.join_hints {
5341 join.join_hint
5342 .as_ref()
5343 .map(|h| format!(" {}", h))
5344 .unwrap_or_default()
5345 } else {
5346 String::new()
5347 };
5348
5349 let clickhouse_join_keyword =
5350 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5351 if let Some(hint) = &join.join_hint {
5352 let mut global = false;
5353 let mut strictness: Option<&'static str> = None;
5354 for part in hint.split_whitespace() {
5355 if part.eq_ignore_ascii_case("GLOBAL") {
5356 global = true;
5357 } else if part.eq_ignore_ascii_case("ANY") {
5358 strictness = Some("ANY");
5359 } else if part.eq_ignore_ascii_case("ASOF") {
5360 strictness = Some("ASOF");
5361 } else if part.eq_ignore_ascii_case("SEMI") {
5362 strictness = Some("SEMI");
5363 } else if part.eq_ignore_ascii_case("ANTI") {
5364 strictness = Some("ANTI");
5365 }
5366 }
5367
5368 if global || strictness.is_some() {
5369 let join_type = match join.kind {
5370 JoinKind::Left => {
5371 if join.use_outer_keyword {
5372 "LEFT OUTER"
5373 } else if join.use_inner_keyword {
5374 "LEFT INNER"
5375 } else {
5376 "LEFT"
5377 }
5378 }
5379 JoinKind::Right => {
5380 if join.use_outer_keyword {
5381 "RIGHT OUTER"
5382 } else if join.use_inner_keyword {
5383 "RIGHT INNER"
5384 } else {
5385 "RIGHT"
5386 }
5387 }
5388 JoinKind::Full => {
5389 if join.use_outer_keyword {
5390 "FULL OUTER"
5391 } else {
5392 "FULL"
5393 }
5394 }
5395 JoinKind::Inner => {
5396 if join.use_inner_keyword {
5397 "INNER"
5398 } else {
5399 ""
5400 }
5401 }
5402 _ => "",
5403 };
5404
5405 let mut parts = Vec::new();
5406 if global {
5407 parts.push("GLOBAL");
5408 }
5409 if !join_type.is_empty() {
5410 parts.push(join_type);
5411 }
5412 if let Some(strict) = strictness {
5413 parts.push(strict);
5414 }
5415 parts.push("JOIN");
5416 Some(parts.join(" "))
5417 } else {
5418 None
5419 }
5420 } else {
5421 None
5422 }
5423 } else {
5424 None
5425 };
5426
5427 if !join.comments.is_empty() {
5431 if self.config.pretty {
5432 let trimmed = self.output.trim_end().len();
5437 self.output.truncate(trimmed);
5438 for comment in &join.comments {
5439 self.write_newline();
5440 self.write_indent();
5441 self.write_formatted_comment(comment);
5442 }
5443 self.write_newline();
5444 self.write_indent();
5445 } else {
5446 for comment in &join.comments {
5447 self.write_formatted_comment(comment);
5448 self.write_space();
5449 }
5450 }
5451 }
5452
5453 let directed_str = if join.directed { " DIRECTED" } else { "" };
5454
5455 if let Some(keyword) = clickhouse_join_keyword {
5456 self.write_keyword(&keyword);
5457 } else {
5458 match join.kind {
5459 JoinKind::Inner => {
5460 if join.use_inner_keyword {
5461 if hint_str.is_empty() && directed_str.is_empty() {
5462 self.write_keyword("INNER JOIN");
5463 } else {
5464 self.write_keyword("INNER");
5465 if !hint_str.is_empty() {
5466 self.write_keyword(&hint_str);
5467 }
5468 if !directed_str.is_empty() {
5469 self.write_keyword(directed_str);
5470 }
5471 self.write_keyword(" JOIN");
5472 }
5473 } else {
5474 if !hint_str.is_empty() {
5475 self.write_keyword(hint_str.trim());
5476 self.write_keyword(" ");
5477 }
5478 if !directed_str.is_empty() {
5479 self.write_keyword("DIRECTED ");
5480 }
5481 self.write_keyword("JOIN");
5482 }
5483 }
5484 JoinKind::Left => {
5485 if join.use_outer_keyword {
5486 if hint_str.is_empty() && directed_str.is_empty() {
5487 self.write_keyword("LEFT OUTER JOIN");
5488 } else {
5489 self.write_keyword("LEFT OUTER");
5490 if !hint_str.is_empty() {
5491 self.write_keyword(&hint_str);
5492 }
5493 if !directed_str.is_empty() {
5494 self.write_keyword(directed_str);
5495 }
5496 self.write_keyword(" JOIN");
5497 }
5498 } else if join.use_inner_keyword {
5499 if hint_str.is_empty() && directed_str.is_empty() {
5500 self.write_keyword("LEFT INNER JOIN");
5501 } else {
5502 self.write_keyword("LEFT INNER");
5503 if !hint_str.is_empty() {
5504 self.write_keyword(&hint_str);
5505 }
5506 if !directed_str.is_empty() {
5507 self.write_keyword(directed_str);
5508 }
5509 self.write_keyword(" JOIN");
5510 }
5511 } else {
5512 if hint_str.is_empty() && directed_str.is_empty() {
5513 self.write_keyword("LEFT JOIN");
5514 } else {
5515 self.write_keyword("LEFT");
5516 if !hint_str.is_empty() {
5517 self.write_keyword(&hint_str);
5518 }
5519 if !directed_str.is_empty() {
5520 self.write_keyword(directed_str);
5521 }
5522 self.write_keyword(" JOIN");
5523 }
5524 }
5525 }
5526 JoinKind::Right => {
5527 if join.use_outer_keyword {
5528 if hint_str.is_empty() && directed_str.is_empty() {
5529 self.write_keyword("RIGHT OUTER JOIN");
5530 } else {
5531 self.write_keyword("RIGHT OUTER");
5532 if !hint_str.is_empty() {
5533 self.write_keyword(&hint_str);
5534 }
5535 if !directed_str.is_empty() {
5536 self.write_keyword(directed_str);
5537 }
5538 self.write_keyword(" JOIN");
5539 }
5540 } else if join.use_inner_keyword {
5541 if hint_str.is_empty() && directed_str.is_empty() {
5542 self.write_keyword("RIGHT INNER JOIN");
5543 } else {
5544 self.write_keyword("RIGHT INNER");
5545 if !hint_str.is_empty() {
5546 self.write_keyword(&hint_str);
5547 }
5548 if !directed_str.is_empty() {
5549 self.write_keyword(directed_str);
5550 }
5551 self.write_keyword(" JOIN");
5552 }
5553 } else {
5554 if hint_str.is_empty() && directed_str.is_empty() {
5555 self.write_keyword("RIGHT JOIN");
5556 } else {
5557 self.write_keyword("RIGHT");
5558 if !hint_str.is_empty() {
5559 self.write_keyword(&hint_str);
5560 }
5561 if !directed_str.is_empty() {
5562 self.write_keyword(directed_str);
5563 }
5564 self.write_keyword(" JOIN");
5565 }
5566 }
5567 }
5568 JoinKind::Full => {
5569 if join.use_outer_keyword {
5570 if hint_str.is_empty() && directed_str.is_empty() {
5571 self.write_keyword("FULL OUTER JOIN");
5572 } else {
5573 self.write_keyword("FULL OUTER");
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("FULL JOIN");
5585 } else {
5586 self.write_keyword("FULL");
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::Outer => {
5598 if directed_str.is_empty() {
5599 self.write_keyword("OUTER JOIN");
5600 } else {
5601 self.write_keyword("OUTER");
5602 self.write_keyword(directed_str);
5603 self.write_keyword(" JOIN");
5604 }
5605 }
5606 JoinKind::Cross => {
5607 if directed_str.is_empty() {
5608 self.write_keyword("CROSS JOIN");
5609 } else {
5610 self.write_keyword("CROSS");
5611 self.write_keyword(directed_str);
5612 self.write_keyword(" JOIN");
5613 }
5614 }
5615 JoinKind::Natural => {
5616 if join.use_inner_keyword {
5617 if directed_str.is_empty() {
5618 self.write_keyword("NATURAL INNER JOIN");
5619 } else {
5620 self.write_keyword("NATURAL INNER");
5621 self.write_keyword(directed_str);
5622 self.write_keyword(" JOIN");
5623 }
5624 } else {
5625 if directed_str.is_empty() {
5626 self.write_keyword("NATURAL JOIN");
5627 } else {
5628 self.write_keyword("NATURAL");
5629 self.write_keyword(directed_str);
5630 self.write_keyword(" JOIN");
5631 }
5632 }
5633 }
5634 JoinKind::NaturalLeft => {
5635 if join.use_outer_keyword {
5636 if directed_str.is_empty() {
5637 self.write_keyword("NATURAL LEFT OUTER JOIN");
5638 } else {
5639 self.write_keyword("NATURAL LEFT OUTER");
5640 self.write_keyword(directed_str);
5641 self.write_keyword(" JOIN");
5642 }
5643 } else {
5644 if directed_str.is_empty() {
5645 self.write_keyword("NATURAL LEFT JOIN");
5646 } else {
5647 self.write_keyword("NATURAL LEFT");
5648 self.write_keyword(directed_str);
5649 self.write_keyword(" JOIN");
5650 }
5651 }
5652 }
5653 JoinKind::NaturalRight => {
5654 if join.use_outer_keyword {
5655 if directed_str.is_empty() {
5656 self.write_keyword("NATURAL RIGHT OUTER JOIN");
5657 } else {
5658 self.write_keyword("NATURAL RIGHT OUTER");
5659 self.write_keyword(directed_str);
5660 self.write_keyword(" JOIN");
5661 }
5662 } else {
5663 if directed_str.is_empty() {
5664 self.write_keyword("NATURAL RIGHT JOIN");
5665 } else {
5666 self.write_keyword("NATURAL RIGHT");
5667 self.write_keyword(directed_str);
5668 self.write_keyword(" JOIN");
5669 }
5670 }
5671 }
5672 JoinKind::NaturalFull => {
5673 if join.use_outer_keyword {
5674 if directed_str.is_empty() {
5675 self.write_keyword("NATURAL FULL OUTER JOIN");
5676 } else {
5677 self.write_keyword("NATURAL FULL OUTER");
5678 self.write_keyword(directed_str);
5679 self.write_keyword(" JOIN");
5680 }
5681 } else {
5682 if directed_str.is_empty() {
5683 self.write_keyword("NATURAL FULL JOIN");
5684 } else {
5685 self.write_keyword("NATURAL FULL");
5686 self.write_keyword(directed_str);
5687 self.write_keyword(" JOIN");
5688 }
5689 }
5690 }
5691 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5692 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5693 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5694 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5695 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5696 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5697 JoinKind::CrossApply => {
5698 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5700 self.write_keyword("CROSS APPLY");
5701 } else {
5702 self.write_keyword("INNER JOIN LATERAL");
5703 }
5704 }
5705 JoinKind::OuterApply => {
5706 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5708 self.write_keyword("OUTER APPLY");
5709 } else {
5710 self.write_keyword("LEFT JOIN LATERAL");
5711 }
5712 }
5713 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5714 JoinKind::AsOfLeft => {
5715 if join.use_outer_keyword {
5716 self.write_keyword("ASOF LEFT OUTER JOIN");
5717 } else {
5718 self.write_keyword("ASOF LEFT JOIN");
5719 }
5720 }
5721 JoinKind::AsOfRight => {
5722 if join.use_outer_keyword {
5723 self.write_keyword("ASOF RIGHT OUTER JOIN");
5724 } else {
5725 self.write_keyword("ASOF RIGHT JOIN");
5726 }
5727 }
5728 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5729 JoinKind::LeftLateral => {
5730 if join.use_outer_keyword {
5731 self.write_keyword("LEFT OUTER LATERAL JOIN");
5732 } else {
5733 self.write_keyword("LEFT LATERAL JOIN");
5734 }
5735 }
5736 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5737 JoinKind::Implicit => {
5738 use crate::dialects::DialectType;
5742 let is_cj_dialect = matches!(
5743 self.config.dialect,
5744 Some(DialectType::BigQuery)
5745 | Some(DialectType::Hive)
5746 | Some(DialectType::Spark)
5747 | Some(DialectType::Databricks)
5748 );
5749 let source_is_same = self.config.source_dialect.is_some()
5750 && self.config.source_dialect == self.config.dialect;
5751 let source_is_cj = matches!(
5752 self.config.source_dialect,
5753 Some(DialectType::BigQuery)
5754 | Some(DialectType::Hive)
5755 | Some(DialectType::Spark)
5756 | Some(DialectType::Databricks)
5757 );
5758 if is_cj_dialect
5759 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5760 {
5761 self.write_keyword("CROSS JOIN");
5762 } else {
5763 self.output.truncate(self.output.trim_end().len());
5767 self.write(",");
5768 }
5769 }
5770 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5771 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5772 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5773 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
5774 }
5775 }
5776
5777 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5779 self.write_space();
5780 match &join.this {
5781 Expression::Tuple(t) => {
5782 for (i, item) in t.expressions.iter().enumerate() {
5783 if i > 0 {
5784 self.write(", ");
5785 }
5786 self.generate_expression(item)?;
5787 }
5788 }
5789 other => {
5790 self.generate_expression(other)?;
5791 }
5792 }
5793 } else {
5794 self.write_space();
5795 self.generate_expression(&join.this)?;
5796 }
5797
5798 if !join.deferred_condition {
5800 if let Some(match_cond) = &join.match_condition {
5802 self.write_space();
5803 self.write_keyword("MATCH_CONDITION");
5804 self.write(" (");
5805 self.generate_expression(match_cond)?;
5806 self.write(")");
5807 }
5808
5809 if let Some(on) = &join.on {
5810 if self.config.pretty {
5811 self.write_newline();
5812 self.indent_level += 1;
5813 self.write_indent();
5814 self.write_keyword("ON");
5815 self.write_space();
5816 self.generate_join_on_condition(on)?;
5817 self.indent_level -= 1;
5818 } else {
5819 self.write_space();
5820 self.write_keyword("ON");
5821 self.write_space();
5822 self.generate_expression(on)?;
5823 }
5824 }
5825
5826 if !join.using.is_empty() {
5827 if self.config.pretty {
5828 self.write_newline();
5829 self.indent_level += 1;
5830 self.write_indent();
5831 self.write_keyword("USING");
5832 self.write(" (");
5833 for (i, col) in join.using.iter().enumerate() {
5834 if i > 0 {
5835 self.write(", ");
5836 }
5837 self.generate_identifier(col)?;
5838 }
5839 self.write(")");
5840 self.indent_level -= 1;
5841 } else {
5842 self.write_space();
5843 self.write_keyword("USING");
5844 self.write(" (");
5845 for (i, col) in join.using.iter().enumerate() {
5846 if i > 0 {
5847 self.write(", ");
5848 }
5849 self.generate_identifier(col)?;
5850 }
5851 self.write(")");
5852 }
5853 }
5854 }
5855
5856 for pivot in &join.pivots {
5858 self.write_space();
5859 self.generate_expression(pivot)?;
5860 }
5861
5862 Ok(())
5863 }
5864
5865 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5867 if let Some(match_cond) = &join.match_condition {
5869 self.write_space();
5870 self.write_keyword("MATCH_CONDITION");
5871 self.write(" (");
5872 self.generate_expression(match_cond)?;
5873 self.write(")");
5874 }
5875
5876 if let Some(on) = &join.on {
5877 if self.config.pretty {
5878 self.write_newline();
5879 self.indent_level += 1;
5880 self.write_indent();
5881 self.write_keyword("ON");
5882 self.write_space();
5883 self.generate_join_on_condition(on)?;
5885 self.indent_level -= 1;
5886 } else {
5887 self.write_space();
5888 self.write_keyword("ON");
5889 self.write_space();
5890 self.generate_expression(on)?;
5891 }
5892 }
5893
5894 if !join.using.is_empty() {
5895 if self.config.pretty {
5896 self.write_newline();
5897 self.indent_level += 1;
5898 self.write_indent();
5899 self.write_keyword("USING");
5900 self.write(" (");
5901 for (i, col) in join.using.iter().enumerate() {
5902 if i > 0 {
5903 self.write(", ");
5904 }
5905 self.generate_identifier(col)?;
5906 }
5907 self.write(")");
5908 self.indent_level -= 1;
5909 } else {
5910 self.write_space();
5911 self.write_keyword("USING");
5912 self.write(" (");
5913 for (i, col) in join.using.iter().enumerate() {
5914 if i > 0 {
5915 self.write(", ");
5916 }
5917 self.generate_identifier(col)?;
5918 }
5919 self.write(")");
5920 }
5921 }
5922
5923 for pivot in &join.pivots {
5925 self.write_space();
5926 self.generate_expression(pivot)?;
5927 }
5928
5929 Ok(())
5930 }
5931
5932 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5934 if let Expression::And(and_op) = expr {
5935 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5936 self.generate_expression(conditions[0])?;
5937 for condition in conditions.iter().skip(1) {
5938 self.write_newline();
5939 self.write_indent();
5940 self.write_keyword("AND");
5941 self.write_space();
5942 self.generate_expression(condition)?;
5943 }
5944 return Ok(());
5945 }
5946 }
5947
5948 self.generate_expression(expr)
5949 }
5950
5951 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5952 self.write("(");
5954 self.generate_expression(&jt.left)?;
5955
5956 for join in &jt.joins {
5958 self.generate_join(join)?;
5959 }
5960
5961 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
5963 self.generate_lateral_view(lv, lv_idx)?;
5964 }
5965
5966 self.write(")");
5967
5968 if let Some(alias) = &jt.alias {
5970 self.write_space();
5971 self.write_keyword("AS");
5972 self.write_space();
5973 self.generate_identifier(alias)?;
5974 }
5975
5976 Ok(())
5977 }
5978
5979 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
5980 use crate::dialects::DialectType;
5981
5982 if self.config.pretty {
5983 self.write_newline();
5984 self.write_indent();
5985 } else {
5986 self.write_space();
5987 }
5988
5989 let use_lateral_join = matches!(
5992 self.config.dialect,
5993 Some(DialectType::PostgreSQL)
5994 | Some(DialectType::DuckDB)
5995 | Some(DialectType::Snowflake)
5996 | Some(DialectType::TSQL)
5997 | Some(DialectType::Presto)
5998 | Some(DialectType::Trino)
5999 | Some(DialectType::Athena)
6000 );
6001
6002 let use_unnest = matches!(
6004 self.config.dialect,
6005 Some(DialectType::DuckDB)
6006 | Some(DialectType::Presto)
6007 | Some(DialectType::Trino)
6008 | Some(DialectType::Athena)
6009 );
6010
6011 let (is_posexplode, is_inline, func_args) = match &lv.this {
6013 Expression::Explode(uf) => {
6014 (false, false, vec![uf.this.clone()])
6016 }
6017 Expression::Unnest(uf) => {
6018 let mut args = vec![uf.this.clone()];
6019 args.extend(uf.expressions.clone());
6020 (false, false, args)
6021 }
6022 Expression::Function(func) => {
6023 if func.name.eq_ignore_ascii_case("POSEXPLODE")
6024 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
6025 {
6026 (true, false, func.args.clone())
6027 } else if func.name.eq_ignore_ascii_case("INLINE") {
6028 (false, true, func.args.clone())
6029 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6030 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6031 {
6032 (false, false, func.args.clone())
6033 } else {
6034 (false, false, vec![])
6035 }
6036 }
6037 _ => (false, false, vec![]),
6038 };
6039
6040 if use_lateral_join {
6041 if lv.outer {
6043 self.write_keyword("LEFT JOIN LATERAL");
6044 } else {
6045 self.write_keyword("CROSS JOIN");
6046 }
6047 self.write_space();
6048
6049 if use_unnest && !func_args.is_empty() {
6050 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6053 func_args
6055 .iter()
6056 .map(|a| {
6057 if let Expression::Function(ref f) = a {
6058 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6059 return Expression::ArrayFunc(Box::new(
6060 crate::expressions::ArrayConstructor {
6061 expressions: f.args.clone(),
6062 bracket_notation: true,
6063 use_list_keyword: false,
6064 },
6065 ));
6066 }
6067 }
6068 a.clone()
6069 })
6070 .collect::<Vec<_>>()
6071 } else if matches!(
6072 self.config.dialect,
6073 Some(DialectType::Presto)
6074 | Some(DialectType::Trino)
6075 | Some(DialectType::Athena)
6076 ) {
6077 func_args
6079 .iter()
6080 .map(|a| {
6081 if let Expression::Function(ref f) = a {
6082 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6083 return Expression::ArrayFunc(Box::new(
6084 crate::expressions::ArrayConstructor {
6085 expressions: f.args.clone(),
6086 bracket_notation: true,
6087 use_list_keyword: false,
6088 },
6089 ));
6090 }
6091 }
6092 a.clone()
6093 })
6094 .collect::<Vec<_>>()
6095 } else {
6096 func_args
6097 };
6098
6099 if is_posexplode {
6101 self.write_keyword("LATERAL");
6102 self.write(" (");
6103 self.write_keyword("SELECT");
6104 self.write_space();
6105
6106 let pos_alias = if !lv.column_aliases.is_empty() {
6109 lv.column_aliases[0].clone()
6110 } else {
6111 Identifier::new("pos")
6112 };
6113 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6114 lv.column_aliases[1..].to_vec()
6115 } else {
6116 vec![Identifier::new("col")]
6117 };
6118
6119 self.generate_identifier(&pos_alias)?;
6121 self.write(" - 1");
6122 self.write_space();
6123 self.write_keyword("AS");
6124 self.write_space();
6125 self.generate_identifier(&pos_alias)?;
6126
6127 for data_col in &data_aliases {
6129 self.write(", ");
6130 self.generate_identifier(data_col)?;
6131 }
6132
6133 self.write_space();
6134 self.write_keyword("FROM");
6135 self.write_space();
6136 self.write_keyword("UNNEST");
6137 self.write("(");
6138 for (i, arg) in unnest_args.iter().enumerate() {
6139 if i > 0 {
6140 self.write(", ");
6141 }
6142 self.generate_expression(arg)?;
6143 }
6144 self.write(")");
6145 self.write_space();
6146 self.write_keyword("WITH ORDINALITY");
6147 self.write_space();
6148 self.write_keyword("AS");
6149 self.write_space();
6150
6151 let table_alias_ident = lv
6153 .table_alias
6154 .clone()
6155 .unwrap_or_else(|| Identifier::new("t"));
6156 self.generate_identifier(&table_alias_ident)?;
6157 self.write("(");
6158 for (i, data_col) in data_aliases.iter().enumerate() {
6159 if i > 0 {
6160 self.write(", ");
6161 }
6162 self.generate_identifier(data_col)?;
6163 }
6164 self.write(", ");
6165 self.generate_identifier(&pos_alias)?;
6166 self.write("))");
6167 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6168 self.write_keyword("LATERAL");
6170 self.write(" (");
6171 self.write_keyword("SELECT");
6172 self.write_space();
6173 self.write_keyword("UNNEST");
6174 self.write("(");
6175 for (i, arg) in unnest_args.iter().enumerate() {
6176 if i > 0 {
6177 self.write(", ");
6178 }
6179 self.generate_expression(arg)?;
6180 }
6181 self.write(", ");
6182 self.write_keyword("max_depth");
6183 self.write(" => 2))");
6184
6185 if let Some(alias) = &lv.table_alias {
6187 self.write_space();
6188 self.write_keyword("AS");
6189 self.write_space();
6190 self.generate_identifier(alias)?;
6191 if !lv.column_aliases.is_empty() {
6192 self.write("(");
6193 for (i, col) in lv.column_aliases.iter().enumerate() {
6194 if i > 0 {
6195 self.write(", ");
6196 }
6197 self.generate_identifier(col)?;
6198 }
6199 self.write(")");
6200 }
6201 } else if !lv.column_aliases.is_empty() {
6202 self.write_space();
6204 self.write_keyword("AS");
6205 self.write_space();
6206 self.write(&format!("_u_{}", lv_index));
6207 self.write("(");
6208 for (i, col) in lv.column_aliases.iter().enumerate() {
6209 if i > 0 {
6210 self.write(", ");
6211 }
6212 self.generate_identifier(col)?;
6213 }
6214 self.write(")");
6215 }
6216 } else {
6217 self.write_keyword("UNNEST");
6218 self.write("(");
6219 for (i, arg) in unnest_args.iter().enumerate() {
6220 if i > 0 {
6221 self.write(", ");
6222 }
6223 self.generate_expression(arg)?;
6224 }
6225 self.write(")");
6226
6227 if let Some(alias) = &lv.table_alias {
6229 self.write_space();
6230 self.write_keyword("AS");
6231 self.write_space();
6232 self.generate_identifier(alias)?;
6233 if !lv.column_aliases.is_empty() {
6234 self.write("(");
6235 for (i, col) in lv.column_aliases.iter().enumerate() {
6236 if i > 0 {
6237 self.write(", ");
6238 }
6239 self.generate_identifier(col)?;
6240 }
6241 self.write(")");
6242 }
6243 } else if !lv.column_aliases.is_empty() {
6244 self.write_space();
6245 self.write_keyword("AS");
6246 self.write(" t(");
6247 for (i, col) in lv.column_aliases.iter().enumerate() {
6248 if i > 0 {
6249 self.write(", ");
6250 }
6251 self.generate_identifier(col)?;
6252 }
6253 self.write(")");
6254 }
6255 }
6256 } else {
6257 if !lv.outer {
6259 self.write_keyword("LATERAL");
6260 self.write_space();
6261 }
6262 self.generate_expression(&lv.this)?;
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();
6282 self.write_keyword("AS");
6283 self.write(" t(");
6284 for (i, col) in lv.column_aliases.iter().enumerate() {
6285 if i > 0 {
6286 self.write(", ");
6287 }
6288 self.generate_identifier(col)?;
6289 }
6290 self.write(")");
6291 }
6292 }
6293
6294 if lv.outer {
6296 self.write_space();
6297 self.write_keyword("ON TRUE");
6298 }
6299 } else {
6300 self.write_keyword("LATERAL VIEW");
6302 if lv.outer {
6303 self.write_space();
6304 self.write_keyword("OUTER");
6305 }
6306 if self.config.pretty {
6307 self.write_newline();
6308 self.write_indent();
6309 } else {
6310 self.write_space();
6311 }
6312 self.generate_expression(&lv.this)?;
6313
6314 if let Some(alias) = &lv.table_alias {
6316 self.write_space();
6317 self.generate_identifier(alias)?;
6318 }
6319
6320 if !lv.column_aliases.is_empty() {
6322 self.write_space();
6323 self.write_keyword("AS");
6324 self.write_space();
6325 for (i, col) in lv.column_aliases.iter().enumerate() {
6326 if i > 0 {
6327 self.write(", ");
6328 }
6329 self.generate_identifier(col)?;
6330 }
6331 }
6332 }
6333
6334 Ok(())
6335 }
6336
6337 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
6338 let mut chain: Vec<&Union> = vec![outermost];
6343 let mut leftmost: &Expression = &outermost.left;
6344 while let Expression::Union(inner) = leftmost {
6345 chain.push(inner);
6346 leftmost = &inner.left;
6347 }
6348 if let Some(with) = &outermost.with {
6353 self.generate_with(with)?;
6354 self.write_space();
6355 }
6356
6357 self.generate_expression(leftmost)?;
6359
6360 for union in chain.iter().rev() {
6362 self.generate_union_step(union)?;
6363 }
6364 Ok(())
6365 }
6366
6367 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
6369 if self.config.pretty {
6370 self.write_newline();
6371 self.write_indent();
6372 } else {
6373 self.write_space();
6374 }
6375
6376 if let Some(side) = &union.side {
6378 self.write_keyword(side);
6379 self.write_space();
6380 }
6381 if let Some(kind) = &union.kind {
6382 self.write_keyword(kind);
6383 self.write_space();
6384 }
6385
6386 self.write_keyword("UNION");
6387 if union.all {
6388 self.write_space();
6389 self.write_keyword("ALL");
6390 } else if union.distinct {
6391 self.write_space();
6392 self.write_keyword("DISTINCT");
6393 }
6394
6395 if union.corresponding || union.by_name {
6398 self.write_space();
6399 self.write_keyword("BY NAME");
6400 }
6401 if !union.on_columns.is_empty() {
6402 self.write_space();
6403 self.write_keyword("ON");
6404 self.write(" (");
6405 for (i, col) in union.on_columns.iter().enumerate() {
6406 if i > 0 {
6407 self.write(", ");
6408 }
6409 self.generate_expression(col)?;
6410 }
6411 self.write(")");
6412 }
6413
6414 if self.config.pretty {
6415 self.write_newline();
6416 self.write_indent();
6417 } else {
6418 self.write_space();
6419 }
6420 self.generate_expression(&union.right)?;
6421 if let Some(order_by) = &union.order_by {
6423 if self.config.pretty {
6424 self.write_newline();
6425 } else {
6426 self.write_space();
6427 }
6428 self.write_keyword("ORDER BY");
6429 self.write_space();
6430 for (i, ordered) in order_by.expressions.iter().enumerate() {
6431 if i > 0 {
6432 self.write(", ");
6433 }
6434 self.generate_ordered(ordered)?;
6435 }
6436 }
6437 if let Some(limit) = &union.limit {
6438 if self.config.pretty {
6439 self.write_newline();
6440 } else {
6441 self.write_space();
6442 }
6443 self.write_keyword("LIMIT");
6444 self.write_space();
6445 self.generate_expression(limit)?;
6446 }
6447 if let Some(offset) = &union.offset {
6448 if self.config.pretty {
6449 self.write_newline();
6450 } else {
6451 self.write_space();
6452 }
6453 self.write_keyword("OFFSET");
6454 self.write_space();
6455 self.generate_expression(offset)?;
6456 }
6457 if let Some(distribute_by) = &union.distribute_by {
6459 self.write_space();
6460 self.write_keyword("DISTRIBUTE BY");
6461 self.write_space();
6462 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6463 if i > 0 {
6464 self.write(", ");
6465 }
6466 self.generate_expression(expr)?;
6467 }
6468 }
6469 if let Some(sort_by) = &union.sort_by {
6471 self.write_space();
6472 self.write_keyword("SORT BY");
6473 self.write_space();
6474 for (i, ord) in sort_by.expressions.iter().enumerate() {
6475 if i > 0 {
6476 self.write(", ");
6477 }
6478 self.generate_ordered(ord)?;
6479 }
6480 }
6481 if let Some(cluster_by) = &union.cluster_by {
6483 self.write_space();
6484 self.write_keyword("CLUSTER BY");
6485 self.write_space();
6486 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6487 if i > 0 {
6488 self.write(", ");
6489 }
6490 self.generate_ordered(ord)?;
6491 }
6492 }
6493 Ok(())
6494 }
6495
6496 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
6497 let mut chain: Vec<&Intersect> = vec![outermost];
6499 let mut leftmost: &Expression = &outermost.left;
6500 while let Expression::Intersect(inner) = leftmost {
6501 chain.push(inner);
6502 leftmost = &inner.left;
6503 }
6504
6505 if let Some(with) = &outermost.with {
6506 self.generate_with(with)?;
6507 self.write_space();
6508 }
6509
6510 self.generate_expression(leftmost)?;
6511
6512 for intersect in chain.iter().rev() {
6513 self.generate_intersect_step(intersect)?;
6514 }
6515 Ok(())
6516 }
6517
6518 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
6520 if self.config.pretty {
6521 self.write_newline();
6522 self.write_indent();
6523 } else {
6524 self.write_space();
6525 }
6526
6527 if let Some(side) = &intersect.side {
6529 self.write_keyword(side);
6530 self.write_space();
6531 }
6532 if let Some(kind) = &intersect.kind {
6533 self.write_keyword(kind);
6534 self.write_space();
6535 }
6536
6537 self.write_keyword("INTERSECT");
6538 if intersect.all {
6539 self.write_space();
6540 self.write_keyword("ALL");
6541 } else if intersect.distinct {
6542 self.write_space();
6543 self.write_keyword("DISTINCT");
6544 }
6545
6546 if intersect.corresponding || intersect.by_name {
6549 self.write_space();
6550 self.write_keyword("BY NAME");
6551 }
6552 if !intersect.on_columns.is_empty() {
6553 self.write_space();
6554 self.write_keyword("ON");
6555 self.write(" (");
6556 for (i, col) in intersect.on_columns.iter().enumerate() {
6557 if i > 0 {
6558 self.write(", ");
6559 }
6560 self.generate_expression(col)?;
6561 }
6562 self.write(")");
6563 }
6564
6565 if self.config.pretty {
6566 self.write_newline();
6567 self.write_indent();
6568 } else {
6569 self.write_space();
6570 }
6571 self.generate_expression(&intersect.right)?;
6572 if let Some(order_by) = &intersect.order_by {
6574 if self.config.pretty {
6575 self.write_newline();
6576 } else {
6577 self.write_space();
6578 }
6579 self.write_keyword("ORDER BY");
6580 self.write_space();
6581 for (i, ordered) in order_by.expressions.iter().enumerate() {
6582 if i > 0 {
6583 self.write(", ");
6584 }
6585 self.generate_ordered(ordered)?;
6586 }
6587 }
6588 if let Some(limit) = &intersect.limit {
6589 if self.config.pretty {
6590 self.write_newline();
6591 } else {
6592 self.write_space();
6593 }
6594 self.write_keyword("LIMIT");
6595 self.write_space();
6596 self.generate_expression(limit)?;
6597 }
6598 if let Some(offset) = &intersect.offset {
6599 if self.config.pretty {
6600 self.write_newline();
6601 } else {
6602 self.write_space();
6603 }
6604 self.write_keyword("OFFSET");
6605 self.write_space();
6606 self.generate_expression(offset)?;
6607 }
6608 if let Some(distribute_by) = &intersect.distribute_by {
6610 self.write_space();
6611 self.write_keyword("DISTRIBUTE BY");
6612 self.write_space();
6613 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6614 if i > 0 {
6615 self.write(", ");
6616 }
6617 self.generate_expression(expr)?;
6618 }
6619 }
6620 if let Some(sort_by) = &intersect.sort_by {
6622 self.write_space();
6623 self.write_keyword("SORT BY");
6624 self.write_space();
6625 for (i, ord) in sort_by.expressions.iter().enumerate() {
6626 if i > 0 {
6627 self.write(", ");
6628 }
6629 self.generate_ordered(ord)?;
6630 }
6631 }
6632 if let Some(cluster_by) = &intersect.cluster_by {
6634 self.write_space();
6635 self.write_keyword("CLUSTER BY");
6636 self.write_space();
6637 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6638 if i > 0 {
6639 self.write(", ");
6640 }
6641 self.generate_ordered(ord)?;
6642 }
6643 }
6644 Ok(())
6645 }
6646
6647 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
6648 let mut chain: Vec<&Except> = vec![outermost];
6650 let mut leftmost: &Expression = &outermost.left;
6651 while let Expression::Except(inner) = leftmost {
6652 chain.push(inner);
6653 leftmost = &inner.left;
6654 }
6655
6656 if let Some(with) = &outermost.with {
6657 self.generate_with(with)?;
6658 self.write_space();
6659 }
6660
6661 self.generate_expression(leftmost)?;
6662
6663 for except in chain.iter().rev() {
6664 self.generate_except_step(except)?;
6665 }
6666 Ok(())
6667 }
6668
6669 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
6671 use crate::dialects::DialectType;
6672
6673 if self.config.pretty {
6674 self.write_newline();
6675 self.write_indent();
6676 } else {
6677 self.write_space();
6678 }
6679
6680 if let Some(side) = &except.side {
6682 self.write_keyword(side);
6683 self.write_space();
6684 }
6685 if let Some(kind) = &except.kind {
6686 self.write_keyword(kind);
6687 self.write_space();
6688 }
6689
6690 match self.config.dialect {
6692 Some(DialectType::Oracle) if !except.all => {
6693 self.write_keyword("MINUS");
6694 }
6695 Some(DialectType::ClickHouse) => {
6696 self.write_keyword("EXCEPT");
6698 if except.distinct {
6699 self.write_space();
6700 self.write_keyword("DISTINCT");
6701 }
6702 }
6703 Some(DialectType::BigQuery) => {
6704 self.write_keyword("EXCEPT");
6706 if except.all {
6707 self.write_space();
6708 self.write_keyword("ALL");
6709 } else {
6710 self.write_space();
6711 self.write_keyword("DISTINCT");
6712 }
6713 }
6714 _ => {
6715 self.write_keyword("EXCEPT");
6716 if except.all {
6717 self.write_space();
6718 self.write_keyword("ALL");
6719 } else if except.distinct {
6720 self.write_space();
6721 self.write_keyword("DISTINCT");
6722 }
6723 }
6724 }
6725
6726 if except.corresponding || except.by_name {
6729 self.write_space();
6730 self.write_keyword("BY NAME");
6731 }
6732 if !except.on_columns.is_empty() {
6733 self.write_space();
6734 self.write_keyword("ON");
6735 self.write(" (");
6736 for (i, col) in except.on_columns.iter().enumerate() {
6737 if i > 0 {
6738 self.write(", ");
6739 }
6740 self.generate_expression(col)?;
6741 }
6742 self.write(")");
6743 }
6744
6745 if self.config.pretty {
6746 self.write_newline();
6747 self.write_indent();
6748 } else {
6749 self.write_space();
6750 }
6751 self.generate_expression(&except.right)?;
6752 if let Some(order_by) = &except.order_by {
6754 if self.config.pretty {
6755 self.write_newline();
6756 } else {
6757 self.write_space();
6758 }
6759 self.write_keyword("ORDER BY");
6760 self.write_space();
6761 for (i, ordered) in order_by.expressions.iter().enumerate() {
6762 if i > 0 {
6763 self.write(", ");
6764 }
6765 self.generate_ordered(ordered)?;
6766 }
6767 }
6768 if let Some(limit) = &except.limit {
6769 if self.config.pretty {
6770 self.write_newline();
6771 } else {
6772 self.write_space();
6773 }
6774 self.write_keyword("LIMIT");
6775 self.write_space();
6776 self.generate_expression(limit)?;
6777 }
6778 if let Some(offset) = &except.offset {
6779 if self.config.pretty {
6780 self.write_newline();
6781 } else {
6782 self.write_space();
6783 }
6784 self.write_keyword("OFFSET");
6785 self.write_space();
6786 self.generate_expression(offset)?;
6787 }
6788 if let Some(distribute_by) = &except.distribute_by {
6790 self.write_space();
6791 self.write_keyword("DISTRIBUTE BY");
6792 self.write_space();
6793 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6794 if i > 0 {
6795 self.write(", ");
6796 }
6797 self.generate_expression(expr)?;
6798 }
6799 }
6800 if let Some(sort_by) = &except.sort_by {
6802 self.write_space();
6803 self.write_keyword("SORT BY");
6804 self.write_space();
6805 for (i, ord) in sort_by.expressions.iter().enumerate() {
6806 if i > 0 {
6807 self.write(", ");
6808 }
6809 self.generate_ordered(ord)?;
6810 }
6811 }
6812 if let Some(cluster_by) = &except.cluster_by {
6814 self.write_space();
6815 self.write_keyword("CLUSTER BY");
6816 self.write_space();
6817 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6818 if i > 0 {
6819 self.write(", ");
6820 }
6821 self.generate_ordered(ord)?;
6822 }
6823 }
6824 Ok(())
6825 }
6826
6827 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6828 let prepend_query_cte = if insert.with.is_none() {
6830 use crate::dialects::DialectType;
6831 let should_prepend = matches!(
6832 self.config.dialect,
6833 Some(DialectType::TSQL)
6834 | Some(DialectType::Fabric)
6835 | Some(DialectType::Spark)
6836 | Some(DialectType::Databricks)
6837 | Some(DialectType::Hive)
6838 );
6839 if should_prepend {
6840 if let Some(Expression::Select(select)) = &insert.query {
6841 select.with.clone()
6842 } else {
6843 None
6844 }
6845 } else {
6846 None
6847 }
6848 } else {
6849 None
6850 };
6851
6852 if let Some(with) = &insert.with {
6854 self.generate_with(with)?;
6855 self.write_space();
6856 } else if let Some(with) = &prepend_query_cte {
6857 self.generate_with(with)?;
6858 self.write_space();
6859 }
6860
6861 for comment in &insert.leading_comments {
6863 self.write_formatted_comment(comment);
6864 self.write(" ");
6865 }
6866
6867 if let Some(dir) = &insert.directory {
6869 self.write_keyword("INSERT OVERWRITE");
6870 if dir.local {
6871 self.write_space();
6872 self.write_keyword("LOCAL");
6873 }
6874 self.write_space();
6875 self.write_keyword("DIRECTORY");
6876 self.write_space();
6877 self.write("'");
6878 self.write(&dir.path);
6879 self.write("'");
6880
6881 if let Some(row_format) = &dir.row_format {
6883 self.write_space();
6884 self.write_keyword("ROW FORMAT");
6885 if row_format.delimited {
6886 self.write_space();
6887 self.write_keyword("DELIMITED");
6888 }
6889 if let Some(val) = &row_format.fields_terminated_by {
6890 self.write_space();
6891 self.write_keyword("FIELDS TERMINATED BY");
6892 self.write_space();
6893 self.write("'");
6894 self.write(val);
6895 self.write("'");
6896 }
6897 if let Some(val) = &row_format.collection_items_terminated_by {
6898 self.write_space();
6899 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6900 self.write_space();
6901 self.write("'");
6902 self.write(val);
6903 self.write("'");
6904 }
6905 if let Some(val) = &row_format.map_keys_terminated_by {
6906 self.write_space();
6907 self.write_keyword("MAP KEYS TERMINATED BY");
6908 self.write_space();
6909 self.write("'");
6910 self.write(val);
6911 self.write("'");
6912 }
6913 if let Some(val) = &row_format.lines_terminated_by {
6914 self.write_space();
6915 self.write_keyword("LINES TERMINATED BY");
6916 self.write_space();
6917 self.write("'");
6918 self.write(val);
6919 self.write("'");
6920 }
6921 if let Some(val) = &row_format.null_defined_as {
6922 self.write_space();
6923 self.write_keyword("NULL DEFINED AS");
6924 self.write_space();
6925 self.write("'");
6926 self.write(val);
6927 self.write("'");
6928 }
6929 }
6930
6931 if let Some(format) = &dir.stored_as {
6933 self.write_space();
6934 self.write_keyword("STORED AS");
6935 self.write_space();
6936 self.write_keyword(format);
6937 }
6938
6939 if let Some(query) = &insert.query {
6941 self.write_space();
6942 self.generate_expression(query)?;
6943 }
6944
6945 return Ok(());
6946 }
6947
6948 if insert.is_replace {
6949 self.write_keyword("REPLACE INTO");
6951 } else if insert.overwrite {
6952 self.write_keyword("INSERT");
6954 if let Some(ref hint) = insert.hint {
6956 self.generate_hint(hint)?;
6957 }
6958 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
6959 } else if let Some(ref action) = insert.conflict_action {
6960 self.write_keyword("INSERT OR");
6962 self.write_space();
6963 self.write_keyword(action);
6964 self.write_space();
6965 self.write_keyword("INTO");
6966 } else if insert.ignore {
6967 self.write_keyword("INSERT IGNORE INTO");
6969 } else {
6970 self.write_keyword("INSERT");
6971 if let Some(ref hint) = insert.hint {
6973 self.generate_hint(hint)?;
6974 }
6975 self.write_space();
6976 self.write_keyword("INTO");
6977 }
6978 if let Some(ref func) = insert.function_target {
6980 self.write_space();
6981 self.write_keyword("FUNCTION");
6982 self.write_space();
6983 self.generate_expression(func)?;
6984 } else {
6985 self.write_space();
6986 self.generate_table(&insert.table)?;
6987 }
6988
6989 if let Some(ref alias) = insert.alias {
6991 self.write_space();
6992 if insert.alias_explicit_as {
6993 self.write_keyword("AS");
6994 self.write_space();
6995 }
6996 self.generate_identifier(alias)?;
6997 }
6998
6999 if insert.if_exists {
7001 self.write_space();
7002 self.write_keyword("IF EXISTS");
7003 }
7004
7005 if let Some(ref replace_where) = insert.replace_where {
7007 if self.config.pretty {
7008 self.write_newline();
7009 self.write_indent();
7010 } else {
7011 self.write_space();
7012 }
7013 self.write_keyword("REPLACE WHERE");
7014 self.write_space();
7015 self.generate_expression(replace_where)?;
7016 }
7017
7018 if !insert.partition.is_empty() {
7020 self.write_space();
7021 self.write_keyword("PARTITION");
7022 self.write("(");
7023 for (i, (col, val)) in insert.partition.iter().enumerate() {
7024 if i > 0 {
7025 self.write(", ");
7026 }
7027 self.generate_identifier(col)?;
7028 if let Some(v) = val {
7029 self.write(" = ");
7030 self.generate_expression(v)?;
7031 }
7032 }
7033 self.write(")");
7034 }
7035
7036 if let Some(ref partition_by) = insert.partition_by {
7038 self.write_space();
7039 self.write_keyword("PARTITION BY");
7040 self.write_space();
7041 self.generate_expression(partition_by)?;
7042 }
7043
7044 if !insert.settings.is_empty() {
7046 self.write_space();
7047 self.write_keyword("SETTINGS");
7048 self.write_space();
7049 for (i, setting) in insert.settings.iter().enumerate() {
7050 if i > 0 {
7051 self.write(", ");
7052 }
7053 self.generate_expression(setting)?;
7054 }
7055 }
7056
7057 if !insert.columns.is_empty() {
7058 if insert.alias.is_some() && insert.alias_explicit_as {
7059 self.write("(");
7061 } else {
7062 self.write(" (");
7064 }
7065 for (i, col) in insert.columns.iter().enumerate() {
7066 if i > 0 {
7067 self.write(", ");
7068 }
7069 self.generate_identifier(col)?;
7070 }
7071 self.write(")");
7072 }
7073
7074 if let Some(ref output) = insert.output {
7076 self.generate_output_clause(output)?;
7077 }
7078
7079 if insert.by_name {
7081 self.write_space();
7082 self.write_keyword("BY NAME");
7083 }
7084
7085 if insert.default_values {
7086 self.write_space();
7087 self.write_keyword("DEFAULT VALUES");
7088 } else if let Some(query) = &insert.query {
7089 if self.config.pretty {
7090 self.write_newline();
7091 } else {
7092 self.write_space();
7093 }
7094 if prepend_query_cte.is_some() {
7096 if let Expression::Select(select) = query {
7097 let mut select_no_with = select.clone();
7098 select_no_with.with = None;
7099 self.generate_select(&select_no_with)?;
7100 } else {
7101 self.generate_expression(query)?;
7102 }
7103 } else {
7104 self.generate_expression(query)?;
7105 }
7106 } else if !insert.values.is_empty() {
7107 if self.config.pretty {
7108 self.write_newline();
7110 self.write_keyword("VALUES");
7111 self.write_newline();
7112 self.indent_level += 1;
7113 for (i, row) in insert.values.iter().enumerate() {
7114 if i > 0 {
7115 self.write(",");
7116 self.write_newline();
7117 }
7118 self.write_indent();
7119 self.write("(");
7120 for (j, val) in row.iter().enumerate() {
7121 if j > 0 {
7122 self.write(", ");
7123 }
7124 self.generate_expression(val)?;
7125 }
7126 self.write(")");
7127 }
7128 self.indent_level -= 1;
7129 } else {
7130 self.write_space();
7132 self.write_keyword("VALUES");
7133 for (i, row) in insert.values.iter().enumerate() {
7134 if i > 0 {
7135 self.write(",");
7136 }
7137 self.write(" (");
7138 for (j, val) in row.iter().enumerate() {
7139 if j > 0 {
7140 self.write(", ");
7141 }
7142 self.generate_expression(val)?;
7143 }
7144 self.write(")");
7145 }
7146 }
7147 }
7148
7149 if let Some(ref source) = insert.source {
7151 self.write_space();
7152 self.write_keyword("TABLE");
7153 self.write_space();
7154 self.generate_expression(source)?;
7155 }
7156
7157 if let Some(alias) = &insert.source_alias {
7159 self.write_space();
7160 self.write_keyword("AS");
7161 self.write_space();
7162 self.generate_identifier(alias)?;
7163 }
7164
7165 if let Some(on_conflict) = &insert.on_conflict {
7167 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7168 self.write_space();
7169 self.generate_expression(on_conflict)?;
7170 }
7171 }
7172
7173 if !insert.returning.is_empty() {
7175 self.write_space();
7176 self.write_keyword("RETURNING");
7177 self.write_space();
7178 for (i, expr) in insert.returning.iter().enumerate() {
7179 if i > 0 {
7180 self.write(", ");
7181 }
7182 self.generate_expression(expr)?;
7183 }
7184 }
7185
7186 Ok(())
7187 }
7188
7189 fn generate_update(&mut self, update: &Update) -> Result<()> {
7190 for comment in &update.leading_comments {
7192 self.write_formatted_comment(comment);
7193 self.write(" ");
7194 }
7195
7196 if let Some(ref with) = update.with {
7198 self.generate_with(with)?;
7199 self.write_space();
7200 }
7201
7202 self.write_keyword("UPDATE");
7203 if let Some(hint) = &update.hint {
7204 self.generate_hint(hint)?;
7205 }
7206 self.write_space();
7207 self.generate_table(&update.table)?;
7208
7209 let mysql_like_update_from = matches!(
7210 self.config.dialect,
7211 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
7212 ) && update.from_clause.is_some();
7213
7214 let mut set_pairs = update.set.clone();
7215
7216 let mut pre_set_joins = update.table_joins.clone();
7218 if mysql_like_update_from {
7219 let target_name = update
7220 .table
7221 .alias
7222 .as_ref()
7223 .map(|a| a.name.clone())
7224 .unwrap_or_else(|| update.table.name.name.clone());
7225
7226 for (col, _) in &mut set_pairs {
7227 if !col.name.contains('.') {
7228 col.name = format!("{}.{}", target_name, col.name);
7229 }
7230 }
7231
7232 if let Some(from_clause) = &update.from_clause {
7233 for table_expr in &from_clause.expressions {
7234 pre_set_joins.push(crate::expressions::Join {
7235 this: table_expr.clone(),
7236 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7237 value: true,
7238 })),
7239 using: Vec::new(),
7240 kind: crate::expressions::JoinKind::Inner,
7241 use_inner_keyword: false,
7242 use_outer_keyword: false,
7243 deferred_condition: false,
7244 join_hint: None,
7245 match_condition: None,
7246 pivots: Vec::new(),
7247 comments: Vec::new(),
7248 nesting_group: 0,
7249 directed: false,
7250 });
7251 }
7252 }
7253 for join in &update.from_joins {
7254 let mut join = join.clone();
7255 if join.on.is_none() && join.using.is_empty() {
7256 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7257 value: true,
7258 }));
7259 }
7260 pre_set_joins.push(join);
7261 }
7262 }
7263
7264 for extra_table in &update.extra_tables {
7266 self.write(", ");
7267 self.generate_table(extra_table)?;
7268 }
7269
7270 for join in &pre_set_joins {
7272 self.generate_join(join)?;
7274 }
7275
7276 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
7278 if teradata_from_before_set && !mysql_like_update_from {
7279 if let Some(ref from_clause) = update.from_clause {
7280 self.write_space();
7281 self.write_keyword("FROM");
7282 self.write_space();
7283 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7284 if i > 0 {
7285 self.write(", ");
7286 }
7287 self.generate_expression(table_expr)?;
7288 }
7289 }
7290 for join in &update.from_joins {
7291 self.generate_join(join)?;
7292 }
7293 }
7294
7295 self.write_space();
7296 self.write_keyword("SET");
7297 self.write_space();
7298
7299 for (i, (col, val)) in set_pairs.iter().enumerate() {
7300 if i > 0 {
7301 self.write(", ");
7302 }
7303 self.generate_identifier(col)?;
7304 self.write(" = ");
7305 self.generate_expression(val)?;
7306 }
7307
7308 if let Some(ref output) = update.output {
7310 self.generate_output_clause(output)?;
7311 }
7312
7313 if !mysql_like_update_from && !teradata_from_before_set {
7315 if let Some(ref from_clause) = update.from_clause {
7316 self.write_space();
7317 self.write_keyword("FROM");
7318 self.write_space();
7319 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7321 if i > 0 {
7322 self.write(", ");
7323 }
7324 self.generate_expression(table_expr)?;
7325 }
7326 }
7327 }
7328
7329 if !mysql_like_update_from && !teradata_from_before_set {
7330 for join in &update.from_joins {
7332 self.generate_join(join)?;
7333 }
7334 }
7335
7336 if let Some(where_clause) = &update.where_clause {
7337 self.write_space();
7338 self.write_keyword("WHERE");
7339 self.write_space();
7340 self.generate_expression(&where_clause.this)?;
7341 }
7342
7343 if !update.returning.is_empty() {
7345 self.write_space();
7346 self.write_keyword("RETURNING");
7347 self.write_space();
7348 for (i, expr) in update.returning.iter().enumerate() {
7349 if i > 0 {
7350 self.write(", ");
7351 }
7352 self.generate_expression(expr)?;
7353 }
7354 }
7355
7356 if let Some(ref order_by) = update.order_by {
7358 self.write_space();
7359 self.generate_order_by(order_by)?;
7360 }
7361
7362 if let Some(ref limit) = update.limit {
7364 self.write_space();
7365 self.write_keyword("LIMIT");
7366 self.write_space();
7367 self.generate_expression(limit)?;
7368 }
7369
7370 Ok(())
7371 }
7372
7373 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
7374 if let Some(with) = &delete.with {
7376 self.generate_with(with)?;
7377 self.write_space();
7378 }
7379
7380 for comment in &delete.leading_comments {
7382 self.write_formatted_comment(comment);
7383 self.write(" ");
7384 }
7385
7386 if !delete.tables.is_empty() && !delete.tables_from_using {
7388 self.write_keyword("DELETE");
7390 if let Some(hint) = &delete.hint {
7391 self.generate_hint(hint)?;
7392 }
7393 self.write_space();
7394 for (i, tbl) in delete.tables.iter().enumerate() {
7395 if i > 0 {
7396 self.write(", ");
7397 }
7398 self.generate_table(tbl)?;
7399 }
7400 if let Some(ref output) = delete.output {
7402 self.generate_output_clause(output)?;
7403 }
7404 self.write_space();
7405 self.write_keyword("FROM");
7406 self.write_space();
7407 self.generate_table(&delete.table)?;
7408 } else if !delete.tables.is_empty() && delete.tables_from_using {
7409 self.write_keyword("DELETE");
7411 if let Some(hint) = &delete.hint {
7412 self.generate_hint(hint)?;
7413 }
7414 self.write_space();
7415 self.write_keyword("FROM");
7416 self.write_space();
7417 for (i, tbl) in delete.tables.iter().enumerate() {
7418 if i > 0 {
7419 self.write(", ");
7420 }
7421 self.generate_table(tbl)?;
7422 }
7423 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
7424 self.write_keyword("DELETE");
7426 if let Some(hint) = &delete.hint {
7427 self.generate_hint(hint)?;
7428 }
7429 self.write_space();
7430 self.generate_table(&delete.table)?;
7431 } else {
7432 self.write_keyword("DELETE");
7433 if let Some(hint) = &delete.hint {
7434 self.generate_hint(hint)?;
7435 }
7436 self.write_space();
7437 self.write_keyword("FROM");
7438 self.write_space();
7439 self.generate_table(&delete.table)?;
7440 }
7441
7442 if let Some(ref on_cluster) = delete.on_cluster {
7444 self.write_space();
7445 self.generate_on_cluster(on_cluster)?;
7446 }
7447
7448 if let Some(ref idx) = delete.force_index {
7450 self.write_space();
7451 self.write_keyword("FORCE INDEX");
7452 self.write(" (");
7453 self.write(idx);
7454 self.write(")");
7455 }
7456
7457 if let Some(ref alias) = delete.alias {
7459 self.write_space();
7460 if delete.alias_explicit_as
7461 || matches!(self.config.dialect, Some(DialectType::BigQuery))
7462 {
7463 self.write_keyword("AS");
7464 self.write_space();
7465 }
7466 self.generate_identifier(alias)?;
7467 }
7468
7469 if !delete.tables_from_using {
7471 for join in &delete.joins {
7472 self.generate_join(join)?;
7473 }
7474 }
7475
7476 if !delete.using.is_empty() {
7478 self.write_space();
7479 self.write_keyword("USING");
7480 for (i, table) in delete.using.iter().enumerate() {
7481 if i > 0 {
7482 self.write(",");
7483 }
7484 self.write_space();
7485 if !table.hints.is_empty() && table.name.is_empty() {
7487 self.generate_expression(&table.hints[0])?;
7489 if let Some(ref alias) = table.alias {
7490 self.write_space();
7491 if table.alias_explicit_as {
7492 self.write_keyword("AS");
7493 self.write_space();
7494 }
7495 self.generate_identifier(alias)?;
7496 if !table.column_aliases.is_empty() {
7497 self.write("(");
7498 for (j, col_alias) in table.column_aliases.iter().enumerate() {
7499 if j > 0 {
7500 self.write(", ");
7501 }
7502 self.generate_identifier(col_alias)?;
7503 }
7504 self.write(")");
7505 }
7506 }
7507 } else {
7508 self.generate_table(table)?;
7509 }
7510 }
7511 }
7512
7513 if delete.tables_from_using {
7515 for join in &delete.joins {
7516 self.generate_join(join)?;
7517 }
7518 }
7519
7520 let output_already_emitted =
7522 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
7523 if !output_already_emitted {
7524 if let Some(ref output) = delete.output {
7525 self.generate_output_clause(output)?;
7526 }
7527 }
7528
7529 if let Some(where_clause) = &delete.where_clause {
7530 self.write_space();
7531 self.write_keyword("WHERE");
7532 self.write_space();
7533 self.generate_expression(&where_clause.this)?;
7534 }
7535
7536 if let Some(ref order_by) = delete.order_by {
7538 self.write_space();
7539 self.generate_order_by(order_by)?;
7540 }
7541
7542 if let Some(ref limit) = delete.limit {
7544 self.write_space();
7545 self.write_keyword("LIMIT");
7546 self.write_space();
7547 self.generate_expression(limit)?;
7548 }
7549
7550 if !delete.returning.is_empty() {
7552 self.write_space();
7553 self.write_keyword("RETURNING");
7554 self.write_space();
7555 for (i, expr) in delete.returning.iter().enumerate() {
7556 if i > 0 {
7557 self.write(", ");
7558 }
7559 self.generate_expression(expr)?;
7560 }
7561 }
7562
7563 Ok(())
7564 }
7565
7566 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7569 let saved_athena_hive_context = self.athena_hive_context;
7573 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7574 if matches!(
7575 self.config.dialect,
7576 Some(crate::dialects::DialectType::Athena)
7577 ) {
7578 let is_external = ct
7582 .table_modifier
7583 .as_ref()
7584 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7585 .unwrap_or(false);
7586 let has_as_select = ct.as_select.is_some();
7587 self.athena_hive_context = is_external || !has_as_select;
7588 }
7589
7590 if matches!(
7592 self.config.dialect,
7593 Some(crate::dialects::DialectType::TSQL)
7594 ) {
7595 if let Some(ref query) = ct.as_select {
7596 if let Some(with_cte) = &ct.with_cte {
7598 self.generate_with(with_cte)?;
7599 self.write_space();
7600 }
7601
7602 self.write_keyword("SELECT");
7604 self.write(" * ");
7605 self.write_keyword("INTO");
7606 self.write_space();
7607
7608 if ct.temporary {
7610 self.write("#");
7611 }
7612 self.generate_table(&ct.name)?;
7613
7614 self.write_space();
7615 self.write_keyword("FROM");
7616 self.write(" (");
7617 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7619 self.generate_expression(&aliased_query)?;
7620 self.write(") ");
7621 self.write_keyword("AS");
7622 self.write(" temp");
7623 return Ok(());
7624 }
7625 }
7626
7627 if let Some(with_cte) = &ct.with_cte {
7629 self.generate_with(with_cte)?;
7630 self.write_space();
7631 }
7632
7633 for comment in &ct.leading_comments {
7635 self.write_formatted_comment(comment);
7636 self.write(" ");
7637 }
7638 self.write_keyword("CREATE");
7639
7640 if ct.or_replace {
7641 self.write_space();
7642 self.write_keyword("OR REPLACE");
7643 }
7644
7645 if ct.temporary {
7646 self.write_space();
7647 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7649 self.write_keyword("GLOBAL TEMPORARY");
7650 } else {
7651 self.write_keyword("TEMPORARY");
7652 }
7653 }
7654
7655 let is_dictionary = ct
7657 .table_modifier
7658 .as_ref()
7659 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7660 .unwrap_or(false);
7661 if let Some(ref modifier) = ct.table_modifier {
7662 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7664 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7665 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7667 || modifier.eq_ignore_ascii_case("SET")
7668 || modifier.eq_ignore_ascii_case("MULTISET")
7669 || modifier.to_ascii_uppercase().contains("VOLATILE")
7670 || modifier.to_ascii_uppercase().starts_with("SET ")
7671 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
7672 let skip_teradata =
7673 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7674 if !skip_transient && !skip_teradata {
7675 self.write_space();
7676 self.write_keyword(modifier);
7677 }
7678 }
7679
7680 if !is_dictionary {
7681 self.write_space();
7682 self.write_keyword("TABLE");
7683 }
7684
7685 if ct.if_not_exists {
7686 self.write_space();
7687 self.write_keyword("IF NOT EXISTS");
7688 }
7689
7690 self.write_space();
7691 self.generate_table(&ct.name)?;
7692
7693 if let Some(ref uuid) = ct.uuid {
7695 self.write_space();
7696 self.write_keyword("UUID");
7697 self.write(" '");
7698 self.write(uuid);
7699 self.write("'");
7700 }
7701
7702 if let Some(ref on_cluster) = ct.on_cluster {
7704 self.write_space();
7705 self.generate_on_cluster(on_cluster)?;
7706 }
7707
7708 if matches!(
7710 self.config.dialect,
7711 Some(crate::dialects::DialectType::Teradata)
7712 ) && !ct.teradata_post_name_options.is_empty()
7713 {
7714 for opt in &ct.teradata_post_name_options {
7715 self.write(", ");
7716 self.write(opt);
7717 }
7718 }
7719
7720 if ct.copy_grants {
7722 self.write_space();
7723 self.write_keyword("COPY GRANTS");
7724 }
7725
7726 if let Some(ref using_template) = ct.using_template {
7728 self.write_space();
7729 self.write_keyword("USING TEMPLATE");
7730 self.write_space();
7731 self.generate_expression(using_template)?;
7732 return Ok(());
7733 }
7734
7735 if let Some(ref clone_source) = ct.clone_source {
7737 self.write_space();
7738 if ct.is_copy && self.config.supports_table_copy {
7739 self.write_keyword("COPY");
7741 } else if ct.shallow_clone {
7742 self.write_keyword("SHALLOW CLONE");
7743 } else if ct.deep_clone {
7744 self.write_keyword("DEEP CLONE");
7745 } else {
7746 self.write_keyword("CLONE");
7747 }
7748 self.write_space();
7749 self.generate_table(clone_source)?;
7750 if let Some(ref at_clause) = ct.clone_at_clause {
7752 self.write_space();
7753 self.generate_expression(at_clause)?;
7754 }
7755 return Ok(());
7756 }
7757
7758 if let Some(ref partition_of) = ct.partition_of {
7762 self.write_space();
7763
7764 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7766 self.write_keyword("PARTITION OF");
7768 self.write_space();
7769 self.generate_expression(&pop.this)?;
7770
7771 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7773 self.write(" (");
7774 let mut first = true;
7775 for col in &ct.columns {
7776 if !first {
7777 self.write(", ");
7778 }
7779 first = false;
7780 self.generate_column_def(col)?;
7781 }
7782 for constraint in &ct.constraints {
7783 if !first {
7784 self.write(", ");
7785 }
7786 first = false;
7787 self.generate_table_constraint(constraint)?;
7788 }
7789 self.write(")");
7790 }
7791
7792 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7794 self.write_space();
7795 self.write_keyword("FOR VALUES");
7796 self.write_space();
7797 self.generate_expression(&pop.expression)?;
7798 } else {
7799 self.write_space();
7800 self.write_keyword("DEFAULT");
7801 }
7802 } else {
7803 self.generate_expression(partition_of)?;
7805
7806 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7808 self.write(" (");
7809 let mut first = true;
7810 for col in &ct.columns {
7811 if !first {
7812 self.write(", ");
7813 }
7814 first = false;
7815 self.generate_column_def(col)?;
7816 }
7817 for constraint in &ct.constraints {
7818 if !first {
7819 self.write(", ");
7820 }
7821 first = false;
7822 self.generate_table_constraint(constraint)?;
7823 }
7824 self.write(")");
7825 }
7826 }
7827
7828 for prop in &ct.properties {
7830 self.write_space();
7831 self.generate_expression(prop)?;
7832 }
7833
7834 return Ok(());
7835 }
7836
7837 self.sqlite_inline_pk_columns.clear();
7840 if matches!(
7841 self.config.dialect,
7842 Some(crate::dialects::DialectType::SQLite)
7843 ) {
7844 for constraint in &ct.constraints {
7845 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7846 if columns.len() == 1 && name.is_none() {
7848 let pk_col_name = columns[0].name.to_ascii_lowercase();
7849 if ct
7851 .columns
7852 .iter()
7853 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
7854 {
7855 self.sqlite_inline_pk_columns.insert(pk_col_name);
7856 }
7857 }
7858 }
7859 }
7860 }
7861
7862 if !ct.columns.is_empty() {
7864 if self.config.pretty {
7865 self.write(" (");
7867 self.write_newline();
7868 self.indent_level += 1;
7869 for (i, col) in ct.columns.iter().enumerate() {
7870 if i > 0 {
7871 self.write(",");
7872 self.write_newline();
7873 }
7874 self.write_indent();
7875 self.generate_column_def(col)?;
7876 }
7877 for constraint in &ct.constraints {
7879 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7881 if columns.len() == 1
7882 && name.is_none()
7883 && self
7884 .sqlite_inline_pk_columns
7885 .contains(&columns[0].name.to_ascii_lowercase())
7886 {
7887 continue;
7888 }
7889 }
7890 self.write(",");
7891 self.write_newline();
7892 self.write_indent();
7893 self.generate_table_constraint(constraint)?;
7894 }
7895 self.indent_level -= 1;
7896 self.write_newline();
7897 self.write(")");
7898 } else {
7899 self.write(" (");
7900 for (i, col) in ct.columns.iter().enumerate() {
7901 if i > 0 {
7902 self.write(", ");
7903 }
7904 self.generate_column_def(col)?;
7905 }
7906 let mut first_constraint = true;
7908 for constraint in &ct.constraints {
7909 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7911 if columns.len() == 1
7912 && name.is_none()
7913 && self
7914 .sqlite_inline_pk_columns
7915 .contains(&columns[0].name.to_ascii_lowercase())
7916 {
7917 continue;
7918 }
7919 }
7920 if first_constraint {
7921 self.write(", ");
7922 first_constraint = false;
7923 } else {
7924 self.write(", ");
7925 }
7926 self.generate_table_constraint(constraint)?;
7927 }
7928 self.write(")");
7929 }
7930 } else if !ct.constraints.is_empty() {
7931 let has_like_only = ct
7933 .constraints
7934 .iter()
7935 .all(|c| matches!(c, TableConstraint::Like { .. }));
7936 let has_tags_only = ct
7937 .constraints
7938 .iter()
7939 .all(|c| matches!(c, TableConstraint::Tags(_)));
7940 let is_pg_like = matches!(
7944 self.config.dialect,
7945 Some(crate::dialects::DialectType::PostgreSQL)
7946 | Some(crate::dialects::DialectType::CockroachDB)
7947 | Some(crate::dialects::DialectType::Materialize)
7948 | Some(crate::dialects::DialectType::RisingWave)
7949 | Some(crate::dialects::DialectType::Redshift)
7950 | Some(crate::dialects::DialectType::Presto)
7951 | Some(crate::dialects::DialectType::Trino)
7952 | Some(crate::dialects::DialectType::Athena)
7953 );
7954 let use_parens = if has_like_only {
7955 is_pg_like
7956 } else {
7957 !has_tags_only
7958 };
7959 if self.config.pretty && use_parens {
7960 self.write(" (");
7961 self.write_newline();
7962 self.indent_level += 1;
7963 for (i, constraint) in ct.constraints.iter().enumerate() {
7964 if i > 0 {
7965 self.write(",");
7966 self.write_newline();
7967 }
7968 self.write_indent();
7969 self.generate_table_constraint(constraint)?;
7970 }
7971 self.indent_level -= 1;
7972 self.write_newline();
7973 self.write(")");
7974 } else {
7975 if use_parens {
7976 self.write(" (");
7977 } else {
7978 self.write_space();
7979 }
7980 for (i, constraint) in ct.constraints.iter().enumerate() {
7981 if i > 0 {
7982 self.write(", ");
7983 }
7984 self.generate_table_constraint(constraint)?;
7985 }
7986 if use_parens {
7987 self.write(")");
7988 }
7989 }
7990 }
7991
7992 if let Some(ref on_prop) = ct.on_property {
7994 self.write(" ");
7995 self.write_keyword("ON");
7996 self.write(" ");
7997 self.generate_expression(&on_prop.this)?;
7998 }
7999
8000 if !ct.with_partition_columns.is_empty() {
8002 if self.config.pretty {
8003 self.write_newline();
8004 } else {
8005 self.write_space();
8006 }
8007 self.write_keyword("WITH PARTITION COLUMNS");
8008 self.write(" (");
8009 if self.config.pretty {
8010 self.write_newline();
8011 self.indent_level += 1;
8012 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8013 if i > 0 {
8014 self.write(",");
8015 self.write_newline();
8016 }
8017 self.write_indent();
8018 self.generate_column_def(col)?;
8019 }
8020 self.indent_level -= 1;
8021 self.write_newline();
8022 } else {
8023 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8024 if i > 0 {
8025 self.write(", ");
8026 }
8027 self.generate_column_def(col)?;
8028 }
8029 }
8030 self.write(")");
8031 }
8032
8033 if let Some(ref conn) = ct.with_connection {
8035 if self.config.pretty {
8036 self.write_newline();
8037 } else {
8038 self.write_space();
8039 }
8040 self.write_keyword("WITH CONNECTION");
8041 self.write_space();
8042 self.generate_table(conn)?;
8043 }
8044
8045 if !is_clickhouse {
8048 for prop in &ct.properties {
8049 if let Expression::SchemaCommentProperty(_) = prop {
8050 if self.config.pretty {
8051 self.write_newline();
8052 } else {
8053 self.write_space();
8054 }
8055 self.generate_expression(prop)?;
8056 }
8057 }
8058 }
8059
8060 if !ct.with_properties.is_empty() {
8062 let is_snowflake_special_table = matches!(
8064 self.config.dialect,
8065 Some(crate::dialects::DialectType::Snowflake)
8066 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8067 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8068 if is_snowflake_special_table {
8069 for (key, value) in &ct.with_properties {
8070 self.write_space();
8071 self.write(key);
8072 self.write("=");
8073 self.write(value);
8074 }
8075 } else if self.config.pretty {
8076 self.write_newline();
8077 self.write_keyword("WITH");
8078 self.write(" (");
8079 self.write_newline();
8080 self.indent_level += 1;
8081 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8082 if i > 0 {
8083 self.write(",");
8084 self.write_newline();
8085 }
8086 self.write_indent();
8087 self.write(key);
8088 self.write("=");
8089 self.write(value);
8090 }
8091 self.indent_level -= 1;
8092 self.write_newline();
8093 self.write(")");
8094 } else {
8095 self.write_space();
8096 self.write_keyword("WITH");
8097 self.write(" (");
8098 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8099 if i > 0 {
8100 self.write(", ");
8101 }
8102 self.write(key);
8103 self.write("=");
8104 self.write(value);
8105 }
8106 self.write(")");
8107 }
8108 }
8109
8110 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8111 if is_clickhouse && ct.as_select.is_some() {
8112 let mut pre = Vec::new();
8113 let mut post = Vec::new();
8114 for prop in &ct.properties {
8115 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8116 post.push(prop);
8117 } else {
8118 pre.push(prop);
8119 }
8120 }
8121 (pre, post)
8122 } else {
8123 (ct.properties.iter().collect(), Vec::new())
8124 };
8125
8126 for prop in pre_as_properties {
8128 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8130 continue;
8131 }
8132 if self.config.pretty {
8133 self.write_newline();
8134 } else {
8135 self.write_space();
8136 }
8137 if let Expression::Properties(props) = prop {
8141 let is_hive_dialect = matches!(
8142 self.config.dialect,
8143 Some(crate::dialects::DialectType::Hive)
8144 | Some(crate::dialects::DialectType::Spark)
8145 | Some(crate::dialects::DialectType::Databricks)
8146 | Some(crate::dialects::DialectType::Athena)
8147 );
8148 let is_doris_starrocks = matches!(
8149 self.config.dialect,
8150 Some(crate::dialects::DialectType::Doris)
8151 | Some(crate::dialects::DialectType::StarRocks)
8152 );
8153 if is_hive_dialect {
8154 self.generate_tblproperties_clause(&props.expressions)?;
8155 } else if is_doris_starrocks {
8156 self.generate_properties_clause(&props.expressions)?;
8157 } else {
8158 self.generate_options_clause(&props.expressions)?;
8159 }
8160 } else {
8161 self.generate_expression(prop)?;
8162 }
8163 }
8164
8165 for prop in &ct.post_table_properties {
8167 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
8168 self.write(" WITH(");
8169 self.generate_system_versioning_content(svp)?;
8170 self.write(")");
8171 } else if let Expression::Properties(props) = prop {
8172 let is_doris_starrocks = matches!(
8174 self.config.dialect,
8175 Some(crate::dialects::DialectType::Doris)
8176 | Some(crate::dialects::DialectType::StarRocks)
8177 );
8178 self.write_space();
8179 if is_doris_starrocks {
8180 self.generate_properties_clause(&props.expressions)?;
8181 } else {
8182 self.generate_options_clause(&props.expressions)?;
8183 }
8184 } else {
8185 self.write_space();
8186 self.generate_expression(prop)?;
8187 }
8188 }
8189
8190 if let Some(ref rollup) = ct.rollup {
8193 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
8194 self.write_space();
8195 self.generate_rollup_property(rollup)?;
8196 }
8197 }
8198
8199 let is_mysql_compatible = matches!(
8203 self.config.dialect,
8204 Some(DialectType::MySQL)
8205 | Some(DialectType::SingleStore)
8206 | Some(DialectType::Doris)
8207 | Some(DialectType::StarRocks)
8208 | None
8209 );
8210 let is_hive_compatible = matches!(
8211 self.config.dialect,
8212 Some(DialectType::Hive)
8213 | Some(DialectType::Spark)
8214 | Some(DialectType::Databricks)
8215 | Some(DialectType::Athena)
8216 );
8217 let mysql_pretty_options =
8218 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
8219 for (key, value) in &ct.mysql_table_options {
8220 let should_output = if is_mysql_compatible {
8222 true
8223 } else if is_hive_compatible && key == "COMMENT" {
8224 true } else {
8226 false
8227 };
8228 if should_output {
8229 if mysql_pretty_options {
8230 self.write_newline();
8231 self.write_indent();
8232 } else {
8233 self.write_space();
8234 }
8235 self.write_keyword(key);
8236 if key == "COMMENT" && !self.config.schema_comment_with_eq {
8238 self.write_space();
8239 } else {
8240 self.write("=");
8241 }
8242 self.write(value);
8243 }
8244 }
8245
8246 if ct.temporary
8248 && matches!(
8249 self.config.dialect,
8250 Some(DialectType::Spark) | Some(DialectType::Databricks)
8251 )
8252 && ct.as_select.is_none()
8253 {
8254 self.write_space();
8255 self.write_keyword("USING PARQUET");
8256 }
8257
8258 if !ct.inherits.is_empty() {
8260 self.write_space();
8261 self.write_keyword("INHERITS");
8262 self.write(" (");
8263 for (i, parent) in ct.inherits.iter().enumerate() {
8264 if i > 0 {
8265 self.write(", ");
8266 }
8267 self.generate_table(parent)?;
8268 }
8269 self.write(")");
8270 }
8271
8272 if let Some(ref query) = ct.as_select {
8274 self.write_space();
8275 self.write_keyword("AS");
8276 self.write_space();
8277 if ct.as_select_parenthesized {
8278 self.write("(");
8279 }
8280 self.generate_expression(query)?;
8281 if ct.as_select_parenthesized {
8282 self.write(")");
8283 }
8284
8285 if let Some(with_data) = ct.with_data {
8287 self.write_space();
8288 self.write_keyword("WITH");
8289 if !with_data {
8290 self.write_space();
8291 self.write_keyword("NO");
8292 }
8293 self.write_space();
8294 self.write_keyword("DATA");
8295 }
8296
8297 if let Some(with_statistics) = ct.with_statistics {
8299 self.write_space();
8300 self.write_keyword("AND");
8301 if !with_statistics {
8302 self.write_space();
8303 self.write_keyword("NO");
8304 }
8305 self.write_space();
8306 self.write_keyword("STATISTICS");
8307 }
8308
8309 for index in &ct.teradata_indexes {
8311 self.write_space();
8312 match index.kind {
8313 TeradataIndexKind::NoPrimary => {
8314 self.write_keyword("NO PRIMARY INDEX");
8315 }
8316 TeradataIndexKind::Primary => {
8317 self.write_keyword("PRIMARY INDEX");
8318 }
8319 TeradataIndexKind::PrimaryAmp => {
8320 self.write_keyword("PRIMARY AMP INDEX");
8321 }
8322 TeradataIndexKind::Unique => {
8323 self.write_keyword("UNIQUE INDEX");
8324 }
8325 TeradataIndexKind::UniquePrimary => {
8326 self.write_keyword("UNIQUE PRIMARY INDEX");
8327 }
8328 TeradataIndexKind::Secondary => {
8329 self.write_keyword("INDEX");
8330 }
8331 }
8332 if let Some(ref name) = index.name {
8334 self.write_space();
8335 self.write(name);
8336 }
8337 if !index.columns.is_empty() {
8339 self.write(" (");
8340 for (i, col) in index.columns.iter().enumerate() {
8341 if i > 0 {
8342 self.write(", ");
8343 }
8344 self.write(col);
8345 }
8346 self.write(")");
8347 }
8348 }
8349
8350 if let Some(ref on_commit) = ct.on_commit {
8352 self.write_space();
8353 self.write_keyword("ON COMMIT");
8354 self.write_space();
8355 match on_commit {
8356 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8357 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8358 }
8359 }
8360
8361 if !post_as_properties.is_empty() {
8362 for prop in post_as_properties {
8363 self.write_space();
8364 self.generate_expression(prop)?;
8365 }
8366 }
8367
8368 self.athena_hive_context = saved_athena_hive_context;
8370 return Ok(());
8371 }
8372
8373 if let Some(ref on_commit) = ct.on_commit {
8375 self.write_space();
8376 self.write_keyword("ON COMMIT");
8377 self.write_space();
8378 match on_commit {
8379 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8380 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8381 }
8382 }
8383
8384 self.athena_hive_context = saved_athena_hive_context;
8386
8387 Ok(())
8388 }
8389
8390 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8393 self.generate_identifier(&col.name)?;
8395 if !matches!(col.data_type, DataType::Unknown) {
8397 self.write_space();
8398 self.generate_data_type(&col.data_type)?;
8399 }
8400 for constraint in &col.constraints {
8402 if let ColumnConstraint::Path(path_expr) = constraint {
8403 self.write_space();
8404 self.write_keyword("PATH");
8405 self.write_space();
8406 self.generate_expression(path_expr)?;
8407 }
8408 }
8409 Ok(())
8410 }
8411
8412 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8413 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8415 && col
8416 .constraints
8417 .iter()
8418 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8419 let omit_computed_type = !self.config.computed_column_with_type
8421 && col
8422 .constraints
8423 .iter()
8424 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8425
8426 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8429
8430 let has_no_type = col.no_type
8433 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8434 && col.constraints.is_empty());
8435
8436 self.generate_identifier(&col.name)?;
8437
8438 let serial_expansion = if matches!(
8440 self.config.dialect,
8441 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
8442 ) {
8443 if let DataType::Custom { ref name } = col.data_type {
8444 if name.eq_ignore_ascii_case("SERIAL") {
8445 Some("INT")
8446 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
8447 Some("BIGINT")
8448 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
8449 Some("SMALLINT")
8450 } else {
8451 None
8452 }
8453 } else {
8454 None
8455 }
8456 } else {
8457 None
8458 };
8459
8460 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
8461 {
8462 self.write_space();
8463 let saved_nullable_depth = self.clickhouse_nullable_depth;
8466 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
8467 self.clickhouse_nullable_depth = -1;
8468 }
8469 if let Some(int_type) = serial_expansion {
8470 self.write_keyword(int_type);
8472 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8473 let unsigned_type = match &col.data_type {
8475 DataType::Int { .. } => Some("UINTEGER"),
8476 DataType::BigInt { .. } => Some("UBIGINT"),
8477 DataType::SmallInt { .. } => Some("USMALLINT"),
8478 DataType::TinyInt { .. } => Some("UTINYINT"),
8479 _ => None,
8480 };
8481 if let Some(utype) = unsigned_type {
8482 self.write_keyword(utype);
8483 } else {
8484 self.generate_data_type(&col.data_type)?;
8485 }
8486 } else {
8487 self.generate_data_type(&col.data_type)?;
8488 }
8489 self.clickhouse_nullable_depth = saved_nullable_depth;
8490 }
8491
8492 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8495 self.write_space();
8496 self.write_keyword("UNSIGNED");
8497 }
8498 if col.zerofill {
8499 self.write_space();
8500 self.write_keyword("ZEROFILL");
8501 }
8502
8503 if let Some(ref charset) = col.character_set {
8507 self.write_space();
8508 self.write_keyword("CHARACTER SET");
8509 self.write_space();
8510 self.write(charset);
8511 }
8512
8513 if col.uppercase {
8514 self.write_space();
8515 self.write_keyword("UPPERCASE");
8516 }
8517
8518 if let Some(casespecific) = col.casespecific {
8519 self.write_space();
8520 if casespecific {
8521 self.write_keyword("CASESPECIFIC");
8522 } else {
8523 self.write_keyword("NOT CASESPECIFIC");
8524 }
8525 }
8526
8527 if let Some(ref format) = col.format {
8528 self.write_space();
8529 self.write_keyword("FORMAT");
8530 self.write(" '");
8531 self.write(format);
8532 self.write("'");
8533 }
8534
8535 if let Some(ref title) = col.title {
8536 self.write_space();
8537 self.write_keyword("TITLE");
8538 self.write(" '");
8539 self.write(title);
8540 self.write("'");
8541 }
8542
8543 if let Some(length) = col.inline_length {
8544 self.write_space();
8545 self.write_keyword("INLINE LENGTH");
8546 self.write(" ");
8547 self.write(&length.to_string());
8548 }
8549
8550 if let Some(ref compress) = col.compress {
8551 self.write_space();
8552 self.write_keyword("COMPRESS");
8553 if !compress.is_empty() {
8554 if compress.len() == 1 {
8556 if let Expression::Literal(lit) = &compress[0] {
8557 if let Literal::String(_) = lit.as_ref() {
8558 self.write_space();
8559 self.generate_expression(&compress[0])?;
8560 }
8561 } else {
8562 self.write(" (");
8563 self.generate_expression(&compress[0])?;
8564 self.write(")");
8565 }
8566 } else {
8567 self.write(" (");
8568 for (i, val) in compress.iter().enumerate() {
8569 if i > 0 {
8570 self.write(", ");
8571 }
8572 self.generate_expression(val)?;
8573 }
8574 self.write(")");
8575 }
8576 }
8577 }
8578
8579 if !col.constraint_order.is_empty() {
8582 let mut references_idx = 0;
8585 let mut check_idx = 0;
8586 let mut generated_idx = 0;
8587 let mut collate_idx = 0;
8588 let mut comment_idx = 0;
8589 let defer_not_null_after_identity = false;
8592 let mut pending_not_null_after_identity = false;
8593
8594 for constraint_type in &col.constraint_order {
8595 match constraint_type {
8596 ConstraintType::PrimaryKey => {
8597 if col.primary_key
8599 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8600 {
8601 if let Some(ref cname) = col.primary_key_constraint_name {
8602 self.write_space();
8603 self.write_keyword("CONSTRAINT");
8604 self.write_space();
8605 self.write(cname);
8606 }
8607 self.write_space();
8608 self.write_keyword("PRIMARY KEY");
8609 if let Some(ref order) = col.primary_key_order {
8610 self.write_space();
8611 match order {
8612 SortOrder::Asc => self.write_keyword("ASC"),
8613 SortOrder::Desc => self.write_keyword("DESC"),
8614 }
8615 }
8616 }
8617 }
8618 ConstraintType::Unique => {
8619 if col.unique {
8620 if let Some(ref cname) = col.unique_constraint_name {
8621 self.write_space();
8622 self.write_keyword("CONSTRAINT");
8623 self.write_space();
8624 self.write(cname);
8625 }
8626 self.write_space();
8627 self.write_keyword("UNIQUE");
8628 if col.unique_nulls_not_distinct {
8630 self.write(" NULLS NOT DISTINCT");
8631 }
8632 }
8633 }
8634 ConstraintType::NotNull => {
8635 if col.nullable == Some(false) {
8636 if defer_not_null_after_identity {
8637 pending_not_null_after_identity = true;
8638 continue;
8639 }
8640 if let Some(ref cname) = col.not_null_constraint_name {
8641 self.write_space();
8642 self.write_keyword("CONSTRAINT");
8643 self.write_space();
8644 self.write(cname);
8645 }
8646 self.write_space();
8647 self.write_keyword("NOT NULL");
8648 }
8649 }
8650 ConstraintType::Null => {
8651 if col.nullable == Some(true) {
8652 self.write_space();
8653 self.write_keyword("NULL");
8654 }
8655 }
8656 ConstraintType::Default => {
8657 if let Some(ref default) = col.default {
8658 self.write_space();
8659 self.write_keyword("DEFAULT");
8660 self.write_space();
8661 self.generate_expression(default)?;
8662 }
8663 }
8664 ConstraintType::AutoIncrement => {
8665 if col.auto_increment {
8666 if matches!(
8668 self.config.dialect,
8669 Some(crate::dialects::DialectType::DuckDB)
8670 ) {
8671 } else if matches!(
8673 self.config.dialect,
8674 Some(crate::dialects::DialectType::Materialize)
8675 ) {
8676 if !matches!(col.nullable, Some(false)) {
8678 self.write_space();
8679 self.write_keyword("NOT NULL");
8680 }
8681 } else if matches!(
8682 self.config.dialect,
8683 Some(crate::dialects::DialectType::PostgreSQL)
8684 ) {
8685 self.write_space();
8687 self.generate_auto_increment_keyword(col)?;
8688 } else {
8689 self.write_space();
8690 self.generate_auto_increment_keyword(col)?;
8691 if pending_not_null_after_identity {
8692 self.write_space();
8693 self.write_keyword("NOT NULL");
8694 pending_not_null_after_identity = false;
8695 }
8696 }
8697 } }
8699 ConstraintType::References => {
8700 while references_idx < col.constraints.len() {
8702 if let ColumnConstraint::References(fk_ref) =
8703 &col.constraints[references_idx]
8704 {
8705 if let Some(ref name) = fk_ref.constraint_name {
8707 self.write_space();
8708 self.write_keyword("CONSTRAINT");
8709 self.write_space();
8710 self.write(name);
8711 }
8712 self.write_space();
8713 if fk_ref.has_foreign_key_keywords {
8714 self.write_keyword("FOREIGN KEY");
8715 self.write_space();
8716 }
8717 self.write_keyword("REFERENCES");
8718 self.write_space();
8719 self.generate_table(&fk_ref.table)?;
8720 if !fk_ref.columns.is_empty() {
8721 self.write(" (");
8722 for (i, c) in fk_ref.columns.iter().enumerate() {
8723 if i > 0 {
8724 self.write(", ");
8725 }
8726 self.generate_identifier(c)?;
8727 }
8728 self.write(")");
8729 }
8730 self.generate_referential_actions(fk_ref)?;
8731 references_idx += 1;
8732 break;
8733 }
8734 references_idx += 1;
8735 }
8736 }
8737 ConstraintType::Check => {
8738 while check_idx < col.constraints.len() {
8740 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8741 if check_idx == 0 {
8743 if let Some(ref cname) = col.check_constraint_name {
8744 self.write_space();
8745 self.write_keyword("CONSTRAINT");
8746 self.write_space();
8747 self.write(cname);
8748 }
8749 }
8750 self.write_space();
8751 self.write_keyword("CHECK");
8752 self.write(" (");
8753 self.generate_expression(expr)?;
8754 self.write(")");
8755 check_idx += 1;
8756 break;
8757 }
8758 check_idx += 1;
8759 }
8760 }
8761 ConstraintType::GeneratedAsIdentity => {
8762 while generated_idx < col.constraints.len() {
8764 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8765 &col.constraints[generated_idx]
8766 {
8767 self.write_space();
8768 if matches!(
8770 self.config.dialect,
8771 Some(crate::dialects::DialectType::Redshift)
8772 ) {
8773 self.write_keyword("IDENTITY");
8774 self.write("(");
8775 if let Some(ref start) = gen.start {
8776 self.generate_expression(start)?;
8777 } else {
8778 self.write("0");
8779 }
8780 self.write(", ");
8781 if let Some(ref incr) = gen.increment {
8782 self.generate_expression(incr)?;
8783 } else {
8784 self.write("1");
8785 }
8786 self.write(")");
8787 } else {
8788 self.write_keyword("GENERATED");
8789 if gen.always {
8790 self.write_space();
8791 self.write_keyword("ALWAYS");
8792 } else {
8793 self.write_space();
8794 self.write_keyword("BY DEFAULT");
8795 if gen.on_null {
8796 self.write_space();
8797 self.write_keyword("ON NULL");
8798 }
8799 }
8800 self.write_space();
8801 self.write_keyword("AS IDENTITY");
8802
8803 let has_options = gen.start.is_some()
8804 || gen.increment.is_some()
8805 || gen.minvalue.is_some()
8806 || gen.maxvalue.is_some()
8807 || gen.cycle.is_some();
8808 if has_options {
8809 self.write(" (");
8810 let mut first = true;
8811 if let Some(ref start) = gen.start {
8812 if !first {
8813 self.write(" ");
8814 }
8815 first = false;
8816 self.write_keyword("START WITH");
8817 self.write_space();
8818 self.generate_expression(start)?;
8819 }
8820 if let Some(ref incr) = gen.increment {
8821 if !first {
8822 self.write(" ");
8823 }
8824 first = false;
8825 self.write_keyword("INCREMENT BY");
8826 self.write_space();
8827 self.generate_expression(incr)?;
8828 }
8829 if let Some(ref minv) = gen.minvalue {
8830 if !first {
8831 self.write(" ");
8832 }
8833 first = false;
8834 self.write_keyword("MINVALUE");
8835 self.write_space();
8836 self.generate_expression(minv)?;
8837 }
8838 if let Some(ref maxv) = gen.maxvalue {
8839 if !first {
8840 self.write(" ");
8841 }
8842 first = false;
8843 self.write_keyword("MAXVALUE");
8844 self.write_space();
8845 self.generate_expression(maxv)?;
8846 }
8847 if let Some(cycle) = gen.cycle {
8848 if !first {
8849 self.write(" ");
8850 }
8851 if cycle {
8852 self.write_keyword("CYCLE");
8853 } else {
8854 self.write_keyword("NO CYCLE");
8855 }
8856 }
8857 self.write(")");
8858 }
8859 }
8860 generated_idx += 1;
8861 break;
8862 }
8863 generated_idx += 1;
8864 }
8865 }
8866 ConstraintType::Collate => {
8867 while collate_idx < col.constraints.len() {
8869 if let ColumnConstraint::Collate(collation) =
8870 &col.constraints[collate_idx]
8871 {
8872 self.write_space();
8873 self.write_keyword("COLLATE");
8874 self.write_space();
8875 self.generate_identifier(collation)?;
8876 collate_idx += 1;
8877 break;
8878 }
8879 collate_idx += 1;
8880 }
8881 }
8882 ConstraintType::Comment => {
8883 while comment_idx < col.constraints.len() {
8885 if let ColumnConstraint::Comment(comment) =
8886 &col.constraints[comment_idx]
8887 {
8888 self.write_space();
8889 self.write_keyword("COMMENT");
8890 self.write_space();
8891 self.generate_string_literal(comment)?;
8892 comment_idx += 1;
8893 break;
8894 }
8895 comment_idx += 1;
8896 }
8897 }
8898 ConstraintType::Tags => {
8899 for constraint in &col.constraints {
8901 if let ColumnConstraint::Tags(tags) = constraint {
8902 self.write_space();
8903 self.write_keyword("TAG");
8904 self.write(" (");
8905 for (i, expr) in tags.expressions.iter().enumerate() {
8906 if i > 0 {
8907 self.write(", ");
8908 }
8909 self.generate_expression(expr)?;
8910 }
8911 self.write(")");
8912 break;
8913 }
8914 }
8915 }
8916 ConstraintType::ComputedColumn => {
8917 for constraint in &col.constraints {
8919 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8920 self.write_space();
8921 self.generate_computed_column_inline(cc)?;
8922 break;
8923 }
8924 }
8925 }
8926 ConstraintType::GeneratedAsRow => {
8927 for constraint in &col.constraints {
8929 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8930 self.write_space();
8931 self.generate_generated_as_row_inline(gar)?;
8932 break;
8933 }
8934 }
8935 }
8936 ConstraintType::OnUpdate => {
8937 if let Some(ref expr) = col.on_update {
8938 self.write_space();
8939 self.write_keyword("ON UPDATE");
8940 self.write_space();
8941 self.generate_expression(expr)?;
8942 }
8943 }
8944 ConstraintType::Encode => {
8945 if let Some(ref encoding) = col.encoding {
8946 self.write_space();
8947 self.write_keyword("ENCODE");
8948 self.write_space();
8949 self.write(encoding);
8950 }
8951 }
8952 ConstraintType::Path => {
8953 for constraint in &col.constraints {
8955 if let ColumnConstraint::Path(path_expr) = constraint {
8956 self.write_space();
8957 self.write_keyword("PATH");
8958 self.write_space();
8959 self.generate_expression(path_expr)?;
8960 break;
8961 }
8962 }
8963 }
8964 }
8965 }
8966 if pending_not_null_after_identity {
8967 self.write_space();
8968 self.write_keyword("NOT NULL");
8969 }
8970 } else {
8971 if col.primary_key {
8973 self.write_space();
8974 self.write_keyword("PRIMARY KEY");
8975 if let Some(ref order) = col.primary_key_order {
8976 self.write_space();
8977 match order {
8978 SortOrder::Asc => self.write_keyword("ASC"),
8979 SortOrder::Desc => self.write_keyword("DESC"),
8980 }
8981 }
8982 }
8983
8984 if col.unique {
8985 self.write_space();
8986 self.write_keyword("UNIQUE");
8987 if col.unique_nulls_not_distinct {
8989 self.write(" NULLS NOT DISTINCT");
8990 }
8991 }
8992
8993 match col.nullable {
8994 Some(false) => {
8995 self.write_space();
8996 self.write_keyword("NOT NULL");
8997 }
8998 Some(true) => {
8999 self.write_space();
9000 self.write_keyword("NULL");
9001 }
9002 None => {}
9003 }
9004
9005 if let Some(ref default) = col.default {
9006 self.write_space();
9007 self.write_keyword("DEFAULT");
9008 self.write_space();
9009 self.generate_expression(default)?;
9010 }
9011
9012 if col.auto_increment {
9013 self.write_space();
9014 self.generate_auto_increment_keyword(col)?;
9015 }
9016
9017 for constraint in &col.constraints {
9019 match constraint {
9020 ColumnConstraint::References(fk_ref) => {
9021 self.write_space();
9022 if fk_ref.has_foreign_key_keywords {
9023 self.write_keyword("FOREIGN KEY");
9024 self.write_space();
9025 }
9026 self.write_keyword("REFERENCES");
9027 self.write_space();
9028 self.generate_table(&fk_ref.table)?;
9029 if !fk_ref.columns.is_empty() {
9030 self.write(" (");
9031 for (i, c) in fk_ref.columns.iter().enumerate() {
9032 if i > 0 {
9033 self.write(", ");
9034 }
9035 self.generate_identifier(c)?;
9036 }
9037 self.write(")");
9038 }
9039 self.generate_referential_actions(fk_ref)?;
9040 }
9041 ColumnConstraint::Check(expr) => {
9042 self.write_space();
9043 self.write_keyword("CHECK");
9044 self.write(" (");
9045 self.generate_expression(expr)?;
9046 self.write(")");
9047 }
9048 ColumnConstraint::GeneratedAsIdentity(gen) => {
9049 self.write_space();
9050 if matches!(
9052 self.config.dialect,
9053 Some(crate::dialects::DialectType::Redshift)
9054 ) {
9055 self.write_keyword("IDENTITY");
9056 self.write("(");
9057 if let Some(ref start) = gen.start {
9058 self.generate_expression(start)?;
9059 } else {
9060 self.write("0");
9061 }
9062 self.write(", ");
9063 if let Some(ref incr) = gen.increment {
9064 self.generate_expression(incr)?;
9065 } else {
9066 self.write("1");
9067 }
9068 self.write(")");
9069 } else {
9070 self.write_keyword("GENERATED");
9071 if gen.always {
9072 self.write_space();
9073 self.write_keyword("ALWAYS");
9074 } else {
9075 self.write_space();
9076 self.write_keyword("BY DEFAULT");
9077 if gen.on_null {
9078 self.write_space();
9079 self.write_keyword("ON NULL");
9080 }
9081 }
9082 self.write_space();
9083 self.write_keyword("AS IDENTITY");
9084
9085 let has_options = gen.start.is_some()
9086 || gen.increment.is_some()
9087 || gen.minvalue.is_some()
9088 || gen.maxvalue.is_some()
9089 || gen.cycle.is_some();
9090 if has_options {
9091 self.write(" (");
9092 let mut first = true;
9093 if let Some(ref start) = gen.start {
9094 if !first {
9095 self.write(" ");
9096 }
9097 first = false;
9098 self.write_keyword("START WITH");
9099 self.write_space();
9100 self.generate_expression(start)?;
9101 }
9102 if let Some(ref incr) = gen.increment {
9103 if !first {
9104 self.write(" ");
9105 }
9106 first = false;
9107 self.write_keyword("INCREMENT BY");
9108 self.write_space();
9109 self.generate_expression(incr)?;
9110 }
9111 if let Some(ref minv) = gen.minvalue {
9112 if !first {
9113 self.write(" ");
9114 }
9115 first = false;
9116 self.write_keyword("MINVALUE");
9117 self.write_space();
9118 self.generate_expression(minv)?;
9119 }
9120 if let Some(ref maxv) = gen.maxvalue {
9121 if !first {
9122 self.write(" ");
9123 }
9124 first = false;
9125 self.write_keyword("MAXVALUE");
9126 self.write_space();
9127 self.generate_expression(maxv)?;
9128 }
9129 if let Some(cycle) = gen.cycle {
9130 if !first {
9131 self.write(" ");
9132 }
9133 if cycle {
9134 self.write_keyword("CYCLE");
9135 } else {
9136 self.write_keyword("NO CYCLE");
9137 }
9138 }
9139 self.write(")");
9140 }
9141 }
9142 }
9143 ColumnConstraint::Collate(collation) => {
9144 self.write_space();
9145 self.write_keyword("COLLATE");
9146 self.write_space();
9147 self.generate_identifier(collation)?;
9148 }
9149 ColumnConstraint::Comment(comment) => {
9150 self.write_space();
9151 self.write_keyword("COMMENT");
9152 self.write_space();
9153 self.generate_string_literal(comment)?;
9154 }
9155 ColumnConstraint::Path(path_expr) => {
9156 self.write_space();
9157 self.write_keyword("PATH");
9158 self.write_space();
9159 self.generate_expression(path_expr)?;
9160 }
9161 _ => {} }
9163 }
9164
9165 if let Some(ref encoding) = col.encoding {
9167 self.write_space();
9168 self.write_keyword("ENCODE");
9169 self.write_space();
9170 self.write(encoding);
9171 }
9172 }
9173
9174 if let Some(ref codec) = col.codec {
9176 self.write_space();
9177 self.write_keyword("CODEC");
9178 self.write("(");
9179 self.write(codec);
9180 self.write(")");
9181 }
9182
9183 if let Some(visible) = col.visible {
9184 self.write_space();
9185 if visible {
9186 self.write_keyword("VISIBLE");
9187 } else {
9188 self.write_keyword("INVISIBLE");
9189 }
9190 }
9191
9192 if let Some(ref ephemeral) = col.ephemeral {
9194 self.write_space();
9195 self.write_keyword("EPHEMERAL");
9196 if let Some(ref expr) = ephemeral {
9197 self.write_space();
9198 self.generate_expression(expr)?;
9199 }
9200 }
9201
9202 if let Some(ref mat_expr) = col.materialized_expr {
9204 self.write_space();
9205 self.write_keyword("MATERIALIZED");
9206 self.write_space();
9207 self.generate_expression(mat_expr)?;
9208 }
9209
9210 if let Some(ref alias_expr) = col.alias_expr {
9212 self.write_space();
9213 self.write_keyword("ALIAS");
9214 self.write_space();
9215 self.generate_expression(alias_expr)?;
9216 }
9217
9218 if let Some(ref ttl_expr) = col.ttl_expr {
9220 self.write_space();
9221 self.write_keyword("TTL");
9222 self.write_space();
9223 self.generate_expression(ttl_expr)?;
9224 }
9225
9226 if col.not_for_replication
9228 && matches!(
9229 self.config.dialect,
9230 Some(crate::dialects::DialectType::TSQL)
9231 | Some(crate::dialects::DialectType::Fabric)
9232 )
9233 {
9234 self.write_space();
9235 self.write_keyword("NOT FOR REPLICATION");
9236 }
9237
9238 if !col.options.is_empty() {
9240 self.write_space();
9241 self.generate_options_clause(&col.options)?;
9242 }
9243
9244 if !col.primary_key
9247 && self
9248 .sqlite_inline_pk_columns
9249 .contains(&col.name.name.to_ascii_lowercase())
9250 {
9251 self.write_space();
9252 self.write_keyword("PRIMARY KEY");
9253 }
9254
9255 if serial_expansion.is_some() {
9258 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
9259 self.write_space();
9260 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
9261 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
9262 self.write_space();
9263 self.write_keyword("NOT NULL");
9264 }
9265 }
9266
9267 Ok(())
9268 }
9269
9270 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
9271 match constraint {
9272 TableConstraint::PrimaryKey {
9273 name,
9274 columns,
9275 include_columns,
9276 modifiers,
9277 has_constraint_keyword,
9278 } => {
9279 if let Some(ref n) = name {
9280 if *has_constraint_keyword {
9281 self.write_keyword("CONSTRAINT");
9282 self.write_space();
9283 self.generate_identifier(n)?;
9284 self.write_space();
9285 }
9286 }
9287 self.write_keyword("PRIMARY KEY");
9288 if let Some(ref clustered) = modifiers.clustered {
9290 self.write_space();
9291 self.write_keyword(clustered);
9292 }
9293 if let Some(ref n) = name {
9295 if !*has_constraint_keyword {
9296 self.write_space();
9297 self.generate_identifier(n)?;
9298 }
9299 }
9300 self.write(" (");
9301 for (i, col) in columns.iter().enumerate() {
9302 if i > 0 {
9303 self.write(", ");
9304 }
9305 self.generate_identifier(col)?;
9306 }
9307 self.write(")");
9308 if !include_columns.is_empty() {
9309 self.write_space();
9310 self.write_keyword("INCLUDE");
9311 self.write(" (");
9312 for (i, col) in include_columns.iter().enumerate() {
9313 if i > 0 {
9314 self.write(", ");
9315 }
9316 self.generate_identifier(col)?;
9317 }
9318 self.write(")");
9319 }
9320 self.generate_constraint_modifiers(modifiers);
9321 }
9322 TableConstraint::Unique {
9323 name,
9324 columns,
9325 columns_parenthesized,
9326 modifiers,
9327 has_constraint_keyword,
9328 nulls_not_distinct,
9329 } => {
9330 if let Some(ref n) = name {
9331 if *has_constraint_keyword {
9332 self.write_keyword("CONSTRAINT");
9333 self.write_space();
9334 self.generate_identifier(n)?;
9335 self.write_space();
9336 }
9337 }
9338 self.write_keyword("UNIQUE");
9339 if let Some(ref clustered) = modifiers.clustered {
9341 self.write_space();
9342 self.write_keyword(clustered);
9343 }
9344 if *nulls_not_distinct {
9346 self.write(" NULLS NOT DISTINCT");
9347 }
9348 if let Some(ref n) = name {
9350 if !*has_constraint_keyword {
9351 self.write_space();
9352 self.generate_identifier(n)?;
9353 }
9354 }
9355 if *columns_parenthesized {
9356 self.write(" (");
9357 for (i, col) in columns.iter().enumerate() {
9358 if i > 0 {
9359 self.write(", ");
9360 }
9361 self.generate_identifier(col)?;
9362 }
9363 self.write(")");
9364 } else {
9365 for col in columns.iter() {
9367 self.write_space();
9368 self.generate_identifier(col)?;
9369 }
9370 }
9371 self.generate_constraint_modifiers(modifiers);
9372 }
9373 TableConstraint::ForeignKey {
9374 name,
9375 columns,
9376 references,
9377 on_delete,
9378 on_update,
9379 modifiers,
9380 } => {
9381 if let Some(ref n) = name {
9382 self.write_keyword("CONSTRAINT");
9383 self.write_space();
9384 self.generate_identifier(n)?;
9385 self.write_space();
9386 }
9387 self.write_keyword("FOREIGN KEY");
9388 self.write(" (");
9389 for (i, col) in columns.iter().enumerate() {
9390 if i > 0 {
9391 self.write(", ");
9392 }
9393 self.generate_identifier(col)?;
9394 }
9395 self.write(")");
9396 if let Some(ref refs) = references {
9397 self.write(" ");
9398 self.write_keyword("REFERENCES");
9399 self.write_space();
9400 self.generate_table(&refs.table)?;
9401 if !refs.columns.is_empty() {
9402 if self.config.pretty {
9403 self.write(" (");
9404 self.write_newline();
9405 self.indent_level += 1;
9406 for (i, col) in refs.columns.iter().enumerate() {
9407 if i > 0 {
9408 self.write(",");
9409 self.write_newline();
9410 }
9411 self.write_indent();
9412 self.generate_identifier(col)?;
9413 }
9414 self.indent_level -= 1;
9415 self.write_newline();
9416 self.write_indent();
9417 self.write(")");
9418 } else {
9419 self.write(" (");
9420 for (i, col) in refs.columns.iter().enumerate() {
9421 if i > 0 {
9422 self.write(", ");
9423 }
9424 self.generate_identifier(col)?;
9425 }
9426 self.write(")");
9427 }
9428 }
9429 self.generate_referential_actions(refs)?;
9430 } else {
9431 if let Some(ref action) = on_delete {
9433 self.write_space();
9434 self.write_keyword("ON DELETE");
9435 self.write_space();
9436 self.generate_referential_action(action);
9437 }
9438 if let Some(ref action) = on_update {
9439 self.write_space();
9440 self.write_keyword("ON UPDATE");
9441 self.write_space();
9442 self.generate_referential_action(action);
9443 }
9444 }
9445 self.generate_constraint_modifiers(modifiers);
9446 }
9447 TableConstraint::Check {
9448 name,
9449 expression,
9450 modifiers,
9451 } => {
9452 if let Some(ref n) = name {
9453 self.write_keyword("CONSTRAINT");
9454 self.write_space();
9455 self.generate_identifier(n)?;
9456 self.write_space();
9457 }
9458 self.write_keyword("CHECK");
9459 self.write(" (");
9460 self.generate_expression(expression)?;
9461 self.write(")");
9462 self.generate_constraint_modifiers(modifiers);
9463 }
9464 TableConstraint::Assume { name, expression } => {
9465 if let Some(ref n) = name {
9466 self.write_keyword("CONSTRAINT");
9467 self.write_space();
9468 self.generate_identifier(n)?;
9469 self.write_space();
9470 }
9471 self.write_keyword("ASSUME");
9472 self.write(" (");
9473 self.generate_expression(expression)?;
9474 self.write(")");
9475 }
9476 TableConstraint::Default {
9477 name,
9478 expression,
9479 column,
9480 } => {
9481 if let Some(ref n) = name {
9482 self.write_keyword("CONSTRAINT");
9483 self.write_space();
9484 self.generate_identifier(n)?;
9485 self.write_space();
9486 }
9487 self.write_keyword("DEFAULT");
9488 self.write_space();
9489 self.generate_expression(expression)?;
9490 self.write_space();
9491 self.write_keyword("FOR");
9492 self.write_space();
9493 self.generate_identifier(column)?;
9494 }
9495 TableConstraint::Index {
9496 name,
9497 columns,
9498 kind,
9499 modifiers,
9500 use_key_keyword,
9501 expression,
9502 index_type,
9503 granularity,
9504 } => {
9505 if expression.is_some() {
9507 self.write_keyword("INDEX");
9508 if let Some(ref n) = name {
9509 self.write_space();
9510 self.generate_identifier(n)?;
9511 }
9512 if let Some(ref expr) = expression {
9513 self.write_space();
9514 self.generate_expression(expr)?;
9515 }
9516 if let Some(ref idx_type) = index_type {
9517 self.write_space();
9518 self.write_keyword("TYPE");
9519 self.write_space();
9520 self.generate_expression(idx_type)?;
9521 }
9522 if let Some(ref gran) = granularity {
9523 self.write_space();
9524 self.write_keyword("GRANULARITY");
9525 self.write_space();
9526 self.generate_expression(gran)?;
9527 }
9528 } else {
9529 use crate::dialects::DialectType;
9533 let index_keyword = if *use_key_keyword
9534 && !matches!(self.config.dialect, Some(DialectType::MySQL))
9535 {
9536 "KEY"
9537 } else {
9538 "INDEX"
9539 };
9540
9541 if let Some(ref k) = kind {
9543 self.write_keyword(k);
9544 if k != "UNIQUE" {
9546 self.write_space();
9547 self.write_keyword(index_keyword);
9548 }
9549 } else {
9550 self.write_keyword(index_keyword);
9551 }
9552
9553 if modifiers.using_before_columns && name.is_none() {
9555 if let Some(ref using) = modifiers.using {
9556 self.write_space();
9557 self.write_keyword("USING");
9558 self.write_space();
9559 self.write_keyword(using);
9560 }
9561 }
9562
9563 if let Some(ref n) = name {
9565 self.write_space();
9566 self.generate_identifier(n)?;
9567 }
9568
9569 if modifiers.using_before_columns && name.is_some() {
9571 if let Some(ref using) = modifiers.using {
9572 self.write_space();
9573 self.write_keyword("USING");
9574 self.write_space();
9575 self.write_keyword(using);
9576 }
9577 }
9578
9579 self.write(" (");
9581 for (i, col) in columns.iter().enumerate() {
9582 if i > 0 {
9583 self.write(", ");
9584 }
9585 self.generate_identifier(col)?;
9586 }
9587 self.write(")");
9588
9589 if !modifiers.using_before_columns {
9591 if let Some(ref using) = modifiers.using {
9592 self.write_space();
9593 self.write_keyword("USING");
9594 self.write_space();
9595 self.write_keyword(using);
9596 }
9597 }
9598
9599 self.generate_constraint_modifiers_without_using(modifiers);
9601 }
9602 }
9603 TableConstraint::Projection { name, expression } => {
9604 self.write_keyword("PROJECTION");
9606 self.write_space();
9607 self.generate_identifier(name)?;
9608 self.write(" (");
9609 self.generate_expression(expression)?;
9610 self.write(")");
9611 }
9612 TableConstraint::Like { source, options } => {
9613 self.write_keyword("LIKE");
9614 self.write_space();
9615 self.generate_table(source)?;
9616 for (action, prop) in options {
9617 self.write_space();
9618 match action {
9619 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9620 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9621 }
9622 self.write_space();
9623 self.write_keyword(prop);
9624 }
9625 }
9626 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9627 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9628 self.write(" (");
9629 self.generate_identifier(start_col)?;
9630 self.write(", ");
9631 self.generate_identifier(end_col)?;
9632 self.write(")");
9633 }
9634 TableConstraint::Exclude {
9635 name,
9636 using,
9637 elements,
9638 include_columns,
9639 where_clause,
9640 with_params,
9641 using_index_tablespace,
9642 modifiers: _,
9643 } => {
9644 if let Some(ref n) = name {
9645 self.write_keyword("CONSTRAINT");
9646 self.write_space();
9647 self.generate_identifier(n)?;
9648 self.write_space();
9649 }
9650 self.write_keyword("EXCLUDE");
9651 if let Some(ref method) = using {
9652 self.write_space();
9653 self.write_keyword("USING");
9654 self.write_space();
9655 self.write(method);
9656 self.write("(");
9657 } else {
9658 self.write(" (");
9659 }
9660 for (i, elem) in elements.iter().enumerate() {
9661 if i > 0 {
9662 self.write(", ");
9663 }
9664 self.write(&elem.expression);
9665 self.write_space();
9666 self.write_keyword("WITH");
9667 self.write_space();
9668 self.write(&elem.operator);
9669 }
9670 self.write(")");
9671 if !include_columns.is_empty() {
9672 self.write_space();
9673 self.write_keyword("INCLUDE");
9674 self.write(" (");
9675 for (i, col) in include_columns.iter().enumerate() {
9676 if i > 0 {
9677 self.write(", ");
9678 }
9679 self.generate_identifier(col)?;
9680 }
9681 self.write(")");
9682 }
9683 if !with_params.is_empty() {
9684 self.write_space();
9685 self.write_keyword("WITH");
9686 self.write(" (");
9687 for (i, (key, val)) in with_params.iter().enumerate() {
9688 if i > 0 {
9689 self.write(", ");
9690 }
9691 self.write(key);
9692 self.write("=");
9693 self.write(val);
9694 }
9695 self.write(")");
9696 }
9697 if let Some(ref tablespace) = using_index_tablespace {
9698 self.write_space();
9699 self.write_keyword("USING INDEX TABLESPACE");
9700 self.write_space();
9701 self.write(tablespace);
9702 }
9703 if let Some(ref where_expr) = where_clause {
9704 self.write_space();
9705 self.write_keyword("WHERE");
9706 self.write(" (");
9707 self.generate_expression(where_expr)?;
9708 self.write(")");
9709 }
9710 }
9711 TableConstraint::Tags(tags) => {
9712 self.write_keyword("TAG");
9713 self.write(" (");
9714 for (i, expr) in tags.expressions.iter().enumerate() {
9715 if i > 0 {
9716 self.write(", ");
9717 }
9718 self.generate_expression(expr)?;
9719 }
9720 self.write(")");
9721 }
9722 TableConstraint::InitiallyDeferred { deferred } => {
9723 self.write_keyword("INITIALLY");
9724 self.write_space();
9725 if *deferred {
9726 self.write_keyword("DEFERRED");
9727 } else {
9728 self.write_keyword("IMMEDIATE");
9729 }
9730 }
9731 }
9732 Ok(())
9733 }
9734
9735 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9736 if let Some(using) = &modifiers.using {
9738 self.write_space();
9739 self.write_keyword("USING");
9740 self.write_space();
9741 self.write_keyword(using);
9742 }
9743 if let Some(enforced) = modifiers.enforced {
9745 self.write_space();
9746 if enforced {
9747 self.write_keyword("ENFORCED");
9748 } else {
9749 self.write_keyword("NOT ENFORCED");
9750 }
9751 }
9752 if let Some(deferrable) = modifiers.deferrable {
9754 self.write_space();
9755 if deferrable {
9756 self.write_keyword("DEFERRABLE");
9757 } else {
9758 self.write_keyword("NOT DEFERRABLE");
9759 }
9760 }
9761 if let Some(initially_deferred) = modifiers.initially_deferred {
9763 self.write_space();
9764 if initially_deferred {
9765 self.write_keyword("INITIALLY DEFERRED");
9766 } else {
9767 self.write_keyword("INITIALLY IMMEDIATE");
9768 }
9769 }
9770 if modifiers.norely {
9772 self.write_space();
9773 self.write_keyword("NORELY");
9774 }
9775 if modifiers.rely {
9777 self.write_space();
9778 self.write_keyword("RELY");
9779 }
9780 if modifiers.not_valid {
9782 self.write_space();
9783 self.write_keyword("NOT VALID");
9784 }
9785 if let Some(on_conflict) = &modifiers.on_conflict {
9787 self.write_space();
9788 self.write_keyword("ON CONFLICT");
9789 self.write_space();
9790 self.write_keyword(on_conflict);
9791 }
9792 if !modifiers.with_options.is_empty() {
9794 self.write_space();
9795 self.write_keyword("WITH");
9796 self.write(" (");
9797 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9798 if i > 0 {
9799 self.write(", ");
9800 }
9801 self.write(key);
9802 self.write("=");
9803 self.write(value);
9804 }
9805 self.write(")");
9806 }
9807 if let Some(ref fg) = modifiers.on_filegroup {
9809 self.write_space();
9810 self.write_keyword("ON");
9811 self.write_space();
9812 let _ = self.generate_identifier(fg);
9813 }
9814 }
9815
9816 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9818 if let Some(enforced) = modifiers.enforced {
9820 self.write_space();
9821 if enforced {
9822 self.write_keyword("ENFORCED");
9823 } else {
9824 self.write_keyword("NOT ENFORCED");
9825 }
9826 }
9827 if let Some(deferrable) = modifiers.deferrable {
9829 self.write_space();
9830 if deferrable {
9831 self.write_keyword("DEFERRABLE");
9832 } else {
9833 self.write_keyword("NOT DEFERRABLE");
9834 }
9835 }
9836 if let Some(initially_deferred) = modifiers.initially_deferred {
9838 self.write_space();
9839 if initially_deferred {
9840 self.write_keyword("INITIALLY DEFERRED");
9841 } else {
9842 self.write_keyword("INITIALLY IMMEDIATE");
9843 }
9844 }
9845 if modifiers.norely {
9847 self.write_space();
9848 self.write_keyword("NORELY");
9849 }
9850 if modifiers.rely {
9852 self.write_space();
9853 self.write_keyword("RELY");
9854 }
9855 if modifiers.not_valid {
9857 self.write_space();
9858 self.write_keyword("NOT VALID");
9859 }
9860 if let Some(on_conflict) = &modifiers.on_conflict {
9862 self.write_space();
9863 self.write_keyword("ON CONFLICT");
9864 self.write_space();
9865 self.write_keyword(on_conflict);
9866 }
9867 self.generate_index_specific_modifiers(modifiers);
9869 }
9870
9871 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9873 if let Some(ref comment) = modifiers.comment {
9874 self.write_space();
9875 self.write_keyword("COMMENT");
9876 self.write(" '");
9877 self.write(comment);
9878 self.write("'");
9879 }
9880 if let Some(visible) = modifiers.visible {
9881 self.write_space();
9882 if visible {
9883 self.write_keyword("VISIBLE");
9884 } else {
9885 self.write_keyword("INVISIBLE");
9886 }
9887 }
9888 if let Some(ref attr) = modifiers.engine_attribute {
9889 self.write_space();
9890 self.write_keyword("ENGINE_ATTRIBUTE");
9891 self.write(" = '");
9892 self.write(attr);
9893 self.write("'");
9894 }
9895 if let Some(ref parser) = modifiers.with_parser {
9896 self.write_space();
9897 self.write_keyword("WITH PARSER");
9898 self.write_space();
9899 self.write(parser);
9900 }
9901 }
9902
9903 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9904 if !fk_ref.match_after_actions {
9906 if let Some(ref match_type) = fk_ref.match_type {
9907 self.write_space();
9908 self.write_keyword("MATCH");
9909 self.write_space();
9910 match match_type {
9911 MatchType::Full => self.write_keyword("FULL"),
9912 MatchType::Partial => self.write_keyword("PARTIAL"),
9913 MatchType::Simple => self.write_keyword("SIMPLE"),
9914 }
9915 }
9916 }
9917
9918 if fk_ref.on_update_first {
9920 if let Some(ref action) = fk_ref.on_update {
9921 self.write_space();
9922 self.write_keyword("ON UPDATE");
9923 self.write_space();
9924 self.generate_referential_action(action);
9925 }
9926 if let Some(ref action) = fk_ref.on_delete {
9927 self.write_space();
9928 self.write_keyword("ON DELETE");
9929 self.write_space();
9930 self.generate_referential_action(action);
9931 }
9932 } else {
9933 if let Some(ref action) = fk_ref.on_delete {
9934 self.write_space();
9935 self.write_keyword("ON DELETE");
9936 self.write_space();
9937 self.generate_referential_action(action);
9938 }
9939 if let Some(ref action) = fk_ref.on_update {
9940 self.write_space();
9941 self.write_keyword("ON UPDATE");
9942 self.write_space();
9943 self.generate_referential_action(action);
9944 }
9945 }
9946
9947 if fk_ref.match_after_actions {
9949 if let Some(ref match_type) = fk_ref.match_type {
9950 self.write_space();
9951 self.write_keyword("MATCH");
9952 self.write_space();
9953 match match_type {
9954 MatchType::Full => self.write_keyword("FULL"),
9955 MatchType::Partial => self.write_keyword("PARTIAL"),
9956 MatchType::Simple => self.write_keyword("SIMPLE"),
9957 }
9958 }
9959 }
9960
9961 if let Some(deferrable) = fk_ref.deferrable {
9963 self.write_space();
9964 if deferrable {
9965 self.write_keyword("DEFERRABLE");
9966 } else {
9967 self.write_keyword("NOT DEFERRABLE");
9968 }
9969 }
9970
9971 Ok(())
9972 }
9973
9974 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9975 match action {
9976 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9977 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9978 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9979 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9980 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9981 }
9982 }
9983
9984 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9985 if let Some(ref object_id_args) = dt.object_id_args {
9987 if matches!(
9988 self.config.dialect,
9989 Some(crate::dialects::DialectType::TSQL)
9990 | Some(crate::dialects::DialectType::Fabric)
9991 ) {
9992 self.write_keyword("IF NOT OBJECT_ID");
9993 self.write("(");
9994 self.write(object_id_args);
9995 self.write(")");
9996 self.write_space();
9997 self.write_keyword("IS NULL BEGIN DROP TABLE");
9998 self.write_space();
9999 for (i, table) in dt.names.iter().enumerate() {
10000 if i > 0 {
10001 self.write(", ");
10002 }
10003 self.generate_table(table)?;
10004 }
10005 self.write("; ");
10006 self.write_keyword("END");
10007 return Ok(());
10008 }
10009 }
10010
10011 let saved_athena_hive_context = self.athena_hive_context;
10013 if matches!(
10014 self.config.dialect,
10015 Some(crate::dialects::DialectType::Athena)
10016 ) {
10017 self.athena_hive_context = true;
10018 }
10019
10020 for comment in &dt.leading_comments {
10022 self.write_formatted_comment(comment);
10023 self.write_space();
10024 }
10025 if dt.iceberg {
10026 self.write_keyword("DROP ICEBERG TABLE");
10027 } else {
10028 self.write_keyword("DROP TABLE");
10029 }
10030
10031 if dt.if_exists {
10032 self.write_space();
10033 self.write_keyword("IF EXISTS");
10034 }
10035
10036 self.write_space();
10037 for (i, table) in dt.names.iter().enumerate() {
10038 if i > 0 {
10039 self.write(", ");
10040 }
10041 self.generate_table(table)?;
10042 }
10043
10044 if dt.cascade_constraints {
10045 self.write_space();
10046 self.write_keyword("CASCADE CONSTRAINTS");
10047 } else if dt.cascade {
10048 self.write_space();
10049 self.write_keyword("CASCADE");
10050 }
10051
10052 if dt.restrict {
10053 self.write_space();
10054 self.write_keyword("RESTRICT");
10055 }
10056
10057 if dt.purge {
10058 self.write_space();
10059 self.write_keyword("PURGE");
10060 }
10061
10062 if dt.sync {
10063 self.write_space();
10064 self.write_keyword("SYNC");
10065 }
10066
10067 self.athena_hive_context = saved_athena_hive_context;
10069
10070 Ok(())
10071 }
10072
10073 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10074 self.write_keyword("UNDROP");
10075 self.write_space();
10076 self.write_keyword(&u.kind);
10077 if u.if_exists {
10078 self.write_space();
10079 self.write_keyword("IF EXISTS");
10080 }
10081 self.write_space();
10082 self.generate_table(&u.name)?;
10083 Ok(())
10084 }
10085
10086 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
10087 let saved_athena_hive_context = self.athena_hive_context;
10089 if matches!(
10090 self.config.dialect,
10091 Some(crate::dialects::DialectType::Athena)
10092 ) {
10093 self.athena_hive_context = true;
10094 }
10095
10096 self.write_keyword("ALTER");
10097 if let Some(ref modifier) = at.table_modifier {
10099 if !matches!(
10100 self.config.dialect,
10101 Some(crate::dialects::DialectType::DuckDB)
10102 ) {
10103 self.write_space();
10104 self.write_keyword(modifier);
10105 }
10106 }
10107 self.write(" ");
10108 self.write_keyword("TABLE");
10109 if at.if_exists {
10110 self.write_space();
10111 self.write_keyword("IF EXISTS");
10112 }
10113 self.write_space();
10114 self.generate_table(&at.name)?;
10115
10116 if let Some(ref on_cluster) = at.on_cluster {
10118 self.write_space();
10119 self.generate_on_cluster(on_cluster)?;
10120 }
10121
10122 if let Some(ref partition) = at.partition {
10124 self.write_space();
10125 self.write_keyword("PARTITION");
10126 self.write("(");
10127 for (i, (key, value)) in partition.iter().enumerate() {
10128 if i > 0 {
10129 self.write(", ");
10130 }
10131 self.generate_identifier(key)?;
10132 self.write(" = ");
10133 self.generate_expression(value)?;
10134 }
10135 self.write(")");
10136 }
10137
10138 if let Some(ref with_check) = at.with_check {
10140 self.write_space();
10141 self.write_keyword(with_check);
10142 }
10143
10144 if self.config.pretty {
10145 self.write_newline();
10147 self.indent_level += 1;
10148 for (i, action) in at.actions.iter().enumerate() {
10149 let is_continuation = i > 0
10151 && matches!(
10152 (&at.actions[i - 1], action),
10153 (
10154 AlterTableAction::AddColumn { .. },
10155 AlterTableAction::AddColumn { .. }
10156 ) | (
10157 AlterTableAction::AddConstraint(_),
10158 AlterTableAction::AddConstraint(_)
10159 )
10160 );
10161 if i > 0 {
10162 self.write(",");
10163 self.write_newline();
10164 }
10165 self.write_indent();
10166 self.generate_alter_action_with_continuation(action, is_continuation)?;
10167 }
10168 self.indent_level -= 1;
10169 } else {
10170 for (i, action) in at.actions.iter().enumerate() {
10171 let is_continuation = i > 0
10173 && matches!(
10174 (&at.actions[i - 1], action),
10175 (
10176 AlterTableAction::AddColumn { .. },
10177 AlterTableAction::AddColumn { .. }
10178 ) | (
10179 AlterTableAction::AddConstraint(_),
10180 AlterTableAction::AddConstraint(_)
10181 )
10182 );
10183 if i > 0 {
10184 self.write(",");
10185 }
10186 self.write_space();
10187 self.generate_alter_action_with_continuation(action, is_continuation)?;
10188 }
10189 }
10190
10191 if let Some(ref algorithm) = at.algorithm {
10193 self.write(", ");
10194 self.write_keyword("ALGORITHM");
10195 self.write("=");
10196 self.write_keyword(algorithm);
10197 }
10198 if let Some(ref lock) = at.lock {
10199 self.write(", ");
10200 self.write_keyword("LOCK");
10201 self.write("=");
10202 self.write_keyword(lock);
10203 }
10204
10205 self.athena_hive_context = saved_athena_hive_context;
10207
10208 Ok(())
10209 }
10210
10211 fn generate_alter_action_with_continuation(
10212 &mut self,
10213 action: &AlterTableAction,
10214 is_continuation: bool,
10215 ) -> Result<()> {
10216 match action {
10217 AlterTableAction::AddColumn {
10218 column,
10219 if_not_exists,
10220 position,
10221 } => {
10222 use crate::dialects::DialectType;
10223 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
10227 let is_tsql_like = matches!(
10228 self.config.dialect,
10229 Some(DialectType::TSQL) | Some(DialectType::Fabric)
10230 );
10231 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
10233
10234 if is_continuation && (is_snowflake || is_tsql_like) {
10235 } else if is_snowflake {
10237 self.write_keyword("ADD");
10238 self.write_space();
10239 } else if is_athena {
10240 self.write_keyword("ADD COLUMNS");
10242 self.write(" (");
10243 } else if self.config.alter_table_include_column_keyword {
10244 self.write_keyword("ADD COLUMN");
10245 self.write_space();
10246 } else {
10247 self.write_keyword("ADD");
10249 self.write_space();
10250 }
10251
10252 if *if_not_exists {
10253 self.write_keyword("IF NOT EXISTS");
10254 self.write_space();
10255 }
10256 self.generate_column_def(column)?;
10257
10258 if is_athena {
10260 self.write(")");
10261 }
10262
10263 if let Some(pos) = position {
10265 self.write_space();
10266 match pos {
10267 ColumnPosition::First => self.write_keyword("FIRST"),
10268 ColumnPosition::After(col_name) => {
10269 self.write_keyword("AFTER");
10270 self.write_space();
10271 self.generate_identifier(col_name)?;
10272 }
10273 }
10274 }
10275 }
10276 AlterTableAction::DropColumn {
10277 name,
10278 if_exists,
10279 cascade,
10280 } => {
10281 self.write_keyword("DROP COLUMN");
10282 if *if_exists {
10283 self.write_space();
10284 self.write_keyword("IF EXISTS");
10285 }
10286 self.write_space();
10287 self.generate_identifier(name)?;
10288 if *cascade {
10289 self.write_space();
10290 self.write_keyword("CASCADE");
10291 }
10292 }
10293 AlterTableAction::DropColumns { names } => {
10294 self.write_keyword("DROP COLUMNS");
10295 self.write(" (");
10296 for (i, name) in names.iter().enumerate() {
10297 if i > 0 {
10298 self.write(", ");
10299 }
10300 self.generate_identifier(name)?;
10301 }
10302 self.write(")");
10303 }
10304 AlterTableAction::RenameColumn {
10305 old_name,
10306 new_name,
10307 if_exists,
10308 } => {
10309 self.write_keyword("RENAME COLUMN");
10310 if *if_exists {
10311 self.write_space();
10312 self.write_keyword("IF EXISTS");
10313 }
10314 self.write_space();
10315 self.generate_identifier(old_name)?;
10316 self.write_space();
10317 self.write_keyword("TO");
10318 self.write_space();
10319 self.generate_identifier(new_name)?;
10320 }
10321 AlterTableAction::AlterColumn {
10322 name,
10323 action,
10324 use_modify_keyword,
10325 } => {
10326 use crate::dialects::DialectType;
10327 let use_modify = *use_modify_keyword
10330 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10331 && matches!(action, AlterColumnAction::SetDataType { .. }));
10332 if use_modify {
10333 self.write_keyword("MODIFY COLUMN");
10334 self.write_space();
10335 self.generate_identifier(name)?;
10336 if let AlterColumnAction::SetDataType {
10338 data_type,
10339 using: _,
10340 collate,
10341 } = action
10342 {
10343 self.write_space();
10344 self.generate_data_type(data_type)?;
10345 if let Some(collate_name) = collate {
10347 self.write_space();
10348 self.write_keyword("COLLATE");
10349 self.write_space();
10350 self.write(&format!("'{}'", collate_name));
10352 }
10353 } else {
10354 self.write_space();
10355 self.generate_alter_column_action(action)?;
10356 }
10357 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10358 && matches!(action, AlterColumnAction::SetDataType { .. })
10359 {
10360 self.write_keyword("CHANGE COLUMN");
10362 self.write_space();
10363 self.generate_identifier(name)?;
10364 self.write_space();
10365 self.generate_identifier(name)?;
10366 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10367 self.write_space();
10368 self.generate_data_type(data_type)?;
10369 }
10370 } else {
10371 self.write_keyword("ALTER COLUMN");
10372 self.write_space();
10373 self.generate_identifier(name)?;
10374 self.write_space();
10375 self.generate_alter_column_action(action)?;
10376 }
10377 }
10378 AlterTableAction::RenameTable(new_name) => {
10379 let mysql_like = matches!(
10381 self.config.dialect,
10382 Some(DialectType::MySQL)
10383 | Some(DialectType::Doris)
10384 | Some(DialectType::StarRocks)
10385 | Some(DialectType::SingleStore)
10386 );
10387 if mysql_like {
10388 self.write_keyword("RENAME");
10389 } else {
10390 self.write_keyword("RENAME TO");
10391 }
10392 self.write_space();
10393 let rename_table_with_db = !matches!(
10395 self.config.dialect,
10396 Some(DialectType::Doris)
10397 | Some(DialectType::DuckDB)
10398 | Some(DialectType::BigQuery)
10399 | Some(DialectType::PostgreSQL)
10400 );
10401 if !rename_table_with_db {
10402 let mut stripped = new_name.clone();
10403 stripped.schema = None;
10404 stripped.catalog = None;
10405 self.generate_table(&stripped)?;
10406 } else {
10407 self.generate_table(new_name)?;
10408 }
10409 }
10410 AlterTableAction::AddConstraint(constraint) => {
10411 if !is_continuation {
10414 self.write_keyword("ADD");
10415 self.write_space();
10416 }
10417 self.generate_table_constraint(constraint)?;
10418 }
10419 AlterTableAction::DropConstraint { name, if_exists } => {
10420 self.write_keyword("DROP CONSTRAINT");
10421 if *if_exists {
10422 self.write_space();
10423 self.write_keyword("IF EXISTS");
10424 }
10425 self.write_space();
10426 self.generate_identifier(name)?;
10427 }
10428 AlterTableAction::DropForeignKey { name } => {
10429 self.write_keyword("DROP FOREIGN KEY");
10430 self.write_space();
10431 self.generate_identifier(name)?;
10432 }
10433 AlterTableAction::DropPartition {
10434 partitions,
10435 if_exists,
10436 } => {
10437 self.write_keyword("DROP");
10438 if *if_exists {
10439 self.write_space();
10440 self.write_keyword("IF EXISTS");
10441 }
10442 for (i, partition) in partitions.iter().enumerate() {
10443 if i > 0 {
10444 self.write(",");
10445 }
10446 self.write_space();
10447 self.write_keyword("PARTITION");
10448 if partition.len() == 1 && partition[0].0.name == "__expr__" {
10450 self.write_space();
10452 self.generate_expression(&partition[0].1)?;
10453 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
10454 self.write_space();
10456 self.write_keyword("ALL");
10457 } else if partition.len() == 1 && partition[0].0.name == "ID" {
10458 self.write_space();
10460 self.write_keyword("ID");
10461 self.write_space();
10462 self.generate_expression(&partition[0].1)?;
10463 } else {
10464 self.write("(");
10466 for (j, (key, value)) in partition.iter().enumerate() {
10467 if j > 0 {
10468 self.write(", ");
10469 }
10470 self.generate_identifier(key)?;
10471 self.write(" = ");
10472 self.generate_expression(value)?;
10473 }
10474 self.write(")");
10475 }
10476 }
10477 }
10478 AlterTableAction::Delete { where_clause } => {
10479 self.write_keyword("DELETE");
10480 self.write_space();
10481 self.write_keyword("WHERE");
10482 self.write_space();
10483 self.generate_expression(where_clause)?;
10484 }
10485 AlterTableAction::SwapWith(target) => {
10486 self.write_keyword("SWAP WITH");
10487 self.write_space();
10488 self.generate_table(target)?;
10489 }
10490 AlterTableAction::SetProperty { properties } => {
10491 use crate::dialects::DialectType;
10492 self.write_keyword("SET");
10493 let is_trino_presto = matches!(
10495 self.config.dialect,
10496 Some(DialectType::Trino) | Some(DialectType::Presto)
10497 );
10498 if is_trino_presto {
10499 self.write_space();
10500 self.write_keyword("PROPERTIES");
10501 }
10502 let eq = if is_trino_presto { " = " } else { "=" };
10503 for (i, (key, value)) in properties.iter().enumerate() {
10504 if i > 0 {
10505 self.write(",");
10506 }
10507 self.write_space();
10508 if key.contains(' ') {
10510 self.generate_string_literal(key)?;
10511 } else {
10512 self.write(key);
10513 }
10514 self.write(eq);
10515 self.generate_expression(value)?;
10516 }
10517 }
10518 AlterTableAction::UnsetProperty { properties } => {
10519 self.write_keyword("UNSET");
10520 for (i, name) in properties.iter().enumerate() {
10521 if i > 0 {
10522 self.write(",");
10523 }
10524 self.write_space();
10525 self.write(name);
10526 }
10527 }
10528 AlterTableAction::ClusterBy { expressions } => {
10529 self.write_keyword("CLUSTER BY");
10530 self.write(" (");
10531 for (i, expr) in expressions.iter().enumerate() {
10532 if i > 0 {
10533 self.write(", ");
10534 }
10535 self.generate_expression(expr)?;
10536 }
10537 self.write(")");
10538 }
10539 AlterTableAction::SetTag { expressions } => {
10540 self.write_keyword("SET TAG");
10541 for (i, (key, value)) in expressions.iter().enumerate() {
10542 if i > 0 {
10543 self.write(",");
10544 }
10545 self.write_space();
10546 self.write(key);
10547 self.write(" = ");
10548 self.generate_expression(value)?;
10549 }
10550 }
10551 AlterTableAction::UnsetTag { names } => {
10552 self.write_keyword("UNSET TAG");
10553 for (i, name) in names.iter().enumerate() {
10554 if i > 0 {
10555 self.write(",");
10556 }
10557 self.write_space();
10558 self.write(name);
10559 }
10560 }
10561 AlterTableAction::SetOptions { expressions } => {
10562 self.write_keyword("SET");
10563 self.write(" (");
10564 for (i, expr) in expressions.iter().enumerate() {
10565 if i > 0 {
10566 self.write(", ");
10567 }
10568 self.generate_expression(expr)?;
10569 }
10570 self.write(")");
10571 }
10572 AlterTableAction::AlterIndex { name, visible } => {
10573 self.write_keyword("ALTER INDEX");
10574 self.write_space();
10575 self.generate_identifier(name)?;
10576 self.write_space();
10577 if *visible {
10578 self.write_keyword("VISIBLE");
10579 } else {
10580 self.write_keyword("INVISIBLE");
10581 }
10582 }
10583 AlterTableAction::SetAttribute { attribute } => {
10584 self.write_keyword("SET");
10585 self.write_space();
10586 self.write_keyword(attribute);
10587 }
10588 AlterTableAction::SetStageFileFormat { options } => {
10589 self.write_keyword("SET");
10590 self.write_space();
10591 self.write_keyword("STAGE_FILE_FORMAT");
10592 self.write(" = (");
10593 if let Some(opts) = options {
10594 self.generate_space_separated_properties(opts)?;
10595 }
10596 self.write(")");
10597 }
10598 AlterTableAction::SetStageCopyOptions { options } => {
10599 self.write_keyword("SET");
10600 self.write_space();
10601 self.write_keyword("STAGE_COPY_OPTIONS");
10602 self.write(" = (");
10603 if let Some(opts) = options {
10604 self.generate_space_separated_properties(opts)?;
10605 }
10606 self.write(")");
10607 }
10608 AlterTableAction::AddColumns { columns, cascade } => {
10609 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
10612 if is_oracle {
10613 self.write_keyword("ADD");
10614 } else {
10615 self.write_keyword("ADD COLUMNS");
10616 }
10617 self.write(" (");
10618 for (i, col) in columns.iter().enumerate() {
10619 if i > 0 {
10620 self.write(", ");
10621 }
10622 self.generate_column_def(col)?;
10623 }
10624 self.write(")");
10625 if *cascade {
10626 self.write_space();
10627 self.write_keyword("CASCADE");
10628 }
10629 }
10630 AlterTableAction::ChangeColumn {
10631 old_name,
10632 new_name,
10633 data_type,
10634 comment,
10635 cascade,
10636 } => {
10637 use crate::dialects::DialectType;
10638 let is_spark = matches!(
10639 self.config.dialect,
10640 Some(DialectType::Spark) | Some(DialectType::Databricks)
10641 );
10642 let is_rename = old_name.name != new_name.name;
10643
10644 if is_spark {
10645 if is_rename {
10646 self.write_keyword("RENAME COLUMN");
10648 self.write_space();
10649 self.generate_identifier(old_name)?;
10650 self.write_space();
10651 self.write_keyword("TO");
10652 self.write_space();
10653 self.generate_identifier(new_name)?;
10654 } else if comment.is_some() {
10655 self.write_keyword("ALTER COLUMN");
10657 self.write_space();
10658 self.generate_identifier(old_name)?;
10659 self.write_space();
10660 self.write_keyword("COMMENT");
10661 self.write_space();
10662 self.write("'");
10663 self.write(comment.as_ref().unwrap());
10664 self.write("'");
10665 } else if data_type.is_some() {
10666 self.write_keyword("ALTER COLUMN");
10668 self.write_space();
10669 self.generate_identifier(old_name)?;
10670 self.write_space();
10671 self.write_keyword("TYPE");
10672 self.write_space();
10673 self.generate_data_type(data_type.as_ref().unwrap())?;
10674 } else {
10675 self.write_keyword("CHANGE COLUMN");
10677 self.write_space();
10678 self.generate_identifier(old_name)?;
10679 self.write_space();
10680 self.generate_identifier(new_name)?;
10681 }
10682 } else {
10683 if data_type.is_some() {
10685 self.write_keyword("CHANGE COLUMN");
10686 } else {
10687 self.write_keyword("CHANGE");
10688 }
10689 self.write_space();
10690 self.generate_identifier(old_name)?;
10691 self.write_space();
10692 self.generate_identifier(new_name)?;
10693 if let Some(ref dt) = data_type {
10694 self.write_space();
10695 self.generate_data_type(dt)?;
10696 }
10697 if let Some(ref c) = comment {
10698 self.write_space();
10699 self.write_keyword("COMMENT");
10700 self.write_space();
10701 self.write("'");
10702 self.write(c);
10703 self.write("'");
10704 }
10705 if *cascade {
10706 self.write_space();
10707 self.write_keyword("CASCADE");
10708 }
10709 }
10710 }
10711 AlterTableAction::AddPartition {
10712 partition,
10713 if_not_exists,
10714 location,
10715 } => {
10716 self.write_keyword("ADD");
10717 self.write_space();
10718 if *if_not_exists {
10719 self.write_keyword("IF NOT EXISTS");
10720 self.write_space();
10721 }
10722 self.generate_expression(partition)?;
10723 if let Some(ref loc) = location {
10724 self.write_space();
10725 self.write_keyword("LOCATION");
10726 self.write_space();
10727 self.generate_expression(loc)?;
10728 }
10729 }
10730 AlterTableAction::AlterSortKey {
10731 this,
10732 expressions,
10733 compound,
10734 } => {
10735 self.write_keyword("ALTER");
10737 if *compound {
10738 self.write_space();
10739 self.write_keyword("COMPOUND");
10740 }
10741 self.write_space();
10742 self.write_keyword("SORTKEY");
10743 self.write_space();
10744 if let Some(style) = this {
10745 self.write_keyword(style);
10746 } else if !expressions.is_empty() {
10747 self.write("(");
10748 for (i, expr) in expressions.iter().enumerate() {
10749 if i > 0 {
10750 self.write(", ");
10751 }
10752 self.generate_expression(expr)?;
10753 }
10754 self.write(")");
10755 }
10756 }
10757 AlterTableAction::AlterDistStyle { style, distkey } => {
10758 self.write_keyword("ALTER");
10760 self.write_space();
10761 self.write_keyword("DISTSTYLE");
10762 self.write_space();
10763 self.write_keyword(style);
10764 if let Some(col) = distkey {
10765 self.write_space();
10766 self.write_keyword("DISTKEY");
10767 self.write_space();
10768 self.generate_identifier(col)?;
10769 }
10770 }
10771 AlterTableAction::SetTableProperties { properties } => {
10772 self.write_keyword("SET TABLE PROPERTIES");
10774 self.write(" (");
10775 for (i, (key, value)) in properties.iter().enumerate() {
10776 if i > 0 {
10777 self.write(", ");
10778 }
10779 self.generate_expression(key)?;
10780 self.write(" = ");
10781 self.generate_expression(value)?;
10782 }
10783 self.write(")");
10784 }
10785 AlterTableAction::SetLocation { location } => {
10786 self.write_keyword("SET LOCATION");
10788 self.write_space();
10789 self.write("'");
10790 self.write(location);
10791 self.write("'");
10792 }
10793 AlterTableAction::SetFileFormat { format } => {
10794 self.write_keyword("SET FILE FORMAT");
10796 self.write_space();
10797 self.write_keyword(format);
10798 }
10799 AlterTableAction::ReplacePartition { partition, source } => {
10800 self.write_keyword("REPLACE PARTITION");
10802 self.write_space();
10803 self.generate_expression(partition)?;
10804 if let Some(src) = source {
10805 self.write_space();
10806 self.write_keyword("FROM");
10807 self.write_space();
10808 self.generate_expression(src)?;
10809 }
10810 }
10811 AlterTableAction::Raw { sql } => {
10812 self.write(sql);
10813 }
10814 }
10815 Ok(())
10816 }
10817
10818 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10819 match action {
10820 AlterColumnAction::SetDataType {
10821 data_type,
10822 using,
10823 collate,
10824 } => {
10825 use crate::dialects::DialectType;
10826 let is_no_prefix = matches!(
10831 self.config.dialect,
10832 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10833 );
10834 let is_type_only = matches!(
10835 self.config.dialect,
10836 Some(DialectType::Redshift)
10837 | Some(DialectType::Spark)
10838 | Some(DialectType::Databricks)
10839 );
10840 if is_type_only {
10841 self.write_keyword("TYPE");
10842 self.write_space();
10843 } else if !is_no_prefix {
10844 self.write_keyword("SET DATA TYPE");
10845 self.write_space();
10846 }
10847 self.generate_data_type(data_type)?;
10848 if let Some(ref collation) = collate {
10849 self.write_space();
10850 self.write_keyword("COLLATE");
10851 self.write_space();
10852 self.write(collation);
10853 }
10854 if let Some(ref using_expr) = using {
10855 self.write_space();
10856 self.write_keyword("USING");
10857 self.write_space();
10858 self.generate_expression(using_expr)?;
10859 }
10860 }
10861 AlterColumnAction::SetDefault(expr) => {
10862 self.write_keyword("SET DEFAULT");
10863 self.write_space();
10864 self.generate_expression(expr)?;
10865 }
10866 AlterColumnAction::DropDefault => {
10867 self.write_keyword("DROP DEFAULT");
10868 }
10869 AlterColumnAction::SetNotNull => {
10870 self.write_keyword("SET NOT NULL");
10871 }
10872 AlterColumnAction::DropNotNull => {
10873 self.write_keyword("DROP NOT NULL");
10874 }
10875 AlterColumnAction::Comment(comment) => {
10876 self.write_keyword("COMMENT");
10877 self.write_space();
10878 self.generate_string_literal(comment)?;
10879 }
10880 AlterColumnAction::SetVisible => {
10881 self.write_keyword("SET VISIBLE");
10882 }
10883 AlterColumnAction::SetInvisible => {
10884 self.write_keyword("SET INVISIBLE");
10885 }
10886 }
10887 Ok(())
10888 }
10889
10890 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10891 self.write_keyword("CREATE");
10892
10893 if ci.unique {
10894 self.write_space();
10895 self.write_keyword("UNIQUE");
10896 }
10897
10898 if let Some(ref clustered) = ci.clustered {
10900 self.write_space();
10901 self.write_keyword(clustered);
10902 }
10903
10904 self.write_space();
10905 self.write_keyword("INDEX");
10906
10907 if ci.concurrently {
10909 self.write_space();
10910 self.write_keyword("CONCURRENTLY");
10911 }
10912
10913 if ci.if_not_exists {
10914 self.write_space();
10915 self.write_keyword("IF NOT EXISTS");
10916 }
10917
10918 if !ci.name.name.is_empty() {
10920 self.write_space();
10921 self.generate_identifier(&ci.name)?;
10922 }
10923 self.write_space();
10924 self.write_keyword("ON");
10925 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10927 self.write_space();
10928 self.write_keyword("TABLE");
10929 }
10930 self.write_space();
10931 self.generate_table(&ci.table)?;
10932
10933 if !ci.columns.is_empty() || ci.using.is_some() {
10936 let space_before_paren = false;
10937
10938 if let Some(ref using) = ci.using {
10939 self.write_space();
10940 self.write_keyword("USING");
10941 self.write_space();
10942 self.write(using);
10943 if space_before_paren {
10944 self.write(" (");
10945 } else {
10946 self.write("(");
10947 }
10948 } else {
10949 if space_before_paren {
10950 self.write(" (");
10951 } else {
10952 self.write("(");
10953 }
10954 }
10955 for (i, col) in ci.columns.iter().enumerate() {
10956 if i > 0 {
10957 self.write(", ");
10958 }
10959 self.generate_identifier(&col.column)?;
10960 if let Some(ref opclass) = col.opclass {
10961 self.write_space();
10962 self.write(opclass);
10963 }
10964 if col.desc {
10965 self.write_space();
10966 self.write_keyword("DESC");
10967 } else if col.asc {
10968 self.write_space();
10969 self.write_keyword("ASC");
10970 }
10971 if let Some(nulls_first) = col.nulls_first {
10972 self.write_space();
10973 self.write_keyword("NULLS");
10974 self.write_space();
10975 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10976 }
10977 }
10978 self.write(")");
10979 }
10980
10981 if !ci.include_columns.is_empty() {
10983 self.write_space();
10984 self.write_keyword("INCLUDE");
10985 self.write(" (");
10986 for (i, col) in ci.include_columns.iter().enumerate() {
10987 if i > 0 {
10988 self.write(", ");
10989 }
10990 self.generate_identifier(col)?;
10991 }
10992 self.write(")");
10993 }
10994
10995 if !ci.with_options.is_empty() {
10997 self.write_space();
10998 self.write_keyword("WITH");
10999 self.write(" (");
11000 for (i, (key, value)) in ci.with_options.iter().enumerate() {
11001 if i > 0 {
11002 self.write(", ");
11003 }
11004 self.write(key);
11005 self.write("=");
11006 self.write(value);
11007 }
11008 self.write(")");
11009 }
11010
11011 if let Some(ref where_clause) = ci.where_clause {
11013 self.write_space();
11014 self.write_keyword("WHERE");
11015 self.write_space();
11016 self.generate_expression(where_clause)?;
11017 }
11018
11019 if let Some(ref on_fg) = ci.on_filegroup {
11021 self.write_space();
11022 self.write_keyword("ON");
11023 self.write_space();
11024 self.write(on_fg);
11025 }
11026
11027 Ok(())
11028 }
11029
11030 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
11031 self.write_keyword("DROP INDEX");
11032
11033 if di.concurrently {
11034 self.write_space();
11035 self.write_keyword("CONCURRENTLY");
11036 }
11037
11038 if di.if_exists {
11039 self.write_space();
11040 self.write_keyword("IF EXISTS");
11041 }
11042
11043 self.write_space();
11044 self.generate_identifier(&di.name)?;
11045
11046 if let Some(ref table) = di.table {
11047 self.write_space();
11048 self.write_keyword("ON");
11049 self.write_space();
11050 self.generate_table(table)?;
11051 }
11052
11053 Ok(())
11054 }
11055
11056 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
11057 self.write_keyword("CREATE");
11058
11059 if let Some(ref algorithm) = cv.algorithm {
11061 self.write_space();
11062 self.write_keyword("ALGORITHM");
11063 self.write("=");
11064 self.write_keyword(algorithm);
11065 }
11066
11067 if let Some(ref definer) = cv.definer {
11069 self.write_space();
11070 self.write_keyword("DEFINER");
11071 self.write("=");
11072 self.write(definer);
11073 }
11074
11075 if cv.security_sql_style && !cv.security_after_name {
11077 if let Some(ref security) = cv.security {
11078 self.write_space();
11079 self.write_keyword("SQL SECURITY");
11080 self.write_space();
11081 match security {
11082 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11083 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11084 FunctionSecurity::None => self.write_keyword("NONE"),
11085 }
11086 }
11087 }
11088
11089 if cv.or_alter {
11090 self.write_space();
11091 self.write_keyword("OR ALTER");
11092 } else if cv.or_replace {
11093 self.write_space();
11094 self.write_keyword("OR REPLACE");
11095 }
11096
11097 if cv.temporary {
11098 self.write_space();
11099 self.write_keyword("TEMPORARY");
11100 }
11101
11102 if cv.materialized {
11103 self.write_space();
11104 self.write_keyword("MATERIALIZED");
11105 }
11106
11107 if cv.secure {
11109 self.write_space();
11110 self.write_keyword("SECURE");
11111 }
11112
11113 self.write_space();
11114 self.write_keyword("VIEW");
11115
11116 if cv.if_not_exists {
11117 self.write_space();
11118 self.write_keyword("IF NOT EXISTS");
11119 }
11120
11121 self.write_space();
11122 self.generate_table(&cv.name)?;
11123
11124 if let Some(ref on_cluster) = cv.on_cluster {
11126 self.write_space();
11127 self.generate_on_cluster(on_cluster)?;
11128 }
11129
11130 if let Some(ref to_table) = cv.to_table {
11132 self.write_space();
11133 self.write_keyword("TO");
11134 self.write_space();
11135 self.generate_table(to_table)?;
11136 }
11137
11138 if !cv.materialized {
11141 if !cv.columns.is_empty() {
11143 self.write(" (");
11144 for (i, col) in cv.columns.iter().enumerate() {
11145 if i > 0 {
11146 self.write(", ");
11147 }
11148 self.generate_identifier(&col.name)?;
11149 if !col.options.is_empty() {
11151 self.write_space();
11152 self.generate_options_clause(&col.options)?;
11153 }
11154 if let Some(ref comment) = col.comment {
11155 self.write_space();
11156 self.write_keyword("COMMENT");
11157 self.write_space();
11158 self.generate_string_literal(comment)?;
11159 }
11160 }
11161 self.write(")");
11162 }
11163
11164 if !cv.security_sql_style || cv.security_after_name {
11167 if let Some(ref security) = cv.security {
11168 self.write_space();
11169 if cv.security_sql_style {
11170 self.write_keyword("SQL SECURITY");
11171 } else {
11172 self.write_keyword("SECURITY");
11173 }
11174 self.write_space();
11175 match security {
11176 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11177 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11178 FunctionSecurity::None => self.write_keyword("NONE"),
11179 }
11180 }
11181 }
11182
11183 if cv.copy_grants {
11185 self.write_space();
11186 self.write_keyword("COPY GRANTS");
11187 }
11188 } else {
11189 if cv.copy_grants {
11191 self.write_space();
11192 self.write_keyword("COPY GRANTS");
11193 }
11194
11195 if let Some(ref schema) = cv.schema {
11197 self.write(" (");
11198 for (i, expr) in schema.expressions.iter().enumerate() {
11199 if i > 0 {
11200 self.write(", ");
11201 }
11202 self.generate_expression(expr)?;
11203 }
11204 self.write(")");
11205 } else if !cv.columns.is_empty() {
11206 self.write(" (");
11208 for (i, col) in cv.columns.iter().enumerate() {
11209 if i > 0 {
11210 self.write(", ");
11211 }
11212 self.generate_identifier(&col.name)?;
11213 if !col.options.is_empty() {
11215 self.write_space();
11216 self.generate_options_clause(&col.options)?;
11217 }
11218 if let Some(ref comment) = col.comment {
11219 self.write_space();
11220 self.write_keyword("COMMENT");
11221 self.write_space();
11222 self.generate_string_literal(comment)?;
11223 }
11224 }
11225 self.write(")");
11226 }
11227
11228 if let Some(ref unique_key) = cv.unique_key {
11230 self.write_space();
11231 self.write_keyword("KEY");
11232 self.write(" (");
11233 for (i, expr) in unique_key.expressions.iter().enumerate() {
11234 if i > 0 {
11235 self.write(", ");
11236 }
11237 self.generate_expression(expr)?;
11238 }
11239 self.write(")");
11240 }
11241 }
11242
11243 if let Some(ref row_access_policy) = cv.row_access_policy {
11244 self.write_space();
11245 self.write_keyword("WITH");
11246 self.write_space();
11247 self.write(row_access_policy);
11248 }
11249
11250 if let Some(ref comment) = cv.comment {
11252 self.write_space();
11253 self.write_keyword("COMMENT");
11254 self.write("=");
11255 self.generate_string_literal(comment)?;
11256 }
11257
11258 if !cv.tags.is_empty() {
11260 self.write_space();
11261 self.write_keyword("TAG");
11262 self.write(" (");
11263 for (i, (name, value)) in cv.tags.iter().enumerate() {
11264 if i > 0 {
11265 self.write(", ");
11266 }
11267 self.write(name);
11268 self.write("='");
11269 self.write(value);
11270 self.write("'");
11271 }
11272 self.write(")");
11273 }
11274
11275 if !cv.options.is_empty() {
11277 self.write_space();
11278 self.generate_options_clause(&cv.options)?;
11279 }
11280
11281 if let Some(ref build) = cv.build {
11283 self.write_space();
11284 self.write_keyword("BUILD");
11285 self.write_space();
11286 self.write_keyword(build);
11287 }
11288
11289 if let Some(ref refresh) = cv.refresh {
11291 self.write_space();
11292 self.generate_refresh_trigger_property(refresh)?;
11293 }
11294
11295 if let Some(auto_refresh) = cv.auto_refresh {
11297 self.write_space();
11298 self.write_keyword("AUTO REFRESH");
11299 self.write_space();
11300 if auto_refresh {
11301 self.write_keyword("YES");
11302 } else {
11303 self.write_keyword("NO");
11304 }
11305 }
11306
11307 for prop in &cv.table_properties {
11309 self.write_space();
11310 self.generate_expression(prop)?;
11311 }
11312
11313 if !matches!(&cv.query, Expression::Null(_)) {
11315 self.write_space();
11316 self.write_keyword("AS");
11317 self.write_space();
11318
11319 if let Some(ref mode) = cv.locking_mode {
11321 self.write_keyword("LOCKING");
11322 self.write_space();
11323 self.write_keyword(mode);
11324 if let Some(ref access) = cv.locking_access {
11325 self.write_space();
11326 self.write_keyword("FOR");
11327 self.write_space();
11328 self.write_keyword(access);
11329 }
11330 self.write_space();
11331 }
11332
11333 if cv.query_parenthesized {
11334 self.write("(");
11335 }
11336 self.generate_expression(&cv.query)?;
11337 if cv.query_parenthesized {
11338 self.write(")");
11339 }
11340 }
11341
11342 if cv.no_schema_binding {
11344 self.write_space();
11345 self.write_keyword("WITH NO SCHEMA BINDING");
11346 }
11347
11348 Ok(())
11349 }
11350
11351 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11352 self.write_keyword("DROP");
11353
11354 if dv.materialized {
11355 self.write_space();
11356 self.write_keyword("MATERIALIZED");
11357 }
11358
11359 self.write_space();
11360 self.write_keyword("VIEW");
11361
11362 if dv.if_exists {
11363 self.write_space();
11364 self.write_keyword("IF EXISTS");
11365 }
11366
11367 self.write_space();
11368 self.generate_table(&dv.name)?;
11369
11370 Ok(())
11371 }
11372
11373 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11374 match tr.target {
11375 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11376 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11377 }
11378 if tr.if_exists {
11379 self.write_space();
11380 self.write_keyword("IF EXISTS");
11381 }
11382 self.write_space();
11383 self.generate_table(&tr.table)?;
11384
11385 if let Some(ref on_cluster) = tr.on_cluster {
11387 self.write_space();
11388 self.generate_on_cluster(on_cluster)?;
11389 }
11390
11391 if !tr.extra_tables.is_empty() {
11393 let skip_first = if let Some(first) = tr.extra_tables.first() {
11395 first.table.name == tr.table.name && first.star
11396 } else {
11397 false
11398 };
11399
11400 let strip_star = matches!(
11402 self.config.dialect,
11403 Some(crate::dialects::DialectType::PostgreSQL)
11404 | Some(crate::dialects::DialectType::Redshift)
11405 );
11406 if skip_first && !strip_star {
11407 self.write("*");
11408 }
11409
11410 for (i, entry) in tr.extra_tables.iter().enumerate() {
11412 if i == 0 && skip_first {
11413 continue; }
11415 self.write(", ");
11416 self.generate_table(&entry.table)?;
11417 if entry.star && !strip_star {
11418 self.write("*");
11419 }
11420 }
11421 }
11422
11423 if let Some(identity) = &tr.identity {
11425 self.write_space();
11426 match identity {
11427 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
11428 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
11429 }
11430 }
11431
11432 if tr.cascade {
11433 self.write_space();
11434 self.write_keyword("CASCADE");
11435 }
11436
11437 if tr.restrict {
11438 self.write_space();
11439 self.write_keyword("RESTRICT");
11440 }
11441
11442 if let Some(ref partition) = tr.partition {
11444 self.write_space();
11445 self.generate_expression(partition)?;
11446 }
11447
11448 Ok(())
11449 }
11450
11451 fn generate_use(&mut self, u: &Use) -> Result<()> {
11452 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
11454 self.write_keyword("DATABASE");
11455 self.write_space();
11456 self.generate_identifier(&u.this)?;
11457 return Ok(());
11458 }
11459
11460 self.write_keyword("USE");
11461
11462 if let Some(kind) = &u.kind {
11463 self.write_space();
11464 match kind {
11465 UseKind::Database => self.write_keyword("DATABASE"),
11466 UseKind::Schema => self.write_keyword("SCHEMA"),
11467 UseKind::Role => self.write_keyword("ROLE"),
11468 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
11469 UseKind::Catalog => self.write_keyword("CATALOG"),
11470 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
11471 }
11472 }
11473
11474 self.write_space();
11475 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
11478 self.write(&u.this.name);
11479 } else {
11480 self.generate_identifier(&u.this)?;
11481 }
11482 Ok(())
11483 }
11484
11485 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
11486 self.write_keyword("CACHE");
11487 if c.lazy {
11488 self.write_space();
11489 self.write_keyword("LAZY");
11490 }
11491 self.write_space();
11492 self.write_keyword("TABLE");
11493 self.write_space();
11494 self.generate_identifier(&c.table)?;
11495
11496 if !c.options.is_empty() {
11498 self.write_space();
11499 self.write_keyword("OPTIONS");
11500 self.write("(");
11501 for (i, (key, value)) in c.options.iter().enumerate() {
11502 if i > 0 {
11503 self.write(", ");
11504 }
11505 self.generate_expression(key)?;
11506 self.write(" = ");
11507 self.generate_expression(value)?;
11508 }
11509 self.write(")");
11510 }
11511
11512 if let Some(query) = &c.query {
11514 self.write_space();
11515 self.write_keyword("AS");
11516 self.write_space();
11517 self.generate_expression(query)?;
11518 }
11519
11520 Ok(())
11521 }
11522
11523 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
11524 self.write_keyword("UNCACHE TABLE");
11525 if u.if_exists {
11526 self.write_space();
11527 self.write_keyword("IF EXISTS");
11528 }
11529 self.write_space();
11530 self.generate_identifier(&u.table)?;
11531 Ok(())
11532 }
11533
11534 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
11535 self.write_keyword("LOAD DATA");
11536 if l.local {
11537 self.write_space();
11538 self.write_keyword("LOCAL");
11539 }
11540 self.write_space();
11541 self.write_keyword("INPATH");
11542 self.write_space();
11543 self.write("'");
11544 self.write(&l.inpath);
11545 self.write("'");
11546
11547 if l.overwrite {
11548 self.write_space();
11549 self.write_keyword("OVERWRITE");
11550 }
11551
11552 self.write_space();
11553 self.write_keyword("INTO TABLE");
11554 self.write_space();
11555 self.generate_expression(&l.table)?;
11556
11557 if !l.partition.is_empty() {
11559 self.write_space();
11560 self.write_keyword("PARTITION");
11561 self.write("(");
11562 for (i, (col, val)) in l.partition.iter().enumerate() {
11563 if i > 0 {
11564 self.write(", ");
11565 }
11566 self.generate_identifier(col)?;
11567 self.write(" = ");
11568 self.generate_expression(val)?;
11569 }
11570 self.write(")");
11571 }
11572
11573 if let Some(fmt) = &l.input_format {
11575 self.write_space();
11576 self.write_keyword("INPUTFORMAT");
11577 self.write_space();
11578 self.write("'");
11579 self.write(fmt);
11580 self.write("'");
11581 }
11582
11583 if let Some(serde) = &l.serde {
11585 self.write_space();
11586 self.write_keyword("SERDE");
11587 self.write_space();
11588 self.write("'");
11589 self.write(serde);
11590 self.write("'");
11591 }
11592
11593 Ok(())
11594 }
11595
11596 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
11597 self.write_keyword("PRAGMA");
11598 self.write_space();
11599
11600 if let Some(schema) = &p.schema {
11602 self.generate_identifier(schema)?;
11603 self.write(".");
11604 }
11605
11606 self.generate_identifier(&p.name)?;
11608
11609 if p.use_assignment_syntax {
11611 self.write(" = ");
11612 if let Some(value) = &p.value {
11613 self.generate_expression(value)?;
11614 } else if let Some(arg) = p.args.first() {
11615 self.generate_expression(arg)?;
11616 }
11617 } else if !p.args.is_empty() {
11618 self.write("(");
11619 for (i, arg) in p.args.iter().enumerate() {
11620 if i > 0 {
11621 self.write(", ");
11622 }
11623 self.generate_expression(arg)?;
11624 }
11625 self.write(")");
11626 }
11627
11628 Ok(())
11629 }
11630
11631 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
11632 self.write_keyword("GRANT");
11633 self.write_space();
11634
11635 for (i, privilege) in g.privileges.iter().enumerate() {
11637 if i > 0 {
11638 self.write(", ");
11639 }
11640 self.write_keyword(&privilege.name);
11641 if !privilege.columns.is_empty() {
11643 self.write("(");
11644 for (j, col) in privilege.columns.iter().enumerate() {
11645 if j > 0 {
11646 self.write(", ");
11647 }
11648 self.write(col);
11649 }
11650 self.write(")");
11651 }
11652 }
11653
11654 self.write_space();
11655 self.write_keyword("ON");
11656 self.write_space();
11657
11658 if let Some(kind) = &g.kind {
11660 self.write_keyword(kind);
11661 self.write_space();
11662 }
11663
11664 {
11666 use crate::dialects::DialectType;
11667 let should_upper = matches!(
11668 self.config.dialect,
11669 Some(DialectType::PostgreSQL)
11670 | Some(DialectType::CockroachDB)
11671 | Some(DialectType::Materialize)
11672 | Some(DialectType::RisingWave)
11673 ) && (g.kind.as_deref() == Some("FUNCTION")
11674 || g.kind.as_deref() == Some("PROCEDURE"));
11675 if should_upper {
11676 use crate::expressions::Identifier;
11677 let upper_id = Identifier {
11678 name: g.securable.name.to_ascii_uppercase(),
11679 quoted: g.securable.quoted,
11680 ..g.securable.clone()
11681 };
11682 self.generate_identifier(&upper_id)?;
11683 } else {
11684 self.generate_identifier(&g.securable)?;
11685 }
11686 }
11687
11688 if !g.function_params.is_empty() {
11690 self.write("(");
11691 for (i, param) in g.function_params.iter().enumerate() {
11692 if i > 0 {
11693 self.write(", ");
11694 }
11695 self.write(param);
11696 }
11697 self.write(")");
11698 }
11699
11700 self.write_space();
11701 self.write_keyword("TO");
11702 self.write_space();
11703
11704 for (i, principal) in g.principals.iter().enumerate() {
11706 if i > 0 {
11707 self.write(", ");
11708 }
11709 if principal.is_role {
11710 self.write_keyword("ROLE");
11711 self.write_space();
11712 } else if principal.is_group {
11713 self.write_keyword("GROUP");
11714 self.write_space();
11715 } else if principal.is_share {
11716 self.write_keyword("SHARE");
11717 self.write_space();
11718 }
11719 self.generate_identifier(&principal.name)?;
11720 }
11721
11722 if g.grant_option {
11724 self.write_space();
11725 self.write_keyword("WITH GRANT OPTION");
11726 }
11727
11728 if let Some(ref principal) = g.as_principal {
11730 self.write_space();
11731 self.write_keyword("AS");
11732 self.write_space();
11733 self.generate_identifier(principal)?;
11734 }
11735
11736 Ok(())
11737 }
11738
11739 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
11740 self.write_keyword("REVOKE");
11741 self.write_space();
11742
11743 if r.grant_option {
11745 self.write_keyword("GRANT OPTION FOR");
11746 self.write_space();
11747 }
11748
11749 for (i, privilege) in r.privileges.iter().enumerate() {
11751 if i > 0 {
11752 self.write(", ");
11753 }
11754 self.write_keyword(&privilege.name);
11755 if !privilege.columns.is_empty() {
11757 self.write("(");
11758 for (j, col) in privilege.columns.iter().enumerate() {
11759 if j > 0 {
11760 self.write(", ");
11761 }
11762 self.write(col);
11763 }
11764 self.write(")");
11765 }
11766 }
11767
11768 self.write_space();
11769 self.write_keyword("ON");
11770 self.write_space();
11771
11772 if let Some(kind) = &r.kind {
11774 self.write_keyword(kind);
11775 self.write_space();
11776 }
11777
11778 {
11780 use crate::dialects::DialectType;
11781 let should_upper = matches!(
11782 self.config.dialect,
11783 Some(DialectType::PostgreSQL)
11784 | Some(DialectType::CockroachDB)
11785 | Some(DialectType::Materialize)
11786 | Some(DialectType::RisingWave)
11787 ) && (r.kind.as_deref() == Some("FUNCTION")
11788 || r.kind.as_deref() == Some("PROCEDURE"));
11789 if should_upper {
11790 use crate::expressions::Identifier;
11791 let upper_id = Identifier {
11792 name: r.securable.name.to_ascii_uppercase(),
11793 quoted: r.securable.quoted,
11794 ..r.securable.clone()
11795 };
11796 self.generate_identifier(&upper_id)?;
11797 } else {
11798 self.generate_identifier(&r.securable)?;
11799 }
11800 }
11801
11802 if !r.function_params.is_empty() {
11804 self.write("(");
11805 for (i, param) in r.function_params.iter().enumerate() {
11806 if i > 0 {
11807 self.write(", ");
11808 }
11809 self.write(param);
11810 }
11811 self.write(")");
11812 }
11813
11814 self.write_space();
11815 self.write_keyword("FROM");
11816 self.write_space();
11817
11818 for (i, principal) in r.principals.iter().enumerate() {
11820 if i > 0 {
11821 self.write(", ");
11822 }
11823 if principal.is_role {
11824 self.write_keyword("ROLE");
11825 self.write_space();
11826 } else if principal.is_group {
11827 self.write_keyword("GROUP");
11828 self.write_space();
11829 } else if principal.is_share {
11830 self.write_keyword("SHARE");
11831 self.write_space();
11832 }
11833 self.generate_identifier(&principal.name)?;
11834 }
11835
11836 if r.cascade {
11838 self.write_space();
11839 self.write_keyword("CASCADE");
11840 } else if r.restrict {
11841 self.write_space();
11842 self.write_keyword("RESTRICT");
11843 }
11844
11845 Ok(())
11846 }
11847
11848 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11849 self.write_keyword("COMMENT");
11850
11851 if c.exists {
11853 self.write_space();
11854 self.write_keyword("IF EXISTS");
11855 }
11856
11857 self.write_space();
11858 self.write_keyword("ON");
11859
11860 if c.materialized {
11862 self.write_space();
11863 self.write_keyword("MATERIALIZED");
11864 }
11865
11866 self.write_space();
11867 self.write_keyword(&c.kind);
11868 self.write_space();
11869
11870 self.generate_expression(&c.this)?;
11872
11873 self.write_space();
11874 self.write_keyword("IS");
11875 self.write_space();
11876
11877 self.generate_expression(&c.expression)?;
11879
11880 Ok(())
11881 }
11882
11883 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11884 self.write_keyword("SET");
11885
11886 for (i, item) in s.items.iter().enumerate() {
11887 if i > 0 {
11888 self.write(",");
11889 }
11890 self.write_space();
11891
11892 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11894 if let Some(ref kind) = item.kind {
11895 if has_variable_kind {
11899 if matches!(
11900 self.config.dialect,
11901 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
11902 ) {
11903 self.write_keyword("VARIABLE");
11904 self.write_space();
11905 }
11906 } else {
11907 self.write_keyword(kind);
11908 self.write_space();
11909 }
11910 }
11911
11912 let name_str = match &item.name {
11914 Expression::Identifier(id) => Some(id.name.as_str()),
11915 _ => None,
11916 };
11917
11918 let is_transaction = name_str == Some("TRANSACTION");
11919 let is_character_set = name_str == Some("CHARACTER SET");
11920 let is_names = name_str == Some("NAMES");
11921 let is_collate = name_str == Some("COLLATE");
11922 let is_value_only =
11923 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11924
11925 if is_transaction {
11926 self.write_keyword("TRANSACTION");
11928 if let Expression::Identifier(id) = &item.value {
11929 if !id.name.is_empty() {
11930 self.write_space();
11931 self.write(&id.name);
11932 }
11933 }
11934 } else if is_character_set {
11935 self.write_keyword("CHARACTER SET");
11937 self.write_space();
11938 self.generate_set_value(&item.value)?;
11939 } else if is_names {
11940 self.write_keyword("NAMES");
11942 self.write_space();
11943 self.generate_set_value(&item.value)?;
11944 } else if is_collate {
11945 self.write_keyword("COLLATE");
11947 self.write_space();
11948 self.generate_set_value(&item.value)?;
11949 } else if has_variable_kind {
11950 if let Some(ns) = name_str {
11953 self.write(ns);
11954 } else {
11955 self.generate_expression(&item.name)?;
11956 }
11957 self.write(" = ");
11958 self.generate_set_value(&item.value)?;
11959 } else if is_value_only {
11960 self.generate_expression(&item.name)?;
11962 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11963 self.generate_expression(&item.name)?;
11965 self.write_space();
11966 self.generate_set_value(&item.value)?;
11967 } else {
11968 match &item.name {
11971 Expression::Identifier(id) => {
11972 self.write(&id.name);
11973 }
11974 _ => {
11975 self.generate_expression(&item.name)?;
11976 }
11977 }
11978 self.write(" = ");
11979 self.generate_set_value(&item.value)?;
11980 }
11981 }
11982
11983 Ok(())
11984 }
11985
11986 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11989 if let Expression::Identifier(id) = value {
11990 match id.name.as_str() {
11991 "DEFAULT" | "ON" | "OFF" => {
11992 self.write_keyword(&id.name);
11993 return Ok(());
11994 }
11995 _ => {}
11996 }
11997 }
11998 self.generate_expression(value)
11999 }
12000
12001 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
12004 self.write_keyword("ALTER");
12005 if let Some(ref algorithm) = av.algorithm {
12007 self.write_space();
12008 self.write_keyword("ALGORITHM");
12009 self.write(" = ");
12010 self.write_keyword(algorithm);
12011 }
12012 if let Some(ref definer) = av.definer {
12013 self.write_space();
12014 self.write_keyword("DEFINER");
12015 self.write(" = ");
12016 self.write(definer);
12017 }
12018 if let Some(ref sql_security) = av.sql_security {
12019 self.write_space();
12020 self.write_keyword("SQL SECURITY");
12021 self.write(" = ");
12022 self.write_keyword(sql_security);
12023 }
12024 self.write_space();
12025 self.write_keyword("VIEW");
12026 self.write_space();
12027 self.generate_table(&av.name)?;
12028
12029 if !av.columns.is_empty() {
12031 self.write(" (");
12032 for (i, col) in av.columns.iter().enumerate() {
12033 if i > 0 {
12034 self.write(", ");
12035 }
12036 self.generate_identifier(&col.name)?;
12037 if let Some(ref comment) = col.comment {
12038 self.write_space();
12039 self.write_keyword("COMMENT");
12040 self.write(" ");
12041 self.generate_string_literal(comment)?;
12042 }
12043 }
12044 self.write(")");
12045 }
12046
12047 if let Some(ref opt) = av.with_option {
12049 self.write_space();
12050 self.write_keyword("WITH");
12051 self.write_space();
12052 self.write_keyword(opt);
12053 }
12054
12055 for action in &av.actions {
12056 self.write_space();
12057 match action {
12058 AlterViewAction::Rename(new_name) => {
12059 self.write_keyword("RENAME TO");
12060 self.write_space();
12061 self.generate_table(new_name)?;
12062 }
12063 AlterViewAction::OwnerTo(owner) => {
12064 self.write_keyword("OWNER TO");
12065 self.write_space();
12066 self.generate_identifier(owner)?;
12067 }
12068 AlterViewAction::SetSchema(schema) => {
12069 self.write_keyword("SET SCHEMA");
12070 self.write_space();
12071 self.generate_identifier(schema)?;
12072 }
12073 AlterViewAction::SetAuthorization(auth) => {
12074 self.write_keyword("SET AUTHORIZATION");
12075 self.write_space();
12076 self.write(auth);
12077 }
12078 AlterViewAction::AlterColumn { name, action } => {
12079 self.write_keyword("ALTER COLUMN");
12080 self.write_space();
12081 self.generate_identifier(name)?;
12082 self.write_space();
12083 self.generate_alter_column_action(action)?;
12084 }
12085 AlterViewAction::AsSelect(query) => {
12086 self.write_keyword("AS");
12087 self.write_space();
12088 self.generate_expression(query)?;
12089 }
12090 AlterViewAction::SetTblproperties(props) => {
12091 self.write_keyword("SET TBLPROPERTIES");
12092 self.write(" (");
12093 for (i, (key, value)) in props.iter().enumerate() {
12094 if i > 0 {
12095 self.write(", ");
12096 }
12097 self.generate_string_literal(key)?;
12098 self.write("=");
12099 self.generate_string_literal(value)?;
12100 }
12101 self.write(")");
12102 }
12103 AlterViewAction::UnsetTblproperties(keys) => {
12104 self.write_keyword("UNSET TBLPROPERTIES");
12105 self.write(" (");
12106 for (i, key) in keys.iter().enumerate() {
12107 if i > 0 {
12108 self.write(", ");
12109 }
12110 self.generate_string_literal(key)?;
12111 }
12112 self.write(")");
12113 }
12114 }
12115 }
12116
12117 Ok(())
12118 }
12119
12120 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
12121 self.write_keyword("ALTER INDEX");
12122 self.write_space();
12123 self.generate_identifier(&ai.name)?;
12124
12125 if let Some(table) = &ai.table {
12126 self.write_space();
12127 self.write_keyword("ON");
12128 self.write_space();
12129 self.generate_table(table)?;
12130 }
12131
12132 for action in &ai.actions {
12133 self.write_space();
12134 match action {
12135 AlterIndexAction::Rename(new_name) => {
12136 self.write_keyword("RENAME TO");
12137 self.write_space();
12138 self.generate_identifier(new_name)?;
12139 }
12140 AlterIndexAction::SetTablespace(tablespace) => {
12141 self.write_keyword("SET TABLESPACE");
12142 self.write_space();
12143 self.generate_identifier(tablespace)?;
12144 }
12145 AlterIndexAction::Visible(visible) => {
12146 if *visible {
12147 self.write_keyword("VISIBLE");
12148 } else {
12149 self.write_keyword("INVISIBLE");
12150 }
12151 }
12152 }
12153 }
12154
12155 Ok(())
12156 }
12157
12158 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
12159 for comment in &cs.leading_comments {
12161 self.write_formatted_comment(comment);
12162 self.write_space();
12163 }
12164
12165 let saved_athena_hive_context = self.athena_hive_context;
12167 if matches!(
12168 self.config.dialect,
12169 Some(crate::dialects::DialectType::Athena)
12170 ) {
12171 self.athena_hive_context = true;
12172 }
12173
12174 self.write_keyword("CREATE SCHEMA");
12175
12176 if cs.if_not_exists {
12177 self.write_space();
12178 self.write_keyword("IF NOT EXISTS");
12179 }
12180
12181 self.write_space();
12182 for (i, part) in cs.name.iter().enumerate() {
12183 if i > 0 {
12184 self.write(".");
12185 }
12186 self.generate_identifier(part)?;
12187 }
12188
12189 if let Some(ref clone_parts) = cs.clone_from {
12190 self.write_keyword(" CLONE ");
12191 for (i, part) in clone_parts.iter().enumerate() {
12192 if i > 0 {
12193 self.write(".");
12194 }
12195 self.generate_identifier(part)?;
12196 }
12197 }
12198
12199 if let Some(ref at_clause) = cs.at_clause {
12200 self.write_space();
12201 self.generate_expression(at_clause)?;
12202 }
12203
12204 if let Some(auth) = &cs.authorization {
12205 self.write_space();
12206 self.write_keyword("AUTHORIZATION");
12207 self.write_space();
12208 self.generate_identifier(auth)?;
12209 }
12210
12211 let with_properties: Vec<_> = cs
12214 .properties
12215 .iter()
12216 .filter(|p| matches!(p, Expression::Property(_)))
12217 .collect();
12218 let other_properties: Vec<_> = cs
12219 .properties
12220 .iter()
12221 .filter(|p| !matches!(p, Expression::Property(_)))
12222 .collect();
12223
12224 if !with_properties.is_empty() {
12226 self.write_space();
12227 self.write_keyword("WITH");
12228 self.write(" (");
12229 for (i, prop) in with_properties.iter().enumerate() {
12230 if i > 0 {
12231 self.write(", ");
12232 }
12233 self.generate_expression(prop)?;
12234 }
12235 self.write(")");
12236 }
12237
12238 for prop in other_properties {
12240 self.write_space();
12241 self.generate_expression(prop)?;
12242 }
12243
12244 self.athena_hive_context = saved_athena_hive_context;
12246
12247 Ok(())
12248 }
12249
12250 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
12251 self.write_keyword("DROP SCHEMA");
12252
12253 if ds.if_exists {
12254 self.write_space();
12255 self.write_keyword("IF EXISTS");
12256 }
12257
12258 self.write_space();
12259 self.generate_identifier(&ds.name)?;
12260
12261 if ds.cascade {
12262 self.write_space();
12263 self.write_keyword("CASCADE");
12264 }
12265
12266 Ok(())
12267 }
12268
12269 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
12270 self.write_keyword("DROP NAMESPACE");
12271
12272 if dn.if_exists {
12273 self.write_space();
12274 self.write_keyword("IF EXISTS");
12275 }
12276
12277 self.write_space();
12278 self.generate_identifier(&dn.name)?;
12279
12280 if dn.cascade {
12281 self.write_space();
12282 self.write_keyword("CASCADE");
12283 }
12284
12285 Ok(())
12286 }
12287
12288 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
12289 self.write_keyword("CREATE DATABASE");
12290
12291 if cd.if_not_exists {
12292 self.write_space();
12293 self.write_keyword("IF NOT EXISTS");
12294 }
12295
12296 self.write_space();
12297 self.generate_identifier(&cd.name)?;
12298
12299 if let Some(ref clone_src) = cd.clone_from {
12300 self.write_keyword(" CLONE ");
12301 self.generate_identifier(clone_src)?;
12302 }
12303
12304 if let Some(ref at_clause) = cd.at_clause {
12306 self.write_space();
12307 self.generate_expression(at_clause)?;
12308 }
12309
12310 for option in &cd.options {
12311 self.write_space();
12312 match option {
12313 DatabaseOption::CharacterSet(charset) => {
12314 self.write_keyword("CHARACTER SET");
12315 self.write(" = ");
12316 self.write(&format!("'{}'", charset));
12317 }
12318 DatabaseOption::Collate(collate) => {
12319 self.write_keyword("COLLATE");
12320 self.write(" = ");
12321 self.write(&format!("'{}'", collate));
12322 }
12323 DatabaseOption::Owner(owner) => {
12324 self.write_keyword("OWNER");
12325 self.write(" = ");
12326 self.generate_identifier(owner)?;
12327 }
12328 DatabaseOption::Template(template) => {
12329 self.write_keyword("TEMPLATE");
12330 self.write(" = ");
12331 self.generate_identifier(template)?;
12332 }
12333 DatabaseOption::Encoding(encoding) => {
12334 self.write_keyword("ENCODING");
12335 self.write(" = ");
12336 self.write(&format!("'{}'", encoding));
12337 }
12338 DatabaseOption::Location(location) => {
12339 self.write_keyword("LOCATION");
12340 self.write(" = ");
12341 self.write(&format!("'{}'", location));
12342 }
12343 }
12344 }
12345
12346 Ok(())
12347 }
12348
12349 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
12350 self.write_keyword("DROP DATABASE");
12351
12352 if dd.if_exists {
12353 self.write_space();
12354 self.write_keyword("IF EXISTS");
12355 }
12356
12357 self.write_space();
12358 self.generate_identifier(&dd.name)?;
12359
12360 if dd.sync {
12361 self.write_space();
12362 self.write_keyword("SYNC");
12363 }
12364
12365 Ok(())
12366 }
12367
12368 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
12369 self.write_keyword("CREATE");
12370
12371 if cf.or_alter {
12372 self.write_space();
12373 self.write_keyword("OR ALTER");
12374 } else if cf.or_replace {
12375 self.write_space();
12376 self.write_keyword("OR REPLACE");
12377 }
12378
12379 if cf.temporary {
12380 self.write_space();
12381 self.write_keyword("TEMPORARY");
12382 }
12383
12384 self.write_space();
12385 if cf.is_table_function {
12386 self.write_keyword("TABLE FUNCTION");
12387 } else {
12388 self.write_keyword("FUNCTION");
12389 }
12390
12391 if cf.if_not_exists {
12392 self.write_space();
12393 self.write_keyword("IF NOT EXISTS");
12394 }
12395
12396 self.write_space();
12397 self.generate_table(&cf.name)?;
12398 if cf.has_parens {
12399 let func_multiline = self.config.pretty
12400 && matches!(
12401 self.config.dialect,
12402 Some(crate::dialects::DialectType::TSQL)
12403 | Some(crate::dialects::DialectType::Fabric)
12404 )
12405 && !cf.parameters.is_empty();
12406 if func_multiline {
12407 self.write("(\n");
12408 self.indent_level += 2;
12409 self.write_indent();
12410 self.generate_function_parameters(&cf.parameters)?;
12411 self.write("\n");
12412 self.indent_level -= 2;
12413 self.write(")");
12414 } else {
12415 self.write("(");
12416 self.generate_function_parameters(&cf.parameters)?;
12417 self.write(")");
12418 }
12419 }
12420
12421 let use_multiline = self.config.pretty
12424 && matches!(
12425 self.config.dialect,
12426 Some(crate::dialects::DialectType::BigQuery)
12427 | Some(crate::dialects::DialectType::TSQL)
12428 | Some(crate::dialects::DialectType::Fabric)
12429 );
12430
12431 if cf.language_first {
12432 if let Some(lang) = &cf.language {
12434 if use_multiline {
12435 self.write_newline();
12436 } else {
12437 self.write_space();
12438 }
12439 self.write_keyword("LANGUAGE");
12440 self.write_space();
12441 self.write(lang);
12442 }
12443
12444 if let Some(sql_data) = &cf.sql_data_access {
12446 self.write_space();
12447 match sql_data {
12448 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12449 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12450 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12451 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12452 }
12453 }
12454
12455 if let Some(ref rtb) = cf.returns_table_body {
12456 if use_multiline {
12457 self.write_newline();
12458 } else {
12459 self.write_space();
12460 }
12461 self.write_keyword("RETURNS");
12462 self.write_space();
12463 self.write(rtb);
12464 } else if let Some(return_type) = &cf.return_type {
12465 if use_multiline {
12466 self.write_newline();
12467 } else {
12468 self.write_space();
12469 }
12470 self.write_keyword("RETURNS");
12471 self.write_space();
12472 self.generate_data_type(return_type)?;
12473 }
12474 } else {
12475 let is_duckdb = matches!(
12478 self.config.dialect,
12479 Some(crate::dialects::DialectType::DuckDB)
12480 );
12481 if let Some(ref rtb) = cf.returns_table_body {
12482 if !(is_duckdb && rtb.is_empty()) {
12483 if use_multiline {
12484 self.write_newline();
12485 } else {
12486 self.write_space();
12487 }
12488 self.write_keyword("RETURNS");
12489 self.write_space();
12490 self.write(rtb);
12491 }
12492 } else if let Some(return_type) = &cf.return_type {
12493 if !is_duckdb {
12495 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
12496 if use_multiline {
12497 self.write_newline();
12498 } else {
12499 self.write_space();
12500 }
12501 self.write_keyword("RETURNS");
12502 self.write_space();
12503 if is_table_return {
12504 self.write_keyword("TABLE");
12505 } else {
12506 self.generate_data_type(return_type)?;
12507 }
12508 }
12509 }
12510 }
12511
12512 if !cf.property_order.is_empty() {
12514 let is_bigquery = matches!(
12516 self.config.dialect,
12517 Some(crate::dialects::DialectType::BigQuery)
12518 );
12519 let property_order = if is_bigquery {
12520 let mut reordered = Vec::new();
12522 let mut has_as = false;
12523 let mut has_options = false;
12524 for prop in &cf.property_order {
12525 match prop {
12526 FunctionPropertyKind::As => has_as = true,
12527 FunctionPropertyKind::Options => has_options = true,
12528 _ => {}
12529 }
12530 }
12531 if has_as && has_options {
12532 for prop in &cf.property_order {
12534 if *prop != FunctionPropertyKind::As
12535 && *prop != FunctionPropertyKind::Options
12536 {
12537 reordered.push(*prop);
12538 }
12539 }
12540 reordered.push(FunctionPropertyKind::Options);
12541 reordered.push(FunctionPropertyKind::As);
12542 reordered
12543 } else {
12544 cf.property_order.clone()
12545 }
12546 } else {
12547 cf.property_order.clone()
12548 };
12549
12550 for prop in &property_order {
12551 match prop {
12552 FunctionPropertyKind::Set => {
12553 self.generate_function_set_options(cf)?;
12554 }
12555 FunctionPropertyKind::As => {
12556 self.generate_function_body(cf)?;
12557 }
12558 FunctionPropertyKind::Using => {
12559 self.generate_function_using_resources(cf)?;
12560 }
12561 FunctionPropertyKind::Language => {
12562 if !cf.language_first {
12563 if let Some(lang) = &cf.language {
12565 let use_multiline = self.config.pretty
12567 && matches!(
12568 self.config.dialect,
12569 Some(crate::dialects::DialectType::BigQuery)
12570 );
12571 if use_multiline {
12572 self.write_newline();
12573 } else {
12574 self.write_space();
12575 }
12576 self.write_keyword("LANGUAGE");
12577 self.write_space();
12578 self.write(lang);
12579 }
12580 }
12581 }
12582 FunctionPropertyKind::Determinism => {
12583 self.generate_function_determinism(cf)?;
12584 }
12585 FunctionPropertyKind::NullInput => {
12586 self.generate_function_null_input(cf)?;
12587 }
12588 FunctionPropertyKind::Security => {
12589 self.generate_function_security(cf)?;
12590 }
12591 FunctionPropertyKind::SqlDataAccess => {
12592 if !cf.language_first {
12593 self.generate_function_sql_data_access(cf)?;
12595 }
12596 }
12597 FunctionPropertyKind::Options => {
12598 if !cf.options.is_empty() {
12599 self.write_space();
12600 self.generate_options_clause(&cf.options)?;
12601 }
12602 }
12603 FunctionPropertyKind::Environment => {
12604 if !cf.environment.is_empty() {
12605 self.write_space();
12606 self.generate_environment_clause(&cf.environment)?;
12607 }
12608 }
12609 FunctionPropertyKind::Handler => {
12610 if let Some(ref h) = cf.handler {
12611 self.write_space();
12612 self.write_keyword("HANDLER");
12613 if cf.handler_uses_eq {
12614 self.write(" = ");
12615 } else {
12616 self.write_space();
12617 }
12618 self.write("'");
12619 self.write(h);
12620 self.write("'");
12621 }
12622 }
12623 FunctionPropertyKind::RuntimeVersion => {
12624 if let Some(ref runtime_version) = cf.runtime_version {
12625 self.write_space();
12626 self.write_keyword("RUNTIME_VERSION");
12627 self.write("='");
12628 self.write(runtime_version);
12629 self.write("'");
12630 }
12631 }
12632 FunctionPropertyKind::Packages => {
12633 if let Some(ref packages) = cf.packages {
12634 self.write_space();
12635 self.write_keyword("PACKAGES");
12636 self.write("=(");
12637 for (i, package) in packages.iter().enumerate() {
12638 if i > 0 {
12639 self.write(", ");
12640 }
12641 self.write("'");
12642 self.write(package);
12643 self.write("'");
12644 }
12645 self.write(")");
12646 }
12647 }
12648 FunctionPropertyKind::ParameterStyle => {
12649 if let Some(ref ps) = cf.parameter_style {
12650 self.write_space();
12651 self.write_keyword("PARAMETER STYLE");
12652 self.write_space();
12653 self.write_keyword(ps);
12654 }
12655 }
12656 }
12657 }
12658
12659 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
12661 {
12662 self.write_space();
12663 self.generate_options_clause(&cf.options)?;
12664 }
12665
12666 if !cf.environment.is_empty()
12668 && !cf
12669 .property_order
12670 .contains(&FunctionPropertyKind::Environment)
12671 {
12672 self.write_space();
12673 self.generate_environment_clause(&cf.environment)?;
12674 }
12675 } else {
12676 if matches!(
12679 self.config.dialect,
12680 Some(crate::dialects::DialectType::BigQuery)
12681 ) {
12682 self.generate_function_determinism(cf)?;
12683 }
12684
12685 let use_multiline = self.config.pretty
12687 && matches!(
12688 self.config.dialect,
12689 Some(crate::dialects::DialectType::BigQuery)
12690 );
12691
12692 if !cf.language_first {
12693 if let Some(lang) = &cf.language {
12694 if use_multiline {
12695 self.write_newline();
12696 } else {
12697 self.write_space();
12698 }
12699 self.write_keyword("LANGUAGE");
12700 self.write_space();
12701 self.write(lang);
12702 }
12703
12704 self.generate_function_sql_data_access(cf)?;
12706 }
12707
12708 if !matches!(
12710 self.config.dialect,
12711 Some(crate::dialects::DialectType::BigQuery)
12712 ) {
12713 self.generate_function_determinism(cf)?;
12714 }
12715
12716 self.generate_function_null_input(cf)?;
12717 self.generate_function_security(cf)?;
12718 self.generate_function_set_options(cf)?;
12719
12720 if !cf.options.is_empty() {
12722 self.write_space();
12723 self.generate_options_clause(&cf.options)?;
12724 }
12725
12726 if !cf.environment.is_empty() {
12728 self.write_space();
12729 self.generate_environment_clause(&cf.environment)?;
12730 }
12731
12732 if let Some(ref h) = cf.handler {
12733 self.write_space();
12734 self.write_keyword("HANDLER");
12735 if cf.handler_uses_eq {
12736 self.write(" = ");
12737 } else {
12738 self.write_space();
12739 }
12740 self.write("'");
12741 self.write(h);
12742 self.write("'");
12743 }
12744
12745 if let Some(ref runtime_version) = cf.runtime_version {
12746 self.write_space();
12747 self.write_keyword("RUNTIME_VERSION");
12748 self.write("='");
12749 self.write(runtime_version);
12750 self.write("'");
12751 }
12752
12753 if let Some(ref packages) = cf.packages {
12754 self.write_space();
12755 self.write_keyword("PACKAGES");
12756 self.write("=(");
12757 for (i, package) in packages.iter().enumerate() {
12758 if i > 0 {
12759 self.write(", ");
12760 }
12761 self.write("'");
12762 self.write(package);
12763 self.write("'");
12764 }
12765 self.write(")");
12766 }
12767
12768 self.generate_function_body(cf)?;
12769 self.generate_function_using_resources(cf)?;
12770 }
12771
12772 Ok(())
12773 }
12774
12775 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
12777 for opt in &cf.set_options {
12778 self.write_space();
12779 self.write_keyword("SET");
12780 self.write_space();
12781 self.write(&opt.name);
12782 match &opt.value {
12783 FunctionSetValue::Value { value, use_to } => {
12784 if *use_to {
12785 self.write(" TO ");
12786 } else {
12787 self.write(" = ");
12788 }
12789 self.write(value);
12790 }
12791 FunctionSetValue::FromCurrent => {
12792 self.write_space();
12793 self.write_keyword("FROM CURRENT");
12794 }
12795 }
12796 }
12797 Ok(())
12798 }
12799
12800 fn generate_function_using_resources(&mut self, cf: &CreateFunction) -> Result<()> {
12801 if cf.using_resources.is_empty() {
12802 return Ok(());
12803 }
12804
12805 self.write_space();
12806 self.write_keyword("USING");
12807 for resource in &cf.using_resources {
12808 self.write_space();
12809 self.write_keyword(&resource.kind);
12810 self.write_space();
12811 self.generate_string_literal(&resource.uri)?;
12812 }
12813 Ok(())
12814 }
12815
12816 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
12818 if let Some(body) = &cf.body {
12819 self.write_space();
12821 let use_multiline = self.config.pretty
12823 && matches!(
12824 self.config.dialect,
12825 Some(crate::dialects::DialectType::BigQuery)
12826 );
12827 match body {
12828 FunctionBody::Block(block) => {
12829 self.write_keyword("AS");
12830 if matches!(
12831 self.config.dialect,
12832 Some(crate::dialects::DialectType::TSQL)
12833 ) {
12834 self.write(" BEGIN ");
12835 self.write(block);
12836 self.write(" END");
12837 } else if matches!(
12838 self.config.dialect,
12839 Some(crate::dialects::DialectType::PostgreSQL)
12840 ) {
12841 self.write(" $$");
12842 self.write(block);
12843 self.write("$$");
12844 } else {
12845 let escaped = self.escape_block_for_single_quote(block);
12847 if use_multiline {
12849 self.write_newline();
12850 } else {
12851 self.write(" ");
12852 }
12853 self.write("'");
12854 self.write(&escaped);
12855 self.write("'");
12856 }
12857 }
12858 FunctionBody::StringLiteral(s) => {
12859 self.write_keyword("AS");
12860 if use_multiline {
12862 self.write_newline();
12863 } else {
12864 self.write(" ");
12865 }
12866 self.write("'");
12867 self.write(s);
12868 self.write("'");
12869 }
12870 FunctionBody::Expression(expr) => {
12871 self.write_keyword("AS");
12872 self.write_space();
12873 self.generate_expression(expr)?;
12874 }
12875 FunctionBody::External(name) => {
12876 self.write_keyword("EXTERNAL NAME");
12877 self.write(" '");
12878 self.write(name);
12879 self.write("'");
12880 }
12881 FunctionBody::Return(expr) => {
12882 if matches!(
12883 self.config.dialect,
12884 Some(crate::dialects::DialectType::DuckDB)
12885 ) {
12886 self.write_keyword("AS");
12888 self.write_space();
12889 let is_table_return = cf.returns_table_body.is_some()
12891 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
12892 if is_table_return {
12893 self.write_keyword("TABLE");
12894 self.write_space();
12895 }
12896 self.generate_expression(expr)?;
12897 } else {
12898 if self.config.create_function_return_as {
12899 self.write_keyword("AS");
12900 if self.config.pretty
12902 && matches!(
12903 self.config.dialect,
12904 Some(crate::dialects::DialectType::TSQL)
12905 | Some(crate::dialects::DialectType::Fabric)
12906 )
12907 {
12908 self.write_newline();
12909 } else {
12910 self.write_space();
12911 }
12912 }
12913 self.write_keyword("RETURN");
12914 self.write_space();
12915 self.generate_expression(expr)?;
12916 }
12917 }
12918 FunctionBody::Statements(stmts) => {
12919 self.write_keyword("AS");
12920 self.write(" BEGIN ");
12921 for (i, stmt) in stmts.iter().enumerate() {
12922 if i > 0 {
12923 self.write(" ");
12924 }
12925 self.generate_expression(stmt)?;
12926 self.write(";");
12927 }
12928 self.write(" END");
12929 }
12930 FunctionBody::RawBlock(text) => {
12931 self.write_newline();
12932 self.write(text);
12933 }
12934 FunctionBody::DollarQuoted { content, tag } => {
12935 self.write_keyword("AS");
12936 self.write(" ");
12937 let supports_dollar_quoting = matches!(
12939 self.config.dialect,
12940 Some(crate::dialects::DialectType::PostgreSQL)
12941 | Some(crate::dialects::DialectType::Databricks)
12942 | Some(crate::dialects::DialectType::Redshift)
12943 | Some(crate::dialects::DialectType::DuckDB)
12944 );
12945 if supports_dollar_quoting {
12946 self.write("$");
12948 if let Some(t) = tag {
12949 self.write(t);
12950 }
12951 self.write("$");
12952 self.write(content);
12953 self.write("$");
12954 if let Some(t) = tag {
12955 self.write(t);
12956 }
12957 self.write("$");
12958 } else {
12959 let escaped = self.escape_block_for_single_quote(content);
12961 self.write("'");
12962 self.write(&escaped);
12963 self.write("'");
12964 }
12965 }
12966 }
12967 }
12968 Ok(())
12969 }
12970
12971 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12973 if let Some(det) = cf.deterministic {
12974 self.write_space();
12975 if matches!(
12976 self.config.dialect,
12977 Some(crate::dialects::DialectType::BigQuery)
12978 ) {
12979 if det {
12981 self.write_keyword("DETERMINISTIC");
12982 } else {
12983 self.write_keyword("NOT DETERMINISTIC");
12984 }
12985 } else {
12986 if det {
12988 self.write_keyword("IMMUTABLE");
12989 } else {
12990 self.write_keyword("VOLATILE");
12991 }
12992 }
12993 }
12994 Ok(())
12995 }
12996
12997 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12999 if let Some(returns_null) = cf.returns_null_on_null_input {
13000 self.write_space();
13001 if returns_null {
13002 if cf.strict {
13003 self.write_keyword("STRICT");
13004 } else {
13005 self.write_keyword("RETURNS NULL ON NULL INPUT");
13006 }
13007 } else {
13008 self.write_keyword("CALLED ON NULL INPUT");
13009 }
13010 }
13011 Ok(())
13012 }
13013
13014 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
13016 if let Some(security) = &cf.security {
13017 self.write_space();
13018 if matches!(
13020 self.config.dialect,
13021 Some(crate::dialects::DialectType::MySQL)
13022 ) {
13023 self.write_keyword("SQL SECURITY");
13024 } else {
13025 self.write_keyword("SECURITY");
13026 }
13027 self.write_space();
13028 match security {
13029 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13030 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13031 FunctionSecurity::None => self.write_keyword("NONE"),
13032 }
13033 }
13034 Ok(())
13035 }
13036
13037 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
13039 if let Some(sql_data) = &cf.sql_data_access {
13040 self.write_space();
13041 match sql_data {
13042 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13043 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13044 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13045 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13046 }
13047 }
13048 Ok(())
13049 }
13050
13051 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
13052 for (i, param) in params.iter().enumerate() {
13053 if i > 0 {
13054 self.write(", ");
13055 }
13056
13057 if let Some(mode) = ¶m.mode {
13058 if let Some(text) = ¶m.mode_text {
13059 self.write(text);
13060 } else {
13061 match mode {
13062 ParameterMode::In => self.write_keyword("IN"),
13063 ParameterMode::Out => self.write_keyword("OUT"),
13064 ParameterMode::InOut => self.write_keyword("INOUT"),
13065 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
13066 }
13067 }
13068 self.write_space();
13069 }
13070
13071 if let Some(name) = ¶m.name {
13072 self.generate_identifier(name)?;
13073 let skip_type =
13075 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
13076 if !skip_type {
13077 self.write_space();
13078 self.generate_data_type(¶m.data_type)?;
13079 }
13080 } else {
13081 self.generate_data_type(¶m.data_type)?;
13082 }
13083
13084 if let Some(default) = ¶m.default {
13085 if self.config.parameter_default_equals {
13086 self.write(" = ");
13087 } else {
13088 self.write(" DEFAULT ");
13089 }
13090 self.generate_expression(default)?;
13091 }
13092 }
13093
13094 Ok(())
13095 }
13096
13097 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
13098 self.write_keyword("DROP FUNCTION");
13099
13100 if df.if_exists {
13101 self.write_space();
13102 self.write_keyword("IF EXISTS");
13103 }
13104
13105 self.write_space();
13106 self.generate_table(&df.name)?;
13107
13108 if let Some(params) = &df.parameters {
13109 self.write(" (");
13110 for (i, dt) in params.iter().enumerate() {
13111 if i > 0 {
13112 self.write(", ");
13113 }
13114 self.generate_data_type(dt)?;
13115 }
13116 self.write(")");
13117 }
13118
13119 if df.cascade {
13120 self.write_space();
13121 self.write_keyword("CASCADE");
13122 }
13123
13124 Ok(())
13125 }
13126
13127 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
13128 self.write_keyword("CREATE");
13129
13130 if cp.or_alter {
13131 self.write_space();
13132 self.write_keyword("OR ALTER");
13133 } else if cp.or_replace {
13134 self.write_space();
13135 self.write_keyword("OR REPLACE");
13136 }
13137
13138 self.write_space();
13139 if cp.use_proc_keyword {
13140 self.write_keyword("PROC");
13141 } else {
13142 self.write_keyword("PROCEDURE");
13143 }
13144
13145 if cp.if_not_exists {
13146 self.write_space();
13147 self.write_keyword("IF NOT EXISTS");
13148 }
13149
13150 self.write_space();
13151 self.generate_table(&cp.name)?;
13152 if cp.has_parens {
13153 self.write("(");
13154 self.generate_function_parameters(&cp.parameters)?;
13155 self.write(")");
13156 } else if !cp.parameters.is_empty() {
13157 self.write_space();
13159 self.generate_function_parameters(&cp.parameters)?;
13160 }
13161
13162 if let Some(return_type) = &cp.return_type {
13164 self.write_space();
13165 self.write_keyword("RETURNS");
13166 self.write_space();
13167 self.generate_data_type(return_type)?;
13168 }
13169
13170 if let Some(execute_as) = &cp.execute_as {
13172 self.write_space();
13173 self.write_keyword("EXECUTE AS");
13174 self.write_space();
13175 self.write_keyword(execute_as);
13176 }
13177
13178 if let Some(lang) = &cp.language {
13179 self.write_space();
13180 self.write_keyword("LANGUAGE");
13181 self.write_space();
13182 self.write(lang);
13183 }
13184
13185 if let Some(security) = &cp.security {
13186 self.write_space();
13187 self.write_keyword("SECURITY");
13188 self.write_space();
13189 match security {
13190 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13191 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13192 FunctionSecurity::None => self.write_keyword("NONE"),
13193 }
13194 }
13195
13196 if !cp.with_options.is_empty() {
13198 self.write_space();
13199 self.write_keyword("WITH");
13200 self.write_space();
13201 for (i, opt) in cp.with_options.iter().enumerate() {
13202 if i > 0 {
13203 self.write(", ");
13204 }
13205 self.write(opt);
13206 }
13207 }
13208
13209 if let Some(body) = &cp.body {
13210 self.write_space();
13211 match body {
13212 FunctionBody::Block(block) => {
13213 self.write_keyword("AS");
13214 if matches!(
13215 self.config.dialect,
13216 Some(crate::dialects::DialectType::TSQL)
13217 ) {
13218 self.write(" BEGIN ");
13219 self.write(block);
13220 self.write(" END");
13221 } else if matches!(
13222 self.config.dialect,
13223 Some(crate::dialects::DialectType::PostgreSQL)
13224 ) {
13225 self.write(" $$");
13226 self.write(block);
13227 self.write("$$");
13228 } else {
13229 let escaped = self.escape_block_for_single_quote(block);
13231 self.write(" '");
13232 self.write(&escaped);
13233 self.write("'");
13234 }
13235 }
13236 FunctionBody::StringLiteral(s) => {
13237 self.write_keyword("AS");
13238 self.write(" '");
13239 self.write(s);
13240 self.write("'");
13241 }
13242 FunctionBody::Expression(expr) => {
13243 self.write_keyword("AS");
13244 self.write_space();
13245 self.generate_expression(expr)?;
13246 }
13247 FunctionBody::External(name) => {
13248 self.write_keyword("EXTERNAL NAME");
13249 self.write(" '");
13250 self.write(name);
13251 self.write("'");
13252 }
13253 FunctionBody::Return(expr) => {
13254 self.write_keyword("RETURN");
13255 self.write_space();
13256 self.generate_expression(expr)?;
13257 }
13258 FunctionBody::Statements(stmts) => {
13259 self.write_keyword("AS");
13260 self.write(" BEGIN ");
13261 for (i, stmt) in stmts.iter().enumerate() {
13262 if i > 0 {
13263 self.write(" ");
13264 }
13265 self.generate_expression(stmt)?;
13266 self.write(";");
13267 }
13268 self.write(" END");
13269 }
13270 FunctionBody::RawBlock(text) => {
13271 self.write_newline();
13272 self.write(text);
13273 }
13274 FunctionBody::DollarQuoted { content, tag } => {
13275 self.write_keyword("AS");
13276 self.write(" ");
13277 let supports_dollar_quoting = matches!(
13279 self.config.dialect,
13280 Some(crate::dialects::DialectType::PostgreSQL)
13281 | Some(crate::dialects::DialectType::Databricks)
13282 | Some(crate::dialects::DialectType::Redshift)
13283 | Some(crate::dialects::DialectType::DuckDB)
13284 );
13285 if supports_dollar_quoting {
13286 self.write("$");
13288 if let Some(t) = tag {
13289 self.write(t);
13290 }
13291 self.write("$");
13292 self.write(content);
13293 self.write("$");
13294 if let Some(t) = tag {
13295 self.write(t);
13296 }
13297 self.write("$");
13298 } else {
13299 let escaped = self.escape_block_for_single_quote(content);
13301 self.write("'");
13302 self.write(&escaped);
13303 self.write("'");
13304 }
13305 }
13306 }
13307 }
13308
13309 Ok(())
13310 }
13311
13312 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
13313 self.write_keyword("DROP PROCEDURE");
13314
13315 if dp.if_exists {
13316 self.write_space();
13317 self.write_keyword("IF EXISTS");
13318 }
13319
13320 self.write_space();
13321 self.generate_table(&dp.name)?;
13322
13323 if let Some(params) = &dp.parameters {
13324 self.write(" (");
13325 for (i, dt) in params.iter().enumerate() {
13326 if i > 0 {
13327 self.write(", ");
13328 }
13329 self.generate_data_type(dt)?;
13330 }
13331 self.write(")");
13332 }
13333
13334 if dp.cascade {
13335 self.write_space();
13336 self.write_keyword("CASCADE");
13337 }
13338
13339 Ok(())
13340 }
13341
13342 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
13343 self.write_keyword("CREATE");
13344
13345 if cs.or_replace {
13346 self.write_space();
13347 self.write_keyword("OR REPLACE");
13348 }
13349
13350 if cs.temporary {
13351 self.write_space();
13352 self.write_keyword("TEMPORARY");
13353 }
13354
13355 self.write_space();
13356 self.write_keyword("SEQUENCE");
13357
13358 if cs.if_not_exists {
13359 self.write_space();
13360 self.write_keyword("IF NOT EXISTS");
13361 }
13362
13363 self.write_space();
13364 self.generate_table(&cs.name)?;
13365
13366 if let Some(as_type) = &cs.as_type {
13368 self.write_space();
13369 self.write_keyword("AS");
13370 self.write_space();
13371 self.generate_data_type(as_type)?;
13372 }
13373
13374 if let Some(comment) = &cs.comment {
13376 self.write_space();
13377 self.write_keyword("COMMENT");
13378 self.write("=");
13379 self.generate_string_literal(comment)?;
13380 }
13381
13382 if !cs.property_order.is_empty() {
13384 for prop in &cs.property_order {
13385 match prop {
13386 SeqPropKind::Start => {
13387 if let Some(start) = cs.start {
13388 self.write_space();
13389 self.write_keyword("START WITH");
13390 self.write(&format!(" {}", start));
13391 }
13392 }
13393 SeqPropKind::Increment => {
13394 if let Some(inc) = cs.increment {
13395 self.write_space();
13396 self.write_keyword("INCREMENT BY");
13397 self.write(&format!(" {}", inc));
13398 }
13399 }
13400 SeqPropKind::Minvalue => {
13401 if let Some(min) = &cs.minvalue {
13402 self.write_space();
13403 match min {
13404 SequenceBound::Value(v) => {
13405 self.write_keyword("MINVALUE");
13406 self.write(&format!(" {}", v));
13407 }
13408 SequenceBound::None => {
13409 self.write_keyword("NO MINVALUE");
13410 }
13411 }
13412 }
13413 }
13414 SeqPropKind::Maxvalue => {
13415 if let Some(max) = &cs.maxvalue {
13416 self.write_space();
13417 match max {
13418 SequenceBound::Value(v) => {
13419 self.write_keyword("MAXVALUE");
13420 self.write(&format!(" {}", v));
13421 }
13422 SequenceBound::None => {
13423 self.write_keyword("NO MAXVALUE");
13424 }
13425 }
13426 }
13427 }
13428 SeqPropKind::Cache => {
13429 if let Some(cache) = cs.cache {
13430 self.write_space();
13431 self.write_keyword("CACHE");
13432 self.write(&format!(" {}", cache));
13433 }
13434 }
13435 SeqPropKind::NoCache => {
13436 self.write_space();
13437 self.write_keyword("NO CACHE");
13438 }
13439 SeqPropKind::NoCacheWord => {
13440 self.write_space();
13441 self.write_keyword("NOCACHE");
13442 }
13443 SeqPropKind::Cycle => {
13444 self.write_space();
13445 self.write_keyword("CYCLE");
13446 }
13447 SeqPropKind::NoCycle => {
13448 self.write_space();
13449 self.write_keyword("NO CYCLE");
13450 }
13451 SeqPropKind::NoCycleWord => {
13452 self.write_space();
13453 self.write_keyword("NOCYCLE");
13454 }
13455 SeqPropKind::OwnedBy => {
13456 if !cs.owned_by_none {
13458 if let Some(owned) = &cs.owned_by {
13459 self.write_space();
13460 self.write_keyword("OWNED BY");
13461 self.write_space();
13462 self.generate_table(owned)?;
13463 }
13464 }
13465 }
13466 SeqPropKind::Order => {
13467 self.write_space();
13468 self.write_keyword("ORDER");
13469 }
13470 SeqPropKind::NoOrder => {
13471 self.write_space();
13472 self.write_keyword("NOORDER");
13473 }
13474 SeqPropKind::Comment => {
13475 }
13477 SeqPropKind::Sharing => {
13478 if let Some(val) = &cs.sharing {
13479 self.write_space();
13480 self.write(&format!("SHARING={}", val));
13481 }
13482 }
13483 SeqPropKind::Keep => {
13484 self.write_space();
13485 self.write_keyword("KEEP");
13486 }
13487 SeqPropKind::NoKeep => {
13488 self.write_space();
13489 self.write_keyword("NOKEEP");
13490 }
13491 SeqPropKind::Scale => {
13492 self.write_space();
13493 self.write_keyword("SCALE");
13494 if let Some(modifier) = &cs.scale_modifier {
13495 if !modifier.is_empty() {
13496 self.write_space();
13497 self.write_keyword(modifier);
13498 }
13499 }
13500 }
13501 SeqPropKind::NoScale => {
13502 self.write_space();
13503 self.write_keyword("NOSCALE");
13504 }
13505 SeqPropKind::Shard => {
13506 self.write_space();
13507 self.write_keyword("SHARD");
13508 if let Some(modifier) = &cs.shard_modifier {
13509 if !modifier.is_empty() {
13510 self.write_space();
13511 self.write_keyword(modifier);
13512 }
13513 }
13514 }
13515 SeqPropKind::NoShard => {
13516 self.write_space();
13517 self.write_keyword("NOSHARD");
13518 }
13519 SeqPropKind::Session => {
13520 self.write_space();
13521 self.write_keyword("SESSION");
13522 }
13523 SeqPropKind::Global => {
13524 self.write_space();
13525 self.write_keyword("GLOBAL");
13526 }
13527 SeqPropKind::NoMinvalueWord => {
13528 self.write_space();
13529 self.write_keyword("NOMINVALUE");
13530 }
13531 SeqPropKind::NoMaxvalueWord => {
13532 self.write_space();
13533 self.write_keyword("NOMAXVALUE");
13534 }
13535 }
13536 }
13537 } else {
13538 if let Some(inc) = cs.increment {
13540 self.write_space();
13541 self.write_keyword("INCREMENT BY");
13542 self.write(&format!(" {}", inc));
13543 }
13544
13545 if let Some(min) = &cs.minvalue {
13546 self.write_space();
13547 match min {
13548 SequenceBound::Value(v) => {
13549 self.write_keyword("MINVALUE");
13550 self.write(&format!(" {}", v));
13551 }
13552 SequenceBound::None => {
13553 self.write_keyword("NO MINVALUE");
13554 }
13555 }
13556 }
13557
13558 if let Some(max) = &cs.maxvalue {
13559 self.write_space();
13560 match max {
13561 SequenceBound::Value(v) => {
13562 self.write_keyword("MAXVALUE");
13563 self.write(&format!(" {}", v));
13564 }
13565 SequenceBound::None => {
13566 self.write_keyword("NO MAXVALUE");
13567 }
13568 }
13569 }
13570
13571 if let Some(start) = cs.start {
13572 self.write_space();
13573 self.write_keyword("START WITH");
13574 self.write(&format!(" {}", start));
13575 }
13576
13577 if let Some(cache) = cs.cache {
13578 self.write_space();
13579 self.write_keyword("CACHE");
13580 self.write(&format!(" {}", cache));
13581 }
13582
13583 if cs.cycle {
13584 self.write_space();
13585 self.write_keyword("CYCLE");
13586 }
13587
13588 if let Some(owned) = &cs.owned_by {
13589 self.write_space();
13590 self.write_keyword("OWNED BY");
13591 self.write_space();
13592 self.generate_table(owned)?;
13593 }
13594 }
13595
13596 Ok(())
13597 }
13598
13599 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
13600 self.write_keyword("DROP SEQUENCE");
13601
13602 if ds.if_exists {
13603 self.write_space();
13604 self.write_keyword("IF EXISTS");
13605 }
13606
13607 self.write_space();
13608 self.generate_table(&ds.name)?;
13609
13610 if ds.cascade {
13611 self.write_space();
13612 self.write_keyword("CASCADE");
13613 }
13614
13615 Ok(())
13616 }
13617
13618 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
13619 self.write_keyword("ALTER SEQUENCE");
13620
13621 if als.if_exists {
13622 self.write_space();
13623 self.write_keyword("IF EXISTS");
13624 }
13625
13626 self.write_space();
13627 self.generate_table(&als.name)?;
13628
13629 if let Some(inc) = als.increment {
13630 self.write_space();
13631 self.write_keyword("INCREMENT BY");
13632 self.write(&format!(" {}", inc));
13633 }
13634
13635 if let Some(min) = &als.minvalue {
13636 self.write_space();
13637 match min {
13638 SequenceBound::Value(v) => {
13639 self.write_keyword("MINVALUE");
13640 self.write(&format!(" {}", v));
13641 }
13642 SequenceBound::None => {
13643 self.write_keyword("NO MINVALUE");
13644 }
13645 }
13646 }
13647
13648 if let Some(max) = &als.maxvalue {
13649 self.write_space();
13650 match max {
13651 SequenceBound::Value(v) => {
13652 self.write_keyword("MAXVALUE");
13653 self.write(&format!(" {}", v));
13654 }
13655 SequenceBound::None => {
13656 self.write_keyword("NO MAXVALUE");
13657 }
13658 }
13659 }
13660
13661 if let Some(start) = als.start {
13662 self.write_space();
13663 self.write_keyword("START WITH");
13664 self.write(&format!(" {}", start));
13665 }
13666
13667 if let Some(restart) = &als.restart {
13668 self.write_space();
13669 self.write_keyword("RESTART");
13670 if let Some(val) = restart {
13671 self.write_keyword(" WITH");
13672 self.write(&format!(" {}", val));
13673 }
13674 }
13675
13676 if let Some(cache) = als.cache {
13677 self.write_space();
13678 self.write_keyword("CACHE");
13679 self.write(&format!(" {}", cache));
13680 }
13681
13682 if let Some(cycle) = als.cycle {
13683 self.write_space();
13684 if cycle {
13685 self.write_keyword("CYCLE");
13686 } else {
13687 self.write_keyword("NO CYCLE");
13688 }
13689 }
13690
13691 if let Some(owned) = &als.owned_by {
13692 self.write_space();
13693 self.write_keyword("OWNED BY");
13694 self.write_space();
13695 if let Some(table) = owned {
13696 self.generate_table(table)?;
13697 } else {
13698 self.write_keyword("NONE");
13699 }
13700 }
13701
13702 Ok(())
13703 }
13704
13705 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
13706 self.write_keyword("CREATE");
13707
13708 if ct.or_alter {
13709 self.write_space();
13710 self.write_keyword("OR ALTER");
13711 } else if ct.or_replace {
13712 self.write_space();
13713 self.write_keyword("OR REPLACE");
13714 }
13715
13716 if ct.constraint {
13717 self.write_space();
13718 self.write_keyword("CONSTRAINT");
13719 }
13720
13721 self.write_space();
13722 self.write_keyword("TRIGGER");
13723 self.write_space();
13724 self.generate_identifier(&ct.name)?;
13725
13726 self.write_space();
13727 match ct.timing {
13728 TriggerTiming::Before => self.write_keyword("BEFORE"),
13729 TriggerTiming::After => self.write_keyword("AFTER"),
13730 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
13731 }
13732
13733 for (i, event) in ct.events.iter().enumerate() {
13735 if i > 0 {
13736 self.write_keyword(" OR");
13737 }
13738 self.write_space();
13739 match event {
13740 TriggerEvent::Insert => self.write_keyword("INSERT"),
13741 TriggerEvent::Update(cols) => {
13742 self.write_keyword("UPDATE");
13743 if let Some(cols) = cols {
13744 self.write_space();
13745 self.write_keyword("OF");
13746 for (j, col) in cols.iter().enumerate() {
13747 if j > 0 {
13748 self.write(",");
13749 }
13750 self.write_space();
13751 self.generate_identifier(col)?;
13752 }
13753 }
13754 }
13755 TriggerEvent::Delete => self.write_keyword("DELETE"),
13756 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
13757 }
13758 }
13759
13760 self.write_space();
13761 self.write_keyword("ON");
13762 self.write_space();
13763 self.generate_table(&ct.table)?;
13764
13765 if let Some(ref_clause) = &ct.referencing {
13767 self.write_space();
13768 self.write_keyword("REFERENCING");
13769 if let Some(old_table) = &ref_clause.old_table {
13770 self.write_space();
13771 self.write_keyword("OLD TABLE AS");
13772 self.write_space();
13773 self.generate_identifier(old_table)?;
13774 }
13775 if let Some(new_table) = &ref_clause.new_table {
13776 self.write_space();
13777 self.write_keyword("NEW TABLE AS");
13778 self.write_space();
13779 self.generate_identifier(new_table)?;
13780 }
13781 if let Some(old_row) = &ref_clause.old_row {
13782 self.write_space();
13783 self.write_keyword("OLD ROW AS");
13784 self.write_space();
13785 self.generate_identifier(old_row)?;
13786 }
13787 if let Some(new_row) = &ref_clause.new_row {
13788 self.write_space();
13789 self.write_keyword("NEW ROW AS");
13790 self.write_space();
13791 self.generate_identifier(new_row)?;
13792 }
13793 }
13794
13795 if let Some(deferrable) = ct.deferrable {
13797 self.write_space();
13798 if deferrable {
13799 self.write_keyword("DEFERRABLE");
13800 } else {
13801 self.write_keyword("NOT DEFERRABLE");
13802 }
13803 }
13804
13805 if let Some(initially) = ct.initially_deferred {
13806 self.write_space();
13807 self.write_keyword("INITIALLY");
13808 self.write_space();
13809 if initially {
13810 self.write_keyword("DEFERRED");
13811 } else {
13812 self.write_keyword("IMMEDIATE");
13813 }
13814 }
13815
13816 if let Some(for_each) = ct.for_each {
13817 self.write_space();
13818 self.write_keyword("FOR EACH");
13819 self.write_space();
13820 match for_each {
13821 TriggerForEach::Row => self.write_keyword("ROW"),
13822 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
13823 }
13824 }
13825
13826 if let Some(when) = &ct.when {
13828 self.write_space();
13829 self.write_keyword("WHEN");
13830 if ct.when_paren {
13831 self.write(" (");
13832 self.generate_expression(when)?;
13833 self.write(")");
13834 } else {
13835 self.write_space();
13836 self.generate_expression(when)?;
13837 }
13838 }
13839
13840 self.write_space();
13842 match &ct.body {
13843 TriggerBody::Execute { function, args } => {
13844 self.write_keyword("EXECUTE FUNCTION");
13845 self.write_space();
13846 self.generate_table(function)?;
13847 self.write("(");
13848 for (i, arg) in args.iter().enumerate() {
13849 if i > 0 {
13850 self.write(", ");
13851 }
13852 self.generate_expression(arg)?;
13853 }
13854 self.write(")");
13855 }
13856 TriggerBody::Block(block) => {
13857 self.write_keyword("BEGIN");
13858 self.write_space();
13859 self.write(block);
13860 self.write_space();
13861 self.write_keyword("END");
13862 }
13863 }
13864
13865 Ok(())
13866 }
13867
13868 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
13869 self.write_keyword("DROP TRIGGER");
13870
13871 if dt.if_exists {
13872 self.write_space();
13873 self.write_keyword("IF EXISTS");
13874 }
13875
13876 self.write_space();
13877 self.generate_identifier(&dt.name)?;
13878
13879 if let Some(table) = &dt.table {
13880 self.write_space();
13881 self.write_keyword("ON");
13882 self.write_space();
13883 self.generate_table(table)?;
13884 }
13885
13886 if dt.cascade {
13887 self.write_space();
13888 self.write_keyword("CASCADE");
13889 }
13890
13891 Ok(())
13892 }
13893
13894 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
13895 self.write_keyword("CREATE TYPE");
13896
13897 if ct.if_not_exists {
13898 self.write_space();
13899 self.write_keyword("IF NOT EXISTS");
13900 }
13901
13902 self.write_space();
13903 self.generate_table(&ct.name)?;
13904
13905 self.write_space();
13906 self.write_keyword("AS");
13907 self.write_space();
13908
13909 match &ct.definition {
13910 TypeDefinition::Enum(values) => {
13911 self.write_keyword("ENUM");
13912 self.write(" (");
13913 for (i, val) in values.iter().enumerate() {
13914 if i > 0 {
13915 self.write(", ");
13916 }
13917 self.write(&format!("'{}'", val));
13918 }
13919 self.write(")");
13920 }
13921 TypeDefinition::Composite(attrs) => {
13922 self.write("(");
13923 for (i, attr) in attrs.iter().enumerate() {
13924 if i > 0 {
13925 self.write(", ");
13926 }
13927 self.generate_identifier(&attr.name)?;
13928 self.write_space();
13929 self.generate_data_type(&attr.data_type)?;
13930 if let Some(collate) = &attr.collate {
13931 self.write_space();
13932 self.write_keyword("COLLATE");
13933 self.write_space();
13934 self.generate_identifier(collate)?;
13935 }
13936 }
13937 self.write(")");
13938 }
13939 TypeDefinition::Range {
13940 subtype,
13941 subtype_diff,
13942 canonical,
13943 } => {
13944 self.write_keyword("RANGE");
13945 self.write(" (");
13946 self.write_keyword("SUBTYPE");
13947 self.write(" = ");
13948 self.generate_data_type(subtype)?;
13949 if let Some(diff) = subtype_diff {
13950 self.write(", ");
13951 self.write_keyword("SUBTYPE_DIFF");
13952 self.write(" = ");
13953 self.write(diff);
13954 }
13955 if let Some(canon) = canonical {
13956 self.write(", ");
13957 self.write_keyword("CANONICAL");
13958 self.write(" = ");
13959 self.write(canon);
13960 }
13961 self.write(")");
13962 }
13963 TypeDefinition::Base {
13964 input,
13965 output,
13966 internallength,
13967 } => {
13968 self.write("(");
13969 self.write_keyword("INPUT");
13970 self.write(" = ");
13971 self.write(input);
13972 self.write(", ");
13973 self.write_keyword("OUTPUT");
13974 self.write(" = ");
13975 self.write(output);
13976 if let Some(len) = internallength {
13977 self.write(", ");
13978 self.write_keyword("INTERNALLENGTH");
13979 self.write(" = ");
13980 self.write(&len.to_string());
13981 }
13982 self.write(")");
13983 }
13984 TypeDefinition::Domain {
13985 base_type,
13986 default,
13987 constraints,
13988 } => {
13989 self.generate_data_type(base_type)?;
13990 if let Some(def) = default {
13991 self.write_space();
13992 self.write_keyword("DEFAULT");
13993 self.write_space();
13994 self.generate_expression(def)?;
13995 }
13996 for constr in constraints {
13997 self.write_space();
13998 if let Some(name) = &constr.name {
13999 self.write_keyword("CONSTRAINT");
14000 self.write_space();
14001 self.generate_identifier(name)?;
14002 self.write_space();
14003 }
14004 self.write_keyword("CHECK");
14005 self.write(" (");
14006 self.generate_expression(&constr.check)?;
14007 self.write(")");
14008 }
14009 }
14010 }
14011
14012 Ok(())
14013 }
14014
14015 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
14016 self.write_keyword("CREATE");
14017 if task.or_replace {
14018 self.write_space();
14019 self.write_keyword("OR REPLACE");
14020 }
14021 self.write_space();
14022 self.write_keyword("TASK");
14023 if task.if_not_exists {
14024 self.write_space();
14025 self.write_keyword("IF NOT EXISTS");
14026 }
14027 self.write_space();
14028 self.write(&task.name);
14029 if !task.properties.is_empty() {
14030 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
14032 self.write_space();
14033 }
14034 self.write(&task.properties);
14035 }
14036 self.write_space();
14037 self.write_keyword("AS");
14038 self.write_space();
14039 self.generate_expression(&task.body)?;
14040 Ok(())
14041 }
14042
14043 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
14044 self.write_keyword("DROP TYPE");
14045
14046 if dt.if_exists {
14047 self.write_space();
14048 self.write_keyword("IF EXISTS");
14049 }
14050
14051 self.write_space();
14052 self.generate_table(&dt.name)?;
14053
14054 if dt.cascade {
14055 self.write_space();
14056 self.write_keyword("CASCADE");
14057 }
14058
14059 Ok(())
14060 }
14061
14062 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
14063 let saved_athena_hive_context = self.athena_hive_context;
14065 if matches!(
14066 self.config.dialect,
14067 Some(crate::dialects::DialectType::Athena)
14068 ) {
14069 self.athena_hive_context = true;
14070 }
14071
14072 for comment in &d.leading_comments {
14074 self.write_formatted_comment(comment);
14075 self.write(" ");
14076 }
14077
14078 self.write_keyword("DESCRIBE");
14079
14080 if d.extended {
14081 self.write_space();
14082 self.write_keyword("EXTENDED");
14083 } else if d.formatted {
14084 self.write_space();
14085 self.write_keyword("FORMATTED");
14086 }
14087
14088 if let Some(ref style) = d.style {
14090 self.write_space();
14091 self.write_keyword(style);
14092 }
14093
14094 let should_output_kind = match self.config.dialect {
14096 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
14098 false
14099 }
14100 Some(DialectType::Snowflake) => true,
14102 _ => d.kind.is_some(),
14103 };
14104 if should_output_kind {
14105 if let Some(ref kind) = d.kind {
14106 self.write_space();
14107 self.write_keyword(kind);
14108 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
14109 self.write_space();
14110 self.write_keyword("TABLE");
14111 }
14112 }
14113
14114 self.write_space();
14115 self.generate_expression(&d.target)?;
14116
14117 if !d.params.is_empty() {
14119 self.write("(");
14120 for (i, param) in d.params.iter().enumerate() {
14121 if i > 0 {
14122 self.write(", ");
14123 }
14124 self.write(param);
14125 }
14126 self.write(")");
14127 }
14128
14129 if let Some(ref partition) = d.partition {
14131 self.write_space();
14132 self.generate_expression(partition)?;
14133 }
14134
14135 if d.as_json {
14137 self.write_space();
14138 self.write_keyword("AS JSON");
14139 }
14140
14141 for (name, value) in &d.properties {
14143 self.write_space();
14144 self.write(name);
14145 self.write("=");
14146 self.write(value);
14147 }
14148
14149 self.athena_hive_context = saved_athena_hive_context;
14151
14152 Ok(())
14153 }
14154
14155 fn generate_show(&mut self, s: &Show) -> Result<()> {
14158 self.write_keyword("SHOW");
14159 self.write_space();
14160
14161 let show_terse = s.terse
14164 && !matches!(
14165 s.this.as_str(),
14166 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
14167 );
14168 if show_terse {
14169 self.write_keyword("TERSE");
14170 self.write_space();
14171 }
14172
14173 self.write_keyword(&s.this);
14175
14176 if let Some(ref target_expr) = s.target {
14178 self.write_space();
14179 self.generate_expression(target_expr)?;
14180 }
14181
14182 if s.history {
14184 self.write_space();
14185 self.write_keyword("HISTORY");
14186 }
14187
14188 if let Some(ref for_target) = s.for_target {
14190 self.write_space();
14191 self.write_keyword("FOR");
14192 self.write_space();
14193 self.generate_expression(for_target)?;
14194 }
14195
14196 use crate::dialects::DialectType;
14200 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
14201
14202 if !is_snowflake && s.from.is_some() {
14203 if let Some(ref scope_kind) = s.scope_kind {
14207 self.write_space();
14208 self.write_keyword("IN");
14209 self.write_space();
14210 self.write_keyword(scope_kind);
14211 if let Some(ref scope) = s.scope {
14212 self.write_space();
14213 self.generate_expression(scope)?;
14214 }
14215 } else if let Some(ref scope) = s.scope {
14216 self.write_space();
14217 self.write_keyword("IN");
14218 self.write_space();
14219 self.generate_expression(scope)?;
14220 }
14221
14222 if let Some(ref from) = s.from {
14224 self.write_space();
14225 self.write_keyword("FROM");
14226 self.write_space();
14227 self.generate_expression(from)?;
14228 }
14229
14230 if let Some(ref db) = s.db {
14232 self.write_space();
14233 self.write_keyword("FROM");
14234 self.write_space();
14235 self.generate_expression(db)?;
14236 }
14237
14238 if let Some(ref like) = s.like {
14240 self.write_space();
14241 self.write_keyword("LIKE");
14242 self.write_space();
14243 self.generate_expression(like)?;
14244 }
14245 } else {
14246 if let Some(ref like) = s.like {
14250 self.write_space();
14251 self.write_keyword("LIKE");
14252 self.write_space();
14253 self.generate_expression(like)?;
14254 }
14255
14256 if let Some(ref scope_kind) = s.scope_kind {
14258 self.write_space();
14259 self.write_keyword("IN");
14260 self.write_space();
14261 self.write_keyword(scope_kind);
14262 if let Some(ref scope) = s.scope {
14263 self.write_space();
14264 self.generate_expression(scope)?;
14265 }
14266 } else if let Some(ref scope) = s.scope {
14267 self.write_space();
14268 self.write_keyword("IN");
14269 self.write_space();
14270 self.generate_expression(scope)?;
14271 }
14272 }
14273
14274 if let Some(ref starts_with) = s.starts_with {
14276 self.write_space();
14277 self.write_keyword("STARTS WITH");
14278 self.write_space();
14279 self.generate_expression(starts_with)?;
14280 }
14281
14282 if let Some(ref limit) = s.limit {
14284 self.write_space();
14285 self.generate_limit(limit)?;
14286 }
14287
14288 if is_snowflake {
14290 if let Some(ref from) = s.from {
14291 self.write_space();
14292 self.write_keyword("FROM");
14293 self.write_space();
14294 self.generate_expression(from)?;
14295 }
14296 }
14297
14298 if let Some(ref where_clause) = s.where_clause {
14300 self.write_space();
14301 self.write_keyword("WHERE");
14302 self.write_space();
14303 self.generate_expression(where_clause)?;
14304 }
14305
14306 if let Some(is_mutex) = s.mutex {
14308 self.write_space();
14309 if is_mutex {
14310 self.write_keyword("MUTEX");
14311 } else {
14312 self.write_keyword("STATUS");
14313 }
14314 }
14315
14316 if !s.privileges.is_empty() {
14318 self.write_space();
14319 self.write_keyword("WITH PRIVILEGES");
14320 self.write_space();
14321 for (i, priv_name) in s.privileges.iter().enumerate() {
14322 if i > 0 {
14323 self.write(", ");
14324 }
14325 self.write_keyword(priv_name);
14326 }
14327 }
14328
14329 Ok(())
14330 }
14331
14332 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
14335 use crate::dialects::DialectType;
14336 match lit {
14337 Literal::String(s) => {
14338 self.generate_string_literal(s)?;
14339 }
14340 Literal::Number(n) => {
14341 if matches!(self.config.dialect, Some(DialectType::MySQL))
14342 && n.len() > 2
14343 && (n.starts_with("0x") || n.starts_with("0X"))
14344 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
14345 {
14346 return self.generate_identifier(&Identifier {
14347 name: n.clone(),
14348 quoted: true,
14349 trailing_comments: Vec::new(),
14350 span: None,
14351 });
14352 }
14353 let n = if n.contains('_')
14357 && !matches!(
14358 self.config.dialect,
14359 Some(DialectType::ClickHouse)
14360 | Some(DialectType::DuckDB)
14361 | Some(DialectType::PostgreSQL)
14362 | Some(DialectType::Hive)
14363 | Some(DialectType::Spark)
14364 | Some(DialectType::Databricks)
14365 ) {
14366 std::borrow::Cow::Owned(n.replace('_', ""))
14367 } else {
14368 std::borrow::Cow::Borrowed(n.as_str())
14369 };
14370 if n.starts_with('.') {
14373 self.write("0");
14374 self.write(&n);
14375 } else if n.starts_with("-.") {
14376 self.write("-0");
14378 self.write(&n[1..]);
14379 } else {
14380 self.write(&n);
14381 }
14382 }
14383 Literal::HexString(h) => {
14384 match self.config.dialect {
14386 Some(DialectType::Spark)
14387 | Some(DialectType::Databricks)
14388 | Some(DialectType::Teradata) => self.write("X'"),
14389 _ => self.write("x'"),
14390 }
14391 self.write(h);
14392 self.write("'");
14393 }
14394 Literal::HexNumber(h) => {
14395 match self.config.dialect {
14399 Some(DialectType::BigQuery)
14400 | Some(DialectType::TSQL)
14401 | Some(DialectType::Fabric) => {
14402 self.write("0x");
14403 self.write(h);
14404 }
14405 _ => {
14406 if let Ok(val) = u64::from_str_radix(h, 16) {
14408 self.write(&val.to_string());
14409 } else {
14410 self.write("0x");
14412 self.write(h);
14413 }
14414 }
14415 }
14416 }
14417 Literal::BitString(b) => {
14418 self.write("B'");
14420 self.write(b);
14421 self.write("'");
14422 }
14423 Literal::ByteString(b) => {
14424 self.write("b'");
14426 self.write_escaped_byte_string(b);
14428 self.write("'");
14429 }
14430 Literal::NationalString(s) => {
14431 let keep_n_prefix = matches!(
14434 self.config.dialect,
14435 Some(DialectType::TSQL)
14436 | Some(DialectType::Oracle)
14437 | Some(DialectType::MySQL)
14438 | None
14439 );
14440 if keep_n_prefix {
14441 self.write("N'");
14442 } else {
14443 self.write("'");
14444 }
14445 self.write(s);
14446 self.write("'");
14447 }
14448 Literal::Date(d) => {
14449 self.generate_date_literal(d)?;
14450 }
14451 Literal::Time(t) => {
14452 self.generate_time_literal(t)?;
14453 }
14454 Literal::Timestamp(ts) => {
14455 self.generate_timestamp_literal(ts)?;
14456 }
14457 Literal::Datetime(dt) => {
14458 self.generate_datetime_literal(dt)?;
14459 }
14460 Literal::TripleQuotedString(s, _quote_char) => {
14461 if matches!(
14463 self.config.dialect,
14464 Some(crate::dialects::DialectType::BigQuery)
14465 | Some(crate::dialects::DialectType::DuckDB)
14466 | Some(crate::dialects::DialectType::Snowflake)
14467 | Some(crate::dialects::DialectType::Spark)
14468 | Some(crate::dialects::DialectType::Hive)
14469 | Some(crate::dialects::DialectType::Presto)
14470 | Some(crate::dialects::DialectType::Trino)
14471 | Some(crate::dialects::DialectType::PostgreSQL)
14472 | Some(crate::dialects::DialectType::MySQL)
14473 | Some(crate::dialects::DialectType::Redshift)
14474 | Some(crate::dialects::DialectType::TSQL)
14475 | Some(crate::dialects::DialectType::Oracle)
14476 | Some(crate::dialects::DialectType::ClickHouse)
14477 | Some(crate::dialects::DialectType::Databricks)
14478 | Some(crate::dialects::DialectType::SQLite)
14479 ) {
14480 self.generate_string_literal(s)?;
14481 } else {
14482 let quotes = format!("{0}{0}{0}", _quote_char);
14484 self.write("es);
14485 self.write(s);
14486 self.write("es);
14487 }
14488 }
14489 Literal::EscapeString(s) => {
14490 use crate::dialects::DialectType;
14494 let content = if let Some(c) = s.strip_prefix("e:") {
14495 c
14496 } else if let Some(c) = s.strip_prefix("E:") {
14497 c
14498 } else {
14499 s.as_str()
14500 };
14501
14502 if matches!(
14504 self.config.dialect,
14505 Some(DialectType::MySQL) | Some(DialectType::TiDB)
14506 ) {
14507 self.write(content);
14508 } else {
14509 let prefix = if matches!(
14511 self.config.dialect,
14512 Some(DialectType::SingleStore)
14513 | Some(DialectType::DuckDB)
14514 | Some(DialectType::PostgreSQL)
14515 | Some(DialectType::CockroachDB)
14516 | Some(DialectType::Materialize)
14517 | Some(DialectType::RisingWave)
14518 ) {
14519 "e'"
14520 } else {
14521 "E'"
14522 };
14523
14524 let normalized = content.replace("\\'", "''");
14526 self.write(prefix);
14527 self.write(&normalized);
14528 self.write("'");
14529 }
14530 }
14531 Literal::DollarString(s) => {
14532 use crate::dialects::DialectType;
14535 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
14537 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
14539 let use_backslash_quote =
14543 matches!(self.config.dialect, Some(DialectType::Snowflake));
14544
14545 let mut escaped = String::with_capacity(content.len() + 4);
14546 for ch in content.chars() {
14547 if escape_backslash && ch == '\\' {
14548 escaped.push('\\');
14550 escaped.push('\\');
14551 } else if ch == '\'' {
14552 if use_backslash_quote {
14553 escaped.push('\\');
14554 escaped.push('\'');
14555 } else {
14556 escaped.push('\'');
14557 escaped.push('\'');
14558 }
14559 } else {
14560 escaped.push(ch);
14561 }
14562 }
14563 self.write("'");
14564 self.write(&escaped);
14565 self.write("'");
14566 }
14567 Literal::RawString(s) => {
14568 use crate::dialects::DialectType;
14574
14575 let escape_backslash = matches!(
14577 self.config.dialect,
14578 Some(DialectType::BigQuery)
14579 | Some(DialectType::MySQL)
14580 | Some(DialectType::SingleStore)
14581 | Some(DialectType::TiDB)
14582 | Some(DialectType::Hive)
14583 | Some(DialectType::Spark)
14584 | Some(DialectType::Databricks)
14585 | Some(DialectType::Drill)
14586 | Some(DialectType::Snowflake)
14587 | Some(DialectType::Redshift)
14588 | Some(DialectType::ClickHouse)
14589 );
14590
14591 let backslash_escapes_quote = matches!(
14594 self.config.dialect,
14595 Some(DialectType::BigQuery)
14596 | Some(DialectType::Hive)
14597 | Some(DialectType::Spark)
14598 | Some(DialectType::Databricks)
14599 | Some(DialectType::Drill)
14600 | Some(DialectType::Snowflake)
14601 | Some(DialectType::Redshift)
14602 );
14603
14604 let supports_escape_sequences = escape_backslash;
14607
14608 let mut escaped = String::with_capacity(s.len() + 4);
14609 for ch in s.chars() {
14610 if escape_backslash && ch == '\\' {
14611 escaped.push('\\');
14613 escaped.push('\\');
14614 } else if ch == '\'' {
14615 if backslash_escapes_quote {
14616 escaped.push('\\');
14618 escaped.push('\'');
14619 } else {
14620 escaped.push('\'');
14622 escaped.push('\'');
14623 }
14624 } else if supports_escape_sequences {
14625 match ch {
14628 '\n' => {
14629 escaped.push('\\');
14630 escaped.push('n');
14631 }
14632 '\r' => {
14633 escaped.push('\\');
14634 escaped.push('r');
14635 }
14636 '\t' => {
14637 escaped.push('\\');
14638 escaped.push('t');
14639 }
14640 '\x07' => {
14641 escaped.push('\\');
14642 escaped.push('a');
14643 }
14644 '\x08' => {
14645 escaped.push('\\');
14646 escaped.push('b');
14647 }
14648 '\x0C' => {
14649 escaped.push('\\');
14650 escaped.push('f');
14651 }
14652 '\x0B' => {
14653 escaped.push('\\');
14654 escaped.push('v');
14655 }
14656 _ => escaped.push(ch),
14657 }
14658 } else {
14659 escaped.push(ch);
14660 }
14661 }
14662 self.write("'");
14663 self.write(&escaped);
14664 self.write("'");
14665 }
14666 }
14667 Ok(())
14668 }
14669
14670 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
14672 use crate::dialects::DialectType;
14673
14674 match self.config.dialect {
14675 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
14677 self.write("CAST('");
14678 self.write(d);
14679 self.write("' AS DATE)");
14680 }
14681 Some(DialectType::BigQuery) => {
14684 self.write("CAST('");
14685 self.write(d);
14686 self.write("' AS DATE)");
14687 }
14688 Some(DialectType::Exasol) => {
14691 self.write("CAST('");
14692 self.write(d);
14693 self.write("' AS DATE)");
14694 }
14695 Some(DialectType::Snowflake) => {
14698 self.write("CAST('");
14699 self.write(d);
14700 self.write("' AS DATE)");
14701 }
14702 Some(DialectType::PostgreSQL)
14704 | Some(DialectType::MySQL)
14705 | Some(DialectType::SingleStore)
14706 | Some(DialectType::TiDB)
14707 | Some(DialectType::Redshift) => {
14708 self.write("CAST('");
14709 self.write(d);
14710 self.write("' AS DATE)");
14711 }
14712 Some(DialectType::DuckDB)
14714 | Some(DialectType::Presto)
14715 | Some(DialectType::Trino)
14716 | Some(DialectType::Athena)
14717 | Some(DialectType::Spark)
14718 | Some(DialectType::Databricks)
14719 | Some(DialectType::Hive) => {
14720 self.write("CAST('");
14721 self.write(d);
14722 self.write("' AS DATE)");
14723 }
14724 Some(DialectType::Oracle) => {
14726 self.write("TO_DATE('");
14727 self.write(d);
14728 self.write("', 'YYYY-MM-DD')");
14729 }
14730 _ => {
14732 self.write_keyword("DATE");
14733 self.write(" '");
14734 self.write(d);
14735 self.write("'");
14736 }
14737 }
14738 Ok(())
14739 }
14740
14741 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
14743 use crate::dialects::DialectType;
14744
14745 match self.config.dialect {
14746 Some(DialectType::TSQL) => {
14748 self.write("CAST('");
14749 self.write(t);
14750 self.write("' AS TIME)");
14751 }
14752 _ => {
14754 self.write_keyword("TIME");
14755 self.write(" '");
14756 self.write(t);
14757 self.write("'");
14758 }
14759 }
14760 Ok(())
14761 }
14762
14763 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
14765 use crate::expressions::Literal;
14766
14767 match expr {
14768 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
14769 let Literal::Date(d) = lit.as_ref() else {
14770 unreachable!()
14771 };
14772 self.write("CAST('");
14774 self.write(d);
14775 self.write("' AS DATE)");
14776 }
14777 _ => {
14778 self.generate_expression(expr)?;
14780 }
14781 }
14782 Ok(())
14783 }
14784
14785 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
14787 use crate::dialects::DialectType;
14788
14789 match self.config.dialect {
14790 Some(DialectType::TSQL) => {
14792 self.write("CAST('");
14793 self.write(ts);
14794 self.write("' AS DATETIME2)");
14795 }
14796 Some(DialectType::BigQuery) => {
14799 self.write("CAST('");
14800 self.write(ts);
14801 self.write("' AS TIMESTAMP)");
14802 }
14803 Some(DialectType::Snowflake) => {
14806 self.write("CAST('");
14807 self.write(ts);
14808 self.write("' AS TIMESTAMP)");
14809 }
14810 Some(DialectType::Dremio) => {
14813 self.write("CAST('");
14814 self.write(ts);
14815 self.write("' AS TIMESTAMP)");
14816 }
14817 Some(DialectType::Exasol) => {
14820 self.write("CAST('");
14821 self.write(ts);
14822 self.write("' AS TIMESTAMP)");
14823 }
14824 Some(DialectType::Oracle) => {
14827 self.write("TO_TIMESTAMP('");
14828 self.write(ts);
14829 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
14830 }
14831 Some(DialectType::Presto) | Some(DialectType::Trino) => {
14833 if Self::timestamp_has_timezone(ts) {
14834 self.write("CAST('");
14835 self.write(ts);
14836 self.write("' AS TIMESTAMP WITH TIME ZONE)");
14837 } else {
14838 self.write("CAST('");
14839 self.write(ts);
14840 self.write("' AS TIMESTAMP)");
14841 }
14842 }
14843 Some(DialectType::ClickHouse) => {
14845 self.write("CAST('");
14846 self.write(ts);
14847 self.write("' AS Nullable(DateTime))");
14848 }
14849 Some(DialectType::Spark) => {
14851 self.write("CAST('");
14852 self.write(ts);
14853 self.write("' AS TIMESTAMP)");
14854 }
14855 Some(DialectType::Redshift) => {
14858 if ts == "epoch" {
14859 self.write_keyword("TIMESTAMP");
14860 self.write(" '");
14861 self.write(ts);
14862 self.write("'");
14863 } else {
14864 self.write("CAST('");
14865 self.write(ts);
14866 self.write("' AS TIMESTAMP)");
14867 }
14868 }
14869 Some(DialectType::PostgreSQL)
14871 | Some(DialectType::Hive)
14872 | Some(DialectType::SQLite)
14873 | Some(DialectType::DuckDB)
14874 | Some(DialectType::Athena)
14875 | Some(DialectType::Drill)
14876 | Some(DialectType::Teradata) => {
14877 self.write("CAST('");
14878 self.write(ts);
14879 self.write("' AS TIMESTAMP)");
14880 }
14881 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
14883 self.write("CAST('");
14884 self.write(ts);
14885 self.write("' AS DATETIME)");
14886 }
14887 Some(DialectType::Databricks) => {
14889 self.write("CAST('");
14890 self.write(ts);
14891 self.write("' AS TIMESTAMP_NTZ)");
14892 }
14893 _ => {
14895 self.write_keyword("TIMESTAMP");
14896 self.write(" '");
14897 self.write(ts);
14898 self.write("'");
14899 }
14900 }
14901 Ok(())
14902 }
14903
14904 fn timestamp_has_timezone(ts: &str) -> bool {
14907 let ts_lower = ts.to_ascii_lowercase();
14911
14912 let continent_prefixes = [
14914 "africa/",
14915 "america/",
14916 "antarctica/",
14917 "arctic/",
14918 "asia/",
14919 "atlantic/",
14920 "australia/",
14921 "europe/",
14922 "indian/",
14923 "pacific/",
14924 "etc/",
14925 "brazil/",
14926 "canada/",
14927 "chile/",
14928 "mexico/",
14929 "us/",
14930 ];
14931
14932 for prefix in &continent_prefixes {
14933 if ts_lower.contains(prefix) {
14934 return true;
14935 }
14936 }
14937
14938 let tz_abbrevs = [
14941 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
14942 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
14943 " sgt", " aest", " aedt", " acst", " acdt", " awst",
14944 ];
14945
14946 for abbrev in &tz_abbrevs {
14947 if ts_lower.ends_with(abbrev) {
14948 return true;
14949 }
14950 }
14951
14952 let trimmed = ts.trim();
14956 if let Some(last_space) = trimmed.rfind(' ') {
14957 let suffix = &trimmed[last_space + 1..];
14958 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
14959 let rest = &suffix[1..];
14961 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
14962 return true;
14963 }
14964 }
14965 }
14966
14967 false
14968 }
14969
14970 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
14972 use crate::dialects::DialectType;
14973
14974 match self.config.dialect {
14975 Some(DialectType::BigQuery) => {
14978 self.write("CAST('");
14979 self.write(dt);
14980 self.write("' AS DATETIME)");
14981 }
14982 Some(DialectType::DuckDB) => {
14984 self.write("CAST('");
14985 self.write(dt);
14986 self.write("' AS TIMESTAMP)");
14987 }
14988 _ => {
14991 self.write_keyword("DATETIME");
14992 self.write(" '");
14993 self.write(dt);
14994 self.write("'");
14995 }
14996 }
14997 Ok(())
14998 }
14999
15000 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
15002 use crate::dialects::DialectType;
15003
15004 match self.config.dialect {
15005 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
15009 self.write("'");
15011 for c in s.chars() {
15012 match c {
15013 '\'' => self.write("\\'"),
15014 '\\' => self.write("\\\\"),
15015 '\n' => self.write("\\n"),
15016 '\r' => self.write("\\r"),
15017 '\t' => self.write("\\t"),
15018 '\0' => self.write("\\0"),
15019 _ => self.output.push(c),
15020 }
15021 }
15022 self.write("'");
15023 }
15024 Some(DialectType::Drill) => {
15025 self.write("'");
15028 for c in s.chars() {
15029 match c {
15030 '\'' => self.write("''"),
15031 '\\' => self.write("\\\\"),
15032 '\n' => self.write("\\n"),
15033 '\r' => self.write("\\r"),
15034 '\t' => self.write("\\t"),
15035 '\0' => self.write("\\0"),
15036 _ => self.output.push(c),
15037 }
15038 }
15039 self.write("'");
15040 }
15041 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
15042 self.write("'");
15043 for c in s.chars() {
15044 match c {
15045 '\'' => self.write("''"),
15047 '\\' => self.write("\\\\"),
15048 '\n' => self.write("\\n"),
15049 '\r' => self.write("\\r"),
15050 '\t' => self.write("\\t"),
15051 '\0' => self.output.push('\0'),
15053 _ => self.output.push(c),
15054 }
15055 }
15056 self.write("'");
15057 }
15058 Some(DialectType::BigQuery) => {
15060 self.write("'");
15061 for c in s.chars() {
15062 match c {
15063 '\'' => self.write("\\'"),
15064 '\\' => self.write("\\\\"),
15065 '\n' => self.write("\\n"),
15066 '\r' => self.write("\\r"),
15067 '\t' => self.write("\\t"),
15068 '\0' => self.write("\\0"),
15069 '\x07' => self.write("\\a"),
15070 '\x08' => self.write("\\b"),
15071 '\x0C' => self.write("\\f"),
15072 '\x0B' => self.write("\\v"),
15073 _ => self.output.push(c),
15074 }
15075 }
15076 self.write("'");
15077 }
15078 Some(DialectType::Athena) => {
15082 if self.athena_hive_context {
15083 self.write("'");
15085 for c in s.chars() {
15086 match c {
15087 '\'' => self.write("\\'"),
15088 '\\' => self.write("\\\\"),
15089 '\n' => self.write("\\n"),
15090 '\r' => self.write("\\r"),
15091 '\t' => self.write("\\t"),
15092 '\0' => self.write("\\0"),
15093 _ => self.output.push(c),
15094 }
15095 }
15096 self.write("'");
15097 } else {
15098 self.write("'");
15100 for c in s.chars() {
15101 match c {
15102 '\'' => self.write("''"),
15103 _ => self.output.push(c),
15105 }
15106 }
15107 self.write("'");
15108 }
15109 }
15110 Some(DialectType::Snowflake) => {
15115 self.write("'");
15116 for c in s.chars() {
15117 match c {
15118 '\'' => self.write("\\'"),
15119 '\n' => self.write("\\n"),
15122 '\r' => self.write("\\r"),
15123 '\t' => self.write("\\t"),
15124 _ => self.output.push(c),
15125 }
15126 }
15127 self.write("'");
15128 }
15129 Some(DialectType::PostgreSQL) => {
15131 self.write("'");
15132 for c in s.chars() {
15133 match c {
15134 '\'' => self.write("''"),
15135 _ => self.output.push(c),
15136 }
15137 }
15138 self.write("'");
15139 }
15140 Some(DialectType::Redshift) => {
15142 self.write("'");
15143 for c in s.chars() {
15144 match c {
15145 '\'' => self.write("\\'"),
15146 _ => self.output.push(c),
15147 }
15148 }
15149 self.write("'");
15150 }
15151 Some(DialectType::Oracle) => {
15153 self.write("'");
15154 for ch in s.chars() {
15155 if ch == '\'' {
15156 self.output.push_str("''");
15157 } else {
15158 self.output.push(ch);
15159 }
15160 }
15161 self.write("'");
15162 }
15163 Some(DialectType::ClickHouse) => {
15166 self.write("'");
15167 for c in s.chars() {
15168 match c {
15169 '\'' => self.write("''"),
15170 '\\' => self.write("\\\\"),
15171 '\n' => self.write("\\n"),
15172 '\r' => self.write("\\r"),
15173 '\t' => self.write("\\t"),
15174 '\0' => self.write("\\0"),
15175 '\x07' => self.write("\\a"),
15176 '\x08' => self.write("\\b"),
15177 '\x0C' => self.write("\\f"),
15178 '\x0B' => self.write("\\v"),
15179 c if c.is_control() || (c as u32) < 0x20 => {
15181 let byte = c as u32;
15182 if byte < 256 {
15183 self.write(&format!("\\x{:02X}", byte));
15184 } else {
15185 self.output.push(c);
15186 }
15187 }
15188 _ => self.output.push(c),
15189 }
15190 }
15191 self.write("'");
15192 }
15193 _ => {
15196 self.write("'");
15197 for ch in s.chars() {
15198 if ch == '\'' {
15199 self.output.push_str("''");
15200 } else {
15201 self.output.push(ch);
15202 }
15203 }
15204 self.write("'");
15205 }
15206 }
15207 Ok(())
15208 }
15209
15210 fn write_escaped_byte_string(&mut self, s: &str) {
15213 for c in s.chars() {
15214 match c {
15215 '\'' => self.write("\\'"),
15217 '\\' => self.write("\\\\"),
15219 _ if !c.is_control() => self.output.push(c),
15221 _ => {
15223 let byte = c as u32;
15224 if byte < 256 {
15225 self.write(&format!("\\x{:02x}", byte));
15226 } else {
15227 for b in c.to_string().as_bytes() {
15229 self.write(&format!("\\x{:02x}", b));
15230 }
15231 }
15232 }
15233 }
15234 }
15235 }
15236
15237 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
15238 use crate::dialects::DialectType;
15239
15240 match self.config.dialect {
15242 Some(DialectType::TSQL) => {
15245 self.write(if b.value { "1" } else { "0" });
15246 }
15247 Some(DialectType::Oracle) => {
15249 self.write(if b.value { "1" } else { "0" });
15250 }
15251 Some(DialectType::MySQL) => {
15253 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15254 }
15255 _ => {
15257 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15258 }
15259 }
15260 Ok(())
15261 }
15262
15263 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
15266 let name = &id.name;
15267 let quote_style = &self.config.identifier_quote_style;
15268
15269 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
15273
15274 let output_name = if self.config.normalize_identifiers && !id.quoted {
15276 name.to_ascii_lowercase()
15277 } else {
15278 name.to_string()
15279 };
15280
15281 if needs_quoting {
15282 let escaped_name = if quote_style.start == quote_style.end {
15284 output_name.replace(
15285 quote_style.end,
15286 &format!("{}{}", quote_style.end, quote_style.end),
15287 )
15288 } else {
15289 output_name.replace(
15290 quote_style.end,
15291 &format!("{}{}", quote_style.end, quote_style.end),
15292 )
15293 };
15294 self.write(&format!(
15295 "{}{}{}",
15296 quote_style.start, escaped_name, quote_style.end
15297 ));
15298 } else {
15299 self.write(&output_name);
15300 }
15301
15302 for comment in &id.trailing_comments {
15304 self.write(" ");
15305 self.write_formatted_comment(comment);
15306 }
15307 Ok(())
15308 }
15309
15310 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
15311 use crate::dialects::DialectType;
15312
15313 let name = &id.name;
15314
15315 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
15317 && self.athena_hive_context
15318 {
15319 &IdentifierQuoteStyle::BACKTICK
15320 } else {
15321 &self.config.identifier_quote_style
15322 };
15323
15324 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
15331 let needs_digit_quoting = starts_with_digit
15332 && !self.config.identifiers_can_start_with_digit
15333 && self.config.dialect.is_some();
15334 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
15335 && name.len() > 2
15336 && (name.starts_with("0x") || name.starts_with("0X"))
15337 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
15338 let needs_quoting = id.quoted
15339 || self.is_reserved_keyword(name)
15340 || self.config.always_quote_identifiers
15341 || needs_digit_quoting
15342 || mysql_invalid_hex_identifier;
15343
15344 let (base_name, suffix) = if needs_quoting {
15347 if let Some(paren_pos) = name.find('(') {
15349 let base = &name[..paren_pos];
15350 let rest = &name[paren_pos..];
15351 if rest.starts_with('(')
15353 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
15354 {
15355 let close_paren = rest.find(')').unwrap_or(rest.len());
15357 let inside = &rest[1..close_paren];
15358 if inside.chars().all(|c| c.is_ascii_digit()) {
15359 (base.to_string(), rest.to_string())
15360 } else {
15361 (name.to_string(), String::new())
15362 }
15363 } else {
15364 (name.to_string(), String::new())
15365 }
15366 } else if name.ends_with(" ASC") {
15367 let base = &name[..name.len() - 4];
15368 (base.to_string(), " ASC".to_string())
15369 } else if name.ends_with(" DESC") {
15370 let base = &name[..name.len() - 5];
15371 (base.to_string(), " DESC".to_string())
15372 } else {
15373 (name.to_string(), String::new())
15374 }
15375 } else {
15376 (name.to_string(), String::new())
15377 };
15378
15379 let output_name = if self.config.normalize_identifiers && !id.quoted {
15383 base_name.to_ascii_lowercase()
15384 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
15385 && !id.quoted
15386 && self.is_reserved_keyword(name)
15387 {
15388 base_name.to_ascii_uppercase()
15391 } else {
15392 base_name
15393 };
15394
15395 if needs_quoting {
15396 let escaped_name = if quote_style.start == quote_style.end {
15398 output_name.replace(
15400 quote_style.end,
15401 &format!("{}{}", quote_style.end, quote_style.end),
15402 )
15403 } else {
15404 output_name.replace(
15406 quote_style.end,
15407 &format!("{}{}", quote_style.end, quote_style.end),
15408 )
15409 };
15410 self.write(&format!(
15411 "{}{}{}{}",
15412 quote_style.start, escaped_name, quote_style.end, suffix
15413 ));
15414 } else {
15415 self.write(&output_name);
15416 }
15417
15418 for comment in &id.trailing_comments {
15420 self.write(" ");
15421 self.write_formatted_comment(comment);
15422 }
15423 Ok(())
15424 }
15425
15426 fn generate_column(&mut self, col: &Column) -> Result<()> {
15427 use crate::dialects::DialectType;
15428
15429 if let Some(table) = &col.table {
15430 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
15434 && !table.quoted
15435 && table.name.eq_ignore_ascii_case("LOCAL");
15436
15437 if is_exasol_local_prefix {
15438 self.write("LOCAL");
15440 } else {
15441 self.generate_identifier(table)?;
15442 }
15443 self.write(".");
15444 }
15445 self.generate_identifier(&col.name)?;
15446 if col.join_mark && self.config.supports_column_join_marks {
15449 self.write(" (+)");
15450 }
15451 for comment in &col.trailing_comments {
15453 self.write_space();
15454 self.write_formatted_comment(comment);
15455 }
15456 Ok(())
15457 }
15458
15459 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
15462 use crate::dialects::DialectType;
15463 use crate::expressions::PseudocolumnType;
15464
15465 if pc.kind == PseudocolumnType::Sysdate
15467 && !matches!(
15468 self.config.dialect,
15469 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
15470 )
15471 {
15472 self.write_keyword("CURRENT_TIMESTAMP");
15473 if matches!(
15475 self.config.dialect,
15476 Some(DialectType::MySQL)
15477 | Some(DialectType::ClickHouse)
15478 | Some(DialectType::Spark)
15479 | Some(DialectType::Databricks)
15480 | Some(DialectType::Hive)
15481 ) {
15482 self.write("()");
15483 }
15484 } else {
15485 self.write(pc.kind.as_str());
15486 }
15487 Ok(())
15488 }
15489
15490 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
15492 use crate::dialects::DialectType;
15493
15494 let supports_connect_by = matches!(
15497 self.config.dialect,
15498 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
15499 );
15500
15501 if !supports_connect_by && self.config.dialect.is_some() {
15502 if self.config.pretty {
15504 self.write_newline();
15505 } else {
15506 self.write_space();
15507 }
15508 self.write_unsupported_comment(
15509 "CONNECT BY requires manual conversion to recursive CTE",
15510 )?;
15511 }
15512
15513 if let Some(start) = &connect.start {
15515 if self.config.pretty {
15516 self.write_newline();
15517 } else {
15518 self.write_space();
15519 }
15520 self.write_keyword("START WITH");
15521 self.write_space();
15522 self.generate_expression(start)?;
15523 }
15524
15525 if self.config.pretty {
15527 self.write_newline();
15528 } else {
15529 self.write_space();
15530 }
15531 self.write_keyword("CONNECT BY");
15532 if connect.nocycle {
15533 self.write_space();
15534 self.write_keyword("NOCYCLE");
15535 }
15536 self.write_space();
15537 self.generate_expression(&connect.connect)?;
15538
15539 Ok(())
15540 }
15541
15542 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
15544 self.generate_connect(connect)
15545 }
15546
15547 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
15549 self.write_keyword("PRIOR");
15550 self.write_space();
15551 self.generate_expression(&prior.this)?;
15552 Ok(())
15553 }
15554
15555 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
15558 self.write_keyword("CONNECT_BY_ROOT");
15559 self.write_space();
15560 self.generate_expression(&cbr.this)?;
15561 Ok(())
15562 }
15563
15564 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
15566 use crate::dialects::DialectType;
15567
15568 let supports_match_recognize = matches!(
15570 self.config.dialect,
15571 Some(DialectType::Oracle)
15572 | Some(DialectType::Snowflake)
15573 | Some(DialectType::Presto)
15574 | Some(DialectType::Trino)
15575 );
15576
15577 if let Some(source) = &mr.this {
15579 self.generate_expression(source)?;
15580 }
15581
15582 if !supports_match_recognize {
15583 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
15584 return Ok(());
15585 }
15586
15587 if self.config.pretty {
15589 self.write_newline();
15590 } else {
15591 self.write_space();
15592 }
15593
15594 self.write_keyword("MATCH_RECOGNIZE");
15595 self.write(" (");
15596
15597 if self.config.pretty {
15598 self.indent_level += 1;
15599 }
15600
15601 let mut needs_separator = false;
15602
15603 if let Some(partition_by) = &mr.partition_by {
15605 if !partition_by.is_empty() {
15606 if self.config.pretty {
15607 self.write_newline();
15608 self.write_indent();
15609 }
15610 self.write_keyword("PARTITION BY");
15611 self.write_space();
15612 for (i, expr) in partition_by.iter().enumerate() {
15613 if i > 0 {
15614 self.write(", ");
15615 }
15616 self.generate_expression(expr)?;
15617 }
15618 needs_separator = true;
15619 }
15620 }
15621
15622 if let Some(order_by) = &mr.order_by {
15624 if !order_by.is_empty() {
15625 if needs_separator {
15626 if self.config.pretty {
15627 self.write_newline();
15628 self.write_indent();
15629 } else {
15630 self.write_space();
15631 }
15632 } else if self.config.pretty {
15633 self.write_newline();
15634 self.write_indent();
15635 }
15636 self.write_keyword("ORDER BY");
15637 if self.config.pretty {
15639 self.indent_level += 1;
15640 for (i, ordered) in order_by.iter().enumerate() {
15641 if i > 0 {
15642 self.write(",");
15643 }
15644 self.write_newline();
15645 self.write_indent();
15646 self.generate_ordered(ordered)?;
15647 }
15648 self.indent_level -= 1;
15649 } else {
15650 self.write_space();
15651 for (i, ordered) in order_by.iter().enumerate() {
15652 if i > 0 {
15653 self.write(", ");
15654 }
15655 self.generate_ordered(ordered)?;
15656 }
15657 }
15658 needs_separator = true;
15659 }
15660 }
15661
15662 if let Some(measures) = &mr.measures {
15664 if !measures.is_empty() {
15665 if needs_separator {
15666 if self.config.pretty {
15667 self.write_newline();
15668 self.write_indent();
15669 } else {
15670 self.write_space();
15671 }
15672 } else if self.config.pretty {
15673 self.write_newline();
15674 self.write_indent();
15675 }
15676 self.write_keyword("MEASURES");
15677 if self.config.pretty {
15679 self.indent_level += 1;
15680 for (i, measure) in measures.iter().enumerate() {
15681 if i > 0 {
15682 self.write(",");
15683 }
15684 self.write_newline();
15685 self.write_indent();
15686 if let Some(semantics) = &measure.window_frame {
15688 match semantics {
15689 MatchRecognizeSemantics::Running => {
15690 self.write_keyword("RUNNING");
15691 self.write_space();
15692 }
15693 MatchRecognizeSemantics::Final => {
15694 self.write_keyword("FINAL");
15695 self.write_space();
15696 }
15697 }
15698 }
15699 self.generate_expression(&measure.this)?;
15700 }
15701 self.indent_level -= 1;
15702 } else {
15703 self.write_space();
15704 for (i, measure) in measures.iter().enumerate() {
15705 if i > 0 {
15706 self.write(", ");
15707 }
15708 if let Some(semantics) = &measure.window_frame {
15710 match semantics {
15711 MatchRecognizeSemantics::Running => {
15712 self.write_keyword("RUNNING");
15713 self.write_space();
15714 }
15715 MatchRecognizeSemantics::Final => {
15716 self.write_keyword("FINAL");
15717 self.write_space();
15718 }
15719 }
15720 }
15721 self.generate_expression(&measure.this)?;
15722 }
15723 }
15724 needs_separator = true;
15725 }
15726 }
15727
15728 if let Some(rows) = &mr.rows {
15730 if needs_separator {
15731 if self.config.pretty {
15732 self.write_newline();
15733 self.write_indent();
15734 } else {
15735 self.write_space();
15736 }
15737 } else if self.config.pretty {
15738 self.write_newline();
15739 self.write_indent();
15740 }
15741 match rows {
15742 MatchRecognizeRows::OneRowPerMatch => {
15743 self.write_keyword("ONE ROW PER MATCH");
15744 }
15745 MatchRecognizeRows::AllRowsPerMatch => {
15746 self.write_keyword("ALL ROWS PER MATCH");
15747 }
15748 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
15749 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
15750 }
15751 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
15752 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
15753 }
15754 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
15755 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
15756 }
15757 }
15758 needs_separator = true;
15759 }
15760
15761 if let Some(after) = &mr.after {
15763 if needs_separator {
15764 if self.config.pretty {
15765 self.write_newline();
15766 self.write_indent();
15767 } else {
15768 self.write_space();
15769 }
15770 } else if self.config.pretty {
15771 self.write_newline();
15772 self.write_indent();
15773 }
15774 match after {
15775 MatchRecognizeAfter::PastLastRow => {
15776 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
15777 }
15778 MatchRecognizeAfter::ToNextRow => {
15779 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
15780 }
15781 MatchRecognizeAfter::ToFirst(ident) => {
15782 self.write_keyword("AFTER MATCH SKIP TO FIRST");
15783 self.write_space();
15784 self.generate_identifier(ident)?;
15785 }
15786 MatchRecognizeAfter::ToLast(ident) => {
15787 self.write_keyword("AFTER MATCH SKIP TO LAST");
15788 self.write_space();
15789 self.generate_identifier(ident)?;
15790 }
15791 }
15792 needs_separator = true;
15793 }
15794
15795 if let Some(pattern) = &mr.pattern {
15797 if needs_separator {
15798 if self.config.pretty {
15799 self.write_newline();
15800 self.write_indent();
15801 } else {
15802 self.write_space();
15803 }
15804 } else if self.config.pretty {
15805 self.write_newline();
15806 self.write_indent();
15807 }
15808 self.write_keyword("PATTERN");
15809 self.write_space();
15810 self.write("(");
15811 self.write(pattern);
15812 self.write(")");
15813 needs_separator = true;
15814 }
15815
15816 if let Some(define) = &mr.define {
15818 if !define.is_empty() {
15819 if needs_separator {
15820 if self.config.pretty {
15821 self.write_newline();
15822 self.write_indent();
15823 } else {
15824 self.write_space();
15825 }
15826 } else if self.config.pretty {
15827 self.write_newline();
15828 self.write_indent();
15829 }
15830 self.write_keyword("DEFINE");
15831 if self.config.pretty {
15833 self.indent_level += 1;
15834 for (i, (name, expr)) in define.iter().enumerate() {
15835 if i > 0 {
15836 self.write(",");
15837 }
15838 self.write_newline();
15839 self.write_indent();
15840 self.generate_identifier(name)?;
15841 self.write(" AS ");
15842 self.generate_expression(expr)?;
15843 }
15844 self.indent_level -= 1;
15845 } else {
15846 self.write_space();
15847 for (i, (name, expr)) in define.iter().enumerate() {
15848 if i > 0 {
15849 self.write(", ");
15850 }
15851 self.generate_identifier(name)?;
15852 self.write(" AS ");
15853 self.generate_expression(expr)?;
15854 }
15855 }
15856 }
15857 }
15858
15859 if self.config.pretty {
15860 self.indent_level -= 1;
15861 self.write_newline();
15862 }
15863 self.write(")");
15864
15865 if let Some(alias) = &mr.alias {
15867 self.write(" ");
15868 if mr.alias_explicit_as {
15869 self.write_keyword("AS");
15870 self.write(" ");
15871 }
15872 self.generate_identifier(alias)?;
15873 }
15874
15875 Ok(())
15876 }
15877
15878 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
15880 use crate::dialects::DialectType;
15881
15882 let supports_hints = matches!(
15884 self.config.dialect,
15885 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
15887 Some(DialectType::Spark) | Some(DialectType::Hive) |
15888 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
15889 );
15890
15891 if !supports_hints || hint.expressions.is_empty() {
15892 return Ok(());
15893 }
15894
15895 let mut hint_strings: Vec<String> = Vec::new();
15898 for expr in &hint.expressions {
15899 match expr {
15900 HintExpression::Raw(text) => {
15901 let parsed = self.parse_raw_hint_text(text);
15903 hint_strings.extend(parsed);
15904 }
15905 _ => {
15906 hint_strings.push(self.hint_expression_to_string(expr)?);
15907 }
15908 }
15909 }
15910
15911 let use_multiline = self.config.pretty && hint_strings.len() > 1;
15915
15916 if use_multiline {
15917 self.write(" /*+ ");
15919 for (i, hint_str) in hint_strings.iter().enumerate() {
15920 if i > 0 {
15921 self.write_newline();
15922 self.write(" "); }
15924 self.write(hint_str);
15925 }
15926 self.write(" */");
15927 } else {
15928 self.write(" /*+ ");
15930 let sep = match self.config.dialect {
15931 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
15932 _ => " ",
15933 };
15934 for (i, hint_str) in hint_strings.iter().enumerate() {
15935 if i > 0 {
15936 self.write(sep);
15937 }
15938 self.write(hint_str);
15939 }
15940 self.write(" */");
15941 }
15942
15943 Ok(())
15944 }
15945
15946 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
15950 let mut results = Vec::new();
15951 let mut chars = text.chars().peekable();
15952 let mut current = String::new();
15953 let mut paren_depth = 0;
15954 let mut has_unparseable_content = false;
15955 let mut position_after_last_function = 0;
15956 let mut char_position = 0;
15957
15958 while let Some(c) = chars.next() {
15959 char_position += c.len_utf8();
15960 match c {
15961 '(' => {
15962 paren_depth += 1;
15963 current.push(c);
15964 }
15965 ')' => {
15966 paren_depth -= 1;
15967 current.push(c);
15968 if paren_depth == 0 {
15970 let trimmed = current.trim().to_string();
15971 if !trimmed.is_empty() {
15972 let formatted = self.format_hint_function(&trimmed);
15974 results.push(formatted);
15975 }
15976 current.clear();
15977 position_after_last_function = char_position;
15978 }
15979 }
15980 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
15981 }
15983 _ if paren_depth == 0 => {
15984 current.push(c);
15986 }
15987 _ => {
15988 current.push(c);
15989 }
15990 }
15991 }
15992
15993 let remaining_text = text[position_after_last_function..].trim();
15995 if !remaining_text.is_empty() {
15996 let words: Vec<&str> = remaining_text.split_whitespace().collect();
16000 let looks_like_hint_functions = words.iter().all(|word| {
16001 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
16003 });
16004
16005 if !looks_like_hint_functions && words.len() > 1 {
16006 has_unparseable_content = true;
16007 }
16008 }
16009
16010 if has_unparseable_content {
16012 return vec![text.trim().to_string()];
16013 }
16014
16015 if results.is_empty() {
16017 results.push(text.trim().to_string());
16018 }
16019
16020 results
16021 }
16022
16023 fn format_hint_function(&self, hint: &str) -> String {
16026 if !self.config.pretty {
16027 return hint.to_string();
16028 }
16029
16030 if let Some(paren_pos) = hint.find('(') {
16032 if hint.ends_with(')') {
16033 let name = &hint[..paren_pos];
16034 let args_str = &hint[paren_pos + 1..hint.len() - 1];
16035
16036 let args: Vec<&str> = args_str.split_whitespace().collect();
16038
16039 let total_args_width: usize =
16041 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() {
16045 let mut result = format!("{}(\n", name);
16046 for arg in &args {
16047 result.push_str(" "); result.push_str(arg);
16049 result.push('\n');
16050 }
16051 result.push_str(" )"); return result;
16053 }
16054 }
16055 }
16056
16057 hint.to_string()
16058 }
16059
16060 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
16062 match expr {
16063 HintExpression::Function { name, args } => {
16064 let arg_strings: Vec<String> = args
16066 .iter()
16067 .map(|arg| {
16068 let mut gen = Generator::with_arc_config(self.config.clone());
16069 gen.generate_expression(arg)?;
16070 Ok(gen.output)
16071 })
16072 .collect::<Result<Vec<_>>>()?;
16073
16074 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
16076 + arg_strings.len().saturating_sub(1); let args_multiline =
16081 self.config.pretty && total_args_width > self.config.max_text_width;
16082
16083 if args_multiline && !arg_strings.is_empty() {
16084 let mut result = format!("{}(\n", name);
16086 for arg_str in &arg_strings {
16087 result.push_str(" "); result.push_str(arg_str);
16089 result.push('\n');
16090 }
16091 result.push_str(" )"); Ok(result)
16093 } else {
16094 let args_str = arg_strings.join(" ");
16096 Ok(format!("{}({})", name, args_str))
16097 }
16098 }
16099 HintExpression::Identifier(name) => Ok(name.clone()),
16100 HintExpression::Raw(text) => {
16101 if self.config.pretty {
16103 Ok(self.format_hint_function(text))
16104 } else {
16105 Ok(text.clone())
16106 }
16107 }
16108 }
16109 }
16110
16111 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
16112 if table.only {
16114 self.write_keyword("ONLY");
16115 self.write_space();
16116 }
16117
16118 if let Some(ref identifier_func) = table.identifier_func {
16120 self.generate_expression(identifier_func)?;
16121 if !table.name.name.is_empty() {
16123 if let Some(catalog) = &table.catalog {
16124 self.write(".");
16125 self.generate_identifier(catalog)?;
16126 }
16127 if let Some(schema) = &table.schema {
16128 self.write(".");
16129 self.generate_identifier(schema)?;
16130 }
16131 self.write(".");
16132 self.generate_identifier(&table.name)?;
16133 }
16134 } else {
16135 if let Some(catalog) = &table.catalog {
16136 self.generate_identifier(catalog)?;
16137 self.write(".");
16138 }
16139 if let Some(schema) = &table.schema {
16140 self.generate_identifier(schema)?;
16141 self.write(".");
16142 }
16143 self.generate_identifier(&table.name)?;
16144 }
16145
16146 if let Some(changes) = &table.changes {
16148 self.write(" ");
16149 self.generate_changes(changes)?;
16150 }
16151
16152 if !table.partitions.is_empty() {
16154 self.write_space();
16155 self.write_keyword("PARTITION");
16156 self.write("(");
16157 for (i, partition) in table.partitions.iter().enumerate() {
16158 if i > 0 {
16159 self.write(", ");
16160 }
16161 self.generate_identifier(partition)?;
16162 }
16163 self.write(")");
16164 }
16165
16166 if table.changes.is_none() {
16169 if let Some(when) = &table.when {
16170 self.write_space();
16171 self.generate_historical_data(when)?;
16172 }
16173 }
16174
16175 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
16177 if !system_time_post_alias {
16178 if let Some(ref system_time) = table.system_time {
16179 self.write_space();
16180 self.write(system_time);
16181 }
16182 }
16183
16184 if let Some(ref version) = table.version {
16186 self.write_space();
16187 self.generate_version(version)?;
16188 }
16189
16190 let alias_post_tablesample = self.config.alias_post_tablesample;
16194
16195 if alias_post_tablesample {
16196 self.generate_table_sample_clause(table)?;
16198 }
16199
16200 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
16203 && table.hints.iter().any(|h| {
16204 if let Expression::Identifier(id) = h {
16205 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
16206 } else {
16207 false
16208 }
16209 });
16210 if !table.hints.is_empty() && !is_sqlite_hint {
16211 for hint in &table.hints {
16212 self.write_space();
16213 self.generate_expression(hint)?;
16214 }
16215 }
16216
16217 if let Some(alias) = &table.alias {
16218 self.write_space();
16219 let always_use_as = self.config.dialect.is_none()
16222 || matches!(
16223 self.config.dialect,
16224 Some(DialectType::Generic)
16225 | Some(DialectType::PostgreSQL)
16226 | Some(DialectType::Redshift)
16227 | Some(DialectType::Snowflake)
16228 | Some(DialectType::BigQuery)
16229 | Some(DialectType::DuckDB)
16230 | Some(DialectType::Presto)
16231 | Some(DialectType::Trino)
16232 | Some(DialectType::TSQL)
16233 | Some(DialectType::Fabric)
16234 | Some(DialectType::MySQL)
16235 | Some(DialectType::Spark)
16236 | Some(DialectType::Hive)
16237 | Some(DialectType::SQLite)
16238 | Some(DialectType::Drill)
16239 );
16240 let is_stage_ref = table.name.name.starts_with('@');
16241 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16243 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
16244 self.write_keyword("AS");
16245 self.write_space();
16246 }
16247 self.generate_identifier(alias)?;
16248
16249 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
16252 self.write("(");
16253 for (i, col_alias) in table.column_aliases.iter().enumerate() {
16254 if i > 0 {
16255 self.write(", ");
16256 }
16257 self.generate_identifier(col_alias)?;
16258 }
16259 self.write(")");
16260 }
16261 }
16262
16263 if system_time_post_alias {
16265 if let Some(ref system_time) = table.system_time {
16266 self.write_space();
16267 self.write(system_time);
16268 }
16269 }
16270
16271 if !alias_post_tablesample {
16273 self.generate_table_sample_clause(table)?;
16274 }
16275
16276 if is_sqlite_hint {
16278 for hint in &table.hints {
16279 self.write_space();
16280 self.generate_expression(hint)?;
16281 }
16282 }
16283
16284 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16286 self.write_space();
16287 self.write_keyword("FINAL");
16288 }
16289
16290 for comment in &table.trailing_comments {
16292 self.write_space();
16293 self.write_formatted_comment(comment);
16294 }
16295 Ok(())
16299 }
16300
16301 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
16303 if let Some(ref ts) = table.table_sample {
16304 self.write_space();
16305 if ts.is_using_sample {
16306 self.write_keyword("USING SAMPLE");
16307 } else {
16308 self.write_keyword(self.config.tablesample_keywords);
16310 }
16311 self.generate_sample_body(ts)?;
16312 if let Some(ref seed) = ts.seed {
16314 self.write_space();
16315 self.write_keyword(self.config.tablesample_seed_keyword);
16316 self.write(" (");
16317 self.generate_expression(seed)?;
16318 self.write(")");
16319 }
16320 }
16321 Ok(())
16322 }
16323
16324 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
16325 if sr.quoted {
16329 self.write("'");
16330 }
16331
16332 self.write(&sr.name);
16333 if let Some(path) = &sr.path {
16334 self.write(path);
16335 }
16336
16337 if sr.quoted {
16338 self.write("'");
16339 }
16340
16341 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
16343 if has_options {
16344 self.write(" (");
16345 let mut first = true;
16346
16347 if let Some(file_format) = &sr.file_format {
16348 if !first {
16349 self.write(", ");
16350 }
16351 self.write_keyword("FILE_FORMAT");
16352 self.write(" => ");
16353 self.generate_expression(file_format)?;
16354 first = false;
16355 }
16356
16357 if let Some(pattern) = &sr.pattern {
16358 if !first {
16359 self.write(", ");
16360 }
16361 self.write_keyword("PATTERN");
16362 self.write(" => '");
16363 self.write(pattern);
16364 self.write("'");
16365 }
16366
16367 self.write(")");
16368 }
16369 Ok(())
16370 }
16371
16372 fn generate_star(&mut self, star: &Star) -> Result<()> {
16373 use crate::dialects::DialectType;
16374
16375 if let Some(table) = &star.table {
16376 self.generate_identifier(table)?;
16377 self.write(".");
16378 }
16379 self.write("*");
16380
16381 if let Some(except) = &star.except {
16383 if !except.is_empty() {
16384 self.write_space();
16385 match self.config.dialect {
16387 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
16388 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
16389 self.write_keyword("EXCLUDE")
16390 }
16391 _ => self.write_keyword("EXCEPT"), }
16393 self.write(" (");
16394 for (i, col) in except.iter().enumerate() {
16395 if i > 0 {
16396 self.write(", ");
16397 }
16398 self.generate_identifier(col)?;
16399 }
16400 self.write(")");
16401 }
16402 }
16403
16404 if let Some(replace) = &star.replace {
16406 if !replace.is_empty() {
16407 self.write_space();
16408 self.write_keyword("REPLACE");
16409 self.write(" (");
16410 for (i, alias) in replace.iter().enumerate() {
16411 if i > 0 {
16412 self.write(", ");
16413 }
16414 self.generate_expression(&alias.this)?;
16415 self.write_space();
16416 self.write_keyword("AS");
16417 self.write_space();
16418 self.generate_identifier(&alias.alias)?;
16419 }
16420 self.write(")");
16421 }
16422 }
16423
16424 if let Some(rename) = &star.rename {
16426 if !rename.is_empty() {
16427 self.write_space();
16428 self.write_keyword("RENAME");
16429 self.write(" (");
16430 for (i, (old_name, new_name)) in rename.iter().enumerate() {
16431 if i > 0 {
16432 self.write(", ");
16433 }
16434 self.generate_identifier(old_name)?;
16435 self.write_space();
16436 self.write_keyword("AS");
16437 self.write_space();
16438 self.generate_identifier(new_name)?;
16439 }
16440 self.write(")");
16441 }
16442 }
16443
16444 for comment in &star.trailing_comments {
16446 self.write_space();
16447 self.write_formatted_comment(comment);
16448 }
16449
16450 Ok(())
16451 }
16452
16453 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
16455 self.write("{");
16456 match expr {
16457 Expression::Star(star) => {
16458 self.generate_star(star)?;
16460 }
16461 Expression::ILike(ilike) => {
16462 self.generate_expression(&ilike.left)?;
16464 self.write_space();
16465 self.write_keyword("ILIKE");
16466 self.write_space();
16467 self.generate_expression(&ilike.right)?;
16468 }
16469 _ => {
16470 self.generate_expression(expr)?;
16471 }
16472 }
16473 self.write("}");
16474 Ok(())
16475 }
16476
16477 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
16478 match &alias.this {
16482 Expression::Column(col) => {
16483 if let Some(table) = &col.table {
16485 self.generate_identifier(table)?;
16486 self.write(".");
16487 }
16488 self.generate_identifier(&col.name)?;
16489 }
16490 _ => {
16491 self.generate_expression(&alias.this)?;
16492 }
16493 }
16494
16495 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
16499 for comment in &alias.pre_alias_comments {
16500 self.write_space();
16501 self.write_formatted_comment(comment);
16502 }
16503 }
16504
16505 use crate::dialects::DialectType;
16506
16507 let is_table_source = matches!(
16513 &alias.this,
16514 Expression::JSONTable(_)
16515 | Expression::XMLTable(_)
16516 | Expression::TableFromRows(_)
16517 | Expression::Unnest(_)
16518 | Expression::MatchRecognize(_)
16519 | Expression::Select(_)
16520 | Expression::Subquery(_)
16521 | Expression::Paren(_)
16522 );
16523 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16524 let skip_as = is_table_source && dialect_skips_table_alias_as;
16525
16526 self.write_space();
16527 if !skip_as {
16528 self.write_keyword("AS");
16529 self.write_space();
16530 }
16531
16532 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
16534
16535 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
16537 self.write("(");
16539 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16540 if i > 0 {
16541 self.write(", ");
16542 }
16543 self.generate_alias_identifier(col_alias)?;
16544 }
16545 self.write(")");
16546 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
16547 self.generate_alias_identifier(&alias.alias)?;
16549 self.write("(");
16550 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16551 if i > 0 {
16552 self.write(", ");
16553 }
16554 self.generate_alias_identifier(col_alias)?;
16555 }
16556 self.write(")");
16557 } else {
16558 self.generate_alias_identifier(&alias.alias)?;
16560 }
16561
16562 for comment in &alias.trailing_comments {
16564 self.write_space();
16565 self.write_formatted_comment(comment);
16566 }
16567
16568 if alias.trailing_comments.is_empty() {
16573 for comment in &alias.pre_alias_comments {
16574 self.write_space();
16575 self.write_formatted_comment(comment);
16576 }
16577 }
16578
16579 Ok(())
16580 }
16581
16582 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
16583 use crate::dialects::DialectType;
16584
16585 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
16587 self.generate_expression(&cast.this)?;
16588 self.write(" :> ");
16589 self.generate_data_type(&cast.to)?;
16590 return Ok(());
16591 }
16592
16593 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
16595 let is_unknown_type = matches!(cast.to, DataType::Unknown)
16596 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
16597 if is_unknown_type {
16598 if let Some(format) = &cast.format {
16599 self.write_keyword("CAST");
16600 self.write("(");
16601 self.generate_expression(&cast.this)?;
16602 self.write_space();
16603 self.write_keyword("AS");
16604 self.write_space();
16605 self.write_keyword("FORMAT");
16606 self.write_space();
16607 self.generate_expression(format)?;
16608 self.write(")");
16609 return Ok(());
16610 }
16611 }
16612 }
16613
16614 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
16617 if let Some(format) = &cast.format {
16618 let is_date = matches!(cast.to, DataType::Date);
16620 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
16621
16622 if is_date || is_timestamp {
16623 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
16624 self.write_keyword(func_name);
16625 self.write("(");
16626 self.generate_expression(&cast.this)?;
16627 self.write(", ");
16628
16629 if let Expression::Literal(lit) = format.as_ref() {
16632 if let Literal::String(fmt_str) = lit.as_ref() {
16633 let normalized = self.normalize_oracle_format(fmt_str);
16634 self.write("'");
16635 self.write(&normalized);
16636 self.write("'");
16637 }
16638 } else {
16639 self.generate_expression(format)?;
16640 }
16641
16642 self.write(")");
16643 return Ok(());
16644 }
16645 }
16646 }
16647
16648 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
16651 if let Expression::Array(arr) = &cast.this {
16652 self.generate_data_type(&cast.to)?;
16653 self.write("[");
16655 for (i, expr) in arr.expressions.iter().enumerate() {
16656 if i > 0 {
16657 self.write(", ");
16658 }
16659 self.generate_expression(expr)?;
16660 }
16661 self.write("]");
16662 return Ok(());
16663 }
16664 if matches!(&cast.this, Expression::ArrayFunc(_)) {
16665 self.generate_data_type(&cast.to)?;
16666 self.generate_expression(&cast.this)?;
16667 return Ok(());
16668 }
16669 }
16670
16671 if matches!(
16674 self.config.dialect,
16675 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
16676 ) {
16677 if let Expression::Struct(ref s) = cast.this {
16678 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
16679 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
16680 self.write_keyword("CAST");
16681 self.write("(");
16682 self.generate_struct_as_row(s)?;
16683 self.write_space();
16684 self.write_keyword("AS");
16685 self.write_space();
16686 self.generate_data_type(&cast.to)?;
16687 self.write(")");
16688 return Ok(());
16689 }
16690 }
16691 }
16692
16693 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
16696
16697 if use_double_colon {
16698 self.generate_expression(&cast.this)?;
16700 self.write("::");
16701 self.generate_data_type(&cast.to)?;
16702 } else {
16703 self.write_keyword("CAST");
16705 self.write("(");
16706 self.generate_expression(&cast.this)?;
16707 self.write_space();
16708 self.write_keyword("AS");
16709 self.write_space();
16710 if matches!(
16713 self.config.dialect,
16714 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
16715 ) {
16716 match &cast.to {
16717 DataType::Custom { ref name } => {
16718 if name.eq_ignore_ascii_case("LONGTEXT")
16719 || name.eq_ignore_ascii_case("MEDIUMTEXT")
16720 || name.eq_ignore_ascii_case("TINYTEXT")
16721 || name.eq_ignore_ascii_case("LONGBLOB")
16722 || name.eq_ignore_ascii_case("MEDIUMBLOB")
16723 || name.eq_ignore_ascii_case("TINYBLOB")
16724 {
16725 self.write_keyword("CHAR");
16726 } else {
16727 self.generate_data_type(&cast.to)?;
16728 }
16729 }
16730 DataType::VarChar { length, .. } => {
16731 self.write_keyword("CHAR");
16733 if let Some(n) = length {
16734 self.write(&format!("({})", n));
16735 }
16736 }
16737 DataType::Text => {
16738 self.write_keyword("CHAR");
16740 }
16741 DataType::Timestamp {
16742 precision,
16743 timezone: false,
16744 } => {
16745 self.write_keyword("DATETIME");
16747 if let Some(p) = precision {
16748 self.write(&format!("({})", p));
16749 }
16750 }
16751 _ => {
16752 self.generate_data_type(&cast.to)?;
16753 }
16754 }
16755 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
16756 match &cast.to {
16758 DataType::String { length } => {
16759 self.write_keyword("VARCHAR");
16760 if let Some(n) = length {
16761 self.write(&format!("({})", n));
16762 }
16763 }
16764 _ => {
16765 self.generate_data_type(&cast.to)?;
16766 }
16767 }
16768 } else {
16769 self.generate_data_type(&cast.to)?;
16770 }
16771
16772 if let Some(default) = &cast.default {
16774 self.write_space();
16775 self.write_keyword("DEFAULT");
16776 self.write_space();
16777 self.generate_expression(default)?;
16778 self.write_space();
16779 self.write_keyword("ON");
16780 self.write_space();
16781 self.write_keyword("CONVERSION");
16782 self.write_space();
16783 self.write_keyword("ERROR");
16784 }
16785
16786 if let Some(format) = &cast.format {
16789 if matches!(
16791 self.config.dialect,
16792 Some(crate::dialects::DialectType::Oracle)
16793 ) {
16794 self.write(", ");
16795 } else {
16796 self.write_space();
16797 self.write_keyword("FORMAT");
16798 self.write_space();
16799 }
16800 self.generate_expression(format)?;
16801 }
16802
16803 self.write(")");
16804 for comment in &cast.trailing_comments {
16806 self.write_space();
16807 self.write_formatted_comment(comment);
16808 }
16809 }
16810 Ok(())
16811 }
16812
16813 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
16816 self.write_keyword("ROW");
16817 self.write("(");
16818 for (i, (_, expr)) in s.fields.iter().enumerate() {
16819 if i > 0 {
16820 self.write(", ");
16821 }
16822 if let Expression::Struct(ref inner_s) = expr {
16824 self.generate_struct_as_row(inner_s)?;
16825 } else {
16826 self.generate_expression(expr)?;
16827 }
16828 }
16829 self.write(")");
16830 Ok(())
16831 }
16832
16833 fn normalize_oracle_format(&self, format: &str) -> String {
16836 let mut result = String::new();
16839 let chars: Vec<char> = format.chars().collect();
16840 let mut i = 0;
16841
16842 while i < chars.len() {
16843 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
16844 if i + 2 < chars.len() {
16846 let next = chars[i + 2];
16847 if next == '1' || next == '2' {
16848 result.push('H');
16850 result.push('H');
16851 i += 2;
16852 continue;
16853 }
16854 }
16855 result.push_str("HH12");
16857 i += 2;
16858 } else {
16859 result.push(chars[i]);
16860 i += 1;
16861 }
16862 }
16863
16864 result
16865 }
16866
16867 fn dialect_prefers_double_colon(&self) -> bool {
16871 false
16874 }
16875
16876 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16878 use crate::dialects::DialectType;
16879
16880 let use_percent_operator = matches!(
16882 self.config.dialect,
16883 Some(DialectType::Snowflake)
16884 | Some(DialectType::MySQL)
16885 | Some(DialectType::Presto)
16886 | Some(DialectType::Trino)
16887 | Some(DialectType::PostgreSQL)
16888 | Some(DialectType::DuckDB)
16889 | Some(DialectType::Hive)
16890 | Some(DialectType::Spark)
16891 | Some(DialectType::Databricks)
16892 | Some(DialectType::Athena)
16893 );
16894
16895 if use_percent_operator {
16896 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
16899 if needs_paren(&f.this) {
16900 self.write("(");
16901 self.generate_expression(&f.this)?;
16902 self.write(")");
16903 } else {
16904 self.generate_expression(&f.this)?;
16905 }
16906 self.write(" % ");
16907 if needs_paren(&f.expression) {
16908 self.write("(");
16909 self.generate_expression(&f.expression)?;
16910 self.write(")");
16911 } else {
16912 self.generate_expression(&f.expression)?;
16913 }
16914 Ok(())
16915 } else {
16916 self.generate_binary_func("MOD", &f.this, &f.expression)
16917 }
16918 }
16919
16920 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16922 use crate::dialects::DialectType;
16923
16924 let func_name = match self.config.dialect {
16926 Some(DialectType::Snowflake) => "COALESCE",
16927 _ => "IFNULL",
16928 };
16929
16930 self.generate_binary_func(func_name, &f.this, &f.expression)
16931 }
16932
16933 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16935 if let Some(ref original_name) = f.original_name {
16937 return self.generate_binary_func(original_name, &f.this, &f.expression);
16938 }
16939
16940 use crate::dialects::DialectType;
16942 let func_name = match self.config.dialect {
16943 Some(DialectType::Snowflake)
16944 | Some(DialectType::ClickHouse)
16945 | Some(DialectType::PostgreSQL)
16946 | Some(DialectType::Presto)
16947 | Some(DialectType::Trino)
16948 | Some(DialectType::Athena)
16949 | Some(DialectType::DuckDB)
16950 | Some(DialectType::BigQuery)
16951 | Some(DialectType::Spark)
16952 | Some(DialectType::Databricks)
16953 | Some(DialectType::Hive) => "COALESCE",
16954 Some(DialectType::MySQL)
16955 | Some(DialectType::Doris)
16956 | Some(DialectType::StarRocks)
16957 | Some(DialectType::SingleStore)
16958 | Some(DialectType::TiDB) => "IFNULL",
16959 _ => "NVL",
16960 };
16961
16962 self.generate_binary_func(func_name, &f.this, &f.expression)
16963 }
16964
16965 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
16967 use crate::dialects::DialectType;
16968
16969 let func_name = match self.config.dialect {
16971 Some(DialectType::Snowflake) => "STDDEV",
16972 _ => "STDDEV_SAMP",
16973 };
16974
16975 self.generate_agg_func(func_name, f)
16976 }
16977
16978 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
16979 self.generate_expression(&coll.this)?;
16980 self.write_space();
16981 self.write_keyword("COLLATE");
16982 self.write_space();
16983 if coll.quoted {
16984 self.write("'");
16986 self.write(&coll.collation);
16987 self.write("'");
16988 } else if coll.double_quoted {
16989 self.write("\"");
16991 self.write(&coll.collation);
16992 self.write("\"");
16993 } else {
16994 self.write(&coll.collation);
16996 }
16997 Ok(())
16998 }
16999
17000 fn generate_case(&mut self, case: &Case) -> Result<()> {
17001 let multiline_case = if self.config.pretty {
17003 let mut statements: Vec<String> = Vec::new();
17005 let operand_str = if let Some(operand) = &case.operand {
17006 let s = self.generate_to_string(operand)?;
17007 statements.push(format!("CASE {}", s));
17008 s
17009 } else {
17010 statements.push("CASE".to_string());
17011 String::new()
17012 };
17013 let _ = operand_str;
17014 for (condition, result) in &case.whens {
17015 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
17016 statements.push(format!("THEN {}", self.generate_to_string(result)?));
17017 }
17018 if let Some(else_) = &case.else_ {
17019 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
17020 }
17021 statements.push("END".to_string());
17022 self.too_wide(&statements)
17023 } else {
17024 false
17025 };
17026
17027 self.write_keyword("CASE");
17028 if let Some(operand) = &case.operand {
17029 self.write_space();
17030 self.generate_expression(operand)?;
17031 }
17032 if multiline_case {
17033 self.indent_level += 1;
17034 }
17035 for (condition, result) in &case.whens {
17036 if multiline_case {
17037 self.write_newline();
17038 self.write_indent();
17039 } else {
17040 self.write_space();
17041 }
17042 self.write_keyword("WHEN");
17043 self.write_space();
17044 self.generate_expression(condition)?;
17045 if multiline_case {
17046 self.write_newline();
17047 self.write_indent();
17048 } else {
17049 self.write_space();
17050 }
17051 self.write_keyword("THEN");
17052 self.write_space();
17053 self.generate_expression(result)?;
17054 }
17055 if let Some(else_) = &case.else_ {
17056 if multiline_case {
17057 self.write_newline();
17058 self.write_indent();
17059 } else {
17060 self.write_space();
17061 }
17062 self.write_keyword("ELSE");
17063 self.write_space();
17064 self.generate_expression(else_)?;
17065 }
17066 if multiline_case {
17067 self.indent_level -= 1;
17068 self.write_newline();
17069 self.write_indent();
17070 } else {
17071 self.write_space();
17072 }
17073 self.write_keyword("END");
17074 for comment in &case.comments {
17076 self.write(" ");
17077 self.write_formatted_comment(comment);
17078 }
17079 Ok(())
17080 }
17081
17082 fn generate_function(&mut self, func: &Function) -> Result<()> {
17083 let normalized_name = self.normalize_func_name(&func.name);
17085
17086 if matches!(self.config.dialect, Some(DialectType::DuckDB))
17088 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
17089 {
17090 self.write("LIST_FILTER(");
17091 self.write("[");
17092 for (i, arg) in func.args.iter().enumerate() {
17093 if i > 0 {
17094 self.write(", ");
17095 }
17096 self.generate_expression(arg)?;
17097 }
17098 self.write("], _u -> NOT _u IS NULL)");
17099 return Ok(());
17100 }
17101
17102 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17105 && func.name.eq_ignore_ascii_case("TO_VARIANT")
17106 && func.args.len() == 1
17107 {
17108 let array_expressions = match &func.args[0] {
17109 Expression::ArrayFunc(arr) => Some(&arr.expressions),
17110 Expression::Array(arr) => Some(&arr.expressions),
17111 _ => None,
17112 };
17113 if let Some(expressions) = array_expressions {
17114 self.write_keyword("TO_VARIANT");
17115 self.write("(");
17116 self.write_keyword("ARRAY_CONSTRUCT");
17117 self.write("(");
17118 for (i, arg) in expressions.iter().enumerate() {
17119 if i > 0 {
17120 self.write(", ");
17121 }
17122 self.generate_expression(arg)?;
17123 }
17124 self.write(")");
17125 self.write(")");
17126 return Ok(());
17127 }
17128 }
17129
17130 if func.name.eq_ignore_ascii_case("STRUCT")
17132 && !matches!(
17133 self.config.dialect,
17134 Some(DialectType::BigQuery)
17135 | Some(DialectType::Spark)
17136 | Some(DialectType::Databricks)
17137 | Some(DialectType::Hive)
17138 | None
17139 )
17140 {
17141 return self.generate_struct_function_cross_dialect(func);
17142 }
17143
17144 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
17147 self.generate_expression(&func.args[0])?;
17148 self.write("::?");
17149 if let Expression::Literal(lit) = &func.args[1] {
17151 if let crate::expressions::Literal::String(key) = lit.as_ref() {
17152 self.write(key);
17153 }
17154 } else {
17155 self.generate_expression(&func.args[1])?;
17156 }
17157 return Ok(());
17158 }
17159
17160 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
17162 self.generate_expression(&func.args[0])?;
17163 self.write(" # ");
17164 self.generate_expression(&func.args[1])?;
17165 return Ok(());
17166 }
17167
17168 if matches!(
17170 self.config.dialect,
17171 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
17172 ) && func.name.eq_ignore_ascii_case("TRY")
17173 && func.args.len() == 1
17174 {
17175 self.generate_expression(&func.args[0])?;
17176 return Ok(());
17177 }
17178
17179 if self.config.dialect == Some(DialectType::ClickHouse)
17181 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
17182 && func.args.len() == 1
17183 {
17184 self.write("dateTrunc('DAY', ");
17185 self.generate_expression(&func.args[0])?;
17186 self.write(")");
17187 return Ok(());
17188 }
17189
17190 if self.config.dialect == Some(DialectType::Redshift)
17192 && func.name.eq_ignore_ascii_case("CONCAT")
17193 && func.args.len() >= 2
17194 {
17195 for (i, arg) in func.args.iter().enumerate() {
17196 if i > 0 {
17197 self.write(" || ");
17198 }
17199 self.generate_expression(arg)?;
17200 }
17201 return Ok(());
17202 }
17203
17204 if self.config.dialect == Some(DialectType::Redshift)
17206 && func.name.eq_ignore_ascii_case("CONCAT_WS")
17207 && func.args.len() >= 2
17208 {
17209 let sep = &func.args[0];
17210 for (i, arg) in func.args.iter().skip(1).enumerate() {
17211 if i > 0 {
17212 self.write(" || ");
17213 self.generate_expression(sep)?;
17214 self.write(" || ");
17215 }
17216 self.generate_expression(arg)?;
17217 }
17218 return Ok(());
17219 }
17220
17221 if self.config.dialect == Some(DialectType::Redshift)
17224 && (func.name.eq_ignore_ascii_case("DATEDIFF")
17225 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
17226 && func.args.len() == 3
17227 {
17228 self.write_keyword("DATEDIFF");
17229 self.write("(");
17230 self.write_redshift_date_part(&func.args[0]);
17232 self.write(", ");
17233 self.generate_expression(&func.args[1])?;
17234 self.write(", ");
17235 self.generate_expression(&func.args[2])?;
17236 self.write(")");
17237 return Ok(());
17238 }
17239
17240 if self.config.dialect == Some(DialectType::Redshift)
17243 && (func.name.eq_ignore_ascii_case("DATEADD")
17244 || func.name.eq_ignore_ascii_case("DATE_ADD"))
17245 && func.args.len() == 3
17246 {
17247 self.write_keyword("DATEADD");
17248 self.write("(");
17249 self.write_redshift_date_part(&func.args[0]);
17251 self.write(", ");
17252 self.generate_expression(&func.args[1])?;
17253 self.write(", ");
17254 self.generate_expression(&func.args[2])?;
17255 self.write(")");
17256 return Ok(());
17257 }
17258
17259 if func.name.eq_ignore_ascii_case("UUID_STRING")
17261 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
17262 {
17263 let func_name = match self.config.dialect {
17264 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
17265 Some(DialectType::BigQuery) => "GENERATE_UUID",
17266 _ => "UUID",
17267 };
17268 self.write_keyword(func_name);
17269 self.write("()");
17270 return Ok(());
17271 }
17272
17273 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17277 && func.name.eq_ignore_ascii_case("GENERATOR")
17278 {
17279 let has_positional_args =
17280 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
17281 if has_positional_args {
17282 let param_names = ["ROWCOUNT", "TIMELIMIT"];
17283 self.write_keyword("GENERATOR");
17284 self.write("(");
17285 for (i, arg) in func.args.iter().enumerate() {
17286 if i > 0 {
17287 self.write(", ");
17288 }
17289 if i < param_names.len() {
17290 self.write_keyword(param_names[i]);
17291 self.write(" => ");
17292 self.generate_expression(arg)?;
17293 } else {
17294 self.generate_expression(arg)?;
17295 }
17296 }
17297 self.write(")");
17298 return Ok(());
17299 }
17300 }
17301
17302 if self.config.dialect == Some(DialectType::Redshift)
17305 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17306 && func.args.len() == 2
17307 {
17308 self.write_keyword("DATE_TRUNC");
17309 self.write("(");
17310 self.write_redshift_date_part_quoted(&func.args[0]);
17312 self.write(", ");
17313 self.generate_expression(&func.args[1])?;
17314 self.write(")");
17315 return Ok(());
17316 }
17317
17318 if matches!(
17320 self.config.dialect,
17321 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17322 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17323 || func.name.eq_ignore_ascii_case("DATEPART"))
17324 && func.args.len() == 2
17325 {
17326 self.write_keyword("DATEPART");
17327 self.write("(");
17328 self.generate_expression(&func.args[0])?;
17329 self.write(", ");
17330 self.generate_expression(&func.args[1])?;
17331 self.write(")");
17332 return Ok(());
17333 }
17334
17335 if matches!(
17337 self.config.dialect,
17338 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
17339 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17340 || func.name.eq_ignore_ascii_case("DATEPART"))
17341 && func.args.len() == 2
17342 {
17343 self.write_keyword("EXTRACT");
17344 self.write("(");
17345 match &func.args[0] {
17347 Expression::Literal(lit)
17348 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
17349 {
17350 let crate::expressions::Literal::String(s) = lit.as_ref() else {
17351 unreachable!()
17352 };
17353 self.write(&s.to_ascii_lowercase());
17354 }
17355 _ => self.generate_expression(&func.args[0])?,
17356 }
17357 self.write_space();
17358 self.write_keyword("FROM");
17359 self.write_space();
17360 self.generate_expression(&func.args[1])?;
17361 self.write(")");
17362 return Ok(());
17363 }
17364
17365 if self.config.dialect == Some(DialectType::PostgreSQL)
17367 && matches!(
17368 func.name.to_ascii_uppercase().as_str(),
17369 "DATE_ADD" | "DATE_SUB"
17370 )
17371 && func.args.len() == 2
17372 && matches!(func.args[1], Expression::Interval(_))
17373 {
17374 self.generate_expression(&func.args[0])?;
17375 self.write_space();
17376 if func.name.eq_ignore_ascii_case("DATE_SUB") {
17377 self.write("-");
17378 } else {
17379 self.write("+");
17380 }
17381 self.write_space();
17382 self.generate_expression(&func.args[1])?;
17383 return Ok(());
17384 }
17385
17386 if self.config.dialect == Some(DialectType::Dremio)
17389 && (func.name.eq_ignore_ascii_case("DATE_PART")
17390 || func.name.eq_ignore_ascii_case("DATEPART"))
17391 && func.args.len() == 2
17392 {
17393 self.write_keyword("EXTRACT");
17394 self.write("(");
17395 self.generate_expression(&func.args[0])?;
17396 self.write_space();
17397 self.write_keyword("FROM");
17398 self.write_space();
17399 self.generate_dremio_date_expression(&func.args[1])?;
17401 self.write(")");
17402 return Ok(());
17403 }
17404
17405 if self.config.dialect == Some(DialectType::Dremio)
17407 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
17408 && func.args.is_empty()
17409 {
17410 self.write_keyword("CURRENT_DATE_UTC");
17411 return Ok(());
17412 }
17413
17414 if self.config.dialect == Some(DialectType::Dremio)
17418 && func.name.eq_ignore_ascii_case("DATETYPE")
17419 && func.args.len() == 3
17420 {
17421 fn get_int_literal(expr: &Expression) -> Option<i64> {
17423 if let Expression::Literal(lit) = expr {
17424 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
17425 s.parse::<i64>().ok()
17426 } else {
17427 None
17428 }
17429 } else {
17430 None
17431 }
17432 }
17433
17434 if let (Some(year), Some(month), Some(day)) = (
17436 get_int_literal(&func.args[0]),
17437 get_int_literal(&func.args[1]),
17438 get_int_literal(&func.args[2]),
17439 ) {
17440 self.write_keyword("DATE");
17442 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
17443 return Ok(());
17444 }
17445
17446 self.write_keyword("CAST");
17448 self.write("(");
17449 self.write_keyword("CONCAT");
17450 self.write("(");
17451 self.generate_expression(&func.args[0])?;
17452 self.write(", '-', ");
17453 self.generate_expression(&func.args[1])?;
17454 self.write(", '-', ");
17455 self.generate_expression(&func.args[2])?;
17456 self.write(")");
17457 self.write_space();
17458 self.write_keyword("AS");
17459 self.write_space();
17460 self.write_keyword("DATE");
17461 self.write(")");
17462 return Ok(());
17463 }
17464
17465 let is_presto_like = matches!(
17468 self.config.dialect,
17469 Some(DialectType::Presto) | Some(DialectType::Trino)
17470 );
17471 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
17472 self.write_keyword("DATE_ADD");
17473 self.write("(");
17474 self.generate_expression(&func.args[0])?;
17476 self.write(", ");
17477 let interval = &func.args[1];
17479 let needs_cast = !self.returns_integer_type(interval);
17480 if needs_cast {
17481 self.write_keyword("CAST");
17482 self.write("(");
17483 }
17484 self.generate_expression(interval)?;
17485 if needs_cast {
17486 self.write_space();
17487 self.write_keyword("AS");
17488 self.write_space();
17489 self.write_keyword("BIGINT");
17490 self.write(")");
17491 }
17492 self.write(", ");
17493 self.generate_expression(&func.args[2])?;
17495 self.write(")");
17496 return Ok(());
17497 }
17498
17499 let use_brackets = func.use_bracket_syntax;
17501
17502 let has_ordinality = func.name.len() >= 16
17507 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
17508 let output_name = if has_ordinality {
17509 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
17510 self.normalize_func_name(base_name)
17511 } else {
17512 normalized_name.clone()
17513 };
17514
17515 if func.name.contains('.') && !has_ordinality {
17518 if func.quoted {
17521 self.write("`");
17522 self.write(&func.name);
17523 self.write("`");
17524 } else {
17525 self.write(&func.name);
17526 }
17527 } else {
17528 self.write(&output_name);
17529 }
17530
17531 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
17534 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
17535 || func.name.eq_ignore_ascii_case("SESSION_USER")
17536 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
17537 {
17538 matches!(
17539 self.config.dialect,
17540 Some(DialectType::Snowflake)
17541 | Some(DialectType::Spark)
17542 | Some(DialectType::Databricks)
17543 | Some(DialectType::Hive)
17544 )
17545 } else {
17546 false
17547 };
17548 !needs_parens
17549 };
17550 if force_parens {
17551 for comment in &func.trailing_comments {
17553 self.write_space();
17554 self.write_formatted_comment(comment);
17555 }
17556 return Ok(());
17557 }
17558
17559 if func.name.eq_ignore_ascii_case("CUBE")
17561 || func.name.eq_ignore_ascii_case("ROLLUP")
17562 || func.name.eq_ignore_ascii_case("GROUPING SETS")
17563 {
17564 self.write(" (");
17565 } else if use_brackets {
17566 self.write("[");
17567 } else {
17568 self.write("(");
17569 }
17570 if func.distinct {
17571 self.write_keyword("DISTINCT");
17572 self.write_space();
17573 }
17574
17575 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
17577 && (func.name.eq_ignore_ascii_case("TABLE")
17578 || func.name.eq_ignore_ascii_case("FLATTEN"));
17579 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
17581 || func.name.eq_ignore_ascii_case("CUBE")
17582 || func.name.eq_ignore_ascii_case("ROLLUP");
17583 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
17584 if is_grouping_func {
17585 true
17586 } else {
17587 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
17589 for arg in &func.args {
17590 let mut temp_gen = Generator::with_arc_config(self.config.clone());
17591 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
17593 expr_strings.push(temp_gen.output);
17594 }
17595 self.too_wide(&expr_strings)
17596 }
17597 } else {
17598 false
17599 };
17600
17601 if should_split {
17602 self.write_newline();
17604 self.indent_level += 1;
17605 for (i, arg) in func.args.iter().enumerate() {
17606 self.write_indent();
17607 self.generate_expression(arg)?;
17608 if i + 1 < func.args.len() {
17609 self.write(",");
17610 }
17611 self.write_newline();
17612 }
17613 self.indent_level -= 1;
17614 self.write_indent();
17615 } else {
17616 for (i, arg) in func.args.iter().enumerate() {
17618 if i > 0 {
17619 self.write(", ");
17620 }
17621 self.generate_expression(arg)?;
17622 }
17623 }
17624
17625 if use_brackets {
17626 self.write("]");
17627 } else {
17628 self.write(")");
17629 }
17630 if has_ordinality {
17632 self.write_space();
17633 self.write_keyword("WITH ORDINALITY");
17634 }
17635 for comment in &func.trailing_comments {
17637 self.write_space();
17638 self.write_formatted_comment(comment);
17639 }
17640 Ok(())
17641 }
17642
17643 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
17644 self.generate_expression(&fe.this)?;
17645 self.write_keyword(" EMITS ");
17646 self.generate_expression(&fe.emits)?;
17647 Ok(())
17648 }
17649
17650 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
17651 let mut normalized_name = self.normalize_func_name(&func.name);
17653
17654 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
17656 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
17657 match self.config.dialect {
17658 Some(DialectType::ClickHouse) => {
17659 normalized_name = if is_max {
17660 Cow::Borrowed("argMax")
17661 } else {
17662 Cow::Borrowed("argMin")
17663 };
17664 }
17665 Some(DialectType::DuckDB) => {
17666 normalized_name = if is_max {
17667 Cow::Borrowed("ARG_MAX")
17668 } else {
17669 Cow::Borrowed("ARG_MIN")
17670 };
17671 }
17672 _ => {}
17673 }
17674 }
17675 self.write(normalized_name.as_ref());
17676 self.write("(");
17677 if func.distinct {
17678 self.write_keyword("DISTINCT");
17679 self.write_space();
17680 }
17681
17682 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
17686 let needs_multi_arg_transform =
17687 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
17688
17689 if needs_multi_arg_transform {
17690 self.write_keyword("CASE");
17692 for arg in &func.args {
17693 self.write_space();
17694 self.write_keyword("WHEN");
17695 self.write_space();
17696 self.generate_expression(arg)?;
17697 self.write_space();
17698 self.write_keyword("IS NULL THEN NULL");
17699 }
17700 self.write_space();
17701 self.write_keyword("ELSE");
17702 self.write(" (");
17703 for (i, arg) in func.args.iter().enumerate() {
17704 if i > 0 {
17705 self.write(", ");
17706 }
17707 self.generate_expression(arg)?;
17708 }
17709 self.write(")");
17710 self.write_space();
17711 self.write_keyword("END");
17712 } else {
17713 for (i, arg) in func.args.iter().enumerate() {
17714 if i > 0 {
17715 self.write(", ");
17716 }
17717 self.generate_expression(arg)?;
17718 }
17719 }
17720
17721 if self.config.ignore_nulls_in_func
17723 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17724 {
17725 if let Some(ignore) = func.ignore_nulls {
17726 self.write_space();
17727 if ignore {
17728 self.write_keyword("IGNORE NULLS");
17729 } else {
17730 self.write_keyword("RESPECT NULLS");
17731 }
17732 }
17733 }
17734
17735 if !func.order_by.is_empty() {
17737 self.write_space();
17738 self.write_keyword("ORDER BY");
17739 self.write_space();
17740 for (i, ord) in func.order_by.iter().enumerate() {
17741 if i > 0 {
17742 self.write(", ");
17743 }
17744 self.generate_ordered(ord)?;
17745 }
17746 }
17747
17748 if let Some(limit) = &func.limit {
17750 self.write_space();
17751 self.write_keyword("LIMIT");
17752 self.write_space();
17753 if let Expression::Tuple(t) = limit.as_ref() {
17755 if t.expressions.len() == 2 {
17756 self.generate_expression(&t.expressions[0])?;
17757 self.write(", ");
17758 self.generate_expression(&t.expressions[1])?;
17759 } else {
17760 self.generate_expression(limit)?;
17761 }
17762 } else {
17763 self.generate_expression(limit)?;
17764 }
17765 }
17766
17767 self.write(")");
17768
17769 if !self.config.ignore_nulls_in_func
17771 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17772 {
17773 if let Some(ignore) = func.ignore_nulls {
17774 self.write_space();
17775 if ignore {
17776 self.write_keyword("IGNORE NULLS");
17777 } else {
17778 self.write_keyword("RESPECT NULLS");
17779 }
17780 }
17781 }
17782
17783 if let Some(filter) = &func.filter {
17784 self.write_space();
17785 self.write_keyword("FILTER");
17786 self.write("(");
17787 self.write_keyword("WHERE");
17788 self.write_space();
17789 self.generate_expression(filter)?;
17790 self.write(")");
17791 }
17792
17793 Ok(())
17794 }
17795
17796 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
17797 self.generate_expression(&wf.this)?;
17798
17799 if let Some(keep) = &wf.keep {
17801 self.write_space();
17802 self.write_keyword("KEEP");
17803 self.write(" (");
17804 self.write_keyword("DENSE_RANK");
17805 self.write_space();
17806 if keep.first {
17807 self.write_keyword("FIRST");
17808 } else {
17809 self.write_keyword("LAST");
17810 }
17811 self.write_space();
17812 self.write_keyword("ORDER BY");
17813 self.write_space();
17814 for (i, ord) in keep.order_by.iter().enumerate() {
17815 if i > 0 {
17816 self.write(", ");
17817 }
17818 self.generate_ordered(ord)?;
17819 }
17820 self.write(")");
17821 }
17822
17823 let has_over = !wf.over.partition_by.is_empty()
17825 || !wf.over.order_by.is_empty()
17826 || wf.over.frame.is_some()
17827 || wf.over.window_name.is_some();
17828
17829 if has_over {
17831 self.write_space();
17832 self.write_keyword("OVER");
17833
17834 let has_specs = !wf.over.partition_by.is_empty()
17836 || !wf.over.order_by.is_empty()
17837 || wf.over.frame.is_some();
17838
17839 if wf.over.window_name.is_some() && !has_specs {
17840 self.write_space();
17842 self.write(&wf.over.window_name.as_ref().unwrap().name);
17843 } else {
17844 self.write(" (");
17846 self.generate_over(&wf.over)?;
17847 self.write(")");
17848 }
17849 } else if wf.keep.is_none() {
17850 self.write_space();
17852 self.write_keyword("OVER");
17853 self.write(" ()");
17854 }
17855
17856 Ok(())
17857 }
17858
17859 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
17861 self.generate_expression(&wg.this)?;
17862 self.write_space();
17863 self.write_keyword("WITHIN GROUP");
17864 self.write(" (");
17865 self.write_keyword("ORDER BY");
17866 self.write_space();
17867 for (i, ord) in wg.order_by.iter().enumerate() {
17868 if i > 0 {
17869 self.write(", ");
17870 }
17871 self.generate_ordered(ord)?;
17872 }
17873 self.write(")");
17874 Ok(())
17875 }
17876
17877 fn generate_over(&mut self, over: &Over) -> Result<()> {
17879 let mut has_content = false;
17880
17881 if let Some(name) = &over.window_name {
17883 self.write(&name.name);
17884 has_content = true;
17885 }
17886
17887 if !over.partition_by.is_empty() {
17889 if has_content {
17890 self.write_space();
17891 }
17892 self.write_keyword("PARTITION BY");
17893 self.write_space();
17894 for (i, expr) in over.partition_by.iter().enumerate() {
17895 if i > 0 {
17896 self.write(", ");
17897 }
17898 self.generate_expression(expr)?;
17899 }
17900 has_content = true;
17901 }
17902
17903 if !over.order_by.is_empty() {
17905 if has_content {
17906 self.write_space();
17907 }
17908 self.write_keyword("ORDER BY");
17909 self.write_space();
17910 for (i, ordered) in over.order_by.iter().enumerate() {
17911 if i > 0 {
17912 self.write(", ");
17913 }
17914 self.generate_ordered(ordered)?;
17915 }
17916 has_content = true;
17917 }
17918
17919 if let Some(frame) = &over.frame {
17921 if has_content {
17922 self.write_space();
17923 }
17924 self.generate_window_frame(frame)?;
17925 }
17926
17927 Ok(())
17928 }
17929
17930 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
17931 let lowercase_frame = self.config.lowercase_window_frame_keywords;
17933
17934 if !lowercase_frame {
17936 if let Some(kind_text) = &frame.kind_text {
17937 self.write(kind_text);
17938 } else {
17939 match frame.kind {
17940 WindowFrameKind::Rows => self.write_keyword("ROWS"),
17941 WindowFrameKind::Range => self.write_keyword("RANGE"),
17942 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
17943 }
17944 }
17945 } else {
17946 match frame.kind {
17947 WindowFrameKind::Rows => self.write("rows"),
17948 WindowFrameKind::Range => self.write("range"),
17949 WindowFrameKind::Groups => self.write("groups"),
17950 }
17951 }
17952
17953 self.write_space();
17956 let should_normalize = self.config.normalize_window_frame_between
17957 && frame.end.is_none()
17958 && matches!(
17959 frame.start,
17960 WindowFrameBound::Preceding(_)
17961 | WindowFrameBound::Following(_)
17962 | WindowFrameBound::UnboundedPreceding
17963 | WindowFrameBound::UnboundedFollowing
17964 );
17965
17966 if let Some(end) = &frame.end {
17967 self.write_keyword("BETWEEN");
17969 self.write_space();
17970 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17971 self.write_space();
17972 self.write_keyword("AND");
17973 self.write_space();
17974 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
17975 } else if should_normalize {
17976 self.write_keyword("BETWEEN");
17978 self.write_space();
17979 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17980 self.write_space();
17981 self.write_keyword("AND");
17982 self.write_space();
17983 self.write_keyword("CURRENT ROW");
17984 } else {
17985 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17987 }
17988
17989 if let Some(exclude) = &frame.exclude {
17991 self.write_space();
17992 self.write_keyword("EXCLUDE");
17993 self.write_space();
17994 match exclude {
17995 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
17996 WindowFrameExclude::Group => self.write_keyword("GROUP"),
17997 WindowFrameExclude::Ties => self.write_keyword("TIES"),
17998 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
17999 }
18000 }
18001
18002 Ok(())
18003 }
18004
18005 fn generate_window_frame_bound(
18006 &mut self,
18007 bound: &WindowFrameBound,
18008 side_text: Option<&str>,
18009 ) -> Result<()> {
18010 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18012
18013 match bound {
18014 WindowFrameBound::CurrentRow => {
18015 self.write_keyword("CURRENT ROW");
18016 }
18017 WindowFrameBound::UnboundedPreceding => {
18018 self.write_keyword("UNBOUNDED");
18019 self.write_space();
18020 if lowercase_frame {
18021 self.write("preceding");
18022 } else if let Some(text) = side_text {
18023 self.write(text);
18024 } else {
18025 self.write_keyword("PRECEDING");
18026 }
18027 }
18028 WindowFrameBound::UnboundedFollowing => {
18029 self.write_keyword("UNBOUNDED");
18030 self.write_space();
18031 if lowercase_frame {
18032 self.write("following");
18033 } else if let Some(text) = side_text {
18034 self.write(text);
18035 } else {
18036 self.write_keyword("FOLLOWING");
18037 }
18038 }
18039 WindowFrameBound::Preceding(expr) => {
18040 self.generate_expression(expr)?;
18041 self.write_space();
18042 if lowercase_frame {
18043 self.write("preceding");
18044 } else if let Some(text) = side_text {
18045 self.write(text);
18046 } else {
18047 self.write_keyword("PRECEDING");
18048 }
18049 }
18050 WindowFrameBound::Following(expr) => {
18051 self.generate_expression(expr)?;
18052 self.write_space();
18053 if lowercase_frame {
18054 self.write("following");
18055 } else if let Some(text) = side_text {
18056 self.write(text);
18057 } else {
18058 self.write_keyword("FOLLOWING");
18059 }
18060 }
18061 WindowFrameBound::BarePreceding => {
18062 if lowercase_frame {
18063 self.write("preceding");
18064 } else if let Some(text) = side_text {
18065 self.write(text);
18066 } else {
18067 self.write_keyword("PRECEDING");
18068 }
18069 }
18070 WindowFrameBound::BareFollowing => {
18071 if lowercase_frame {
18072 self.write("following");
18073 } else if let Some(text) = side_text {
18074 self.write(text);
18075 } else {
18076 self.write_keyword("FOLLOWING");
18077 }
18078 }
18079 WindowFrameBound::Value(expr) => {
18080 self.generate_expression(expr)?;
18082 }
18083 }
18084 Ok(())
18085 }
18086
18087 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
18088 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
18091 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
18092 && !matches!(&interval.this, Some(Expression::Literal(_)));
18093
18094 if self.config.single_string_interval {
18097 if let (
18098 Some(Expression::Literal(lit)),
18099 Some(IntervalUnitSpec::Simple {
18100 ref unit,
18101 ref use_plural,
18102 }),
18103 ) = (&interval.this, &interval.unit)
18104 {
18105 if let Literal::String(ref val) = lit.as_ref() {
18106 self.write_keyword("INTERVAL");
18107 self.write_space();
18108 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18109 let unit_str = self.interval_unit_str(unit, effective_plural);
18110 self.write("'");
18111 self.write(val);
18112 self.write(" ");
18113 self.write(&unit_str);
18114 self.write("'");
18115 return Ok(());
18116 }
18117 }
18118 }
18119
18120 if !skip_interval_keyword {
18121 self.write_keyword("INTERVAL");
18122 }
18123
18124 if let Some(ref value) = interval.this {
18126 if !skip_interval_keyword {
18127 self.write_space();
18128 }
18129 let needs_parens = interval.unit.is_some()
18133 && matches!(
18134 value,
18135 Expression::Add(_)
18136 | Expression::Sub(_)
18137 | Expression::Mul(_)
18138 | Expression::Div(_)
18139 | Expression::Mod(_)
18140 | Expression::BitwiseAnd(_)
18141 | Expression::BitwiseOr(_)
18142 | Expression::BitwiseXor(_)
18143 );
18144 if needs_parens {
18145 self.write("(");
18146 }
18147 self.generate_expression(value)?;
18148 if needs_parens {
18149 self.write(")");
18150 }
18151 }
18152
18153 if let Some(ref unit_spec) = interval.unit {
18155 self.write_space();
18156 self.write_interval_unit_spec(unit_spec)?;
18157 }
18158
18159 Ok(())
18160 }
18161
18162 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
18164 match (unit, use_plural) {
18165 (IntervalUnit::Year, false) => "YEAR",
18166 (IntervalUnit::Year, true) => "YEARS",
18167 (IntervalUnit::Quarter, false) => "QUARTER",
18168 (IntervalUnit::Quarter, true) => "QUARTERS",
18169 (IntervalUnit::Month, false) => "MONTH",
18170 (IntervalUnit::Month, true) => "MONTHS",
18171 (IntervalUnit::Week, false) => "WEEK",
18172 (IntervalUnit::Week, true) => "WEEKS",
18173 (IntervalUnit::Day, false) => "DAY",
18174 (IntervalUnit::Day, true) => "DAYS",
18175 (IntervalUnit::Hour, false) => "HOUR",
18176 (IntervalUnit::Hour, true) => "HOURS",
18177 (IntervalUnit::Minute, false) => "MINUTE",
18178 (IntervalUnit::Minute, true) => "MINUTES",
18179 (IntervalUnit::Second, false) => "SECOND",
18180 (IntervalUnit::Second, true) => "SECONDS",
18181 (IntervalUnit::Millisecond, false) => "MILLISECOND",
18182 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
18183 (IntervalUnit::Microsecond, false) => "MICROSECOND",
18184 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
18185 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
18186 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
18187 }
18188 }
18189
18190 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
18191 match unit_spec {
18192 IntervalUnitSpec::Simple { unit, use_plural } => {
18193 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18195 self.write_simple_interval_unit(unit, effective_plural);
18196 }
18197 IntervalUnitSpec::Span(span) => {
18198 self.write_simple_interval_unit(&span.this, false);
18199 self.write_space();
18200 self.write_keyword("TO");
18201 self.write_space();
18202 self.write_simple_interval_unit(&span.expression, false);
18203 }
18204 IntervalUnitSpec::ExprSpan(span) => {
18205 self.generate_expression(&span.this)?;
18207 self.write_space();
18208 self.write_keyword("TO");
18209 self.write_space();
18210 self.generate_expression(&span.expression)?;
18211 }
18212 IntervalUnitSpec::Expr(expr) => {
18213 self.generate_expression(expr)?;
18214 }
18215 }
18216 Ok(())
18217 }
18218
18219 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
18220 match (unit, use_plural) {
18222 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
18223 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
18224 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
18225 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
18226 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
18227 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
18228 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
18229 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
18230 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
18231 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
18232 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
18233 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
18234 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
18235 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
18236 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
18237 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
18238 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
18239 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
18240 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
18241 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
18242 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
18243 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
18244 }
18245 }
18246
18247 fn write_redshift_date_part(&mut self, expr: &Expression) {
18250 let part_str = self.extract_date_part_string(expr);
18251 if let Some(part) = part_str {
18252 let normalized = self.normalize_date_part(&part);
18253 self.write_keyword(&normalized);
18254 } else {
18255 let _ = self.generate_expression(expr);
18257 }
18258 }
18259
18260 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
18263 let part_str = self.extract_date_part_string(expr);
18264 if let Some(part) = part_str {
18265 let normalized = self.normalize_date_part(&part);
18266 self.write("'");
18267 self.write(&normalized);
18268 self.write("'");
18269 } else {
18270 let _ = self.generate_expression(expr);
18272 }
18273 }
18274
18275 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
18277 match expr {
18278 Expression::Literal(lit)
18279 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18280 {
18281 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18282 unreachable!()
18283 };
18284 Some(s.clone())
18285 }
18286 Expression::Identifier(id) => Some(id.name.clone()),
18287 Expression::Var(v) => Some(v.this.clone()),
18288 Expression::Column(col) if col.table.is_none() => {
18289 Some(col.name.name.clone())
18291 }
18292 _ => None,
18293 }
18294 }
18295
18296 fn normalize_date_part(&self, part: &str) -> String {
18299 let mut buf = [0u8; 64];
18300 let lower: &str = if part.len() <= 64 {
18301 for (i, b) in part.bytes().enumerate() {
18302 buf[i] = b.to_ascii_lowercase();
18303 }
18304 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
18305 } else {
18306 return part.to_ascii_uppercase();
18307 };
18308 match lower {
18309 "day" | "days" | "d" => "DAY".to_string(),
18310 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
18311 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
18312 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
18313 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
18314 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
18315 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
18316 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
18317 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
18318 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
18319 _ => part.to_ascii_uppercase(),
18320 }
18321 }
18322
18323 fn write_datetime_field(&mut self, field: &DateTimeField) {
18324 match field {
18325 DateTimeField::Year => self.write_keyword("YEAR"),
18326 DateTimeField::Month => self.write_keyword("MONTH"),
18327 DateTimeField::Day => self.write_keyword("DAY"),
18328 DateTimeField::Hour => self.write_keyword("HOUR"),
18329 DateTimeField::Minute => self.write_keyword("MINUTE"),
18330 DateTimeField::Second => self.write_keyword("SECOND"),
18331 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
18332 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
18333 DateTimeField::DayOfWeek => {
18334 let name = match self.config.dialect {
18335 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
18336 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
18337 _ => "DOW",
18338 };
18339 self.write_keyword(name);
18340 }
18341 DateTimeField::DayOfYear => {
18342 let name = match self.config.dialect {
18343 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
18344 _ => "DOY",
18345 };
18346 self.write_keyword(name);
18347 }
18348 DateTimeField::Week => self.write_keyword("WEEK"),
18349 DateTimeField::WeekWithModifier(modifier) => {
18350 self.write_keyword("WEEK");
18351 self.write("(");
18352 self.write(modifier);
18353 self.write(")");
18354 }
18355 DateTimeField::Quarter => self.write_keyword("QUARTER"),
18356 DateTimeField::Epoch => self.write_keyword("EPOCH"),
18357 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
18358 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
18359 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
18360 DateTimeField::Date => self.write_keyword("DATE"),
18361 DateTimeField::Time => self.write_keyword("TIME"),
18362 DateTimeField::Custom(name) => self.write(name),
18363 }
18364 }
18365
18366 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
18368 match field {
18369 DateTimeField::Year => self.write("year"),
18370 DateTimeField::Month => self.write("month"),
18371 DateTimeField::Day => self.write("day"),
18372 DateTimeField::Hour => self.write("hour"),
18373 DateTimeField::Minute => self.write("minute"),
18374 DateTimeField::Second => self.write("second"),
18375 DateTimeField::Millisecond => self.write("millisecond"),
18376 DateTimeField::Microsecond => self.write("microsecond"),
18377 DateTimeField::DayOfWeek => self.write("dow"),
18378 DateTimeField::DayOfYear => self.write("doy"),
18379 DateTimeField::Week => self.write("week"),
18380 DateTimeField::WeekWithModifier(modifier) => {
18381 self.write("week(");
18382 self.write(modifier);
18383 self.write(")");
18384 }
18385 DateTimeField::Quarter => self.write("quarter"),
18386 DateTimeField::Epoch => self.write("epoch"),
18387 DateTimeField::Timezone => self.write("timezone"),
18388 DateTimeField::TimezoneHour => self.write("timezone_hour"),
18389 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
18390 DateTimeField::Date => self.write("date"),
18391 DateTimeField::Time => self.write("time"),
18392 DateTimeField::Custom(name) => self.write(name),
18393 }
18394 }
18395
18396 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
18399 self.write_keyword(name);
18400 self.write("(");
18401 self.generate_expression(arg)?;
18402 self.write(")");
18403 Ok(())
18404 }
18405
18406 fn generate_unary_func(
18408 &mut self,
18409 default_name: &str,
18410 f: &crate::expressions::UnaryFunc,
18411 ) -> Result<()> {
18412 let name = f.original_name.as_deref().unwrap_or(default_name);
18413 self.write_keyword(name);
18414 self.write("(");
18415 self.generate_expression(&f.this)?;
18416 self.write(")");
18417 Ok(())
18418 }
18419
18420 fn generate_sqrt_cbrt(
18422 &mut self,
18423 f: &crate::expressions::UnaryFunc,
18424 func_name: &str,
18425 _op: &str,
18426 ) -> Result<()> {
18427 self.write_keyword(func_name);
18430 self.write("(");
18431 self.generate_expression(&f.this)?;
18432 self.write(")");
18433 Ok(())
18434 }
18435
18436 fn generate_binary_func(
18437 &mut self,
18438 name: &str,
18439 arg1: &Expression,
18440 arg2: &Expression,
18441 ) -> Result<()> {
18442 self.write_keyword(name);
18443 self.write("(");
18444 self.generate_expression(arg1)?;
18445 self.write(", ");
18446 self.generate_expression(arg2)?;
18447 self.write(")");
18448 Ok(())
18449 }
18450
18451 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
18455 let func_name = f.name.as_deref().unwrap_or("CHAR");
18457 self.write_keyword(func_name);
18458 self.write("(");
18459 for (i, arg) in f.args.iter().enumerate() {
18460 if i > 0 {
18461 self.write(", ");
18462 }
18463 self.generate_expression(arg)?;
18464 }
18465 if let Some(ref charset) = f.charset {
18466 self.write(" ");
18467 self.write_keyword("USING");
18468 self.write(" ");
18469 self.write(charset);
18470 }
18471 self.write(")");
18472 Ok(())
18473 }
18474
18475 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
18476 use crate::dialects::DialectType;
18477
18478 match self.config.dialect {
18479 Some(DialectType::Teradata) => {
18480 self.generate_expression(&f.this)?;
18482 self.write(" ** ");
18483 self.generate_expression(&f.expression)?;
18484 Ok(())
18485 }
18486 _ => {
18487 self.generate_binary_func("POWER", &f.this, &f.expression)
18489 }
18490 }
18491 }
18492
18493 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
18494 self.write_func_name(name);
18495 self.write("(");
18496 for (i, arg) in args.iter().enumerate() {
18497 if i > 0 {
18498 self.write(", ");
18499 }
18500 self.generate_expression(arg)?;
18501 }
18502 self.write(")");
18503 Ok(())
18504 }
18505
18506 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
18509 self.write_keyword("CONCAT_WS");
18510 self.write("(");
18511 self.generate_expression(&f.separator)?;
18512 for expr in &f.expressions {
18513 self.write(", ");
18514 self.generate_expression(expr)?;
18515 }
18516 self.write(")");
18517 Ok(())
18518 }
18519
18520 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18521 if let Expression::Concat(op) = expr {
18522 Self::collect_concat_operands(&op.left, out);
18523 Self::collect_concat_operands(&op.right, out);
18524 } else {
18525 out.push(expr);
18526 }
18527 }
18528
18529 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
18530 let mut operands = Vec::new();
18531 Self::collect_concat_operands(&op.left, &mut operands);
18532 Self::collect_concat_operands(&op.right, &mut operands);
18533
18534 self.write_keyword("CONCAT");
18535 self.write("(");
18536 for (i, operand) in operands.iter().enumerate() {
18537 if i > 0 {
18538 self.write(", ");
18539 }
18540 self.generate_expression(operand)?;
18541 }
18542 self.write(")");
18543 Ok(())
18544 }
18545
18546 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18547 if let Expression::DPipe(dpipe) = expr {
18548 Self::collect_dpipe_operands(&dpipe.this, out);
18549 Self::collect_dpipe_operands(&dpipe.expression, out);
18550 } else {
18551 out.push(expr);
18552 }
18553 }
18554
18555 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
18556 let mut operands = Vec::new();
18557 Self::collect_dpipe_operands(&e.this, &mut operands);
18558 Self::collect_dpipe_operands(&e.expression, &mut operands);
18559
18560 self.write_keyword("CONCAT");
18561 self.write("(");
18562 for (i, operand) in operands.iter().enumerate() {
18563 if i > 0 {
18564 self.write(", ");
18565 }
18566 self.generate_expression(operand)?;
18567 }
18568 self.write(")");
18569 Ok(())
18570 }
18571
18572 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
18573 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
18575 if is_oracle {
18576 self.write_keyword("SUBSTR");
18577 } else {
18578 self.write_keyword("SUBSTRING");
18579 }
18580 self.write("(");
18581 self.generate_expression(&f.this)?;
18582 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
18584 let use_comma_syntax = matches!(
18586 self.config.dialect,
18587 Some(DialectType::Spark)
18588 | Some(DialectType::Hive)
18589 | Some(DialectType::Databricks)
18590 | Some(DialectType::TSQL)
18591 | Some(DialectType::Fabric)
18592 );
18593 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
18594 self.write_space();
18596 self.write_keyword("FROM");
18597 self.write_space();
18598 self.generate_expression(&f.start)?;
18599 if let Some(length) = &f.length {
18600 self.write_space();
18601 self.write_keyword("FOR");
18602 self.write_space();
18603 self.generate_expression(length)?;
18604 }
18605 } else {
18606 self.write(", ");
18608 self.generate_expression(&f.start)?;
18609 if let Some(length) = &f.length {
18610 self.write(", ");
18611 self.generate_expression(length)?;
18612 }
18613 }
18614 self.write(")");
18615 Ok(())
18616 }
18617
18618 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
18619 self.write_keyword("OVERLAY");
18620 self.write("(");
18621 self.generate_expression(&f.this)?;
18622 self.write_space();
18623 self.write_keyword("PLACING");
18624 self.write_space();
18625 self.generate_expression(&f.replacement)?;
18626 self.write_space();
18627 self.write_keyword("FROM");
18628 self.write_space();
18629 self.generate_expression(&f.from)?;
18630 if let Some(length) = &f.length {
18631 self.write_space();
18632 self.write_keyword("FOR");
18633 self.write_space();
18634 self.generate_expression(length)?;
18635 }
18636 self.write(")");
18637 Ok(())
18638 }
18639
18640 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
18641 if f.position_explicit && f.characters.is_none() {
18644 match f.position {
18645 TrimPosition::Leading => {
18646 self.write_keyword("LTRIM");
18647 self.write("(");
18648 self.generate_expression(&f.this)?;
18649 self.write(")");
18650 return Ok(());
18651 }
18652 TrimPosition::Trailing => {
18653 self.write_keyword("RTRIM");
18654 self.write("(");
18655 self.generate_expression(&f.this)?;
18656 self.write(")");
18657 return Ok(());
18658 }
18659 TrimPosition::Both => {
18660 }
18663 }
18664 }
18665
18666 self.write_keyword("TRIM");
18667 self.write("(");
18668 let force_standard = f.characters.is_some()
18671 && !f.sql_standard_syntax
18672 && matches!(
18673 self.config.dialect,
18674 Some(DialectType::Hive)
18675 | Some(DialectType::Spark)
18676 | Some(DialectType::Databricks)
18677 | Some(DialectType::ClickHouse)
18678 );
18679 let use_standard = (f.sql_standard_syntax || force_standard)
18680 && !(f.position_explicit
18681 && f.characters.is_none()
18682 && matches!(f.position, TrimPosition::Both));
18683 if use_standard {
18684 if f.position_explicit {
18687 match f.position {
18688 TrimPosition::Both => self.write_keyword("BOTH"),
18689 TrimPosition::Leading => self.write_keyword("LEADING"),
18690 TrimPosition::Trailing => self.write_keyword("TRAILING"),
18691 }
18692 self.write_space();
18693 }
18694 if let Some(chars) = &f.characters {
18695 self.generate_expression(chars)?;
18696 self.write_space();
18697 }
18698 self.write_keyword("FROM");
18699 self.write_space();
18700 self.generate_expression(&f.this)?;
18701 } else {
18702 self.generate_expression(&f.this)?;
18704 if let Some(chars) = &f.characters {
18705 self.write(", ");
18706 self.generate_expression(chars)?;
18707 }
18708 }
18709 self.write(")");
18710 Ok(())
18711 }
18712
18713 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
18714 self.write_keyword("REPLACE");
18715 self.write("(");
18716 self.generate_expression(&f.this)?;
18717 self.write(", ");
18718 self.generate_expression(&f.old)?;
18719 self.write(", ");
18720 self.generate_expression(&f.new)?;
18721 self.write(")");
18722 Ok(())
18723 }
18724
18725 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
18726 self.write_keyword(name);
18727 self.write("(");
18728 self.generate_expression(&f.this)?;
18729 self.write(", ");
18730 self.generate_expression(&f.length)?;
18731 self.write(")");
18732 Ok(())
18733 }
18734
18735 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
18736 self.write_keyword("REPEAT");
18737 self.write("(");
18738 self.generate_expression(&f.this)?;
18739 self.write(", ");
18740 self.generate_expression(&f.times)?;
18741 self.write(")");
18742 Ok(())
18743 }
18744
18745 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
18746 self.write_keyword(name);
18747 self.write("(");
18748 self.generate_expression(&f.this)?;
18749 self.write(", ");
18750 self.generate_expression(&f.length)?;
18751 if let Some(fill) = &f.fill {
18752 self.write(", ");
18753 self.generate_expression(fill)?;
18754 }
18755 self.write(")");
18756 Ok(())
18757 }
18758
18759 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
18760 self.write_keyword("SPLIT");
18761 self.write("(");
18762 self.generate_expression(&f.this)?;
18763 self.write(", ");
18764 self.generate_expression(&f.delimiter)?;
18765 self.write(")");
18766 Ok(())
18767 }
18768
18769 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
18770 use crate::dialects::DialectType;
18771 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
18773 self.generate_expression(&f.this)?;
18774 self.write(" ~ ");
18775 self.generate_expression(&f.pattern)?;
18776 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
18777 self.generate_expression(&f.this)?;
18779 self.write_keyword(" REGEXP_LIKE ");
18780 self.generate_expression(&f.pattern)?;
18781 } else if matches!(
18782 self.config.dialect,
18783 Some(DialectType::SingleStore)
18784 | Some(DialectType::Spark)
18785 | Some(DialectType::Hive)
18786 | Some(DialectType::Databricks)
18787 ) && f.flags.is_none()
18788 {
18789 self.generate_expression(&f.this)?;
18791 self.write_keyword(" RLIKE ");
18792 self.generate_expression(&f.pattern)?;
18793 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
18794 self.write_keyword("REGEXP");
18796 self.write("(");
18797 self.generate_expression(&f.this)?;
18798 self.write(", ");
18799 self.generate_expression(&f.pattern)?;
18800 if let Some(flags) = &f.flags {
18801 self.write(", ");
18802 self.generate_expression(flags)?;
18803 }
18804 self.write(")");
18805 } else {
18806 self.write_keyword("REGEXP_LIKE");
18807 self.write("(");
18808 self.generate_expression(&f.this)?;
18809 self.write(", ");
18810 self.generate_expression(&f.pattern)?;
18811 if let Some(flags) = &f.flags {
18812 self.write(", ");
18813 self.generate_expression(flags)?;
18814 }
18815 self.write(")");
18816 }
18817 Ok(())
18818 }
18819
18820 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
18821 self.write_keyword("REGEXP_REPLACE");
18822 self.write("(");
18823 self.generate_expression(&f.this)?;
18824 self.write(", ");
18825 self.generate_expression(&f.pattern)?;
18826 self.write(", ");
18827 self.generate_expression(&f.replacement)?;
18828 if let Some(flags) = &f.flags {
18829 self.write(", ");
18830 self.generate_expression(flags)?;
18831 }
18832 self.write(")");
18833 Ok(())
18834 }
18835
18836 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
18837 self.write_keyword("REGEXP_EXTRACT");
18838 self.write("(");
18839 self.generate_expression(&f.this)?;
18840 self.write(", ");
18841 self.generate_expression(&f.pattern)?;
18842 if let Some(group) = &f.group {
18843 self.write(", ");
18844 self.generate_expression(group)?;
18845 }
18846 self.write(")");
18847 Ok(())
18848 }
18849
18850 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
18853 self.write_keyword("ROUND");
18854 self.write("(");
18855 self.generate_expression(&f.this)?;
18856 if let Some(decimals) = &f.decimals {
18857 self.write(", ");
18858 self.generate_expression(decimals)?;
18859 }
18860 self.write(")");
18861 Ok(())
18862 }
18863
18864 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
18865 self.write_keyword("FLOOR");
18866 self.write("(");
18867 self.generate_expression(&f.this)?;
18868 if let Some(to) = &f.to {
18870 self.write(" ");
18871 self.write_keyword("TO");
18872 self.write(" ");
18873 self.generate_expression(to)?;
18874 } else if let Some(scale) = &f.scale {
18875 self.write(", ");
18876 self.generate_expression(scale)?;
18877 }
18878 self.write(")");
18879 Ok(())
18880 }
18881
18882 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
18883 self.write_keyword("CEIL");
18884 self.write("(");
18885 self.generate_expression(&f.this)?;
18886 if let Some(to) = &f.to {
18888 self.write(" ");
18889 self.write_keyword("TO");
18890 self.write(" ");
18891 self.generate_expression(to)?;
18892 } else if let Some(decimals) = &f.decimals {
18893 self.write(", ");
18894 self.generate_expression(decimals)?;
18895 }
18896 self.write(")");
18897 Ok(())
18898 }
18899
18900 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
18901 use crate::expressions::Literal;
18902
18903 if let Some(base) = &f.base {
18904 if self.is_log_base_none() {
18907 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
18908 {
18909 self.write_func_name("LOG2");
18910 self.write("(");
18911 self.generate_expression(&f.this)?;
18912 self.write(")");
18913 return Ok(());
18914 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
18915 {
18916 self.write_func_name("LOG10");
18917 self.write("(");
18918 self.generate_expression(&f.this)?;
18919 self.write(")");
18920 return Ok(());
18921 }
18922 }
18924
18925 self.write_func_name("LOG");
18926 self.write("(");
18927 if self.is_log_value_first() {
18928 self.generate_expression(&f.this)?;
18930 self.write(", ");
18931 self.generate_expression(base)?;
18932 } else {
18933 self.generate_expression(base)?;
18935 self.write(", ");
18936 self.generate_expression(&f.this)?;
18937 }
18938 self.write(")");
18939 } else {
18940 self.write_func_name("LOG");
18942 self.write("(");
18943 self.generate_expression(&f.this)?;
18944 self.write(")");
18945 }
18946 Ok(())
18947 }
18948
18949 fn is_log_value_first(&self) -> bool {
18952 use crate::dialects::DialectType;
18953 matches!(
18954 self.config.dialect,
18955 Some(DialectType::BigQuery)
18956 | Some(DialectType::TSQL)
18957 | Some(DialectType::Tableau)
18958 | Some(DialectType::Fabric)
18959 )
18960 }
18961
18962 fn is_log_base_none(&self) -> bool {
18965 use crate::dialects::DialectType;
18966 matches!(
18967 self.config.dialect,
18968 Some(DialectType::Presto)
18969 | Some(DialectType::Trino)
18970 | Some(DialectType::ClickHouse)
18971 | Some(DialectType::Athena)
18972 )
18973 }
18974
18975 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
18978 self.write_keyword("CURRENT_TIME");
18979 if let Some(precision) = f.precision {
18980 self.write(&format!("({})", precision));
18981 } else if matches!(
18982 self.config.dialect,
18983 Some(crate::dialects::DialectType::MySQL)
18984 | Some(crate::dialects::DialectType::SingleStore)
18985 | Some(crate::dialects::DialectType::TiDB)
18986 ) {
18987 self.write("()");
18988 }
18989 Ok(())
18990 }
18991
18992 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
18993 use crate::dialects::DialectType;
18994
18995 if f.sysdate {
18997 match self.config.dialect {
18998 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
18999 self.write_keyword("SYSDATE");
19000 return Ok(());
19001 }
19002 Some(DialectType::Snowflake) => {
19003 self.write_keyword("SYSDATE");
19005 self.write("()");
19006 return Ok(());
19007 }
19008 _ => {
19009 }
19011 }
19012 }
19013
19014 self.write_keyword("CURRENT_TIMESTAMP");
19015 if let Some(precision) = f.precision {
19017 self.write(&format!("({})", precision));
19018 } else if matches!(
19019 self.config.dialect,
19020 Some(crate::dialects::DialectType::MySQL)
19021 | Some(crate::dialects::DialectType::SingleStore)
19022 | Some(crate::dialects::DialectType::TiDB)
19023 | Some(crate::dialects::DialectType::Spark)
19024 | Some(crate::dialects::DialectType::Hive)
19025 | Some(crate::dialects::DialectType::Databricks)
19026 | Some(crate::dialects::DialectType::ClickHouse)
19027 | Some(crate::dialects::DialectType::BigQuery)
19028 | Some(crate::dialects::DialectType::Snowflake)
19029 | Some(crate::dialects::DialectType::Exasol)
19030 ) {
19031 self.write("()");
19032 }
19033 Ok(())
19034 }
19035
19036 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
19037 if self.config.dialect == Some(DialectType::Exasol) {
19039 self.write_keyword("CONVERT_TZ");
19040 self.write("(");
19041 self.generate_expression(&f.this)?;
19042 self.write(", 'UTC', ");
19043 self.generate_expression(&f.zone)?;
19044 self.write(")");
19045 return Ok(());
19046 }
19047
19048 self.generate_expression(&f.this)?;
19049 self.write_space();
19050 self.write_keyword("AT TIME ZONE");
19051 self.write_space();
19052 self.generate_expression(&f.zone)?;
19053 Ok(())
19054 }
19055
19056 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
19057 use crate::dialects::DialectType;
19058
19059 let is_presto_like = matches!(
19062 self.config.dialect,
19063 Some(DialectType::Presto) | Some(DialectType::Trino)
19064 );
19065
19066 if is_presto_like {
19067 self.write_keyword(name);
19068 self.write("(");
19069 self.write("'");
19071 self.write_simple_interval_unit(&f.unit, false);
19072 self.write("'");
19073 self.write(", ");
19074 let needs_cast = !self.returns_integer_type(&f.interval);
19076 if needs_cast {
19077 self.write_keyword("CAST");
19078 self.write("(");
19079 }
19080 self.generate_expression(&f.interval)?;
19081 if needs_cast {
19082 self.write_space();
19083 self.write_keyword("AS");
19084 self.write_space();
19085 self.write_keyword("BIGINT");
19086 self.write(")");
19087 }
19088 self.write(", ");
19089 self.generate_expression(&f.this)?;
19090 self.write(")");
19091 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19092 self.generate_expression(&f.this)?;
19093 self.write_space();
19094 if name.eq_ignore_ascii_case("DATE_SUB") {
19095 self.write("-");
19096 } else {
19097 self.write("+");
19098 }
19099 self.write_space();
19100 self.write_keyword("INTERVAL");
19101 self.write_space();
19102 self.write("'");
19103 let mut interval_gen = Generator::with_arc_config(self.config.clone());
19104 let interval_sql = interval_gen.generate(&f.interval)?;
19105 self.write(&interval_sql);
19106 self.write(" ");
19107 self.write_simple_interval_unit(&f.unit, false);
19108 self.write("'");
19109 } else {
19110 self.write_keyword(name);
19111 self.write("(");
19112 self.generate_expression(&f.this)?;
19113 self.write(", ");
19114 self.write_keyword("INTERVAL");
19115 self.write_space();
19116 self.generate_expression(&f.interval)?;
19117 self.write_space();
19118 self.write_simple_interval_unit(&f.unit, false); self.write(")");
19120 }
19121 Ok(())
19122 }
19123
19124 fn returns_integer_type(&self, expr: &Expression) -> bool {
19127 use crate::expressions::{DataType, Literal};
19128 match expr {
19129 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
19131 let Literal::Number(n) = lit.as_ref() else {
19132 unreachable!()
19133 };
19134 !n.contains('.')
19135 }
19136
19137 Expression::Floor(f) => self.returns_integer_type(&f.this),
19139
19140 Expression::Round(f) => {
19142 f.decimals.is_none() && self.returns_integer_type(&f.this)
19144 }
19145
19146 Expression::Sign(f) => self.returns_integer_type(&f.this),
19148
19149 Expression::Abs(f) => self.returns_integer_type(&f.this),
19151
19152 Expression::Mul(op) => {
19154 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19155 }
19156 Expression::Add(op) => {
19157 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19158 }
19159 Expression::Sub(op) => {
19160 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19161 }
19162 Expression::Mod(op) => self.returns_integer_type(&op.left),
19163
19164 Expression::Cast(c) => matches!(
19166 &c.to,
19167 DataType::BigInt { .. }
19168 | DataType::Int { .. }
19169 | DataType::SmallInt { .. }
19170 | DataType::TinyInt { .. }
19171 ),
19172
19173 Expression::Neg(op) => self.returns_integer_type(&op.this),
19175
19176 Expression::Paren(p) => self.returns_integer_type(&p.this),
19178
19179 _ => false,
19182 }
19183 }
19184
19185 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
19186 self.write_keyword("DATEDIFF");
19187 self.write("(");
19188 if let Some(unit) = &f.unit {
19189 self.write_simple_interval_unit(unit, false); self.write(", ");
19191 }
19192 self.generate_expression(&f.this)?;
19193 self.write(", ");
19194 self.generate_expression(&f.expression)?;
19195 self.write(")");
19196 Ok(())
19197 }
19198
19199 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
19200 self.write_keyword("DATE_TRUNC");
19201 self.write("('");
19202 self.write_datetime_field(&f.unit);
19203 self.write("', ");
19204 self.generate_expression(&f.this)?;
19205 self.write(")");
19206 Ok(())
19207 }
19208
19209 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
19210 use crate::dialects::DialectType;
19211 use crate::expressions::DateTimeField;
19212
19213 self.write_keyword("LAST_DAY");
19214 self.write("(");
19215 self.generate_expression(&f.this)?;
19216 if let Some(unit) = &f.unit {
19217 self.write(", ");
19218 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
19221 if let DateTimeField::WeekWithModifier(_) = unit {
19222 self.write_keyword("WEEK");
19223 } else {
19224 self.write_datetime_field(unit);
19225 }
19226 } else {
19227 self.write_datetime_field(unit);
19228 }
19229 }
19230 self.write(")");
19231 Ok(())
19232 }
19233
19234 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
19235 if matches!(
19237 self.config.dialect,
19238 Some(DialectType::TSQL) | Some(DialectType::Fabric)
19239 ) {
19240 self.write_keyword("DATEPART");
19241 self.write("(");
19242 self.write_datetime_field(&f.field);
19243 self.write(", ");
19244 self.generate_expression(&f.this)?;
19245 self.write(")");
19246 return Ok(());
19247 }
19248 self.write_keyword("EXTRACT");
19249 self.write("(");
19250 if matches!(
19252 self.config.dialect,
19253 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
19254 ) {
19255 self.write_datetime_field_lower(&f.field);
19256 } else {
19257 self.write_datetime_field(&f.field);
19258 }
19259 self.write_space();
19260 self.write_keyword("FROM");
19261 self.write_space();
19262 self.generate_expression(&f.this)?;
19263 self.write(")");
19264 Ok(())
19265 }
19266
19267 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
19268 self.write_keyword("TO_DATE");
19269 self.write("(");
19270 self.generate_expression(&f.this)?;
19271 if let Some(format) = &f.format {
19272 self.write(", ");
19273 self.generate_expression(format)?;
19274 }
19275 self.write(")");
19276 Ok(())
19277 }
19278
19279 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
19280 self.write_keyword("TO_TIMESTAMP");
19281 self.write("(");
19282 self.generate_expression(&f.this)?;
19283 if let Some(format) = &f.format {
19284 self.write(", ");
19285 self.generate_expression(format)?;
19286 }
19287 self.write(")");
19288 Ok(())
19289 }
19290
19291 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
19294 use crate::dialects::DialectType;
19295
19296 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
19298 self.write_keyword("CASE WHEN");
19299 self.write_space();
19300 self.generate_expression(&f.condition)?;
19301 self.write_space();
19302 self.write_keyword("THEN");
19303 self.write_space();
19304 self.generate_expression(&f.true_value)?;
19305 if let Some(false_val) = &f.false_value {
19306 self.write_space();
19307 self.write_keyword("ELSE");
19308 self.write_space();
19309 self.generate_expression(false_val)?;
19310 }
19311 self.write_space();
19312 self.write_keyword("END");
19313 return Ok(());
19314 }
19315
19316 if self.config.dialect == Some(DialectType::Exasol) {
19318 self.write_keyword("IF");
19319 self.write_space();
19320 self.generate_expression(&f.condition)?;
19321 self.write_space();
19322 self.write_keyword("THEN");
19323 self.write_space();
19324 self.generate_expression(&f.true_value)?;
19325 if let Some(false_val) = &f.false_value {
19326 self.write_space();
19327 self.write_keyword("ELSE");
19328 self.write_space();
19329 self.generate_expression(false_val)?;
19330 }
19331 self.write_space();
19332 self.write_keyword("ENDIF");
19333 return Ok(());
19334 }
19335
19336 let func_name = match self.config.dialect {
19338 Some(DialectType::Snowflake) => "IFF",
19339 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
19340 Some(DialectType::Drill) => "`IF`",
19341 _ => "IF",
19342 };
19343 self.write(func_name);
19344 self.write("(");
19345 self.generate_expression(&f.condition)?;
19346 self.write(", ");
19347 self.generate_expression(&f.true_value)?;
19348 if let Some(false_val) = &f.false_value {
19349 self.write(", ");
19350 self.generate_expression(false_val)?;
19351 }
19352 self.write(")");
19353 Ok(())
19354 }
19355
19356 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
19357 self.write_keyword("NVL2");
19358 self.write("(");
19359 self.generate_expression(&f.this)?;
19360 self.write(", ");
19361 self.generate_expression(&f.true_value)?;
19362 self.write(", ");
19363 self.generate_expression(&f.false_value)?;
19364 self.write(")");
19365 Ok(())
19366 }
19367
19368 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
19371 let count_name = match self.config.normalize_functions {
19373 NormalizeFunctions::Upper => "COUNT".to_string(),
19374 NormalizeFunctions::Lower => "count".to_string(),
19375 NormalizeFunctions::None => f
19376 .original_name
19377 .clone()
19378 .unwrap_or_else(|| "COUNT".to_string()),
19379 };
19380 self.write(&count_name);
19381 self.write("(");
19382 if f.distinct {
19383 self.write_keyword("DISTINCT");
19384 self.write_space();
19385 }
19386 if f.star {
19387 self.write("*");
19388 } else if let Some(ref expr) = f.this {
19389 if let Expression::Tuple(tuple) = expr {
19391 let needs_transform =
19395 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
19396
19397 if needs_transform {
19398 self.write_keyword("CASE");
19400 for e in &tuple.expressions {
19401 self.write_space();
19402 self.write_keyword("WHEN");
19403 self.write_space();
19404 self.generate_expression(e)?;
19405 self.write_space();
19406 self.write_keyword("IS NULL THEN NULL");
19407 }
19408 self.write_space();
19409 self.write_keyword("ELSE");
19410 self.write(" (");
19411 for (i, e) in tuple.expressions.iter().enumerate() {
19412 if i > 0 {
19413 self.write(", ");
19414 }
19415 self.generate_expression(e)?;
19416 }
19417 self.write(")");
19418 self.write_space();
19419 self.write_keyword("END");
19420 } else {
19421 for (i, e) in tuple.expressions.iter().enumerate() {
19422 if i > 0 {
19423 self.write(", ");
19424 }
19425 self.generate_expression(e)?;
19426 }
19427 }
19428 } else {
19429 self.generate_expression(expr)?;
19430 }
19431 }
19432 if let Some(ignore) = f.ignore_nulls {
19434 self.write_space();
19435 if ignore {
19436 self.write_keyword("IGNORE NULLS");
19437 } else {
19438 self.write_keyword("RESPECT NULLS");
19439 }
19440 }
19441 self.write(")");
19442 if let Some(ref filter) = f.filter {
19443 self.write_space();
19444 self.write_keyword("FILTER");
19445 self.write("(");
19446 self.write_keyword("WHERE");
19447 self.write_space();
19448 self.generate_expression(filter)?;
19449 self.write(")");
19450 }
19451 Ok(())
19452 }
19453
19454 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19455 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19457 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19458 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19459 NormalizeFunctions::None => {
19460 if let Some(ref original) = f.name {
19463 Cow::Owned(original.clone())
19464 } else {
19465 Cow::Owned(name.to_ascii_lowercase())
19466 }
19467 }
19468 };
19469 self.write(func_name.as_ref());
19470 self.write("(");
19471 if f.distinct {
19472 self.write_keyword("DISTINCT");
19473 self.write_space();
19474 }
19475 if !matches!(f.this, Expression::Null(_)) {
19477 self.generate_expression(&f.this)?;
19478 }
19479 if self.config.ignore_nulls_in_func
19482 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19483 {
19484 match f.ignore_nulls {
19485 Some(true) => {
19486 self.write_space();
19487 self.write_keyword("IGNORE NULLS");
19488 }
19489 Some(false) => {
19490 self.write_space();
19491 self.write_keyword("RESPECT NULLS");
19492 }
19493 None => {}
19494 }
19495 }
19496 if let Some((ref expr, is_max)) = f.having_max {
19499 self.write_space();
19500 self.write_keyword("HAVING");
19501 self.write_space();
19502 if is_max {
19503 self.write_keyword("MAX");
19504 } else {
19505 self.write_keyword("MIN");
19506 }
19507 self.write_space();
19508 self.generate_expression(expr)?;
19509 }
19510 if !f.order_by.is_empty() {
19512 self.write_space();
19513 self.write_keyword("ORDER BY");
19514 self.write_space();
19515 for (i, ord) in f.order_by.iter().enumerate() {
19516 if i > 0 {
19517 self.write(", ");
19518 }
19519 self.generate_ordered(ord)?;
19520 }
19521 }
19522 if let Some(ref limit) = f.limit {
19524 self.write_space();
19525 self.write_keyword("LIMIT");
19526 self.write_space();
19527 if let Expression::Tuple(t) = limit.as_ref() {
19529 if t.expressions.len() == 2 {
19530 self.generate_expression(&t.expressions[0])?;
19531 self.write(", ");
19532 self.generate_expression(&t.expressions[1])?;
19533 } else {
19534 self.generate_expression(limit)?;
19535 }
19536 } else {
19537 self.generate_expression(limit)?;
19538 }
19539 }
19540 self.write(")");
19541 if !self.config.ignore_nulls_in_func
19544 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19545 {
19546 match f.ignore_nulls {
19547 Some(true) => {
19548 self.write_space();
19549 self.write_keyword("IGNORE NULLS");
19550 }
19551 Some(false) => {
19552 self.write_space();
19553 self.write_keyword("RESPECT NULLS");
19554 }
19555 None => {}
19556 }
19557 }
19558 if let Some(ref filter) = f.filter {
19559 self.write_space();
19560 self.write_keyword("FILTER");
19561 self.write("(");
19562 self.write_keyword("WHERE");
19563 self.write_space();
19564 self.generate_expression(filter)?;
19565 self.write(")");
19566 }
19567 Ok(())
19568 }
19569
19570 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19573 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19575 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19577 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19578 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19579 NormalizeFunctions::None => {
19580 if let Some(ref original) = f.name {
19581 Cow::Owned(original.clone())
19582 } else {
19583 Cow::Owned(name.to_ascii_lowercase())
19584 }
19585 }
19586 };
19587 self.write(func_name.as_ref());
19588 self.write("(");
19589 if f.distinct {
19590 self.write_keyword("DISTINCT");
19591 self.write_space();
19592 }
19593 if !matches!(f.this, Expression::Null(_)) {
19594 self.generate_expression(&f.this)?;
19595 }
19596 self.write(", ");
19597 self.write_keyword("TRUE");
19598 self.write(")");
19599 return Ok(());
19600 }
19601 self.generate_agg_func(name, f)
19602 }
19603
19604 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
19605 self.write_keyword("GROUP_CONCAT");
19606 self.write("(");
19607 if f.distinct {
19608 self.write_keyword("DISTINCT");
19609 self.write_space();
19610 }
19611 self.generate_expression(&f.this)?;
19612 if let Some(ref order_by) = f.order_by {
19613 self.write_space();
19614 self.write_keyword("ORDER BY");
19615 self.write_space();
19616 for (i, ord) in order_by.iter().enumerate() {
19617 if i > 0 {
19618 self.write(", ");
19619 }
19620 self.generate_ordered(ord)?;
19621 }
19622 }
19623 if let Some(ref sep) = f.separator {
19624 if matches!(
19627 self.config.dialect,
19628 Some(crate::dialects::DialectType::SQLite)
19629 ) {
19630 self.write(", ");
19631 self.generate_expression(sep)?;
19632 } else {
19633 self.write_space();
19634 self.write_keyword("SEPARATOR");
19635 self.write_space();
19636 self.generate_expression(sep)?;
19637 }
19638 }
19639 if let Some(ref limit) = f.limit {
19640 self.write_space();
19641 self.write_keyword("LIMIT");
19642 self.write_space();
19643 self.generate_expression(limit)?;
19644 }
19645 self.write(")");
19646 if let Some(ref filter) = f.filter {
19647 self.write_space();
19648 self.write_keyword("FILTER");
19649 self.write("(");
19650 self.write_keyword("WHERE");
19651 self.write_space();
19652 self.generate_expression(filter)?;
19653 self.write(")");
19654 }
19655 Ok(())
19656 }
19657
19658 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
19659 let is_tsql = matches!(
19660 self.config.dialect,
19661 Some(crate::dialects::DialectType::TSQL)
19662 );
19663 self.write_keyword("STRING_AGG");
19664 self.write("(");
19665 if f.distinct {
19666 self.write_keyword("DISTINCT");
19667 self.write_space();
19668 }
19669 self.generate_expression(&f.this)?;
19670 if let Some(ref separator) = f.separator {
19671 self.write(", ");
19672 self.generate_expression(separator)?;
19673 }
19674 if !is_tsql {
19676 if let Some(ref order_by) = f.order_by {
19677 self.write_space();
19678 self.write_keyword("ORDER BY");
19679 self.write_space();
19680 for (i, ord) in order_by.iter().enumerate() {
19681 if i > 0 {
19682 self.write(", ");
19683 }
19684 self.generate_ordered(ord)?;
19685 }
19686 }
19687 }
19688 if let Some(ref limit) = f.limit {
19689 self.write_space();
19690 self.write_keyword("LIMIT");
19691 self.write_space();
19692 self.generate_expression(limit)?;
19693 }
19694 self.write(")");
19695 if is_tsql {
19697 if let Some(ref order_by) = f.order_by {
19698 self.write_space();
19699 self.write_keyword("WITHIN GROUP");
19700 self.write(" (");
19701 self.write_keyword("ORDER BY");
19702 self.write_space();
19703 for (i, ord) in order_by.iter().enumerate() {
19704 if i > 0 {
19705 self.write(", ");
19706 }
19707 self.generate_ordered(ord)?;
19708 }
19709 self.write(")");
19710 }
19711 }
19712 if let Some(ref filter) = f.filter {
19713 self.write_space();
19714 self.write_keyword("FILTER");
19715 self.write("(");
19716 self.write_keyword("WHERE");
19717 self.write_space();
19718 self.generate_expression(filter)?;
19719 self.write(")");
19720 }
19721 Ok(())
19722 }
19723
19724 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
19725 use crate::dialects::DialectType;
19726 self.write_keyword("LISTAGG");
19727 self.write("(");
19728 if f.distinct {
19729 self.write_keyword("DISTINCT");
19730 self.write_space();
19731 }
19732 self.generate_expression(&f.this)?;
19733 if let Some(ref sep) = f.separator {
19734 self.write(", ");
19735 self.generate_expression(sep)?;
19736 } else if matches!(
19737 self.config.dialect,
19738 Some(DialectType::Trino) | Some(DialectType::Presto)
19739 ) {
19740 self.write(", ','");
19742 }
19743 if let Some(ref overflow) = f.on_overflow {
19744 self.write_space();
19745 self.write_keyword("ON OVERFLOW");
19746 self.write_space();
19747 match overflow {
19748 ListAggOverflow::Error => self.write_keyword("ERROR"),
19749 ListAggOverflow::Truncate { filler, with_count } => {
19750 self.write_keyword("TRUNCATE");
19751 if let Some(ref fill) = filler {
19752 self.write_space();
19753 self.generate_expression(fill)?;
19754 }
19755 if *with_count {
19756 self.write_space();
19757 self.write_keyword("WITH COUNT");
19758 } else {
19759 self.write_space();
19760 self.write_keyword("WITHOUT COUNT");
19761 }
19762 }
19763 }
19764 }
19765 self.write(")");
19766 if let Some(ref order_by) = f.order_by {
19767 self.write_space();
19768 self.write_keyword("WITHIN GROUP");
19769 self.write(" (");
19770 self.write_keyword("ORDER BY");
19771 self.write_space();
19772 for (i, ord) in order_by.iter().enumerate() {
19773 if i > 0 {
19774 self.write(", ");
19775 }
19776 self.generate_ordered(ord)?;
19777 }
19778 self.write(")");
19779 }
19780 if let Some(ref filter) = f.filter {
19781 self.write_space();
19782 self.write_keyword("FILTER");
19783 self.write("(");
19784 self.write_keyword("WHERE");
19785 self.write_space();
19786 self.generate_expression(filter)?;
19787 self.write(")");
19788 }
19789 Ok(())
19790 }
19791
19792 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
19793 self.write_keyword("SUM_IF");
19794 self.write("(");
19795 self.generate_expression(&f.this)?;
19796 self.write(", ");
19797 self.generate_expression(&f.condition)?;
19798 self.write(")");
19799 if let Some(ref filter) = f.filter {
19800 self.write_space();
19801 self.write_keyword("FILTER");
19802 self.write("(");
19803 self.write_keyword("WHERE");
19804 self.write_space();
19805 self.generate_expression(filter)?;
19806 self.write(")");
19807 }
19808 Ok(())
19809 }
19810
19811 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
19812 self.write_keyword("APPROX_PERCENTILE");
19813 self.write("(");
19814 self.generate_expression(&f.this)?;
19815 self.write(", ");
19816 self.generate_expression(&f.percentile)?;
19817 if let Some(ref acc) = f.accuracy {
19818 self.write(", ");
19819 self.generate_expression(acc)?;
19820 }
19821 self.write(")");
19822 if let Some(ref filter) = f.filter {
19823 self.write_space();
19824 self.write_keyword("FILTER");
19825 self.write("(");
19826 self.write_keyword("WHERE");
19827 self.write_space();
19828 self.generate_expression(filter)?;
19829 self.write(")");
19830 }
19831 Ok(())
19832 }
19833
19834 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
19835 self.write_keyword(name);
19836 self.write("(");
19837 self.generate_expression(&f.percentile)?;
19838 self.write(")");
19839 if let Some(ref order_by) = f.order_by {
19840 self.write_space();
19841 self.write_keyword("WITHIN GROUP");
19842 self.write(" (");
19843 self.write_keyword("ORDER BY");
19844 self.write_space();
19845 self.generate_expression(&f.this)?;
19846 for ord in order_by.iter() {
19847 if ord.desc {
19848 self.write_space();
19849 self.write_keyword("DESC");
19850 }
19851 }
19852 self.write(")");
19853 }
19854 if let Some(ref filter) = f.filter {
19855 self.write_space();
19856 self.write_keyword("FILTER");
19857 self.write("(");
19858 self.write_keyword("WHERE");
19859 self.write_space();
19860 self.generate_expression(filter)?;
19861 self.write(")");
19862 }
19863 Ok(())
19864 }
19865
19866 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
19869 self.write_keyword("NTILE");
19870 self.write("(");
19871 if let Some(num_buckets) = &f.num_buckets {
19872 self.generate_expression(num_buckets)?;
19873 }
19874 if let Some(order_by) = &f.order_by {
19875 self.write_keyword(" ORDER BY ");
19876 for (i, ob) in order_by.iter().enumerate() {
19877 if i > 0 {
19878 self.write(", ");
19879 }
19880 self.generate_ordered(ob)?;
19881 }
19882 }
19883 self.write(")");
19884 Ok(())
19885 }
19886
19887 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
19888 self.write_keyword(name);
19889 self.write("(");
19890 self.generate_expression(&f.this)?;
19891 if let Some(ref offset) = f.offset {
19892 self.write(", ");
19893 self.generate_expression(offset)?;
19894 if let Some(ref default) = f.default {
19895 self.write(", ");
19896 self.generate_expression(default)?;
19897 }
19898 }
19899 if self.config.ignore_nulls_in_func {
19901 match f.ignore_nulls {
19902 Some(true) => {
19903 self.write_space();
19904 self.write_keyword("IGNORE NULLS");
19905 }
19906 Some(false) => {
19907 self.write_space();
19908 self.write_keyword("RESPECT NULLS");
19909 }
19910 None => {}
19911 }
19912 }
19913 self.write(")");
19914 if !self.config.ignore_nulls_in_func {
19916 match f.ignore_nulls {
19917 Some(true) => {
19918 self.write_space();
19919 self.write_keyword("IGNORE NULLS");
19920 }
19921 Some(false) => {
19922 self.write_space();
19923 self.write_keyword("RESPECT NULLS");
19924 }
19925 None => {}
19926 }
19927 }
19928 Ok(())
19929 }
19930
19931 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
19932 self.write_keyword(name);
19933 self.write("(");
19934 self.generate_expression(&f.this)?;
19935 if !f.order_by.is_empty() {
19937 self.write_space();
19938 self.write_keyword("ORDER BY");
19939 self.write_space();
19940 for (i, ordered) in f.order_by.iter().enumerate() {
19941 if i > 0 {
19942 self.write(", ");
19943 }
19944 self.generate_ordered(ordered)?;
19945 }
19946 }
19947 if self.config.ignore_nulls_in_func {
19949 match f.ignore_nulls {
19950 Some(true) => {
19951 self.write_space();
19952 self.write_keyword("IGNORE NULLS");
19953 }
19954 Some(false) => {
19955 self.write_space();
19956 self.write_keyword("RESPECT NULLS");
19957 }
19958 None => {}
19959 }
19960 }
19961 self.write(")");
19962 if !self.config.ignore_nulls_in_func {
19964 match f.ignore_nulls {
19965 Some(true) => {
19966 self.write_space();
19967 self.write_keyword("IGNORE NULLS");
19968 }
19969 Some(false) => {
19970 self.write_space();
19971 self.write_keyword("RESPECT NULLS");
19972 }
19973 None => {}
19974 }
19975 }
19976 Ok(())
19977 }
19978
19979 fn generate_value_func_with_ignore_nulls_bool(
19982 &mut self,
19983 name: &str,
19984 f: &ValueFunc,
19985 ) -> Result<()> {
19986 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19987 self.write_keyword(name);
19988 self.write("(");
19989 self.generate_expression(&f.this)?;
19990 self.write(", ");
19991 self.write_keyword("TRUE");
19992 self.write(")");
19993 return Ok(());
19994 }
19995 self.generate_value_func(name, f)
19996 }
19997
19998 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
19999 self.write_keyword("NTH_VALUE");
20000 self.write("(");
20001 self.generate_expression(&f.this)?;
20002 self.write(", ");
20003 self.generate_expression(&f.offset)?;
20004 if self.config.ignore_nulls_in_func {
20006 match f.ignore_nulls {
20007 Some(true) => {
20008 self.write_space();
20009 self.write_keyword("IGNORE NULLS");
20010 }
20011 Some(false) => {
20012 self.write_space();
20013 self.write_keyword("RESPECT NULLS");
20014 }
20015 None => {}
20016 }
20017 }
20018 self.write(")");
20019 if matches!(
20021 self.config.dialect,
20022 Some(crate::dialects::DialectType::Snowflake)
20023 ) {
20024 match f.from_first {
20025 Some(true) => {
20026 self.write_space();
20027 self.write_keyword("FROM FIRST");
20028 }
20029 Some(false) => {
20030 self.write_space();
20031 self.write_keyword("FROM LAST");
20032 }
20033 None => {}
20034 }
20035 }
20036 if !self.config.ignore_nulls_in_func {
20038 match f.ignore_nulls {
20039 Some(true) => {
20040 self.write_space();
20041 self.write_keyword("IGNORE NULLS");
20042 }
20043 Some(false) => {
20044 self.write_space();
20045 self.write_keyword("RESPECT NULLS");
20046 }
20047 None => {}
20048 }
20049 }
20050 Ok(())
20051 }
20052
20053 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
20056 if matches!(
20059 self.config.dialect,
20060 Some(crate::dialects::DialectType::ClickHouse)
20061 ) {
20062 self.write_keyword("POSITION");
20063 self.write("(");
20064 self.generate_expression(&f.string)?;
20065 self.write(", ");
20066 self.generate_expression(&f.substring)?;
20067 if let Some(ref start) = f.start {
20068 self.write(", ");
20069 self.generate_expression(start)?;
20070 }
20071 self.write(")");
20072 return Ok(());
20073 }
20074
20075 self.write_keyword("POSITION");
20076 self.write("(");
20077 self.generate_expression(&f.substring)?;
20078 self.write_space();
20079 self.write_keyword("IN");
20080 self.write_space();
20081 self.generate_expression(&f.string)?;
20082 if let Some(ref start) = f.start {
20083 self.write(", ");
20084 self.generate_expression(start)?;
20085 }
20086 self.write(")");
20087 Ok(())
20088 }
20089
20090 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
20093 if f.lower.is_some() || f.upper.is_some() {
20095 self.write_keyword("RANDOM");
20096 self.write("(");
20097 if let Some(ref lower) = f.lower {
20098 self.generate_expression(lower)?;
20099 }
20100 if let Some(ref upper) = f.upper {
20101 self.write(", ");
20102 self.generate_expression(upper)?;
20103 }
20104 self.write(")");
20105 return Ok(());
20106 }
20107 let func_name = match self.config.dialect {
20109 Some(crate::dialects::DialectType::Snowflake)
20110 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
20111 _ => "RAND",
20112 };
20113 self.write_keyword(func_name);
20114 self.write("(");
20115 if !matches!(
20117 self.config.dialect,
20118 Some(crate::dialects::DialectType::DuckDB)
20119 ) {
20120 if let Some(ref seed) = f.seed {
20121 self.generate_expression(seed)?;
20122 }
20123 }
20124 self.write(")");
20125 Ok(())
20126 }
20127
20128 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
20129 self.write_keyword("TRUNCATE");
20130 self.write("(");
20131 self.generate_expression(&f.this)?;
20132 if let Some(ref decimals) = f.decimals {
20133 self.write(", ");
20134 self.generate_expression(decimals)?;
20135 }
20136 self.write(")");
20137 Ok(())
20138 }
20139
20140 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
20143 self.write_keyword("DECODE");
20144 self.write("(");
20145 self.generate_expression(&f.this)?;
20146 for (search, result) in &f.search_results {
20147 self.write(", ");
20148 self.generate_expression(search)?;
20149 self.write(", ");
20150 self.generate_expression(result)?;
20151 }
20152 if let Some(ref default) = f.default {
20153 self.write(", ");
20154 self.generate_expression(default)?;
20155 }
20156 self.write(")");
20157 Ok(())
20158 }
20159
20160 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
20163 self.write_keyword(name);
20164 self.write("(");
20165 self.generate_expression(&f.this)?;
20166 self.write(", ");
20167 self.generate_expression(&f.format)?;
20168 self.write(")");
20169 Ok(())
20170 }
20171
20172 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
20173 self.write_keyword("FROM_UNIXTIME");
20174 self.write("(");
20175 self.generate_expression(&f.this)?;
20176 if let Some(ref format) = f.format {
20177 self.write(", ");
20178 self.generate_expression(format)?;
20179 }
20180 self.write(")");
20181 Ok(())
20182 }
20183
20184 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
20185 self.write_keyword("UNIX_TIMESTAMP");
20186 self.write("(");
20187 if let Some(ref expr) = f.this {
20188 self.generate_expression(expr)?;
20189 if let Some(ref format) = f.format {
20190 self.write(", ");
20191 self.generate_expression(format)?;
20192 }
20193 } else if matches!(
20194 self.config.dialect,
20195 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
20196 ) {
20197 self.write_keyword("CURRENT_TIMESTAMP");
20199 self.write("()");
20200 }
20201 self.write(")");
20202 Ok(())
20203 }
20204
20205 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
20206 self.write_keyword("MAKE_DATE");
20207 self.write("(");
20208 self.generate_expression(&f.year)?;
20209 self.write(", ");
20210 self.generate_expression(&f.month)?;
20211 self.write(", ");
20212 self.generate_expression(&f.day)?;
20213 self.write(")");
20214 Ok(())
20215 }
20216
20217 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
20218 self.write_keyword("MAKE_TIMESTAMP");
20219 self.write("(");
20220 self.generate_expression(&f.year)?;
20221 self.write(", ");
20222 self.generate_expression(&f.month)?;
20223 self.write(", ");
20224 self.generate_expression(&f.day)?;
20225 self.write(", ");
20226 self.generate_expression(&f.hour)?;
20227 self.write(", ");
20228 self.generate_expression(&f.minute)?;
20229 self.write(", ");
20230 self.generate_expression(&f.second)?;
20231 if let Some(ref tz) = f.timezone {
20232 self.write(", ");
20233 self.generate_expression(tz)?;
20234 }
20235 self.write(")");
20236 Ok(())
20237 }
20238
20239 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
20241 match expr {
20242 Expression::Struct(s) => {
20243 if s.fields.iter().all(|(name, _)| name.is_some()) {
20244 Some(
20245 s.fields
20246 .iter()
20247 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
20248 .collect(),
20249 )
20250 } else {
20251 None
20252 }
20253 }
20254 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20255 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
20257 Some(
20258 f.args
20259 .iter()
20260 .filter_map(|a| {
20261 if let Expression::Alias(alias) = a {
20262 Some(alias.alias.name.clone())
20263 } else {
20264 None
20265 }
20266 })
20267 .collect(),
20268 )
20269 } else {
20270 None
20271 }
20272 }
20273 _ => None,
20274 }
20275 }
20276
20277 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
20279 match expr {
20280 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
20281 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20282 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
20283 }
20284 _ => false,
20285 }
20286 }
20287
20288 fn struct_field_count(expr: &Expression) -> usize {
20290 match expr {
20291 Expression::Struct(s) => s.fields.len(),
20292 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
20293 _ => 0,
20294 }
20295 }
20296
20297 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
20299 match expr {
20300 Expression::Struct(s) => {
20301 let mut new_fields = Vec::with_capacity(s.fields.len());
20302 for (i, (name, value)) in s.fields.iter().enumerate() {
20303 if name.is_none() && i < field_names.len() {
20304 new_fields.push((Some(field_names[i].clone()), value.clone()));
20305 } else {
20306 new_fields.push((name.clone(), value.clone()));
20307 }
20308 }
20309 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
20310 }
20311 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20312 let mut new_args = Vec::with_capacity(f.args.len());
20313 for (i, arg) in f.args.iter().enumerate() {
20314 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
20315 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
20317 this: arg.clone(),
20318 alias: crate::expressions::Identifier::new(field_names[i].clone()),
20319 column_aliases: Vec::new(),
20320 pre_alias_comments: Vec::new(),
20321 trailing_comments: Vec::new(),
20322 inferred_type: None,
20323 })));
20324 } else {
20325 new_args.push(arg.clone());
20326 }
20327 }
20328 Expression::Function(Box::new(crate::expressions::Function {
20329 name: f.name.clone(),
20330 args: new_args,
20331 distinct: f.distinct,
20332 trailing_comments: f.trailing_comments.clone(),
20333 use_bracket_syntax: f.use_bracket_syntax,
20334 no_parens: f.no_parens,
20335 quoted: f.quoted,
20336 span: None,
20337 inferred_type: None,
20338 }))
20339 }
20340 _ => expr.clone(),
20341 }
20342 }
20343
20344 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
20348 let first = match expressions.first() {
20349 Some(e) => e,
20350 None => return expressions.to_vec(),
20351 };
20352
20353 let field_names = match Self::extract_struct_field_names(first) {
20354 Some(names) if !names.is_empty() => names,
20355 _ => return expressions.to_vec(),
20356 };
20357
20358 let mut result = Vec::with_capacity(expressions.len());
20359 for (idx, expr) in expressions.iter().enumerate() {
20360 if idx == 0 {
20361 result.push(expr.clone());
20362 continue;
20363 }
20364 if Self::struct_field_count(expr) == field_names.len()
20366 && Self::struct_has_unnamed_fields(expr)
20367 {
20368 result.push(Self::apply_struct_field_names(expr, &field_names));
20369 } else {
20370 result.push(expr.clone());
20371 }
20372 }
20373 result
20374 }
20375
20376 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
20379 let needs_inheritance = matches!(
20382 self.config.dialect,
20383 Some(DialectType::DuckDB)
20384 | Some(DialectType::Spark)
20385 | Some(DialectType::Databricks)
20386 | Some(DialectType::Hive)
20387 | Some(DialectType::Snowflake)
20388 | Some(DialectType::Presto)
20389 | Some(DialectType::Trino)
20390 );
20391 let propagated: Vec<Expression>;
20392 let expressions = if needs_inheritance && f.expressions.len() > 1 {
20393 propagated = Self::inherit_struct_field_names(&f.expressions);
20394 &propagated
20395 } else {
20396 &f.expressions
20397 };
20398
20399 let should_split = if self.config.pretty && !expressions.is_empty() {
20401 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
20402 for expr in expressions {
20403 let mut temp_gen = Generator::with_arc_config(self.config.clone());
20404 Arc::make_mut(&mut temp_gen.config).pretty = false;
20405 temp_gen.generate_expression(expr)?;
20406 expr_strings.push(temp_gen.output);
20407 }
20408 self.too_wide(&expr_strings)
20409 } else {
20410 false
20411 };
20412
20413 if f.bracket_notation {
20414 let (open, close) = match self.config.dialect {
20418 None
20419 | Some(DialectType::Generic)
20420 | Some(DialectType::Spark)
20421 | Some(DialectType::Databricks)
20422 | Some(DialectType::Hive) => {
20423 self.write_keyword("ARRAY");
20424 ("(", ")")
20425 }
20426 Some(DialectType::Presto)
20427 | Some(DialectType::Trino)
20428 | Some(DialectType::PostgreSQL)
20429 | Some(DialectType::Redshift)
20430 | Some(DialectType::Materialize)
20431 | Some(DialectType::RisingWave)
20432 | Some(DialectType::CockroachDB) => {
20433 self.write_keyword("ARRAY");
20434 ("[", "]")
20435 }
20436 _ => ("[", "]"),
20437 };
20438 self.write(open);
20439 if should_split {
20440 self.write_newline();
20441 self.indent_level += 1;
20442 for (i, expr) in expressions.iter().enumerate() {
20443 self.write_indent();
20444 self.generate_expression(expr)?;
20445 if i + 1 < expressions.len() {
20446 self.write(",");
20447 }
20448 self.write_newline();
20449 }
20450 self.indent_level -= 1;
20451 self.write_indent();
20452 } else {
20453 for (i, expr) in expressions.iter().enumerate() {
20454 if i > 0 {
20455 self.write(", ");
20456 }
20457 self.generate_expression(expr)?;
20458 }
20459 }
20460 self.write(close);
20461 } else {
20462 if f.use_list_keyword {
20464 self.write_keyword("LIST");
20465 } else {
20466 self.write_keyword("ARRAY");
20467 }
20468 let has_subquery = expressions
20471 .iter()
20472 .any(|e| matches!(e, Expression::Select(_)));
20473 let (open, close) = if matches!(
20474 self.config.dialect,
20475 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
20476 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
20477 && has_subquery)
20478 {
20479 ("(", ")")
20480 } else {
20481 ("[", "]")
20482 };
20483 self.write(open);
20484 if should_split {
20485 self.write_newline();
20486 self.indent_level += 1;
20487 for (i, expr) in expressions.iter().enumerate() {
20488 self.write_indent();
20489 self.generate_expression(expr)?;
20490 if i + 1 < expressions.len() {
20491 self.write(",");
20492 }
20493 self.write_newline();
20494 }
20495 self.indent_level -= 1;
20496 self.write_indent();
20497 } else {
20498 for (i, expr) in expressions.iter().enumerate() {
20499 if i > 0 {
20500 self.write(", ");
20501 }
20502 self.generate_expression(expr)?;
20503 }
20504 }
20505 self.write(close);
20506 }
20507 Ok(())
20508 }
20509
20510 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
20511 self.write_keyword("ARRAY_SORT");
20512 self.write("(");
20513 self.generate_expression(&f.this)?;
20514 if let Some(ref comp) = f.comparator {
20515 self.write(", ");
20516 self.generate_expression(comp)?;
20517 }
20518 self.write(")");
20519 Ok(())
20520 }
20521
20522 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
20523 self.write_keyword(name);
20524 self.write("(");
20525 self.generate_expression(&f.this)?;
20526 self.write(", ");
20527 self.generate_expression(&f.separator)?;
20528 if let Some(ref null_rep) = f.null_replacement {
20529 self.write(", ");
20530 self.generate_expression(null_rep)?;
20531 }
20532 self.write(")");
20533 Ok(())
20534 }
20535
20536 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
20537 self.write_keyword("UNNEST");
20538 self.write("(");
20539 self.generate_expression(&f.this)?;
20540 for extra in &f.expressions {
20541 self.write(", ");
20542 self.generate_expression(extra)?;
20543 }
20544 self.write(")");
20545 if f.with_ordinality {
20546 self.write_space();
20547 if self.config.unnest_with_ordinality {
20548 self.write_keyword("WITH ORDINALITY");
20550 } else if f.offset_alias.is_some() {
20551 if let Some(ref alias) = f.alias {
20554 self.write_keyword("AS");
20555 self.write_space();
20556 self.generate_identifier(alias)?;
20557 self.write_space();
20558 }
20559 self.write_keyword("WITH OFFSET");
20560 if let Some(ref offset_alias) = f.offset_alias {
20561 self.write_space();
20562 self.write_keyword("AS");
20563 self.write_space();
20564 self.generate_identifier(offset_alias)?;
20565 }
20566 } else {
20567 self.write_keyword("WITH OFFSET");
20569 if f.alias.is_none() {
20570 self.write(" AS offset");
20571 }
20572 }
20573 }
20574 if let Some(ref alias) = f.alias {
20575 let should_add_alias = if !f.with_ordinality {
20577 true
20578 } else if self.config.unnest_with_ordinality {
20579 true
20581 } else if f.offset_alias.is_some() {
20582 false
20584 } else {
20585 true
20587 };
20588 if should_add_alias {
20589 self.write_space();
20590 self.write_keyword("AS");
20591 self.write_space();
20592 self.generate_identifier(alias)?;
20593 }
20594 }
20595 Ok(())
20596 }
20597
20598 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
20599 self.write_keyword("FILTER");
20600 self.write("(");
20601 self.generate_expression(&f.this)?;
20602 self.write(", ");
20603 self.generate_expression(&f.filter)?;
20604 self.write(")");
20605 Ok(())
20606 }
20607
20608 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
20609 self.write_keyword("TRANSFORM");
20610 self.write("(");
20611 self.generate_expression(&f.this)?;
20612 self.write(", ");
20613 self.generate_expression(&f.transform)?;
20614 self.write(")");
20615 Ok(())
20616 }
20617
20618 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
20619 self.write_keyword(name);
20620 self.write("(");
20621 self.generate_expression(&f.start)?;
20622 self.write(", ");
20623 self.generate_expression(&f.stop)?;
20624 if let Some(ref step) = f.step {
20625 self.write(", ");
20626 self.generate_expression(step)?;
20627 }
20628 self.write(")");
20629 Ok(())
20630 }
20631
20632 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
20635 self.write_keyword("STRUCT");
20636 self.write("(");
20637 for (i, (name, expr)) in f.fields.iter().enumerate() {
20638 if i > 0 {
20639 self.write(", ");
20640 }
20641 if let Some(ref id) = name {
20642 self.generate_identifier(id)?;
20643 self.write(" ");
20644 self.write_keyword("AS");
20645 self.write(" ");
20646 }
20647 self.generate_expression(expr)?;
20648 }
20649 self.write(")");
20650 Ok(())
20651 }
20652
20653 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
20655 let mut names: Vec<Option<String>> = Vec::new();
20658 let mut values: Vec<&Expression> = Vec::new();
20659 let mut all_named = true;
20660
20661 for arg in &func.args {
20662 match arg {
20663 Expression::Alias(a) => {
20664 names.push(Some(a.alias.name.clone()));
20665 values.push(&a.this);
20666 }
20667 _ => {
20668 names.push(None);
20669 values.push(arg);
20670 all_named = false;
20671 }
20672 }
20673 }
20674
20675 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20676 self.write("{");
20678 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20679 if i > 0 {
20680 self.write(", ");
20681 }
20682 if let Some(n) = name {
20683 self.write("'");
20684 self.write(n);
20685 self.write("'");
20686 } else {
20687 self.write("'_");
20688 self.write(&i.to_string());
20689 self.write("'");
20690 }
20691 self.write(": ");
20692 self.generate_expression(value)?;
20693 }
20694 self.write("}");
20695 return Ok(());
20696 }
20697
20698 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20699 self.write_keyword("OBJECT_CONSTRUCT");
20701 self.write("(");
20702 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20703 if i > 0 {
20704 self.write(", ");
20705 }
20706 if let Some(n) = name {
20707 self.write("'");
20708 self.write(n);
20709 self.write("'");
20710 } else {
20711 self.write("'_");
20712 self.write(&i.to_string());
20713 self.write("'");
20714 }
20715 self.write(", ");
20716 self.generate_expression(value)?;
20717 }
20718 self.write(")");
20719 return Ok(());
20720 }
20721
20722 if matches!(
20723 self.config.dialect,
20724 Some(DialectType::Presto) | Some(DialectType::Trino)
20725 ) {
20726 if all_named && !names.is_empty() {
20727 self.write_keyword("CAST");
20730 self.write("(");
20731 self.write_keyword("ROW");
20732 self.write("(");
20733 for (i, value) in values.iter().enumerate() {
20734 if i > 0 {
20735 self.write(", ");
20736 }
20737 self.generate_expression(value)?;
20738 }
20739 self.write(")");
20740 self.write(" ");
20741 self.write_keyword("AS");
20742 self.write(" ");
20743 self.write_keyword("ROW");
20744 self.write("(");
20745 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20746 if i > 0 {
20747 self.write(", ");
20748 }
20749 if let Some(n) = name {
20750 self.write(n);
20751 }
20752 self.write(" ");
20753 let type_str = Self::infer_sql_type_for_presto(value);
20754 self.write_keyword(&type_str);
20755 }
20756 self.write(")");
20757 self.write(")");
20758 } else {
20759 self.write_keyword("ROW");
20761 self.write("(");
20762 for (i, value) in values.iter().enumerate() {
20763 if i > 0 {
20764 self.write(", ");
20765 }
20766 self.generate_expression(value)?;
20767 }
20768 self.write(")");
20769 }
20770 return Ok(());
20771 }
20772
20773 self.write_keyword("ROW");
20775 self.write("(");
20776 for (i, value) in values.iter().enumerate() {
20777 if i > 0 {
20778 self.write(", ");
20779 }
20780 self.generate_expression(value)?;
20781 }
20782 self.write(")");
20783 Ok(())
20784 }
20785
20786 fn infer_sql_type_for_presto(expr: &Expression) -> String {
20788 match expr {
20789 Expression::Literal(lit)
20790 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
20791 {
20792 "VARCHAR".to_string()
20793 }
20794 Expression::Literal(lit)
20795 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
20796 {
20797 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
20798 unreachable!()
20799 };
20800 if n.contains('.') {
20801 "DOUBLE".to_string()
20802 } else {
20803 "INTEGER".to_string()
20804 }
20805 }
20806 Expression::Boolean(_) => "BOOLEAN".to_string(),
20807 Expression::Literal(lit)
20808 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
20809 {
20810 "DATE".to_string()
20811 }
20812 Expression::Literal(lit)
20813 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
20814 {
20815 "TIMESTAMP".to_string()
20816 }
20817 Expression::Literal(lit)
20818 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
20819 {
20820 "TIMESTAMP".to_string()
20821 }
20822 Expression::Array(_) | Expression::ArrayFunc(_) => {
20823 "ARRAY(VARCHAR)".to_string()
20825 }
20826 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
20828 Expression::Function(f) => {
20829 if f.name.eq_ignore_ascii_case("STRUCT") {
20830 "ROW".to_string()
20831 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
20832 "DATE".to_string()
20833 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
20834 || f.name.eq_ignore_ascii_case("NOW")
20835 {
20836 "TIMESTAMP".to_string()
20837 } else {
20838 "VARCHAR".to_string()
20839 }
20840 }
20841 _ => "VARCHAR".to_string(),
20842 }
20843 }
20844
20845 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
20846 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20848 self.write_keyword("STRUCT_EXTRACT");
20849 self.write("(");
20850 self.generate_expression(&f.this)?;
20851 self.write(", ");
20852 self.write("'");
20854 self.write(&f.field.name);
20855 self.write("'");
20856 self.write(")");
20857 return Ok(());
20858 }
20859 self.generate_expression(&f.this)?;
20860 self.write(".");
20861 self.generate_identifier(&f.field)
20862 }
20863
20864 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
20865 self.write_keyword("NAMED_STRUCT");
20866 self.write("(");
20867 for (i, (name, value)) in f.pairs.iter().enumerate() {
20868 if i > 0 {
20869 self.write(", ");
20870 }
20871 self.generate_expression(name)?;
20872 self.write(", ");
20873 self.generate_expression(value)?;
20874 }
20875 self.write(")");
20876 Ok(())
20877 }
20878
20879 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
20882 if f.curly_brace_syntax {
20883 if f.with_map_keyword {
20885 self.write_keyword("MAP");
20886 self.write(" ");
20887 }
20888 self.write("{");
20889 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
20890 if i > 0 {
20891 self.write(", ");
20892 }
20893 self.generate_expression(key)?;
20894 self.write(": ");
20895 self.generate_expression(val)?;
20896 }
20897 self.write("}");
20898 } else {
20899 self.write_keyword("MAP");
20901 self.write("(");
20902 self.write_keyword("ARRAY");
20903 self.write("[");
20904 for (i, key) in f.keys.iter().enumerate() {
20905 if i > 0 {
20906 self.write(", ");
20907 }
20908 self.generate_expression(key)?;
20909 }
20910 self.write("], ");
20911 self.write_keyword("ARRAY");
20912 self.write("[");
20913 for (i, val) in f.values.iter().enumerate() {
20914 if i > 0 {
20915 self.write(", ");
20916 }
20917 self.generate_expression(val)?;
20918 }
20919 self.write("])");
20920 }
20921 Ok(())
20922 }
20923
20924 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
20925 self.write_keyword(name);
20926 self.write("(");
20927 self.generate_expression(&f.this)?;
20928 self.write(", ");
20929 self.generate_expression(&f.transform)?;
20930 self.write(")");
20931 Ok(())
20932 }
20933
20934 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
20937 use crate::dialects::DialectType;
20938
20939 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
20941
20942 if use_arrow {
20943 self.generate_expression(&f.this)?;
20945 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
20946 self.write(" ->> ");
20947 } else {
20948 self.write(" -> ");
20949 }
20950 self.generate_expression(&f.path)?;
20951 return Ok(());
20952 }
20953
20954 if f.hash_arrow_syntax
20956 && matches!(
20957 self.config.dialect,
20958 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20959 )
20960 {
20961 self.generate_expression(&f.this)?;
20962 self.write(" #>> ");
20963 self.generate_expression(&f.path)?;
20964 return Ok(());
20965 }
20966
20967 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20970 match name {
20971 "JSON_EXTRACT_SCALAR"
20972 | "JSON_EXTRACT_PATH_TEXT"
20973 | "JSON_EXTRACT"
20974 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
20975 _ => name,
20976 }
20977 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20978 match name {
20979 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
20980 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
20981 _ => name,
20982 }
20983 } else {
20984 name
20985 };
20986
20987 self.write_keyword(func_name);
20988 self.write("(");
20989 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20991 if let Expression::Cast(ref cast) = f.this {
20992 if matches!(cast.to, crate::expressions::DataType::Json) {
20993 self.generate_expression(&cast.this)?;
20994 } else {
20995 self.generate_expression(&f.this)?;
20996 }
20997 } else {
20998 self.generate_expression(&f.this)?;
20999 }
21000 } else {
21001 self.generate_expression(&f.this)?;
21002 }
21003 if matches!(
21006 self.config.dialect,
21007 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21008 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
21009 {
21010 if let Expression::Literal(ref lit) = f.path {
21011 if let Literal::String(ref s) = lit.as_ref() {
21012 let parts = Self::decompose_json_path(s);
21013 for part in &parts {
21014 self.write(", '");
21015 self.write(part);
21016 self.write("'");
21017 }
21018 }
21019 } else {
21020 self.write(", ");
21021 self.generate_expression(&f.path)?;
21022 }
21023 } else {
21024 self.write(", ");
21025 self.generate_expression(&f.path)?;
21026 }
21027
21028 if let Some(ref wrapper) = f.wrapper_option {
21031 self.write_space();
21032 self.write_keyword(wrapper);
21033 }
21034 if let Some(ref quotes) = f.quotes_option {
21035 self.write_space();
21036 self.write_keyword(quotes);
21037 if f.on_scalar_string {
21038 self.write_space();
21039 self.write_keyword("ON SCALAR STRING");
21040 }
21041 }
21042 if let Some(ref on_err) = f.on_error {
21043 self.write_space();
21044 self.write_keyword(on_err);
21045 }
21046 if let Some(ref ret_type) = f.returning {
21047 self.write_space();
21048 self.write_keyword("RETURNING");
21049 self.write_space();
21050 self.generate_data_type(ret_type)?;
21051 }
21052
21053 self.write(")");
21054 Ok(())
21055 }
21056
21057 fn dialect_supports_json_arrow(&self) -> bool {
21059 use crate::dialects::DialectType;
21060 match self.config.dialect {
21061 Some(DialectType::PostgreSQL) => true,
21063 Some(DialectType::MySQL) => true,
21064 Some(DialectType::DuckDB) => true,
21065 Some(DialectType::CockroachDB) => true,
21066 Some(DialectType::StarRocks) => true,
21067 Some(DialectType::SQLite) => true,
21068 _ => false,
21070 }
21071 }
21072
21073 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
21074 use crate::dialects::DialectType;
21075
21076 if matches!(
21078 self.config.dialect,
21079 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21080 ) && name == "JSON_EXTRACT_PATH"
21081 {
21082 self.generate_expression(&f.this)?;
21083 self.write(" #> ");
21084 if f.paths.len() == 1 {
21085 self.generate_expression(&f.paths[0])?;
21086 } else {
21087 self.write_keyword("ARRAY");
21089 self.write("[");
21090 for (i, path) in f.paths.iter().enumerate() {
21091 if i > 0 {
21092 self.write(", ");
21093 }
21094 self.generate_expression(path)?;
21095 }
21096 self.write("]");
21097 }
21098 return Ok(());
21099 }
21100
21101 self.write_keyword(name);
21102 self.write("(");
21103 self.generate_expression(&f.this)?;
21104 for path in &f.paths {
21105 self.write(", ");
21106 self.generate_expression(path)?;
21107 }
21108 self.write(")");
21109 Ok(())
21110 }
21111
21112 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
21113 use crate::dialects::DialectType;
21114
21115 self.write_keyword("JSON_OBJECT");
21116 self.write("(");
21117 if f.star {
21118 self.write("*");
21119 } else {
21120 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
21124 || matches!(
21125 self.config.dialect,
21126 Some(DialectType::BigQuery)
21127 | Some(DialectType::MySQL)
21128 | Some(DialectType::SQLite)
21129 );
21130
21131 for (i, (key, value)) in f.pairs.iter().enumerate() {
21132 if i > 0 {
21133 self.write(", ");
21134 }
21135 self.generate_expression(key)?;
21136 if use_comma_syntax {
21137 self.write(", ");
21138 } else {
21139 self.write(": ");
21140 }
21141 self.generate_expression(value)?;
21142 }
21143 }
21144 if let Some(null_handling) = f.null_handling {
21145 self.write_space();
21146 match null_handling {
21147 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21148 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21149 }
21150 }
21151 if f.with_unique_keys {
21152 self.write_space();
21153 self.write_keyword("WITH UNIQUE KEYS");
21154 }
21155 if let Some(ref ret_type) = f.returning_type {
21156 self.write_space();
21157 self.write_keyword("RETURNING");
21158 self.write_space();
21159 self.generate_data_type(ret_type)?;
21160 if f.format_json {
21161 self.write_space();
21162 self.write_keyword("FORMAT JSON");
21163 }
21164 if let Some(ref enc) = f.encoding {
21165 self.write_space();
21166 self.write_keyword("ENCODING");
21167 self.write_space();
21168 self.write(enc);
21169 }
21170 }
21171 self.write(")");
21172 Ok(())
21173 }
21174
21175 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
21176 self.write_keyword(name);
21177 self.write("(");
21178 self.generate_expression(&f.this)?;
21179 for (path, value) in &f.path_values {
21180 self.write(", ");
21181 self.generate_expression(path)?;
21182 self.write(", ");
21183 self.generate_expression(value)?;
21184 }
21185 self.write(")");
21186 Ok(())
21187 }
21188
21189 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
21190 self.write_keyword("JSON_ARRAYAGG");
21191 self.write("(");
21192 self.generate_expression(&f.this)?;
21193 if let Some(ref order_by) = f.order_by {
21194 self.write_space();
21195 self.write_keyword("ORDER BY");
21196 self.write_space();
21197 for (i, ord) in order_by.iter().enumerate() {
21198 if i > 0 {
21199 self.write(", ");
21200 }
21201 self.generate_ordered(ord)?;
21202 }
21203 }
21204 if let Some(null_handling) = f.null_handling {
21205 self.write_space();
21206 match null_handling {
21207 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21208 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21209 }
21210 }
21211 self.write(")");
21212 if let Some(ref filter) = f.filter {
21213 self.write_space();
21214 self.write_keyword("FILTER");
21215 self.write("(");
21216 self.write_keyword("WHERE");
21217 self.write_space();
21218 self.generate_expression(filter)?;
21219 self.write(")");
21220 }
21221 Ok(())
21222 }
21223
21224 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
21225 self.write_keyword("JSON_OBJECTAGG");
21226 self.write("(");
21227 self.generate_expression(&f.key)?;
21228 self.write(": ");
21229 self.generate_expression(&f.value)?;
21230 if let Some(null_handling) = f.null_handling {
21231 self.write_space();
21232 match null_handling {
21233 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21234 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21235 }
21236 }
21237 self.write(")");
21238 if let Some(ref filter) = f.filter {
21239 self.write_space();
21240 self.write_keyword("FILTER");
21241 self.write("(");
21242 self.write_keyword("WHERE");
21243 self.write_space();
21244 self.generate_expression(filter)?;
21245 self.write(")");
21246 }
21247 Ok(())
21248 }
21249
21250 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
21253 use crate::dialects::DialectType;
21254
21255 if self.config.dialect == Some(DialectType::Redshift) {
21257 self.write_keyword("CAST");
21258 self.write("(");
21259 self.generate_expression(&f.this)?;
21260 self.write_space();
21261 self.write_keyword("AS");
21262 self.write_space();
21263 self.generate_data_type(&f.to)?;
21264 self.write(")");
21265 return Ok(());
21266 }
21267
21268 self.write_keyword("CONVERT");
21269 self.write("(");
21270 self.generate_data_type(&f.to)?;
21271 self.write(", ");
21272 self.generate_expression(&f.this)?;
21273 if let Some(ref style) = f.style {
21274 self.write(", ");
21275 self.generate_expression(style)?;
21276 }
21277 self.write(")");
21278 Ok(())
21279 }
21280
21281 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
21284 if f.colon {
21285 self.write_keyword("LAMBDA");
21287 self.write_space();
21288 for (i, param) in f.parameters.iter().enumerate() {
21289 if i > 0 {
21290 self.write(", ");
21291 }
21292 self.generate_identifier(param)?;
21293 }
21294 self.write(" : ");
21295 } else {
21296 if f.parameters.len() == 1 {
21298 self.generate_identifier(&f.parameters[0])?;
21299 } else {
21300 self.write("(");
21301 for (i, param) in f.parameters.iter().enumerate() {
21302 if i > 0 {
21303 self.write(", ");
21304 }
21305 self.generate_identifier(param)?;
21306 }
21307 self.write(")");
21308 }
21309 self.write(" -> ");
21310 }
21311 self.generate_expression(&f.body)
21312 }
21313
21314 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
21315 self.generate_identifier(&f.name)?;
21316 match f.separator {
21317 NamedArgSeparator::DArrow => self.write(" => "),
21318 NamedArgSeparator::ColonEq => self.write(" := "),
21319 NamedArgSeparator::Eq => self.write(" = "),
21320 }
21321 self.generate_expression(&f.value)
21322 }
21323
21324 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
21325 self.write_keyword(&f.prefix);
21326 self.write(" ");
21327 self.generate_expression(&f.this)
21328 }
21329
21330 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
21331 match f.style {
21332 ParameterStyle::Question => self.write("?"),
21333 ParameterStyle::Dollar => {
21334 self.write("$");
21335 if let Some(idx) = f.index {
21336 self.write(&idx.to_string());
21337 } else if let Some(ref name) = f.name {
21338 self.write(name);
21340 }
21341 }
21342 ParameterStyle::DollarBrace => {
21343 self.write("${");
21345 if let Some(ref name) = f.name {
21346 self.write(name);
21347 }
21348 if let Some(ref expr) = f.expression {
21349 self.write(":");
21350 self.write(expr);
21351 }
21352 self.write("}");
21353 }
21354 ParameterStyle::Colon => {
21355 self.write(":");
21356 if let Some(idx) = f.index {
21357 self.write(&idx.to_string());
21358 } else if let Some(ref name) = f.name {
21359 self.write(name);
21360 }
21361 }
21362 ParameterStyle::At => {
21363 self.write("@");
21364 if let Some(ref name) = f.name {
21365 if f.string_quoted {
21366 self.write("'");
21367 self.write(name);
21368 self.write("'");
21369 } else if f.quoted {
21370 self.write("\"");
21371 self.write(name);
21372 self.write("\"");
21373 } else {
21374 self.write(name);
21375 }
21376 }
21377 }
21378 ParameterStyle::DoubleAt => {
21379 self.write("@@");
21380 if let Some(ref name) = f.name {
21381 self.write(name);
21382 }
21383 }
21384 ParameterStyle::DoubleDollar => {
21385 self.write("$$");
21386 if let Some(ref name) = f.name {
21387 self.write(name);
21388 }
21389 }
21390 ParameterStyle::Percent => {
21391 if let Some(ref name) = f.name {
21392 self.write("%(");
21394 self.write(name);
21395 self.write(")s");
21396 } else {
21397 self.write("%s");
21399 }
21400 }
21401 ParameterStyle::Brace => {
21402 self.write("{");
21405 if let Some(ref name) = f.name {
21406 self.write(name);
21407 }
21408 if let Some(ref expr) = f.expression {
21409 self.write(": ");
21410 self.write(expr);
21411 }
21412 self.write("}");
21413 }
21414 }
21415 Ok(())
21416 }
21417
21418 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
21419 self.write("?");
21420 if let Some(idx) = f.index {
21421 self.write(&idx.to_string());
21422 }
21423 Ok(())
21424 }
21425
21426 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
21427 if f.is_block {
21428 self.write("/*");
21429 self.write(&f.text);
21430 self.write("*/");
21431 } else {
21432 self.write("--");
21433 self.write(&f.text);
21434 }
21435 Ok(())
21436 }
21437
21438 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
21441 self.generate_expression(&f.this)?;
21442 if f.not {
21443 self.write_space();
21444 self.write_keyword("NOT");
21445 }
21446 self.write_space();
21447 self.write_keyword("SIMILAR TO");
21448 self.write_space();
21449 self.generate_expression(&f.pattern)?;
21450 if let Some(ref escape) = f.escape {
21451 self.write_space();
21452 self.write_keyword("ESCAPE");
21453 self.write_space();
21454 self.generate_expression(escape)?;
21455 }
21456 Ok(())
21457 }
21458
21459 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
21460 self.generate_expression(&f.this)?;
21461 self.write_space();
21462 if let Some(op) = &f.op {
21464 match op {
21465 QuantifiedOp::Eq => self.write("="),
21466 QuantifiedOp::Neq => self.write("<>"),
21467 QuantifiedOp::Lt => self.write("<"),
21468 QuantifiedOp::Lte => self.write("<="),
21469 QuantifiedOp::Gt => self.write(">"),
21470 QuantifiedOp::Gte => self.write(">="),
21471 }
21472 self.write_space();
21473 }
21474 self.write_keyword(name);
21475
21476 if matches!(&f.subquery, Expression::Subquery(_)) {
21478 self.write_space();
21479 self.generate_expression(&f.subquery)?;
21480 } else {
21481 self.write("(");
21482
21483 let is_statement = matches!(
21484 &f.subquery,
21485 Expression::Select(_)
21486 | Expression::Union(_)
21487 | Expression::Intersect(_)
21488 | Expression::Except(_)
21489 );
21490
21491 if self.config.pretty && is_statement {
21492 self.write_newline();
21493 self.indent_level += 1;
21494 self.write_indent();
21495 }
21496 self.generate_expression(&f.subquery)?;
21497 if self.config.pretty && is_statement {
21498 self.write_newline();
21499 self.indent_level -= 1;
21500 self.write_indent();
21501 }
21502 self.write(")");
21503 }
21504 Ok(())
21505 }
21506
21507 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
21508 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
21510 self.generate_expression(this)?;
21511 self.write_space();
21512 self.write_keyword("OVERLAPS");
21513 self.write_space();
21514 self.generate_expression(expr)?;
21515 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
21516 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
21517 {
21518 self.write("(");
21520 self.generate_expression(ls)?;
21521 self.write(", ");
21522 self.generate_expression(le)?;
21523 self.write(")");
21524 self.write_space();
21525 self.write_keyword("OVERLAPS");
21526 self.write_space();
21527 self.write("(");
21528 self.generate_expression(rs)?;
21529 self.write(", ");
21530 self.generate_expression(re)?;
21531 self.write(")");
21532 }
21533 Ok(())
21534 }
21535
21536 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
21539 use crate::dialects::DialectType;
21540
21541 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
21543 self.generate_expression(&cast.this)?;
21544 self.write(" !:> ");
21545 self.generate_data_type(&cast.to)?;
21546 return Ok(());
21547 }
21548
21549 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
21551 self.write_keyword("TRYCAST");
21552 self.write("(");
21553 self.generate_expression(&cast.this)?;
21554 self.write_space();
21555 self.write_keyword("AS");
21556 self.write_space();
21557 self.generate_data_type(&cast.to)?;
21558 self.write(")");
21559 return Ok(());
21560 }
21561
21562 let keyword = if matches!(
21564 self.config.dialect,
21565 Some(DialectType::Hive)
21566 | Some(DialectType::MySQL)
21567 | Some(DialectType::SQLite)
21568 | Some(DialectType::Oracle)
21569 | Some(DialectType::ClickHouse)
21570 | Some(DialectType::Redshift)
21571 | Some(DialectType::PostgreSQL)
21572 | Some(DialectType::StarRocks)
21573 | Some(DialectType::Doris)
21574 ) {
21575 "CAST"
21576 } else {
21577 "TRY_CAST"
21578 };
21579
21580 self.write_keyword(keyword);
21581 self.write("(");
21582 self.generate_expression(&cast.this)?;
21583 self.write_space();
21584 self.write_keyword("AS");
21585 self.write_space();
21586 self.generate_data_type(&cast.to)?;
21587
21588 if let Some(format) = &cast.format {
21590 self.write_space();
21591 self.write_keyword("FORMAT");
21592 self.write_space();
21593 self.generate_expression(format)?;
21594 }
21595
21596 self.write(")");
21597 Ok(())
21598 }
21599
21600 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
21601 self.write_keyword("SAFE_CAST");
21602 self.write("(");
21603 self.generate_expression(&cast.this)?;
21604 self.write_space();
21605 self.write_keyword("AS");
21606 self.write_space();
21607 self.generate_data_type(&cast.to)?;
21608
21609 if let Some(format) = &cast.format {
21611 self.write_space();
21612 self.write_keyword("FORMAT");
21613 self.write_space();
21614 self.generate_expression(format)?;
21615 }
21616
21617 self.write(")");
21618 Ok(())
21619 }
21620
21621 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
21624 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
21628 if needs_parens {
21629 self.write("(");
21630 }
21631 self.generate_expression(&s.this)?;
21632 if needs_parens {
21633 self.write(")");
21634 }
21635 self.write("[");
21636 self.generate_expression(&s.index)?;
21637 self.write("]");
21638 Ok(())
21639 }
21640
21641 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
21642 self.generate_expression(&d.this)?;
21643 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
21646 && matches!(
21647 &d.this,
21648 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
21649 );
21650 if use_colon {
21651 self.write(":");
21652 } else {
21653 self.write(".");
21654 }
21655 self.generate_identifier(&d.field)
21656 }
21657
21658 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
21659 self.generate_expression(&m.this)?;
21660 self.write(".");
21661 if m.method.quoted {
21664 let q = self.config.identifier_quote;
21665 self.write(&format!("{}{}{}", q, m.method.name, q));
21666 } else {
21667 self.write(&m.method.name);
21668 }
21669 self.write("(");
21670 for (i, arg) in m.args.iter().enumerate() {
21671 if i > 0 {
21672 self.write(", ");
21673 }
21674 self.generate_expression(arg)?;
21675 }
21676 self.write(")");
21677 Ok(())
21678 }
21679
21680 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
21681 let needs_parens = matches!(
21684 &s.this,
21685 Expression::JsonExtract(f) if f.arrow_syntax
21686 ) || matches!(
21687 &s.this,
21688 Expression::JsonExtractScalar(f) if f.arrow_syntax
21689 );
21690
21691 if needs_parens {
21692 self.write("(");
21693 }
21694 self.generate_expression(&s.this)?;
21695 if needs_parens {
21696 self.write(")");
21697 }
21698 self.write("[");
21699 if let Some(start) = &s.start {
21700 self.generate_expression(start)?;
21701 }
21702 self.write(":");
21703 if let Some(end) = &s.end {
21704 self.generate_expression(end)?;
21705 }
21706 self.write("]");
21707 Ok(())
21708 }
21709
21710 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
21711 match &op.left {
21715 Expression::Column(col) => {
21716 if let Some(table) = &col.table {
21719 self.generate_identifier(table)?;
21720 self.write(".");
21721 }
21722 self.generate_identifier(&col.name)?;
21723 if col.join_mark && self.config.supports_column_join_marks {
21725 self.write(" (+)");
21726 }
21727 if op.left_comments.is_empty() {
21729 for comment in &col.trailing_comments {
21730 self.write_space();
21731 self.write_formatted_comment(comment);
21732 }
21733 }
21734 }
21735 Expression::Add(inner_op)
21736 | Expression::Sub(inner_op)
21737 | Expression::Mul(inner_op)
21738 | Expression::Div(inner_op)
21739 | Expression::Concat(inner_op) => {
21740 self.generate_binary_op_no_trailing(inner_op, match &op.left {
21742 Expression::Add(_) => "+",
21743 Expression::Sub(_) => "-",
21744 Expression::Mul(_) => "*",
21745 Expression::Div(_) => "/",
21746 Expression::Concat(_) => "||",
21747 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
21748 })?;
21749 }
21750 _ => {
21751 self.generate_expression(&op.left)?;
21752 }
21753 }
21754 for comment in &op.left_comments {
21756 self.write_space();
21757 self.write_formatted_comment(comment);
21758 }
21759 if self.config.pretty
21760 && matches!(self.config.dialect, Some(DialectType::Snowflake))
21761 && (operator == "AND" || operator == "OR")
21762 {
21763 self.write_newline();
21764 self.write_indent();
21765 self.write_keyword(operator);
21766 } else {
21767 self.write_space();
21768 if operator.chars().all(|c| c.is_alphabetic()) {
21769 self.write_keyword(operator);
21770 } else {
21771 self.write(operator);
21772 }
21773 }
21774 for comment in &op.operator_comments {
21776 self.write_space();
21777 self.write_formatted_comment(comment);
21778 }
21779 self.write_space();
21780 self.generate_expression(&op.right)?;
21781 for comment in &op.trailing_comments {
21783 self.write_space();
21784 self.write_formatted_comment(comment);
21785 }
21786 Ok(())
21787 }
21788
21789 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
21790 let keyword = connector.keyword();
21791 let Some(terms) = self.flatten_connector_terms(op, connector) else {
21792 return self.generate_binary_op(op, keyword);
21793 };
21794
21795 self.generate_expression(terms[0])?;
21796 for term in terms.iter().skip(1) {
21797 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21798 self.write_newline();
21799 self.write_indent();
21800 self.write_keyword(keyword);
21801 } else {
21802 self.write_space();
21803 self.write_keyword(keyword);
21804 }
21805 self.write_space();
21806 self.generate_expression(term)?;
21807 }
21808
21809 Ok(())
21810 }
21811
21812 fn flatten_connector_terms<'a>(
21813 &self,
21814 root: &'a BinaryOp,
21815 connector: ConnectorOperator,
21816 ) -> Option<Vec<&'a Expression>> {
21817 if !root.left_comments.is_empty()
21818 || !root.operator_comments.is_empty()
21819 || !root.trailing_comments.is_empty()
21820 {
21821 return None;
21822 }
21823
21824 let mut terms = Vec::new();
21825 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
21826
21827 while let Some(expr) = stack.pop() {
21828 match (connector, expr) {
21829 (ConnectorOperator::And, Expression::And(inner))
21830 if inner.left_comments.is_empty()
21831 && inner.operator_comments.is_empty()
21832 && inner.trailing_comments.is_empty() =>
21833 {
21834 stack.push(&inner.right);
21835 stack.push(&inner.left);
21836 }
21837 (ConnectorOperator::Or, Expression::Or(inner))
21838 if inner.left_comments.is_empty()
21839 && inner.operator_comments.is_empty()
21840 && inner.trailing_comments.is_empty() =>
21841 {
21842 stack.push(&inner.right);
21843 stack.push(&inner.left);
21844 }
21845 _ => terms.push(expr),
21846 }
21847 }
21848
21849 if terms.len() > 1 {
21850 Some(terms)
21851 } else {
21852 None
21853 }
21854 }
21855
21856 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
21858 self.generate_expression(&op.left)?;
21859 self.write_space();
21860 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
21862 self.write("`ILIKE`");
21863 } else {
21864 self.write_keyword(operator);
21865 }
21866 if let Some(quantifier) = &op.quantifier {
21867 self.write_space();
21868 self.write_keyword(quantifier);
21869 let is_any =
21874 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
21875 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
21876 self.write_space();
21877 }
21878 } else {
21879 self.write_space();
21880 }
21881 self.generate_expression(&op.right)?;
21882 if let Some(escape) = &op.escape {
21883 self.write_space();
21884 self.write_keyword("ESCAPE");
21885 self.write_space();
21886 self.generate_expression(escape)?;
21887 }
21888 Ok(())
21889 }
21890
21891 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
21894 use crate::dialects::DialectType;
21895 self.generate_expression(&op.left)?;
21896 self.write_space();
21897 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
21898 self.write("<=>");
21899 } else {
21900 self.write_keyword("IS NOT DISTINCT FROM");
21901 }
21902 self.write_space();
21903 self.generate_expression(&op.right)?;
21904 Ok(())
21905 }
21906
21907 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
21909 self.generate_expression(&op.left)?;
21910 self.write_space();
21911 self.write_keyword("IS DISTINCT FROM");
21912 self.write_space();
21913 self.generate_expression(&op.right)?;
21914 Ok(())
21915 }
21916
21917 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
21919 match &op.left {
21921 Expression::Column(col) => {
21922 if let Some(table) = &col.table {
21923 self.generate_identifier(table)?;
21924 self.write(".");
21925 }
21926 self.generate_identifier(&col.name)?;
21927 if col.join_mark && self.config.supports_column_join_marks {
21929 self.write(" (+)");
21930 }
21931 }
21932 Expression::Add(inner_op)
21933 | Expression::Sub(inner_op)
21934 | Expression::Mul(inner_op)
21935 | Expression::Div(inner_op)
21936 | Expression::Concat(inner_op) => {
21937 self.generate_binary_op_no_trailing(inner_op, match &op.left {
21938 Expression::Add(_) => "+",
21939 Expression::Sub(_) => "-",
21940 Expression::Mul(_) => "*",
21941 Expression::Div(_) => "/",
21942 Expression::Concat(_) => "||",
21943 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
21944 })?;
21945 }
21946 _ => {
21947 self.generate_expression(&op.left)?;
21948 }
21949 }
21950 for comment in &op.left_comments {
21952 self.write_space();
21953 self.write_formatted_comment(comment);
21954 }
21955 self.write_space();
21956 if operator.chars().all(|c| c.is_alphabetic()) {
21957 self.write_keyword(operator);
21958 } else {
21959 self.write(operator);
21960 }
21961 for comment in &op.operator_comments {
21963 self.write_space();
21964 self.write_formatted_comment(comment);
21965 }
21966 self.write_space();
21967 match &op.right {
21970 Expression::Column(col) => {
21971 if let Some(table) = &col.table {
21972 self.generate_identifier(table)?;
21973 self.write(".");
21974 }
21975 self.generate_identifier(&col.name)?;
21976 if col.join_mark && self.config.supports_column_join_marks {
21978 self.write(" (+)");
21979 }
21980 }
21981 _ => {
21982 self.generate_expression(&op.right)?;
21983 }
21984 }
21985 Ok(())
21987 }
21988
21989 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
21990 if operator.chars().all(|c| c.is_alphabetic()) {
21991 self.write_keyword(operator);
21992 self.write_space();
21993 } else {
21994 self.write(operator);
21995 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
21997 self.write_space();
21998 }
21999 }
22000 self.generate_expression(&op.this)
22001 }
22002
22003 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
22004 let is_generic =
22008 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22009 let use_prefix_not =
22010 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
22011 if use_prefix_not {
22012 self.write_keyword("NOT");
22013 self.write_space();
22014 }
22015 self.generate_expression(&in_expr.this)?;
22016 if in_expr.global {
22017 self.write_space();
22018 self.write_keyword("GLOBAL");
22019 }
22020 if in_expr.not && !use_prefix_not {
22021 self.write_space();
22022 self.write_keyword("NOT");
22023 }
22024 self.write_space();
22025 self.write_keyword("IN");
22026
22027 if let Some(unnest_expr) = &in_expr.unnest {
22029 self.write_space();
22030 self.write_keyword("UNNEST");
22031 self.write("(");
22032 self.generate_expression(unnest_expr)?;
22033 self.write(")");
22034 return Ok(());
22035 }
22036
22037 if let Some(query) = &in_expr.query {
22038 let is_bare = in_expr.expressions.is_empty()
22041 && !matches!(
22042 query,
22043 Expression::Select(_)
22044 | Expression::Union(_)
22045 | Expression::Intersect(_)
22046 | Expression::Except(_)
22047 | Expression::Subquery(_)
22048 );
22049 if is_bare {
22050 self.write_space();
22052 self.generate_expression(query)?;
22053 } else {
22054 self.write(" (");
22056 let is_statement = matches!(
22057 query,
22058 Expression::Select(_)
22059 | Expression::Union(_)
22060 | Expression::Intersect(_)
22061 | Expression::Except(_)
22062 | Expression::Subquery(_)
22063 );
22064 if self.config.pretty && is_statement {
22065 self.write_newline();
22066 self.indent_level += 1;
22067 self.write_indent();
22068 }
22069 self.generate_expression(query)?;
22070 if self.config.pretty && is_statement {
22071 self.write_newline();
22072 self.indent_level -= 1;
22073 self.write_indent();
22074 }
22075 self.write(")");
22076 }
22077 } else {
22078 let is_duckdb = matches!(
22082 self.config.dialect,
22083 Some(crate::dialects::DialectType::DuckDB)
22084 );
22085 let is_clickhouse = matches!(
22086 self.config.dialect,
22087 Some(crate::dialects::DialectType::ClickHouse)
22088 );
22089 let single_expr = in_expr.expressions.len() == 1;
22090 if is_clickhouse && single_expr {
22091 if let Expression::Array(arr) = &in_expr.expressions[0] {
22092 self.write(" (");
22094 for (i, expr) in arr.expressions.iter().enumerate() {
22095 if i > 0 {
22096 self.write(", ");
22097 }
22098 self.generate_expression(expr)?;
22099 }
22100 self.write(")");
22101 } else {
22102 self.write_space();
22103 self.generate_expression(&in_expr.expressions[0])?;
22104 }
22105 } else {
22106 let is_bare_ref = single_expr
22107 && matches!(
22108 &in_expr.expressions[0],
22109 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
22110 );
22111 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
22112 self.write_space();
22115 self.generate_expression(&in_expr.expressions[0])?;
22116 } else {
22117 self.write(" (");
22119 for (i, expr) in in_expr.expressions.iter().enumerate() {
22120 if i > 0 {
22121 self.write(", ");
22122 }
22123 self.generate_expression(expr)?;
22124 }
22125 self.write(")");
22126 }
22127 }
22128 }
22129
22130 Ok(())
22131 }
22132
22133 fn generate_between(&mut self, between: &Between) -> Result<()> {
22134 let use_prefix_not = between.not
22136 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
22137 if use_prefix_not {
22138 self.write_keyword("NOT");
22139 self.write_space();
22140 }
22141 self.generate_expression(&between.this)?;
22142 if between.not && !use_prefix_not {
22143 self.write_space();
22144 self.write_keyword("NOT");
22145 }
22146 self.write_space();
22147 self.write_keyword("BETWEEN");
22148 if let Some(sym) = between.symmetric {
22150 if sym {
22151 self.write(" SYMMETRIC");
22152 } else {
22153 self.write(" ASYMMETRIC");
22154 }
22155 }
22156 self.write_space();
22157 self.generate_expression(&between.low)?;
22158 self.write_space();
22159 self.write_keyword("AND");
22160 self.write_space();
22161 self.generate_expression(&between.high)
22162 }
22163
22164 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
22165 let use_prefix_not = is_null.not
22167 && (self.config.dialect.is_none()
22168 || self.config.dialect == Some(DialectType::Generic)
22169 || is_null.postfix_form);
22170 if use_prefix_not {
22171 self.write_keyword("NOT");
22173 self.write_space();
22174 self.generate_expression(&is_null.this)?;
22175 self.write_space();
22176 self.write_keyword("IS");
22177 self.write_space();
22178 self.write_keyword("NULL");
22179 } else {
22180 self.generate_expression(&is_null.this)?;
22181 self.write_space();
22182 self.write_keyword("IS");
22183 if is_null.not {
22184 self.write_space();
22185 self.write_keyword("NOT");
22186 }
22187 self.write_space();
22188 self.write_keyword("NULL");
22189 }
22190 Ok(())
22191 }
22192
22193 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
22194 self.generate_expression(&is_true.this)?;
22195 self.write_space();
22196 self.write_keyword("IS");
22197 if is_true.not {
22198 self.write_space();
22199 self.write_keyword("NOT");
22200 }
22201 self.write_space();
22202 self.write_keyword("TRUE");
22203 Ok(())
22204 }
22205
22206 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
22207 self.generate_expression(&is_false.this)?;
22208 self.write_space();
22209 self.write_keyword("IS");
22210 if is_false.not {
22211 self.write_space();
22212 self.write_keyword("NOT");
22213 }
22214 self.write_space();
22215 self.write_keyword("FALSE");
22216 Ok(())
22217 }
22218
22219 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
22220 self.generate_expression(&is_json.this)?;
22221 self.write_space();
22222 self.write_keyword("IS");
22223 if is_json.negated {
22224 self.write_space();
22225 self.write_keyword("NOT");
22226 }
22227 self.write_space();
22228 self.write_keyword("JSON");
22229
22230 if let Some(ref json_type) = is_json.json_type {
22232 self.write_space();
22233 self.write_keyword(json_type);
22234 }
22235
22236 match &is_json.unique_keys {
22238 Some(JsonUniqueKeys::With) => {
22239 self.write_space();
22240 self.write_keyword("WITH UNIQUE KEYS");
22241 }
22242 Some(JsonUniqueKeys::Without) => {
22243 self.write_space();
22244 self.write_keyword("WITHOUT UNIQUE KEYS");
22245 }
22246 Some(JsonUniqueKeys::Shorthand) => {
22247 self.write_space();
22248 self.write_keyword("UNIQUE KEYS");
22249 }
22250 None => {}
22251 }
22252
22253 Ok(())
22254 }
22255
22256 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
22257 self.generate_expression(&is_expr.left)?;
22258 self.write_space();
22259 self.write_keyword("IS");
22260 self.write_space();
22261 self.generate_expression(&is_expr.right)
22262 }
22263
22264 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
22265 if exists.not {
22266 self.write_keyword("NOT");
22267 self.write_space();
22268 }
22269 self.write_keyword("EXISTS");
22270 self.write("(");
22271 let is_statement = matches!(
22272 &exists.this,
22273 Expression::Select(_)
22274 | Expression::Union(_)
22275 | Expression::Intersect(_)
22276 | Expression::Except(_)
22277 );
22278 if self.config.pretty && is_statement {
22279 self.write_newline();
22280 self.indent_level += 1;
22281 self.write_indent();
22282 self.generate_expression(&exists.this)?;
22283 self.write_newline();
22284 self.indent_level -= 1;
22285 self.write_indent();
22286 self.write(")");
22287 } else {
22288 self.generate_expression(&exists.this)?;
22289 self.write(")");
22290 }
22291 Ok(())
22292 }
22293
22294 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
22295 self.generate_expression(&op.left)?;
22296 self.write_space();
22297 self.write_keyword("MEMBER OF");
22298 self.write("(");
22299 self.generate_expression(&op.right)?;
22300 self.write(")");
22301 Ok(())
22302 }
22303
22304 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
22305 if subquery.lateral {
22306 self.write_keyword("LATERAL");
22307 self.write_space();
22308 }
22309
22310 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
22314 matches!(
22315 &p.this,
22316 Expression::Select(_)
22317 | Expression::Union(_)
22318 | Expression::Intersect(_)
22319 | Expression::Except(_)
22320 | Expression::Subquery(_)
22321 )
22322 } else {
22323 false
22324 };
22325
22326 let is_statement = matches!(
22328 &subquery.this,
22329 Expression::Select(_)
22330 | Expression::Union(_)
22331 | Expression::Intersect(_)
22332 | Expression::Except(_)
22333 | Expression::Merge(_)
22334 );
22335
22336 if !skip_outer_parens {
22337 self.write("(");
22338 if self.config.pretty && is_statement {
22339 self.write_newline();
22340 self.indent_level += 1;
22341 self.write_indent();
22342 }
22343 }
22344 self.generate_expression(&subquery.this)?;
22345
22346 if subquery.modifiers_inside {
22348 if let Some(order_by) = &subquery.order_by {
22350 self.write_space();
22351 self.write_keyword("ORDER BY");
22352 self.write_space();
22353 for (i, ord) in order_by.expressions.iter().enumerate() {
22354 if i > 0 {
22355 self.write(", ");
22356 }
22357 self.generate_ordered(ord)?;
22358 }
22359 }
22360
22361 if let Some(limit) = &subquery.limit {
22362 self.write_space();
22363 self.write_keyword("LIMIT");
22364 self.write_space();
22365 self.generate_expression(&limit.this)?;
22366 if limit.percent {
22367 self.write_space();
22368 self.write_keyword("PERCENT");
22369 }
22370 }
22371
22372 if let Some(offset) = &subquery.offset {
22373 self.write_space();
22374 self.write_keyword("OFFSET");
22375 self.write_space();
22376 self.generate_expression(&offset.this)?;
22377 }
22378 }
22379
22380 if !skip_outer_parens {
22381 if self.config.pretty && is_statement {
22382 self.write_newline();
22383 self.indent_level -= 1;
22384 self.write_indent();
22385 }
22386 self.write(")");
22387 }
22388
22389 if !subquery.modifiers_inside {
22391 if let Some(order_by) = &subquery.order_by {
22392 self.write_space();
22393 self.write_keyword("ORDER BY");
22394 self.write_space();
22395 for (i, ord) in order_by.expressions.iter().enumerate() {
22396 if i > 0 {
22397 self.write(", ");
22398 }
22399 self.generate_ordered(ord)?;
22400 }
22401 }
22402
22403 if let Some(limit) = &subquery.limit {
22404 self.write_space();
22405 self.write_keyword("LIMIT");
22406 self.write_space();
22407 self.generate_expression(&limit.this)?;
22408 if limit.percent {
22409 self.write_space();
22410 self.write_keyword("PERCENT");
22411 }
22412 }
22413
22414 if let Some(offset) = &subquery.offset {
22415 self.write_space();
22416 self.write_keyword("OFFSET");
22417 self.write_space();
22418 self.generate_expression(&offset.this)?;
22419 }
22420
22421 if let Some(distribute_by) = &subquery.distribute_by {
22423 self.write_space();
22424 self.write_keyword("DISTRIBUTE BY");
22425 self.write_space();
22426 for (i, expr) in distribute_by.expressions.iter().enumerate() {
22427 if i > 0 {
22428 self.write(", ");
22429 }
22430 self.generate_expression(expr)?;
22431 }
22432 }
22433
22434 if let Some(sort_by) = &subquery.sort_by {
22436 self.write_space();
22437 self.write_keyword("SORT BY");
22438 self.write_space();
22439 for (i, ord) in sort_by.expressions.iter().enumerate() {
22440 if i > 0 {
22441 self.write(", ");
22442 }
22443 self.generate_ordered(ord)?;
22444 }
22445 }
22446
22447 if let Some(cluster_by) = &subquery.cluster_by {
22449 self.write_space();
22450 self.write_keyword("CLUSTER BY");
22451 self.write_space();
22452 for (i, ord) in cluster_by.expressions.iter().enumerate() {
22453 if i > 0 {
22454 self.write(", ");
22455 }
22456 self.generate_ordered(ord)?;
22457 }
22458 }
22459 }
22460
22461 if let Some(alias) = &subquery.alias {
22462 self.write_space();
22463 let skip_as = matches!(
22465 self.config.dialect,
22466 Some(crate::dialects::DialectType::Oracle)
22467 );
22468 if !skip_as {
22469 self.write_keyword("AS");
22470 self.write_space();
22471 }
22472 self.generate_identifier(alias)?;
22473 if !subquery.column_aliases.is_empty() {
22474 self.write("(");
22475 for (i, col) in subquery.column_aliases.iter().enumerate() {
22476 if i > 0 {
22477 self.write(", ");
22478 }
22479 self.generate_identifier(col)?;
22480 }
22481 self.write(")");
22482 }
22483 }
22484 for comment in &subquery.trailing_comments {
22486 self.write(" ");
22487 self.write_formatted_comment(comment);
22488 }
22489 Ok(())
22490 }
22491
22492 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
22493 if let Some(ref with) = pivot.with {
22495 self.generate_with(with)?;
22496 self.write_space();
22497 }
22498
22499 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
22500
22501 let is_redshift_unpivot = pivot.unpivot
22505 && pivot.expressions.is_empty()
22506 && pivot.fields.is_empty()
22507 && pivot.using.is_empty()
22508 && pivot.into.is_none()
22509 && !matches!(&pivot.this, Expression::Null(_));
22510
22511 if is_redshift_unpivot {
22512 self.write_keyword("UNPIVOT");
22514 self.write_space();
22515 self.generate_expression(&pivot.this)?;
22516 if let Some(alias) = &pivot.alias {
22518 self.write_space();
22519 self.write_keyword("AS");
22520 self.write_space();
22521 self.write(&alias.name);
22523 }
22524 return Ok(());
22525 }
22526
22527 let is_simplified = !pivot.using.is_empty()
22529 || pivot.into.is_some()
22530 || (pivot.fields.is_empty()
22531 && !pivot.expressions.is_empty()
22532 && !matches!(&pivot.this, Expression::Null(_)));
22533
22534 if is_simplified {
22535 self.write_keyword(direction);
22539 self.write_space();
22540 self.generate_expression(&pivot.this)?;
22541
22542 if !pivot.expressions.is_empty() {
22543 self.write_space();
22544 self.write_keyword("ON");
22545 self.write_space();
22546 for (i, expr) in pivot.expressions.iter().enumerate() {
22547 if i > 0 {
22548 self.write(", ");
22549 }
22550 self.generate_expression(expr)?;
22551 }
22552 }
22553
22554 if let Some(into) = &pivot.into {
22556 self.write_space();
22557 self.write_keyword("INTO");
22558 self.write_space();
22559 self.generate_expression(into)?;
22560 }
22561
22562 if !pivot.using.is_empty() {
22564 self.write_space();
22565 self.write_keyword("USING");
22566 self.write_space();
22567 for (i, expr) in pivot.using.iter().enumerate() {
22568 if i > 0 {
22569 self.write(", ");
22570 }
22571 self.generate_expression(expr)?;
22572 }
22573 }
22574
22575 if let Some(group) = &pivot.group {
22577 self.write_space();
22578 self.generate_expression(group)?;
22579 }
22580 } else {
22581 if !matches!(&pivot.this, Expression::Null(_)) {
22586 self.generate_expression(&pivot.this)?;
22587 self.write_space();
22588 }
22589 self.write_keyword(direction);
22590 self.write("(");
22591
22592 for (i, expr) in pivot.expressions.iter().enumerate() {
22594 if i > 0 {
22595 self.write(", ");
22596 }
22597 self.generate_expression(expr)?;
22598 }
22599
22600 if !pivot.fields.is_empty() {
22602 if !pivot.expressions.is_empty() {
22603 self.write_space();
22604 }
22605 self.write_keyword("FOR");
22606 self.write_space();
22607 for (i, field) in pivot.fields.iter().enumerate() {
22608 if i > 0 {
22609 self.write_space();
22610 }
22611 self.generate_expression(field)?;
22613 }
22614 }
22615
22616 if let Some(default_val) = &pivot.default_on_null {
22618 self.write_space();
22619 self.write_keyword("DEFAULT ON NULL");
22620 self.write(" (");
22621 self.generate_expression(default_val)?;
22622 self.write(")");
22623 }
22624
22625 if let Some(group) = &pivot.group {
22627 self.write_space();
22628 self.generate_expression(group)?;
22629 }
22630
22631 self.write(")");
22632 }
22633
22634 if let Some(alias) = &pivot.alias {
22636 self.write_space();
22637 self.write_keyword("AS");
22638 self.write_space();
22639 self.generate_identifier(alias)?;
22640 }
22641
22642 Ok(())
22643 }
22644
22645 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
22646 self.generate_expression(&unpivot.this)?;
22647 self.write_space();
22648 self.write_keyword("UNPIVOT");
22649 if let Some(include) = unpivot.include_nulls {
22651 self.write_space();
22652 if include {
22653 self.write_keyword("INCLUDE NULLS");
22654 } else {
22655 self.write_keyword("EXCLUDE NULLS");
22656 }
22657 self.write_space();
22658 }
22659 self.write("(");
22660 if unpivot.value_column_parenthesized {
22661 self.write("(");
22662 }
22663 self.generate_identifier(&unpivot.value_column)?;
22664 for extra_col in &unpivot.extra_value_columns {
22666 self.write(", ");
22667 self.generate_identifier(extra_col)?;
22668 }
22669 if unpivot.value_column_parenthesized {
22670 self.write(")");
22671 }
22672 self.write_space();
22673 self.write_keyword("FOR");
22674 self.write_space();
22675 self.generate_identifier(&unpivot.name_column)?;
22676 self.write_space();
22677 self.write_keyword("IN");
22678 self.write(" (");
22679 for (i, col) in unpivot.columns.iter().enumerate() {
22680 if i > 0 {
22681 self.write(", ");
22682 }
22683 self.generate_expression(col)?;
22684 }
22685 self.write("))");
22686 if let Some(alias) = &unpivot.alias {
22687 self.write_space();
22688 self.write_keyword("AS");
22689 self.write_space();
22690 self.generate_identifier(alias)?;
22691 }
22692 Ok(())
22693 }
22694
22695 fn generate_values(&mut self, values: &Values) -> Result<()> {
22696 self.write_keyword("VALUES");
22697 for (i, row) in values.expressions.iter().enumerate() {
22698 if i > 0 {
22699 self.write(",");
22700 }
22701 self.write(" (");
22702 for (j, expr) in row.expressions.iter().enumerate() {
22703 if j > 0 {
22704 self.write(", ");
22705 }
22706 self.generate_expression(expr)?;
22707 }
22708 self.write(")");
22709 }
22710 if let Some(alias) = &values.alias {
22711 self.write_space();
22712 self.write_keyword("AS");
22713 self.write_space();
22714 self.generate_identifier(alias)?;
22715 if !values.column_aliases.is_empty() {
22716 self.write("(");
22717 for (i, col) in values.column_aliases.iter().enumerate() {
22718 if i > 0 {
22719 self.write(", ");
22720 }
22721 self.generate_identifier(col)?;
22722 }
22723 self.write(")");
22724 }
22725 }
22726 Ok(())
22727 }
22728
22729 fn generate_array(&mut self, arr: &Array) -> Result<()> {
22730 let needs_inheritance = matches!(
22732 self.config.dialect,
22733 Some(DialectType::DuckDB)
22734 | Some(DialectType::Spark)
22735 | Some(DialectType::Databricks)
22736 | Some(DialectType::Hive)
22737 | Some(DialectType::Snowflake)
22738 | Some(DialectType::Presto)
22739 | Some(DialectType::Trino)
22740 );
22741 let propagated: Vec<Expression>;
22742 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
22743 propagated = Self::inherit_struct_field_names(&arr.expressions);
22744 &propagated
22745 } else {
22746 &arr.expressions
22747 };
22748
22749 let use_parens =
22752 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22753 if !self.config.array_bracket_only {
22754 self.write_keyword("ARRAY");
22755 }
22756 if use_parens {
22757 self.write("(");
22758 } else {
22759 self.write("[");
22760 }
22761 for (i, expr) in expressions.iter().enumerate() {
22762 if i > 0 {
22763 self.write(", ");
22764 }
22765 self.generate_expression(expr)?;
22766 }
22767 if use_parens {
22768 self.write(")");
22769 } else {
22770 self.write("]");
22771 }
22772 Ok(())
22773 }
22774
22775 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
22776 if tuple.expressions.len() == 2 {
22779 if let Expression::TableAlias(_) = &tuple.expressions[1] {
22780 self.generate_expression(&tuple.expressions[0])?;
22782 self.write_space();
22783 self.write_keyword("AS");
22784 self.write_space();
22785 self.generate_expression(&tuple.expressions[1])?;
22786 return Ok(());
22787 }
22788 }
22789
22790 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
22793 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
22794 for expr in &tuple.expressions {
22795 expr_strings.push(self.generate_to_string(expr)?);
22796 }
22797 self.too_wide(&expr_strings)
22798 } else {
22799 false
22800 };
22801
22802 if expand_tuple {
22803 self.write("(");
22804 self.write_newline();
22805 self.indent_level += 1;
22806 for (i, expr) in tuple.expressions.iter().enumerate() {
22807 if i > 0 {
22808 self.write(",");
22809 self.write_newline();
22810 }
22811 self.write_indent();
22812 self.generate_expression(expr)?;
22813 }
22814 self.indent_level -= 1;
22815 self.write_newline();
22816 self.write_indent();
22817 self.write(")");
22818 } else {
22819 self.write("(");
22820 for (i, expr) in tuple.expressions.iter().enumerate() {
22821 if i > 0 {
22822 self.write(", ");
22823 }
22824 self.generate_expression(expr)?;
22825 }
22826 self.write(")");
22827 }
22828 Ok(())
22829 }
22830
22831 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
22832 self.generate_expression(&pipe.this)?;
22833 self.write(" |> ");
22834 self.generate_expression(&pipe.expression)?;
22835 Ok(())
22836 }
22837
22838 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
22839 self.generate_expression(&ordered.this)?;
22840 if ordered.desc {
22841 self.write_space();
22842 self.write_keyword("DESC");
22843 } else if ordered.explicit_asc {
22844 self.write_space();
22845 self.write_keyword("ASC");
22846 }
22847 if let Some(nulls_first) = ordered.nulls_first {
22848 if self.config.null_ordering_supported
22849 || !matches!(self.config.dialect, Some(DialectType::Fabric))
22850 {
22851 let is_asc = !ordered.desc;
22865 let is_nulls_are_large = matches!(
22866 self.config.dialect,
22867 Some(DialectType::Oracle)
22868 | Some(DialectType::PostgreSQL)
22869 | Some(DialectType::Redshift)
22870 | Some(DialectType::Snowflake)
22871 );
22872 let is_nulls_are_last = matches!(
22873 self.config.dialect,
22874 Some(DialectType::Dremio)
22875 | Some(DialectType::DuckDB)
22876 | Some(DialectType::Presto)
22877 | Some(DialectType::Trino)
22878 | Some(DialectType::Athena)
22879 | Some(DialectType::ClickHouse)
22880 | Some(DialectType::Drill)
22881 | Some(DialectType::Exasol)
22882 );
22883
22884 let is_default_nulls = if is_nulls_are_large {
22886 (is_asc && !nulls_first) || (!is_asc && nulls_first)
22888 } else if is_nulls_are_last {
22889 !nulls_first
22891 } else {
22892 false
22893 };
22894
22895 if !is_default_nulls {
22896 self.write_space();
22897 self.write_keyword("NULLS");
22898 self.write_space();
22899 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
22900 }
22901 }
22902 }
22903 if let Some(ref with_fill) = ordered.with_fill {
22905 self.write_space();
22906 self.generate_with_fill(with_fill)?;
22907 }
22908 Ok(())
22909 }
22910
22911 fn write_clickhouse_type(&mut self, type_str: &str) {
22913 if self.clickhouse_nullable_depth < 0 {
22914 self.write(type_str);
22916 } else {
22917 self.write(&format!("Nullable({})", type_str));
22918 }
22919 }
22920
22921 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
22922 use crate::dialects::DialectType;
22923
22924 match dt {
22925 DataType::Boolean => {
22926 match self.config.dialect {
22928 Some(DialectType::TSQL) => self.write_keyword("BIT"),
22929 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
22931 self.write_keyword("NUMBER(1)")
22933 }
22934 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
22936 }
22937 }
22938 DataType::TinyInt { length } => {
22939 match self.config.dialect {
22943 Some(DialectType::PostgreSQL)
22944 | Some(DialectType::Redshift)
22945 | Some(DialectType::Oracle)
22946 | Some(DialectType::Exasol) => {
22947 self.write_keyword("SMALLINT");
22948 }
22949 Some(DialectType::Teradata) => {
22950 self.write_keyword("BYTEINT");
22952 }
22953 Some(DialectType::Dremio) => {
22954 self.write_keyword("INT");
22956 }
22957 Some(DialectType::ClickHouse) => {
22958 self.write_clickhouse_type("Int8");
22959 }
22960 _ => {
22961 self.write_keyword("TINYINT");
22962 }
22963 }
22964 if let Some(n) = length {
22965 if !matches!(
22966 self.config.dialect,
22967 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
22968 ) {
22969 self.write(&format!("({})", n));
22970 }
22971 }
22972 }
22973 DataType::SmallInt { length } => {
22974 match self.config.dialect {
22976 Some(DialectType::Dremio) => {
22977 self.write_keyword("INT");
22978 }
22979 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
22980 self.write_keyword("INTEGER");
22981 }
22982 Some(DialectType::BigQuery) => {
22983 self.write_keyword("INT64");
22984 }
22985 Some(DialectType::ClickHouse) => {
22986 self.write_clickhouse_type("Int16");
22987 }
22988 _ => {
22989 self.write_keyword("SMALLINT");
22990 if let Some(n) = length {
22991 self.write(&format!("({})", n));
22992 }
22993 }
22994 }
22995 }
22996 DataType::Int {
22997 length,
22998 integer_spelling: _,
22999 } => {
23000 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
23002 self.write_keyword("INT64");
23003 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23004 self.write_clickhouse_type("Int32");
23005 } else {
23006 let use_integer = match self.config.dialect {
23008 Some(DialectType::TSQL)
23009 | Some(DialectType::Fabric)
23010 | Some(DialectType::Presto)
23011 | Some(DialectType::Trino)
23012 | Some(DialectType::SQLite)
23013 | Some(DialectType::Redshift) => true,
23014 _ => false,
23015 };
23016 if use_integer {
23017 self.write_keyword("INTEGER");
23018 } else {
23019 self.write_keyword("INT");
23020 }
23021 if let Some(n) = length {
23022 self.write(&format!("({})", n));
23023 }
23024 }
23025 }
23026 DataType::BigInt { length } => {
23027 match self.config.dialect {
23029 Some(DialectType::Oracle) => {
23030 self.write_keyword("INT");
23032 }
23033 Some(DialectType::ClickHouse) => {
23034 self.write_clickhouse_type("Int64");
23035 }
23036 _ => {
23037 self.write_keyword("BIGINT");
23038 if let Some(n) = length {
23039 self.write(&format!("({})", n));
23040 }
23041 }
23042 }
23043 }
23044 DataType::Float {
23045 precision,
23046 scale,
23047 real_spelling,
23048 } => {
23049 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23053 self.write_clickhouse_type("Float32");
23054 } else if *real_spelling
23055 && !matches!(
23056 self.config.dialect,
23057 Some(DialectType::Spark)
23058 | Some(DialectType::Databricks)
23059 | Some(DialectType::Hive)
23060 | Some(DialectType::Snowflake)
23061 | Some(DialectType::MySQL)
23062 | Some(DialectType::BigQuery)
23063 )
23064 {
23065 self.write_keyword("REAL")
23066 } else {
23067 match self.config.dialect {
23068 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
23069 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23070 _ => self.write_keyword("FLOAT"),
23071 }
23072 }
23073 if !matches!(
23076 self.config.dialect,
23077 Some(DialectType::Spark)
23078 | Some(DialectType::Databricks)
23079 | Some(DialectType::Hive)
23080 | Some(DialectType::Presto)
23081 | Some(DialectType::Trino)
23082 ) {
23083 if let Some(p) = precision {
23084 self.write(&format!("({}", p));
23085 if let Some(s) = scale {
23086 self.write(&format!(", {})", s));
23087 } else {
23088 self.write(")");
23089 }
23090 }
23091 }
23092 }
23093 DataType::Double { precision, scale } => {
23094 match self.config.dialect {
23096 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23097 self.write_keyword("FLOAT")
23098 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
23100 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
23101 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23102 Some(DialectType::SQLite) => self.write_keyword("REAL"),
23103 Some(DialectType::PostgreSQL)
23104 | Some(DialectType::Redshift)
23105 | Some(DialectType::Teradata)
23106 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
23107 _ => self.write_keyword("DOUBLE"),
23108 }
23109 if let Some(p) = precision {
23111 self.write(&format!("({}", p));
23112 if let Some(s) = scale {
23113 self.write(&format!(", {})", s));
23114 } else {
23115 self.write(")");
23116 }
23117 }
23118 }
23119 DataType::Decimal { precision, scale } => {
23120 match self.config.dialect {
23122 Some(DialectType::ClickHouse) => {
23123 self.write("Decimal");
23124 if let Some(p) = precision {
23125 self.write(&format!("({}", p));
23126 if let Some(s) = scale {
23127 self.write(&format!(", {}", s));
23128 }
23129 self.write(")");
23130 }
23131 }
23132 Some(DialectType::Oracle) => {
23133 self.write_keyword("NUMBER");
23135 if let Some(p) = precision {
23136 self.write(&format!("({}", p));
23137 if let Some(s) = scale {
23138 self.write(&format!(", {}", s));
23139 }
23140 self.write(")");
23141 }
23142 }
23143 Some(DialectType::BigQuery) => {
23144 self.write_keyword("NUMERIC");
23146 if let Some(p) = precision {
23147 self.write(&format!("({}", p));
23148 if let Some(s) = scale {
23149 self.write(&format!(", {}", s));
23150 }
23151 self.write(")");
23152 }
23153 }
23154 _ => {
23155 self.write_keyword("DECIMAL");
23156 if let Some(p) = precision {
23157 self.write(&format!("({}", p));
23158 if let Some(s) = scale {
23159 self.write(&format!(", {}", s));
23160 }
23161 self.write(")");
23162 }
23163 }
23164 }
23165 }
23166 DataType::Char { length } => {
23167 match self.config.dialect {
23169 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23170 self.write_keyword("TEXT");
23172 }
23173 Some(DialectType::Hive)
23174 | Some(DialectType::Spark)
23175 | Some(DialectType::Databricks) => {
23176 if length.is_some()
23179 && !matches!(self.config.dialect, Some(DialectType::Hive))
23180 {
23181 self.write_keyword("CHAR");
23182 if let Some(n) = length {
23183 self.write(&format!("({})", n));
23184 }
23185 } else {
23186 self.write_keyword("STRING");
23187 }
23188 }
23189 Some(DialectType::Dremio) => {
23190 self.write_keyword("VARCHAR");
23192 if let Some(n) = length {
23193 self.write(&format!("({})", n));
23194 }
23195 }
23196 _ => {
23197 self.write_keyword("CHAR");
23198 if let Some(n) = length {
23199 self.write(&format!("({})", n));
23200 }
23201 }
23202 }
23203 }
23204 DataType::VarChar {
23205 length,
23206 parenthesized_length,
23207 } => {
23208 match self.config.dialect {
23210 Some(DialectType::Oracle) => {
23211 self.write_keyword("VARCHAR2");
23212 if let Some(n) = length {
23213 self.write(&format!("({})", n));
23214 }
23215 }
23216 Some(DialectType::DuckDB) => {
23217 self.write_keyword("TEXT");
23219 if let Some(n) = length {
23220 self.write(&format!("({})", n));
23221 }
23222 }
23223 Some(DialectType::SQLite) => {
23224 self.write_keyword("TEXT");
23226 if let Some(n) = length {
23227 self.write(&format!("({})", n));
23228 }
23229 }
23230 Some(DialectType::MySQL) if length.is_none() => {
23231 self.write_keyword("TEXT");
23233 }
23234 Some(DialectType::Hive)
23235 | Some(DialectType::Spark)
23236 | Some(DialectType::Databricks)
23237 if length.is_none() =>
23238 {
23239 self.write_keyword("STRING");
23241 }
23242 _ => {
23243 self.write_keyword("VARCHAR");
23244 if let Some(n) = length {
23245 if *parenthesized_length {
23247 self.write(&format!("(({}))", n));
23248 } else {
23249 self.write(&format!("({})", n));
23250 }
23251 }
23252 }
23253 }
23254 }
23255 DataType::Text => {
23256 match self.config.dialect {
23258 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
23259 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23260 self.write_keyword("VARCHAR(MAX)")
23261 }
23262 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23263 Some(DialectType::Snowflake)
23264 | Some(DialectType::Dremio)
23265 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
23266 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
23267 Some(DialectType::Presto)
23268 | Some(DialectType::Trino)
23269 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23270 Some(DialectType::Spark)
23271 | Some(DialectType::Databricks)
23272 | Some(DialectType::Hive) => self.write_keyword("STRING"),
23273 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
23274 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23275 self.write_keyword("STRING")
23276 }
23277 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23278 _ => self.write_keyword("TEXT"),
23279 }
23280 }
23281 DataType::TextWithLength { length } => {
23282 match self.config.dialect {
23284 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
23285 Some(DialectType::Hive)
23286 | Some(DialectType::Spark)
23287 | Some(DialectType::Databricks) => {
23288 self.write(&format!("VARCHAR({})", length));
23289 }
23290 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
23291 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
23292 Some(DialectType::Snowflake)
23293 | Some(DialectType::Presto)
23294 | Some(DialectType::Trino)
23295 | Some(DialectType::Athena)
23296 | Some(DialectType::Drill)
23297 | Some(DialectType::Dremio) => {
23298 self.write(&format!("VARCHAR({})", length));
23299 }
23300 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23301 self.write(&format!("VARCHAR({})", length))
23302 }
23303 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23304 self.write(&format!("STRING({})", length))
23305 }
23306 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23307 _ => self.write(&format!("TEXT({})", length)),
23308 }
23309 }
23310 DataType::String { length } => {
23311 match self.config.dialect {
23313 Some(DialectType::ClickHouse) => {
23314 self.write("String");
23316 if let Some(n) = length {
23317 self.write(&format!("({})", n));
23318 }
23319 }
23320 Some(DialectType::BigQuery)
23321 | Some(DialectType::Hive)
23322 | Some(DialectType::Spark)
23323 | Some(DialectType::Databricks)
23324 | Some(DialectType::StarRocks)
23325 | Some(DialectType::Doris) => {
23326 self.write_keyword("STRING");
23327 if let Some(n) = length {
23328 self.write(&format!("({})", n));
23329 }
23330 }
23331 Some(DialectType::PostgreSQL) => {
23332 if let Some(n) = length {
23334 self.write_keyword("VARCHAR");
23335 self.write(&format!("({})", n));
23336 } else {
23337 self.write_keyword("TEXT");
23338 }
23339 }
23340 Some(DialectType::Redshift) => {
23341 if let Some(n) = length {
23343 self.write_keyword("VARCHAR");
23344 self.write(&format!("({})", n));
23345 } else {
23346 self.write_keyword("VARCHAR(MAX)");
23347 }
23348 }
23349 Some(DialectType::MySQL) => {
23350 if let Some(n) = length {
23352 self.write_keyword("VARCHAR");
23353 self.write(&format!("({})", n));
23354 } else {
23355 self.write_keyword("TEXT");
23356 }
23357 }
23358 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23359 if let Some(n) = length {
23361 self.write_keyword("VARCHAR");
23362 self.write(&format!("({})", n));
23363 } else {
23364 self.write_keyword("VARCHAR(MAX)");
23365 }
23366 }
23367 Some(DialectType::Oracle) => {
23368 self.write_keyword("CLOB");
23370 }
23371 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
23372 self.write_keyword("TEXT");
23374 if let Some(n) = length {
23375 self.write(&format!("({})", n));
23376 }
23377 }
23378 Some(DialectType::Presto)
23379 | Some(DialectType::Trino)
23380 | Some(DialectType::Drill)
23381 | Some(DialectType::Dremio) => {
23382 self.write_keyword("VARCHAR");
23384 if let Some(n) = length {
23385 self.write(&format!("({})", n));
23386 }
23387 }
23388 Some(DialectType::Snowflake) => {
23389 self.write_keyword("STRING");
23392 if let Some(n) = length {
23393 self.write(&format!("({})", n));
23394 }
23395 }
23396 _ => {
23397 self.write_keyword("STRING");
23399 if let Some(n) = length {
23400 self.write(&format!("({})", n));
23401 }
23402 }
23403 }
23404 }
23405 DataType::Binary { length } => {
23406 match self.config.dialect {
23408 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23409 self.write_keyword("BYTEA");
23410 if let Some(n) = length {
23411 self.write(&format!("({})", n));
23412 }
23413 }
23414 Some(DialectType::Redshift) => {
23415 self.write_keyword("VARBYTE");
23416 if let Some(n) = length {
23417 self.write(&format!("({})", n));
23418 }
23419 }
23420 Some(DialectType::DuckDB)
23421 | Some(DialectType::SQLite)
23422 | Some(DialectType::Oracle) => {
23423 self.write_keyword("BLOB");
23425 if let Some(n) = length {
23426 self.write(&format!("({})", n));
23427 }
23428 }
23429 Some(DialectType::Presto)
23430 | Some(DialectType::Trino)
23431 | Some(DialectType::Athena)
23432 | Some(DialectType::Drill)
23433 | Some(DialectType::Dremio) => {
23434 self.write_keyword("VARBINARY");
23436 if let Some(n) = length {
23437 self.write(&format!("({})", n));
23438 }
23439 }
23440 Some(DialectType::ClickHouse) => {
23441 if self.clickhouse_nullable_depth < 0 {
23443 self.write("BINARY");
23444 } else {
23445 self.write("Nullable(BINARY");
23446 }
23447 if let Some(n) = length {
23448 self.write(&format!("({})", n));
23449 }
23450 if self.clickhouse_nullable_depth >= 0 {
23451 self.write(")");
23452 }
23453 }
23454 _ => {
23455 self.write_keyword("BINARY");
23456 if let Some(n) = length {
23457 self.write(&format!("({})", n));
23458 }
23459 }
23460 }
23461 }
23462 DataType::VarBinary { length } => {
23463 match self.config.dialect {
23465 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23466 self.write_keyword("BYTEA");
23467 if let Some(n) = length {
23468 self.write(&format!("({})", n));
23469 }
23470 }
23471 Some(DialectType::Redshift) => {
23472 self.write_keyword("VARBYTE");
23473 if let Some(n) = length {
23474 self.write(&format!("({})", n));
23475 }
23476 }
23477 Some(DialectType::DuckDB)
23478 | Some(DialectType::SQLite)
23479 | Some(DialectType::Oracle) => {
23480 self.write_keyword("BLOB");
23482 if let Some(n) = length {
23483 self.write(&format!("({})", n));
23484 }
23485 }
23486 Some(DialectType::Exasol) => {
23487 self.write_keyword("VARCHAR");
23489 }
23490 Some(DialectType::Spark)
23491 | Some(DialectType::Hive)
23492 | Some(DialectType::Databricks) => {
23493 self.write_keyword("BINARY");
23495 if let Some(n) = length {
23496 self.write(&format!("({})", n));
23497 }
23498 }
23499 Some(DialectType::ClickHouse) => {
23500 self.write_clickhouse_type("String");
23502 }
23503 _ => {
23504 self.write_keyword("VARBINARY");
23505 if let Some(n) = length {
23506 self.write(&format!("({})", n));
23507 }
23508 }
23509 }
23510 }
23511 DataType::Blob => {
23512 match self.config.dialect {
23514 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
23515 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
23516 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23517 self.write_keyword("VARBINARY")
23518 }
23519 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23520 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
23521 Some(DialectType::Presto)
23522 | Some(DialectType::Trino)
23523 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23524 Some(DialectType::DuckDB) => {
23525 self.write_keyword("VARBINARY");
23528 }
23529 Some(DialectType::Spark)
23530 | Some(DialectType::Databricks)
23531 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
23532 Some(DialectType::ClickHouse) => {
23533 self.write("Nullable(String)");
23537 }
23538 _ => self.write_keyword("BLOB"),
23539 }
23540 }
23541 DataType::Bit { length } => {
23542 match self.config.dialect {
23544 Some(DialectType::Dremio)
23545 | Some(DialectType::Spark)
23546 | Some(DialectType::Databricks)
23547 | Some(DialectType::Hive)
23548 | Some(DialectType::Snowflake)
23549 | Some(DialectType::BigQuery)
23550 | Some(DialectType::Presto)
23551 | Some(DialectType::Trino)
23552 | Some(DialectType::ClickHouse)
23553 | Some(DialectType::Redshift) => {
23554 self.write_keyword("BOOLEAN");
23556 }
23557 _ => {
23558 self.write_keyword("BIT");
23559 if let Some(n) = length {
23560 self.write(&format!("({})", n));
23561 }
23562 }
23563 }
23564 }
23565 DataType::VarBit { length } => {
23566 self.write_keyword("VARBIT");
23567 if let Some(n) = length {
23568 self.write(&format!("({})", n));
23569 }
23570 }
23571 DataType::Date => self.write_keyword("DATE"),
23572 DataType::Time {
23573 precision,
23574 timezone,
23575 } => {
23576 if *timezone {
23577 match self.config.dialect {
23579 Some(DialectType::DuckDB) => {
23580 self.write_keyword("TIMETZ");
23582 }
23583 Some(DialectType::PostgreSQL) => {
23584 self.write_keyword("TIMETZ");
23586 if let Some(p) = precision {
23587 self.write(&format!("({})", p));
23588 }
23589 }
23590 _ => {
23591 self.write_keyword("TIME");
23593 if let Some(p) = precision {
23594 self.write(&format!("({})", p));
23595 }
23596 self.write_keyword(" WITH TIME ZONE");
23597 }
23598 }
23599 } else {
23600 if matches!(
23602 self.config.dialect,
23603 Some(DialectType::Spark)
23604 | Some(DialectType::Databricks)
23605 | Some(DialectType::Hive)
23606 ) {
23607 self.write_keyword("TIMESTAMP");
23608 } else {
23609 self.write_keyword("TIME");
23610 if let Some(p) = precision {
23611 self.write(&format!("({})", p));
23612 }
23613 }
23614 }
23615 }
23616 DataType::Timestamp {
23617 precision,
23618 timezone,
23619 } => {
23620 match self.config.dialect {
23622 Some(DialectType::ClickHouse) => {
23623 self.write("DateTime");
23624 if let Some(p) = precision {
23625 self.write(&format!("({})", p));
23626 }
23627 }
23628 Some(DialectType::TSQL) => {
23629 if *timezone {
23630 self.write_keyword("DATETIMEOFFSET");
23631 } else {
23632 self.write_keyword("DATETIME2");
23633 }
23634 if let Some(p) = precision {
23635 self.write(&format!("({})", p));
23636 }
23637 }
23638 Some(DialectType::MySQL) => {
23639 self.write_keyword("TIMESTAMP");
23641 if let Some(p) = precision {
23642 self.write(&format!("({})", p));
23643 }
23644 }
23645 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
23646 self.write_keyword("DATETIME");
23648 if let Some(p) = precision {
23649 self.write(&format!("({})", p));
23650 }
23651 }
23652 Some(DialectType::BigQuery) => {
23653 if *timezone {
23655 self.write_keyword("TIMESTAMP");
23656 } else {
23657 self.write_keyword("DATETIME");
23658 }
23659 }
23660 Some(DialectType::DuckDB) => {
23661 if *timezone {
23663 self.write_keyword("TIMESTAMPTZ");
23664 } else {
23665 self.write_keyword("TIMESTAMP");
23666 if let Some(p) = precision {
23667 self.write(&format!("({})", p));
23668 }
23669 }
23670 }
23671 _ => {
23672 if *timezone && !self.config.tz_to_with_time_zone {
23673 self.write_keyword("TIMESTAMPTZ");
23675 if let Some(p) = precision {
23676 self.write(&format!("({})", p));
23677 }
23678 } else {
23679 self.write_keyword("TIMESTAMP");
23680 if let Some(p) = precision {
23681 self.write(&format!("({})", p));
23682 }
23683 if *timezone {
23684 self.write_space();
23685 self.write_keyword("WITH TIME ZONE");
23686 }
23687 }
23688 }
23689 }
23690 }
23691 DataType::Interval { unit, to } => {
23692 self.write_keyword("INTERVAL");
23693 if let Some(u) = unit {
23694 self.write_space();
23695 self.write_keyword(u);
23696 }
23697 if let Some(t) = to {
23699 self.write_space();
23700 self.write_keyword("TO");
23701 self.write_space();
23702 self.write_keyword(t);
23703 }
23704 }
23705 DataType::Json => {
23706 match self.config.dialect {
23708 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
23711 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23712 _ => self.write_keyword("JSON"),
23713 }
23714 }
23715 DataType::JsonB => {
23716 match self.config.dialect {
23718 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
23719 Some(DialectType::Doris) => self.write_keyword("JSONB"),
23720 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23721 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23722 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
23725 }
23726 DataType::Uuid => {
23727 match self.config.dialect {
23729 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
23730 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
23731 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
23732 Some(DialectType::BigQuery)
23733 | Some(DialectType::Spark)
23734 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
23735 _ => self.write_keyword("UUID"),
23736 }
23737 }
23738 DataType::Array {
23739 element_type,
23740 dimension,
23741 } => {
23742 match self.config.dialect {
23744 Some(DialectType::PostgreSQL)
23745 | Some(DialectType::Redshift)
23746 | Some(DialectType::DuckDB) => {
23747 self.generate_data_type(element_type)?;
23749 if let Some(dim) = dimension {
23750 self.write(&format!("[{}]", dim));
23751 } else {
23752 self.write("[]");
23753 }
23754 }
23755 Some(DialectType::BigQuery) => {
23756 self.write_keyword("ARRAY<");
23757 self.generate_data_type(element_type)?;
23758 self.write(">");
23759 }
23760 Some(DialectType::Snowflake)
23761 | Some(DialectType::Presto)
23762 | Some(DialectType::Trino)
23763 | Some(DialectType::ClickHouse) => {
23764 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23766 self.write("Array(");
23767 } else {
23768 self.write_keyword("ARRAY(");
23769 }
23770 self.generate_data_type(element_type)?;
23771 self.write(")");
23772 }
23773 Some(DialectType::TSQL)
23774 | Some(DialectType::MySQL)
23775 | Some(DialectType::Oracle) => {
23776 match self.config.dialect {
23779 Some(DialectType::MySQL) => self.write_keyword("JSON"),
23780 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23781 _ => self.write_keyword("JSON"),
23782 }
23783 }
23784 _ => {
23785 self.write_keyword("ARRAY<");
23787 self.generate_data_type(element_type)?;
23788 self.write(">");
23789 }
23790 }
23791 }
23792 DataType::List { element_type } => {
23793 self.generate_data_type(element_type)?;
23795 self.write_keyword(" LIST");
23796 }
23797 DataType::Map {
23798 key_type,
23799 value_type,
23800 } => {
23801 match self.config.dialect {
23803 Some(DialectType::Materialize) => {
23804 self.write_keyword("MAP[");
23806 self.generate_data_type(key_type)?;
23807 self.write(" => ");
23808 self.generate_data_type(value_type)?;
23809 self.write("]");
23810 }
23811 Some(DialectType::Snowflake)
23812 | Some(DialectType::RisingWave)
23813 | Some(DialectType::DuckDB)
23814 | Some(DialectType::Presto)
23815 | Some(DialectType::Trino)
23816 | Some(DialectType::Athena) => {
23817 self.write_keyword("MAP(");
23818 self.generate_data_type(key_type)?;
23819 self.write(", ");
23820 self.generate_data_type(value_type)?;
23821 self.write(")");
23822 }
23823 Some(DialectType::ClickHouse) => {
23824 self.write("Map(");
23827 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
23829 self.clickhouse_nullable_depth = 0;
23830 self.write(", ");
23831 self.generate_data_type(value_type)?;
23832 self.write(")");
23833 }
23834 _ => {
23835 self.write_keyword("MAP<");
23836 self.generate_data_type(key_type)?;
23837 self.write(", ");
23838 self.generate_data_type(value_type)?;
23839 self.write(">");
23840 }
23841 }
23842 }
23843 DataType::Vector {
23844 element_type,
23845 dimension,
23846 } => {
23847 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
23848 self.write_keyword("VECTOR(");
23850 if let Some(dim) = dimension {
23851 self.write(&dim.to_string());
23852 }
23853 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
23855 DataType::TinyInt { .. } => Some("I8"),
23856 DataType::SmallInt { .. } => Some("I16"),
23857 DataType::Int { .. } => Some("I32"),
23858 DataType::BigInt { .. } => Some("I64"),
23859 DataType::Float { .. } => Some("F32"),
23860 DataType::Double { .. } => Some("F64"),
23861 _ => None,
23862 });
23863 if let Some(alias) = type_alias {
23864 if dimension.is_some() {
23865 self.write(", ");
23866 }
23867 self.write(alias);
23868 }
23869 self.write(")");
23870 } else {
23871 self.write_keyword("VECTOR(");
23873 if let Some(ref et) = element_type {
23874 self.generate_data_type(et)?;
23875 if dimension.is_some() {
23876 self.write(", ");
23877 }
23878 }
23879 if let Some(dim) = dimension {
23880 self.write(&dim.to_string());
23881 }
23882 self.write(")");
23883 }
23884 }
23885 DataType::Object { fields, modifier } => {
23886 self.write_keyword("OBJECT(");
23887 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
23888 if i > 0 {
23889 self.write(", ");
23890 }
23891 self.write(name);
23892 self.write(" ");
23893 self.generate_data_type(dt)?;
23894 if *not_null {
23895 self.write_keyword(" NOT NULL");
23896 }
23897 }
23898 self.write(")");
23899 if let Some(mod_str) = modifier {
23900 self.write(" ");
23901 self.write_keyword(mod_str);
23902 }
23903 }
23904 DataType::Struct { fields, nested } => {
23905 match self.config.dialect {
23907 Some(DialectType::Snowflake) => {
23908 self.write_keyword("OBJECT(");
23910 for (i, field) in fields.iter().enumerate() {
23911 if i > 0 {
23912 self.write(", ");
23913 }
23914 if !field.name.is_empty() {
23915 self.write(&field.name);
23916 self.write(" ");
23917 }
23918 self.generate_data_type(&field.data_type)?;
23919 }
23920 self.write(")");
23921 }
23922 Some(DialectType::Presto) | Some(DialectType::Trino) => {
23923 self.write_keyword("ROW(");
23925 for (i, field) in fields.iter().enumerate() {
23926 if i > 0 {
23927 self.write(", ");
23928 }
23929 if !field.name.is_empty() {
23930 self.write(&field.name);
23931 self.write(" ");
23932 }
23933 self.generate_data_type(&field.data_type)?;
23934 }
23935 self.write(")");
23936 }
23937 Some(DialectType::DuckDB) => {
23938 self.write_keyword("STRUCT(");
23940 for (i, field) in fields.iter().enumerate() {
23941 if i > 0 {
23942 self.write(", ");
23943 }
23944 if !field.name.is_empty() {
23945 self.write(&field.name);
23946 self.write(" ");
23947 }
23948 self.generate_data_type(&field.data_type)?;
23949 }
23950 self.write(")");
23951 }
23952 Some(DialectType::ClickHouse) => {
23953 self.write("Tuple(");
23955 for (i, field) in fields.iter().enumerate() {
23956 if i > 0 {
23957 self.write(", ");
23958 }
23959 if !field.name.is_empty() {
23960 self.write(&field.name);
23961 self.write(" ");
23962 }
23963 self.generate_data_type(&field.data_type)?;
23964 }
23965 self.write(")");
23966 }
23967 Some(DialectType::SingleStore) => {
23968 self.write_keyword("RECORD(");
23970 for (i, field) in fields.iter().enumerate() {
23971 if i > 0 {
23972 self.write(", ");
23973 }
23974 if !field.name.is_empty() {
23975 self.write(&field.name);
23976 self.write(" ");
23977 }
23978 self.generate_data_type(&field.data_type)?;
23979 }
23980 self.write(")");
23981 }
23982 _ => {
23983 let force_angle_brackets = matches!(
23985 self.config.dialect,
23986 Some(DialectType::Hive)
23987 | Some(DialectType::Spark)
23988 | Some(DialectType::Databricks)
23989 );
23990 if *nested && !force_angle_brackets {
23991 self.write_keyword("STRUCT(");
23992 for (i, field) in fields.iter().enumerate() {
23993 if i > 0 {
23994 self.write(", ");
23995 }
23996 if !field.name.is_empty() {
23997 self.write(&field.name);
23998 self.write(" ");
23999 }
24000 self.generate_data_type(&field.data_type)?;
24001 }
24002 self.write(")");
24003 } else {
24004 self.write_keyword("STRUCT<");
24005 for (i, field) in fields.iter().enumerate() {
24006 if i > 0 {
24007 self.write(", ");
24008 }
24009 if !field.name.is_empty() {
24010 self.write(&field.name);
24012 self.write(self.config.struct_field_sep);
24013 }
24014 self.generate_data_type(&field.data_type)?;
24016 if let Some(comment) = &field.comment {
24018 self.write(" COMMENT '");
24019 self.write(comment);
24020 self.write("'");
24021 }
24022 if !field.options.is_empty() {
24024 self.write(" ");
24025 self.generate_options_clause(&field.options)?;
24026 }
24027 }
24028 self.write(">");
24029 }
24030 }
24031 }
24032 }
24033 DataType::Enum {
24034 values,
24035 assignments,
24036 } => {
24037 if self.config.dialect == Some(DialectType::ClickHouse) {
24040 self.write("Enum(");
24041 } else {
24042 self.write_keyword("ENUM(");
24043 }
24044 for (i, val) in values.iter().enumerate() {
24045 if i > 0 {
24046 self.write(", ");
24047 }
24048 self.write("'");
24049 self.write(val);
24050 self.write("'");
24051 if let Some(Some(assignment)) = assignments.get(i) {
24052 self.write(" = ");
24053 self.write(assignment);
24054 }
24055 }
24056 self.write(")");
24057 }
24058 DataType::Set { values } => {
24059 self.write_keyword("SET(");
24061 for (i, val) in values.iter().enumerate() {
24062 if i > 0 {
24063 self.write(", ");
24064 }
24065 self.write("'");
24066 self.write(val);
24067 self.write("'");
24068 }
24069 self.write(")");
24070 }
24071 DataType::Union { fields } => {
24072 self.write_keyword("UNION(");
24074 for (i, (name, dt)) in fields.iter().enumerate() {
24075 if i > 0 {
24076 self.write(", ");
24077 }
24078 if !name.is_empty() {
24079 self.write(name);
24080 self.write(" ");
24081 }
24082 self.generate_data_type(dt)?;
24083 }
24084 self.write(")");
24085 }
24086 DataType::Nullable { inner } => {
24087 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24089 self.write("Nullable(");
24090 let saved_depth = self.clickhouse_nullable_depth;
24092 self.clickhouse_nullable_depth = -1;
24093 self.generate_data_type(inner)?;
24094 self.clickhouse_nullable_depth = saved_depth;
24095 self.write(")");
24096 } else {
24097 match inner.as_ref() {
24099 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
24100 self.generate_data_type(&DataType::Timestamp {
24101 precision: None,
24102 timezone: false,
24103 })?;
24104 }
24105 _ => {
24106 self.generate_data_type(inner)?;
24107 }
24108 }
24109 }
24110 }
24111 DataType::Custom { name } => {
24112 let name_upper = name.to_ascii_uppercase();
24114 match self.config.dialect {
24115 Some(DialectType::ClickHouse) => {
24116 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
24117 (name_upper[..idx].to_string(), &name[idx..])
24118 } else {
24119 (name_upper.clone(), "")
24120 };
24121 let mapped = match base_upper.as_str() {
24122 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
24123 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
24124 "DATETIME64" => "DateTime64",
24125 "DATE32" => "Date32",
24126 "INT" => "Int32",
24127 "MEDIUMINT" => "Int32",
24128 "INT8" => "Int8",
24129 "INT16" => "Int16",
24130 "INT32" => "Int32",
24131 "INT64" => "Int64",
24132 "INT128" => "Int128",
24133 "INT256" => "Int256",
24134 "UINT8" => "UInt8",
24135 "UINT16" => "UInt16",
24136 "UINT32" => "UInt32",
24137 "UINT64" => "UInt64",
24138 "UINT128" => "UInt128",
24139 "UINT256" => "UInt256",
24140 "FLOAT32" => "Float32",
24141 "FLOAT64" => "Float64",
24142 "DECIMAL32" => "Decimal32",
24143 "DECIMAL64" => "Decimal64",
24144 "DECIMAL128" => "Decimal128",
24145 "DECIMAL256" => "Decimal256",
24146 "ENUM" => "Enum",
24147 "ENUM8" => "Enum8",
24148 "ENUM16" => "Enum16",
24149 "FIXEDSTRING" => "FixedString",
24150 "NESTED" => "Nested",
24151 "LOWCARDINALITY" => "LowCardinality",
24152 "NULLABLE" => "Nullable",
24153 "IPV4" => "IPv4",
24154 "IPV6" => "IPv6",
24155 "POINT" => "Point",
24156 "RING" => "Ring",
24157 "LINESTRING" => "LineString",
24158 "MULTILINESTRING" => "MultiLineString",
24159 "POLYGON" => "Polygon",
24160 "MULTIPOLYGON" => "MultiPolygon",
24161 "AGGREGATEFUNCTION" => "AggregateFunction",
24162 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
24163 "DYNAMIC" => "Dynamic",
24164 _ => "",
24165 };
24166 if mapped.is_empty() {
24167 self.write(name);
24168 } else {
24169 self.write(mapped);
24170 self.write(suffix);
24171 }
24172 }
24173 Some(DialectType::MySQL)
24174 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
24175 {
24176 self.write_keyword("TIMESTAMP");
24178 }
24179 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
24180 self.write_keyword("SQL_VARIANT");
24181 }
24182 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
24183 self.write_keyword("DECIMAL(38, 5)");
24184 }
24185 Some(DialectType::Exasol) => {
24186 match name_upper.as_str() {
24188 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
24190 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
24192 "MEDIUMINT" => self.write_keyword("INT"),
24194 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
24196 self.write_keyword("DECIMAL")
24197 }
24198 "DATETIME" => self.write_keyword("TIMESTAMP"),
24200 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
24201 _ => self.write(name),
24202 }
24203 }
24204 Some(DialectType::Dremio) => {
24205 match name_upper.as_str() {
24207 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
24208 "ARRAY" => self.write_keyword("LIST"),
24209 "NCHAR" => self.write_keyword("VARCHAR"),
24210 _ => self.write(name),
24211 }
24212 }
24213 _ => {
24215 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
24217 (name_upper[..idx].to_string(), Some(&name[idx..]))
24218 } else {
24219 (name_upper.clone(), None)
24220 };
24221
24222 match base_upper.as_str() {
24223 "INT64"
24224 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24225 {
24226 self.write_keyword("BIGINT");
24227 }
24228 "FLOAT64"
24229 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24230 {
24231 self.write_keyword("DOUBLE");
24232 }
24233 "BOOL"
24234 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24235 {
24236 self.write_keyword("BOOLEAN");
24237 }
24238 "BYTES"
24239 if matches!(
24240 self.config.dialect,
24241 Some(DialectType::Spark)
24242 | Some(DialectType::Hive)
24243 | Some(DialectType::Databricks)
24244 ) =>
24245 {
24246 self.write_keyword("BINARY");
24247 }
24248 "BYTES"
24249 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24250 {
24251 self.write_keyword("VARBINARY");
24252 }
24253 "DATETIME2" | "SMALLDATETIME"
24255 if !matches!(
24256 self.config.dialect,
24257 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24258 ) =>
24259 {
24260 if matches!(
24262 self.config.dialect,
24263 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24264 ) {
24265 self.write_keyword("TIMESTAMP");
24266 if let Some(args) = _args_str {
24267 self.write(args);
24268 }
24269 } else {
24270 self.write_keyword("TIMESTAMP");
24271 }
24272 }
24273 "DATETIMEOFFSET"
24275 if !matches!(
24276 self.config.dialect,
24277 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24278 ) =>
24279 {
24280 if matches!(
24281 self.config.dialect,
24282 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24283 ) {
24284 self.write_keyword("TIMESTAMPTZ");
24285 if let Some(args) = _args_str {
24286 self.write(args);
24287 }
24288 } else {
24289 self.write_keyword("TIMESTAMPTZ");
24290 }
24291 }
24292 "UNIQUEIDENTIFIER"
24294 if !matches!(
24295 self.config.dialect,
24296 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24297 ) =>
24298 {
24299 match self.config.dialect {
24300 Some(DialectType::Spark)
24301 | Some(DialectType::Databricks)
24302 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24303 _ => self.write_keyword("UUID"),
24304 }
24305 }
24306 "BIT"
24308 if !matches!(
24309 self.config.dialect,
24310 Some(DialectType::TSQL)
24311 | Some(DialectType::Fabric)
24312 | Some(DialectType::PostgreSQL)
24313 | Some(DialectType::MySQL)
24314 | Some(DialectType::DuckDB)
24315 ) =>
24316 {
24317 self.write_keyword("BOOLEAN");
24318 }
24319 "NVARCHAR"
24321 if !matches!(
24322 self.config.dialect,
24323 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24324 ) =>
24325 {
24326 match self.config.dialect {
24327 Some(DialectType::Oracle) => {
24328 self.write_keyword("NVARCHAR2");
24330 if let Some(args) = _args_str {
24331 self.write(args);
24332 }
24333 }
24334 Some(DialectType::BigQuery) => {
24335 self.write_keyword("STRING");
24337 }
24338 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24339 self.write_keyword("TEXT");
24340 if let Some(args) = _args_str {
24341 self.write(args);
24342 }
24343 }
24344 Some(DialectType::Hive) => {
24345 self.write_keyword("STRING");
24347 }
24348 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24349 if _args_str.is_some() {
24350 self.write_keyword("VARCHAR");
24351 self.write(_args_str.unwrap());
24352 } else {
24353 self.write_keyword("STRING");
24354 }
24355 }
24356 _ => {
24357 self.write_keyword("VARCHAR");
24358 if let Some(args) = _args_str {
24359 self.write(args);
24360 }
24361 }
24362 }
24363 }
24364 "NCHAR"
24366 if !matches!(
24367 self.config.dialect,
24368 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24369 ) =>
24370 {
24371 match self.config.dialect {
24372 Some(DialectType::Oracle) => {
24373 self.write_keyword("NCHAR");
24375 if let Some(args) = _args_str {
24376 self.write(args);
24377 }
24378 }
24379 Some(DialectType::BigQuery) => {
24380 self.write_keyword("STRING");
24382 }
24383 Some(DialectType::Hive) => {
24384 self.write_keyword("STRING");
24386 }
24387 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24388 self.write_keyword("TEXT");
24389 if let Some(args) = _args_str {
24390 self.write(args);
24391 }
24392 }
24393 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24394 if _args_str.is_some() {
24395 self.write_keyword("CHAR");
24396 self.write(_args_str.unwrap());
24397 } else {
24398 self.write_keyword("STRING");
24399 }
24400 }
24401 _ => {
24402 self.write_keyword("CHAR");
24403 if let Some(args) = _args_str {
24404 self.write(args);
24405 }
24406 }
24407 }
24408 }
24409 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
24412 Some(DialectType::MySQL)
24413 | Some(DialectType::SingleStore)
24414 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24415 Some(DialectType::Spark)
24416 | Some(DialectType::Databricks)
24417 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
24418 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24419 Some(DialectType::Presto)
24420 | Some(DialectType::Trino)
24421 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24422 Some(DialectType::Snowflake)
24423 | Some(DialectType::Redshift)
24424 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
24425 _ => self.write_keyword("TEXT"),
24426 },
24427 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
24430 Some(DialectType::MySQL)
24431 | Some(DialectType::SingleStore)
24432 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24433 Some(DialectType::Spark)
24434 | Some(DialectType::Databricks)
24435 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
24436 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
24437 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24438 Some(DialectType::Presto)
24439 | Some(DialectType::Trino)
24440 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24441 Some(DialectType::Snowflake)
24442 | Some(DialectType::Redshift)
24443 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
24444 _ => self.write_keyword("BLOB"),
24445 },
24446 "LONGVARCHAR" => match self.config.dialect {
24448 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
24449 _ => self.write_keyword("VARCHAR"),
24450 },
24451 "DATETIME" => {
24453 match self.config.dialect {
24454 Some(DialectType::MySQL)
24455 | Some(DialectType::Doris)
24456 | Some(DialectType::StarRocks)
24457 | Some(DialectType::TSQL)
24458 | Some(DialectType::Fabric)
24459 | Some(DialectType::BigQuery)
24460 | Some(DialectType::SQLite)
24461 | Some(DialectType::Snowflake) => {
24462 self.write_keyword("DATETIME");
24463 if let Some(args) = _args_str {
24464 self.write(args);
24465 }
24466 }
24467 Some(_) => {
24468 self.write_keyword("TIMESTAMP");
24470 if let Some(args) = _args_str {
24471 self.write(args);
24472 }
24473 }
24474 None => {
24475 self.write(name);
24477 }
24478 }
24479 }
24480 "VARCHAR2"
24482 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24483 {
24484 match self.config.dialect {
24485 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24486 self.write_keyword("TEXT");
24487 }
24488 Some(DialectType::Hive)
24489 | Some(DialectType::Spark)
24490 | Some(DialectType::Databricks)
24491 | Some(DialectType::BigQuery)
24492 | Some(DialectType::ClickHouse)
24493 | Some(DialectType::StarRocks)
24494 | Some(DialectType::Doris) => {
24495 self.write_keyword("STRING");
24496 }
24497 _ => {
24498 self.write_keyword("VARCHAR");
24499 if let Some(args) = _args_str {
24500 self.write(args);
24501 }
24502 }
24503 }
24504 }
24505 "NVARCHAR2"
24506 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24507 {
24508 match self.config.dialect {
24509 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24510 self.write_keyword("TEXT");
24511 }
24512 Some(DialectType::Hive)
24513 | Some(DialectType::Spark)
24514 | Some(DialectType::Databricks)
24515 | Some(DialectType::BigQuery)
24516 | Some(DialectType::ClickHouse)
24517 | Some(DialectType::StarRocks)
24518 | Some(DialectType::Doris) => {
24519 self.write_keyword("STRING");
24520 }
24521 _ => {
24522 self.write_keyword("VARCHAR");
24523 if let Some(args) = _args_str {
24524 self.write(args);
24525 }
24526 }
24527 }
24528 }
24529 _ => self.write(name),
24530 }
24531 }
24532 }
24533 }
24534 DataType::Geometry { subtype, srid } => {
24535 match self.config.dialect {
24537 Some(DialectType::MySQL) => {
24538 if let Some(sub) = subtype {
24540 self.write_keyword(sub);
24541 if let Some(s) = srid {
24542 self.write(" SRID ");
24543 self.write(&s.to_string());
24544 }
24545 } else {
24546 self.write_keyword("GEOMETRY");
24547 }
24548 }
24549 Some(DialectType::BigQuery) => {
24550 self.write_keyword("GEOGRAPHY");
24552 }
24553 Some(DialectType::Teradata) => {
24554 self.write_keyword("ST_GEOMETRY");
24556 if subtype.is_some() || srid.is_some() {
24557 self.write("(");
24558 if let Some(sub) = subtype {
24559 self.write_keyword(sub);
24560 }
24561 if let Some(s) = srid {
24562 if subtype.is_some() {
24563 self.write(", ");
24564 }
24565 self.write(&s.to_string());
24566 }
24567 self.write(")");
24568 }
24569 }
24570 _ => {
24571 self.write_keyword("GEOMETRY");
24573 if subtype.is_some() || srid.is_some() {
24574 self.write("(");
24575 if let Some(sub) = subtype {
24576 self.write_keyword(sub);
24577 }
24578 if let Some(s) = srid {
24579 if subtype.is_some() {
24580 self.write(", ");
24581 }
24582 self.write(&s.to_string());
24583 }
24584 self.write(")");
24585 }
24586 }
24587 }
24588 }
24589 DataType::Geography { subtype, srid } => {
24590 match self.config.dialect {
24592 Some(DialectType::MySQL) => {
24593 if let Some(sub) = subtype {
24595 self.write_keyword(sub);
24596 } else {
24597 self.write_keyword("GEOMETRY");
24598 }
24599 let effective_srid = srid.unwrap_or(4326);
24601 self.write(" SRID ");
24602 self.write(&effective_srid.to_string());
24603 }
24604 Some(DialectType::BigQuery) => {
24605 self.write_keyword("GEOGRAPHY");
24607 }
24608 Some(DialectType::Snowflake) => {
24609 self.write_keyword("GEOGRAPHY");
24611 }
24612 _ => {
24613 self.write_keyword("GEOGRAPHY");
24615 if subtype.is_some() || srid.is_some() {
24616 self.write("(");
24617 if let Some(sub) = subtype {
24618 self.write_keyword(sub);
24619 }
24620 if let Some(s) = srid {
24621 if subtype.is_some() {
24622 self.write(", ");
24623 }
24624 self.write(&s.to_string());
24625 }
24626 self.write(")");
24627 }
24628 }
24629 }
24630 }
24631 DataType::CharacterSet { name } => {
24632 self.write_keyword("CHAR CHARACTER SET ");
24634 self.write(name);
24635 }
24636 _ => self.write("UNKNOWN"),
24637 }
24638 Ok(())
24639 }
24640
24641 #[inline]
24644 fn write(&mut self, s: &str) {
24645 self.output.push_str(s);
24646 }
24647
24648 #[inline]
24649 fn write_space(&mut self) {
24650 self.output.push(' ');
24651 }
24652
24653 #[inline]
24654 fn write_keyword(&mut self, keyword: &str) {
24655 if self.config.uppercase_keywords {
24656 self.output.push_str(keyword);
24657 } else {
24658 for b in keyword.bytes() {
24659 self.output.push(b.to_ascii_lowercase() as char);
24660 }
24661 }
24662 }
24663
24664 fn write_func_name(&mut self, name: &str) {
24666 let normalized = self.normalize_func_name(name);
24667 self.output.push_str(normalized.as_ref());
24668 }
24669
24670 fn convert_strptime_to_exasol_format(format: &str) -> String {
24674 let mut result = String::new();
24675 let chars: Vec<char> = format.chars().collect();
24676 let mut i = 0;
24677 while i < chars.len() {
24678 if chars[i] == '%' && i + 1 < chars.len() {
24679 let spec = chars[i + 1];
24680 let exasol_spec = match spec {
24681 'Y' => "YYYY",
24682 'y' => "YY",
24683 'm' => "MM",
24684 'd' => "DD",
24685 'H' => "HH",
24686 'M' => "MI",
24687 'S' => "SS",
24688 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
24700 result.push('%');
24702 result.push(spec);
24703 i += 2;
24704 continue;
24705 }
24706 };
24707 result.push_str(exasol_spec);
24708 i += 2;
24709 } else {
24710 result.push(chars[i]);
24711 i += 1;
24712 }
24713 }
24714 result
24715 }
24716
24717 fn convert_strptime_to_postgres_format(format: &str) -> String {
24721 let mut result = String::new();
24722 let chars: Vec<char> = format.chars().collect();
24723 let mut i = 0;
24724 while i < chars.len() {
24725 if chars[i] == '%' && i + 1 < chars.len() {
24726 if chars[i + 1] == '-' && i + 2 < chars.len() {
24728 let spec = chars[i + 2];
24729 let pg_spec = match spec {
24730 'd' => "FMDD",
24731 'm' => "FMMM",
24732 'H' => "FMHH24",
24733 'M' => "FMMI",
24734 'S' => "FMSS",
24735 _ => {
24736 result.push('%');
24737 result.push('-');
24738 result.push(spec);
24739 i += 3;
24740 continue;
24741 }
24742 };
24743 result.push_str(pg_spec);
24744 i += 3;
24745 continue;
24746 }
24747 let spec = chars[i + 1];
24748 let pg_spec = match spec {
24749 'Y' => "YYYY",
24750 'y' => "YY",
24751 'm' => "MM",
24752 'd' => "DD",
24753 'H' => "HH24",
24754 'I' => "HH12",
24755 'M' => "MI",
24756 'S' => "SS",
24757 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
24768 result.push('%');
24770 result.push(spec);
24771 i += 2;
24772 continue;
24773 }
24774 };
24775 result.push_str(pg_spec);
24776 i += 2;
24777 } else {
24778 result.push(chars[i]);
24779 i += 1;
24780 }
24781 }
24782 result
24783 }
24784
24785 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
24787 if self.config.limit_only_literals {
24788 if let Some(value) = Self::try_evaluate_constant(expr) {
24789 self.write(&value.to_string());
24790 return Ok(());
24791 }
24792 }
24793 self.generate_expression(expr)
24794 }
24795
24796 fn write_formatted_comment(&mut self, comment: &str) {
24800 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
24803 &comment[2..comment.len() - 2]
24806 } else if comment.starts_with("--") {
24807 &comment[2..]
24810 } else {
24811 comment
24813 };
24814 if content.trim().is_empty() {
24816 return;
24817 }
24818 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
24821 let content = &sanitized;
24822 self.output.push_str("/*");
24824 if !content.starts_with(' ') {
24825 self.output.push(' ');
24826 }
24827 self.output.push_str(content);
24828 if !content.ends_with(' ') {
24829 self.output.push(' ');
24830 }
24831 self.output.push_str("*/");
24832 }
24833
24834 fn escape_block_for_single_quote(&self, block: &str) -> String {
24837 let escape_backslash = matches!(
24838 self.config.dialect,
24839 Some(crate::dialects::DialectType::Snowflake)
24840 );
24841 let mut escaped = String::with_capacity(block.len() + 4);
24842 for ch in block.chars() {
24843 if ch == '\'' {
24844 escaped.push('\\');
24845 escaped.push('\'');
24846 } else if escape_backslash && ch == '\\' {
24847 escaped.push('\\');
24848 escaped.push('\\');
24849 } else {
24850 escaped.push(ch);
24851 }
24852 }
24853 escaped
24854 }
24855
24856 fn write_newline(&mut self) {
24857 self.output.push('\n');
24858 }
24859
24860 fn write_indent(&mut self) {
24861 for _ in 0..self.indent_level {
24862 self.output.push_str(self.config.indent);
24863 }
24864 }
24865
24866 fn too_wide(&self, args: &[String]) -> bool {
24872 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
24873 }
24874
24875 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
24878 let config = GeneratorConfig {
24879 pretty: false,
24880 dialect: self.config.dialect,
24881 ..Default::default()
24882 };
24883 let mut gen = Generator::with_config(config);
24884 gen.generate_expression(expr)?;
24885 Ok(gen.output)
24886 }
24887
24888 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
24891 if self.config.pretty {
24892 self.write_newline();
24893 self.write_indent();
24894 self.write_keyword(keyword);
24895 self.write_newline();
24896 self.indent_level += 1;
24897 self.write_indent();
24898 self.generate_expression(condition)?;
24899 self.indent_level -= 1;
24900 } else {
24901 self.write_space();
24902 self.write_keyword(keyword);
24903 self.write_space();
24904 self.generate_expression(condition)?;
24905 }
24906 Ok(())
24907 }
24908
24909 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
24912 if exprs.is_empty() {
24913 return Ok(());
24914 }
24915
24916 if self.config.pretty {
24917 self.write_newline();
24918 self.write_indent();
24919 self.write_keyword(keyword);
24920 self.write_newline();
24921 self.indent_level += 1;
24922 for (i, expr) in exprs.iter().enumerate() {
24923 if i > 0 {
24924 self.write(",");
24925 self.write_newline();
24926 }
24927 self.write_indent();
24928 self.generate_expression(expr)?;
24929 }
24930 self.indent_level -= 1;
24931 } else {
24932 self.write_space();
24933 self.write_keyword(keyword);
24934 self.write_space();
24935 for (i, expr) in exprs.iter().enumerate() {
24936 if i > 0 {
24937 self.write(", ");
24938 }
24939 self.generate_expression(expr)?;
24940 }
24941 }
24942 Ok(())
24943 }
24944
24945 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
24947 if orderings.is_empty() {
24948 return Ok(());
24949 }
24950
24951 if self.config.pretty {
24952 self.write_newline();
24953 self.write_indent();
24954 self.write_keyword(keyword);
24955 self.write_newline();
24956 self.indent_level += 1;
24957 for (i, ordered) in orderings.iter().enumerate() {
24958 if i > 0 {
24959 self.write(",");
24960 self.write_newline();
24961 }
24962 self.write_indent();
24963 self.generate_ordered(ordered)?;
24964 }
24965 self.indent_level -= 1;
24966 } else {
24967 self.write_space();
24968 self.write_keyword(keyword);
24969 self.write_space();
24970 for (i, ordered) in orderings.iter().enumerate() {
24971 if i > 0 {
24972 self.write(", ");
24973 }
24974 self.generate_ordered(ordered)?;
24975 }
24976 }
24977 Ok(())
24978 }
24979
24980 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
24982 if windows.is_empty() {
24983 return Ok(());
24984 }
24985
24986 if self.config.pretty {
24987 self.write_newline();
24988 self.write_indent();
24989 self.write_keyword("WINDOW");
24990 self.write_newline();
24991 self.indent_level += 1;
24992 for (i, named_window) in windows.iter().enumerate() {
24993 if i > 0 {
24994 self.write(",");
24995 self.write_newline();
24996 }
24997 self.write_indent();
24998 self.generate_identifier(&named_window.name)?;
24999 self.write_space();
25000 self.write_keyword("AS");
25001 self.write(" (");
25002 self.generate_over(&named_window.spec)?;
25003 self.write(")");
25004 }
25005 self.indent_level -= 1;
25006 } else {
25007 self.write_space();
25008 self.write_keyword("WINDOW");
25009 self.write_space();
25010 for (i, named_window) in windows.iter().enumerate() {
25011 if i > 0 {
25012 self.write(", ");
25013 }
25014 self.generate_identifier(&named_window.name)?;
25015 self.write_space();
25016 self.write_keyword("AS");
25017 self.write(" (");
25018 self.generate_over(&named_window.spec)?;
25019 self.write(")");
25020 }
25021 }
25022 Ok(())
25023 }
25024
25025 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
25027 self.write_keyword("AI_AGG");
25029 self.write("(");
25030 self.generate_expression(&e.this)?;
25031 self.write(", ");
25032 self.generate_expression(&e.expression)?;
25033 self.write(")");
25034 Ok(())
25035 }
25036
25037 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
25038 self.write_keyword("AI_CLASSIFY");
25040 self.write("(");
25041 self.generate_expression(&e.this)?;
25042 if let Some(categories) = &e.categories {
25043 self.write(", ");
25044 self.generate_expression(categories)?;
25045 }
25046 if let Some(config) = &e.config {
25047 self.write(", ");
25048 self.generate_expression(config)?;
25049 }
25050 self.write(")");
25051 Ok(())
25052 }
25053
25054 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
25055 self.write_keyword("ADD");
25057 self.write_space();
25058 if e.exists {
25059 self.write_keyword("IF NOT EXISTS");
25060 self.write_space();
25061 }
25062 self.generate_expression(&e.this)?;
25063 if let Some(location) = &e.location {
25064 self.write_space();
25065 self.generate_expression(location)?;
25066 }
25067 Ok(())
25068 }
25069
25070 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
25071 self.write_keyword("ALGORITHM");
25073 self.write("=");
25074 self.generate_expression(&e.this)?;
25075 Ok(())
25076 }
25077
25078 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
25079 self.generate_expression(&e.this)?;
25081 self.write_space();
25082 self.write_keyword("AS");
25083 self.write(" (");
25084 for (i, expr) in e.expressions.iter().enumerate() {
25085 if i > 0 {
25086 self.write(", ");
25087 }
25088 self.generate_expression(expr)?;
25089 }
25090 self.write(")");
25091 Ok(())
25092 }
25093
25094 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
25095 self.write_keyword("ALLOWED_VALUES");
25097 self.write_space();
25098 for (i, expr) in e.expressions.iter().enumerate() {
25099 if i > 0 {
25100 self.write(", ");
25101 }
25102 self.generate_expression(expr)?;
25103 }
25104 Ok(())
25105 }
25106
25107 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
25108 self.write_keyword("ALTER COLUMN");
25110 self.write_space();
25111 self.generate_expression(&e.this)?;
25112
25113 if let Some(dtype) = &e.dtype {
25114 self.write_space();
25115 self.write_keyword("SET DATA TYPE");
25116 self.write_space();
25117 self.generate_expression(dtype)?;
25118 if let Some(collate) = &e.collate {
25119 self.write_space();
25120 self.write_keyword("COLLATE");
25121 self.write_space();
25122 self.generate_expression(collate)?;
25123 }
25124 if let Some(using) = &e.using {
25125 self.write_space();
25126 self.write_keyword("USING");
25127 self.write_space();
25128 self.generate_expression(using)?;
25129 }
25130 } else if let Some(default) = &e.default {
25131 self.write_space();
25132 self.write_keyword("SET DEFAULT");
25133 self.write_space();
25134 self.generate_expression(default)?;
25135 } else if let Some(comment) = &e.comment {
25136 self.write_space();
25137 self.write_keyword("COMMENT");
25138 self.write_space();
25139 self.generate_expression(comment)?;
25140 } else if let Some(drop) = &e.drop {
25141 self.write_space();
25142 self.write_keyword("DROP");
25143 self.write_space();
25144 self.generate_expression(drop)?;
25145 } else if let Some(visible) = &e.visible {
25146 self.write_space();
25147 self.generate_expression(visible)?;
25148 } else if let Some(rename_to) = &e.rename_to {
25149 self.write_space();
25150 self.write_keyword("RENAME TO");
25151 self.write_space();
25152 self.generate_expression(rename_to)?;
25153 } else if let Some(allow_null) = &e.allow_null {
25154 self.write_space();
25155 self.generate_expression(allow_null)?;
25156 }
25157 Ok(())
25158 }
25159
25160 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
25161 self.write_keyword("ALTER SESSION");
25163 self.write_space();
25164 if e.unset.is_some() {
25165 self.write_keyword("UNSET");
25166 } else {
25167 self.write_keyword("SET");
25168 }
25169 self.write_space();
25170 for (i, expr) in e.expressions.iter().enumerate() {
25171 if i > 0 {
25172 self.write(", ");
25173 }
25174 self.generate_expression(expr)?;
25175 }
25176 Ok(())
25177 }
25178
25179 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
25180 self.write_keyword("SET");
25182
25183 if let Some(opt) = &e.option {
25185 self.write_space();
25186 self.generate_expression(opt)?;
25187 }
25188
25189 if !e.expressions.is_empty() {
25192 let is_properties = e
25194 .expressions
25195 .iter()
25196 .any(|expr| matches!(expr, Expression::Eq(_)));
25197 if is_properties && e.option.is_none() {
25198 self.write_space();
25199 self.write_keyword("PROPERTIES");
25200 }
25201 self.write_space();
25202 for (i, expr) in e.expressions.iter().enumerate() {
25203 if i > 0 {
25204 self.write(", ");
25205 }
25206 self.generate_expression(expr)?;
25207 }
25208 }
25209
25210 if let Some(file_format) = &e.file_format {
25212 self.write(" ");
25213 self.write_keyword("STAGE_FILE_FORMAT");
25214 self.write(" = (");
25215 self.generate_space_separated_properties(file_format)?;
25216 self.write(")");
25217 }
25218
25219 if let Some(copy_options) = &e.copy_options {
25221 self.write(" ");
25222 self.write_keyword("STAGE_COPY_OPTIONS");
25223 self.write(" = (");
25224 self.generate_space_separated_properties(copy_options)?;
25225 self.write(")");
25226 }
25227
25228 if let Some(tag) = &e.tag {
25230 self.write(" ");
25231 self.write_keyword("TAG");
25232 self.write(" ");
25233 self.generate_expression(tag)?;
25234 }
25235
25236 Ok(())
25237 }
25238
25239 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
25241 match expr {
25242 Expression::Tuple(t) => {
25243 for (i, prop) in t.expressions.iter().enumerate() {
25244 if i > 0 {
25245 self.write(" ");
25246 }
25247 self.generate_expression(prop)?;
25248 }
25249 }
25250 _ => {
25251 self.generate_expression(expr)?;
25252 }
25253 }
25254 Ok(())
25255 }
25256
25257 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
25258 self.write_keyword("ALTER");
25260 if e.compound.is_some() {
25261 self.write_space();
25262 self.write_keyword("COMPOUND");
25263 }
25264 self.write_space();
25265 self.write_keyword("SORTKEY");
25266 self.write_space();
25267 if let Some(this) = &e.this {
25268 self.generate_expression(this)?;
25269 } else if !e.expressions.is_empty() {
25270 self.write("(");
25271 for (i, expr) in e.expressions.iter().enumerate() {
25272 if i > 0 {
25273 self.write(", ");
25274 }
25275 self.generate_expression(expr)?;
25276 }
25277 self.write(")");
25278 }
25279 Ok(())
25280 }
25281
25282 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
25283 self.write_keyword("ANALYZE");
25285 if !e.options.is_empty() {
25286 self.write_space();
25287 for (i, opt) in e.options.iter().enumerate() {
25288 if i > 0 {
25289 self.write_space();
25290 }
25291 if let Expression::Identifier(id) = opt {
25293 self.write_keyword(&id.name);
25294 } else {
25295 self.generate_expression(opt)?;
25296 }
25297 }
25298 }
25299 if let Some(kind) = &e.kind {
25300 self.write_space();
25301 self.write_keyword(kind);
25302 }
25303 if let Some(this) = &e.this {
25304 self.write_space();
25305 self.generate_expression(this)?;
25306 }
25307 if !e.columns.is_empty() {
25309 self.write("(");
25310 for (i, col) in e.columns.iter().enumerate() {
25311 if i > 0 {
25312 self.write(", ");
25313 }
25314 self.write(col);
25315 }
25316 self.write(")");
25317 }
25318 if let Some(partition) = &e.partition {
25319 self.write_space();
25320 self.generate_expression(partition)?;
25321 }
25322 if let Some(mode) = &e.mode {
25323 self.write_space();
25324 self.generate_expression(mode)?;
25325 }
25326 if let Some(expression) = &e.expression {
25327 self.write_space();
25328 self.generate_expression(expression)?;
25329 }
25330 if !e.properties.is_empty() {
25331 self.write_space();
25332 self.write_keyword(self.config.with_properties_prefix);
25333 self.write(" (");
25334 for (i, prop) in e.properties.iter().enumerate() {
25335 if i > 0 {
25336 self.write(", ");
25337 }
25338 self.generate_expression(prop)?;
25339 }
25340 self.write(")");
25341 }
25342 Ok(())
25343 }
25344
25345 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
25346 self.write_keyword("DELETE");
25348 if let Some(kind) = &e.kind {
25349 self.write_space();
25350 self.write_keyword(kind);
25351 }
25352 self.write_space();
25353 self.write_keyword("STATISTICS");
25354 Ok(())
25355 }
25356
25357 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
25358 if let Expression::Identifier(id) = e.this.as_ref() {
25361 self.write_keyword(&id.name);
25362 } else {
25363 self.generate_expression(&e.this)?;
25364 }
25365 self.write_space();
25366 self.write_keyword("HISTOGRAM ON");
25367 self.write_space();
25368 for (i, expr) in e.expressions.iter().enumerate() {
25369 if i > 0 {
25370 self.write(", ");
25371 }
25372 self.generate_expression(expr)?;
25373 }
25374 if let Some(expression) = &e.expression {
25375 self.write_space();
25376 self.generate_expression(expression)?;
25377 }
25378 if let Some(update_options) = &e.update_options {
25379 self.write_space();
25380 self.generate_expression(update_options)?;
25381 self.write_space();
25382 self.write_keyword("UPDATE");
25383 }
25384 Ok(())
25385 }
25386
25387 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
25388 self.write_keyword("LIST CHAINED ROWS");
25390 if let Some(expression) = &e.expression {
25391 self.write_space();
25392 self.write_keyword("INTO");
25393 self.write_space();
25394 self.generate_expression(expression)?;
25395 }
25396 Ok(())
25397 }
25398
25399 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
25400 self.write_keyword("SAMPLE");
25402 self.write_space();
25403 if let Some(sample) = &e.sample {
25404 self.generate_expression(sample)?;
25405 self.write_space();
25406 }
25407 self.write_keyword(&e.kind);
25408 Ok(())
25409 }
25410
25411 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
25412 self.write_keyword(&e.kind);
25414 if let Some(option) = &e.option {
25415 self.write_space();
25416 self.generate_expression(option)?;
25417 }
25418 self.write_space();
25419 self.write_keyword("STATISTICS");
25420 if let Some(this) = &e.this {
25421 self.write_space();
25422 self.generate_expression(this)?;
25423 }
25424 if !e.expressions.is_empty() {
25425 self.write_space();
25426 for (i, expr) in e.expressions.iter().enumerate() {
25427 if i > 0 {
25428 self.write(", ");
25429 }
25430 self.generate_expression(expr)?;
25431 }
25432 }
25433 Ok(())
25434 }
25435
25436 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
25437 self.write_keyword("VALIDATE");
25439 self.write_space();
25440 self.write_keyword(&e.kind);
25441 if let Some(this) = &e.this {
25442 self.write_space();
25443 if let Expression::Identifier(id) = this.as_ref() {
25445 self.write_keyword(&id.name);
25446 } else {
25447 self.generate_expression(this)?;
25448 }
25449 }
25450 if let Some(expression) = &e.expression {
25451 self.write_space();
25452 self.write_keyword("INTO");
25453 self.write_space();
25454 self.generate_expression(expression)?;
25455 }
25456 Ok(())
25457 }
25458
25459 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
25460 self.write_keyword("WITH");
25462 self.write_space();
25463 for (i, expr) in e.expressions.iter().enumerate() {
25464 if i > 0 {
25465 self.write(", ");
25466 }
25467 self.generate_expression(expr)?;
25468 }
25469 Ok(())
25470 }
25471
25472 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
25473 self.generate_expression(&e.this)?;
25476 self.write("(");
25477 for (i, arg) in e.expressions.iter().enumerate() {
25478 if i > 0 {
25479 self.write(", ");
25480 }
25481 self.generate_expression(arg)?;
25482 }
25483 self.write(")");
25484 Ok(())
25485 }
25486
25487 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
25488 self.generate_expression(&e.this)?;
25490 self.write("(");
25491 for (i, arg) in e.expressions.iter().enumerate() {
25492 if i > 0 {
25493 self.write(", ");
25494 }
25495 self.generate_expression(arg)?;
25496 }
25497 self.write(")");
25498 Ok(())
25499 }
25500
25501 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
25502 self.generate_expression(&e.this)?;
25504 self.write_space();
25505 self.write_keyword("APPLY");
25506 self.write("(");
25507 self.generate_expression(&e.expression)?;
25508 self.write(")");
25509 Ok(())
25510 }
25511
25512 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
25513 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
25515 self.write("(");
25516 self.generate_expression(&e.this)?;
25517 if let Some(percentile) = &e.percentile {
25518 self.write(", ");
25519 self.generate_expression(percentile)?;
25520 }
25521 self.write(")");
25522 Ok(())
25523 }
25524
25525 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
25526 self.write_keyword("APPROX_QUANTILE");
25528 self.write("(");
25529 self.generate_expression(&e.this)?;
25530 if let Some(quantile) = &e.quantile {
25531 self.write(", ");
25532 self.generate_expression(quantile)?;
25533 }
25534 if let Some(accuracy) = &e.accuracy {
25535 self.write(", ");
25536 self.generate_expression(accuracy)?;
25537 }
25538 if let Some(weight) = &e.weight {
25539 self.write(", ");
25540 self.generate_expression(weight)?;
25541 }
25542 self.write(")");
25543 Ok(())
25544 }
25545
25546 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
25547 self.write_keyword("APPROX_QUANTILES");
25549 self.write("(");
25550 self.generate_expression(&e.this)?;
25551 if let Some(expression) = &e.expression {
25552 self.write(", ");
25553 self.generate_expression(expression)?;
25554 }
25555 self.write(")");
25556 Ok(())
25557 }
25558
25559 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
25560 self.write_keyword("APPROX_TOP_K");
25562 self.write("(");
25563 self.generate_expression(&e.this)?;
25564 if let Some(expression) = &e.expression {
25565 self.write(", ");
25566 self.generate_expression(expression)?;
25567 }
25568 if let Some(counters) = &e.counters {
25569 self.write(", ");
25570 self.generate_expression(counters)?;
25571 }
25572 self.write(")");
25573 Ok(())
25574 }
25575
25576 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
25577 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
25579 self.write("(");
25580 self.generate_expression(&e.this)?;
25581 if let Some(expression) = &e.expression {
25582 self.write(", ");
25583 self.generate_expression(expression)?;
25584 }
25585 self.write(")");
25586 Ok(())
25587 }
25588
25589 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
25590 self.write_keyword("APPROX_TOP_K_COMBINE");
25592 self.write("(");
25593 self.generate_expression(&e.this)?;
25594 if let Some(expression) = &e.expression {
25595 self.write(", ");
25596 self.generate_expression(expression)?;
25597 }
25598 self.write(")");
25599 Ok(())
25600 }
25601
25602 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
25603 self.write_keyword("APPROX_TOP_K_ESTIMATE");
25605 self.write("(");
25606 self.generate_expression(&e.this)?;
25607 if let Some(expression) = &e.expression {
25608 self.write(", ");
25609 self.generate_expression(expression)?;
25610 }
25611 self.write(")");
25612 Ok(())
25613 }
25614
25615 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
25616 self.write_keyword("APPROX_TOP_SUM");
25618 self.write("(");
25619 self.generate_expression(&e.this)?;
25620 self.write(", ");
25621 self.generate_expression(&e.expression)?;
25622 if let Some(count) = &e.count {
25623 self.write(", ");
25624 self.generate_expression(count)?;
25625 }
25626 self.write(")");
25627 Ok(())
25628 }
25629
25630 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
25631 self.write_keyword("ARG_MAX");
25633 self.write("(");
25634 self.generate_expression(&e.this)?;
25635 self.write(", ");
25636 self.generate_expression(&e.expression)?;
25637 if let Some(count) = &e.count {
25638 self.write(", ");
25639 self.generate_expression(count)?;
25640 }
25641 self.write(")");
25642 Ok(())
25643 }
25644
25645 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
25646 self.write_keyword("ARG_MIN");
25648 self.write("(");
25649 self.generate_expression(&e.this)?;
25650 self.write(", ");
25651 self.generate_expression(&e.expression)?;
25652 if let Some(count) = &e.count {
25653 self.write(", ");
25654 self.generate_expression(count)?;
25655 }
25656 self.write(")");
25657 Ok(())
25658 }
25659
25660 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
25661 self.write_keyword("ARRAY_ALL");
25663 self.write("(");
25664 self.generate_expression(&e.this)?;
25665 self.write(", ");
25666 self.generate_expression(&e.expression)?;
25667 self.write(")");
25668 Ok(())
25669 }
25670
25671 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
25672 self.write_keyword("ARRAY_ANY");
25674 self.write("(");
25675 self.generate_expression(&e.this)?;
25676 self.write(", ");
25677 self.generate_expression(&e.expression)?;
25678 self.write(")");
25679 Ok(())
25680 }
25681
25682 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
25683 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
25685 self.write("(");
25686 for (i, expr) in e.expressions.iter().enumerate() {
25687 if i > 0 {
25688 self.write(", ");
25689 }
25690 self.generate_expression(expr)?;
25691 }
25692 self.write(")");
25693 Ok(())
25694 }
25695
25696 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
25697 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25699 self.write("arraySum");
25700 } else {
25701 self.write_keyword("ARRAY_SUM");
25702 }
25703 self.write("(");
25704 self.generate_expression(&e.this)?;
25705 if let Some(expression) = &e.expression {
25706 self.write(", ");
25707 self.generate_expression(expression)?;
25708 }
25709 self.write(")");
25710 Ok(())
25711 }
25712
25713 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
25714 self.generate_expression(&e.this)?;
25716 self.write_space();
25717 self.write_keyword("AT");
25718 self.write_space();
25719 self.generate_expression(&e.expression)?;
25720 Ok(())
25721 }
25722
25723 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
25724 self.write_keyword("ATTACH");
25726 if e.exists {
25727 self.write_space();
25728 self.write_keyword("IF NOT EXISTS");
25729 }
25730 self.write_space();
25731 self.generate_expression(&e.this)?;
25732 if !e.expressions.is_empty() {
25733 self.write(" (");
25734 for (i, expr) in e.expressions.iter().enumerate() {
25735 if i > 0 {
25736 self.write(", ");
25737 }
25738 self.generate_expression(expr)?;
25739 }
25740 self.write(")");
25741 }
25742 Ok(())
25743 }
25744
25745 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
25746 self.generate_expression(&e.this)?;
25749 if let Some(expression) = &e.expression {
25750 self.write_space();
25751 self.generate_expression(expression)?;
25752 }
25753 Ok(())
25754 }
25755
25756 fn generate_auto_increment_keyword(
25760 &mut self,
25761 col: &crate::expressions::ColumnDef,
25762 ) -> Result<()> {
25763 use crate::dialects::DialectType;
25764 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
25765 self.write_keyword("IDENTITY");
25766 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25767 self.write("(");
25768 if let Some(ref start) = col.auto_increment_start {
25769 self.generate_expression(start)?;
25770 } else {
25771 self.write("0");
25772 }
25773 self.write(", ");
25774 if let Some(ref inc) = col.auto_increment_increment {
25775 self.generate_expression(inc)?;
25776 } else {
25777 self.write("1");
25778 }
25779 self.write(")");
25780 }
25781 } else if matches!(
25782 self.config.dialect,
25783 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
25784 ) {
25785 self.write_keyword("AUTOINCREMENT");
25786 if let Some(ref start) = col.auto_increment_start {
25787 self.write_space();
25788 self.write_keyword("START");
25789 self.write_space();
25790 self.generate_expression(start)?;
25791 }
25792 if let Some(ref inc) = col.auto_increment_increment {
25793 self.write_space();
25794 self.write_keyword("INCREMENT");
25795 self.write_space();
25796 self.generate_expression(inc)?;
25797 }
25798 if let Some(order) = col.auto_increment_order {
25799 self.write_space();
25800 if order {
25801 self.write_keyword("ORDER");
25802 } else {
25803 self.write_keyword("NOORDER");
25804 }
25805 }
25806 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
25807 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25808 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25809 self.write(" (");
25810 let mut first = true;
25811 if let Some(ref start) = col.auto_increment_start {
25812 self.write_keyword("START WITH");
25813 self.write_space();
25814 self.generate_expression(start)?;
25815 first = false;
25816 }
25817 if let Some(ref inc) = col.auto_increment_increment {
25818 if !first {
25819 self.write_space();
25820 }
25821 self.write_keyword("INCREMENT BY");
25822 self.write_space();
25823 self.generate_expression(inc)?;
25824 }
25825 self.write(")");
25826 }
25827 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
25828 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25831 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25832 } else {
25833 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
25834 }
25835 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25836 self.write(" (");
25837 let mut first = true;
25838 if let Some(ref start) = col.auto_increment_start {
25839 self.write_keyword("START WITH");
25840 self.write_space();
25841 self.generate_expression(start)?;
25842 first = false;
25843 }
25844 if let Some(ref inc) = col.auto_increment_increment {
25845 if !first {
25846 self.write_space();
25847 }
25848 self.write_keyword("INCREMENT BY");
25849 self.write_space();
25850 self.generate_expression(inc)?;
25851 }
25852 self.write(")");
25853 }
25854 } else if matches!(
25855 self.config.dialect,
25856 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25857 ) {
25858 self.write_keyword("IDENTITY");
25859 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25860 self.write("(");
25861 if let Some(ref start) = col.auto_increment_start {
25862 self.generate_expression(start)?;
25863 } else {
25864 self.write("0");
25865 }
25866 self.write(", ");
25867 if let Some(ref inc) = col.auto_increment_increment {
25868 self.generate_expression(inc)?;
25869 } else {
25870 self.write("1");
25871 }
25872 self.write(")");
25873 }
25874 } else {
25875 self.write_keyword("AUTO_INCREMENT");
25876 if let Some(ref start) = col.auto_increment_start {
25877 self.write_space();
25878 self.write_keyword("START");
25879 self.write_space();
25880 self.generate_expression(start)?;
25881 }
25882 if let Some(ref inc) = col.auto_increment_increment {
25883 self.write_space();
25884 self.write_keyword("INCREMENT");
25885 self.write_space();
25886 self.generate_expression(inc)?;
25887 }
25888 if let Some(order) = col.auto_increment_order {
25889 self.write_space();
25890 if order {
25891 self.write_keyword("ORDER");
25892 } else {
25893 self.write_keyword("NOORDER");
25894 }
25895 }
25896 }
25897 Ok(())
25898 }
25899
25900 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
25901 self.write_keyword("AUTO_INCREMENT");
25903 self.write("=");
25904 self.generate_expression(&e.this)?;
25905 Ok(())
25906 }
25907
25908 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
25909 self.write_keyword("AUTO_REFRESH");
25911 self.write("=");
25912 self.generate_expression(&e.this)?;
25913 Ok(())
25914 }
25915
25916 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
25917 self.write_keyword("BACKUP");
25919 self.write_space();
25920 self.generate_expression(&e.this)?;
25921 Ok(())
25922 }
25923
25924 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
25925 self.write_keyword("BASE64_DECODE_BINARY");
25927 self.write("(");
25928 self.generate_expression(&e.this)?;
25929 if let Some(alphabet) = &e.alphabet {
25930 self.write(", ");
25931 self.generate_expression(alphabet)?;
25932 }
25933 self.write(")");
25934 Ok(())
25935 }
25936
25937 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
25938 self.write_keyword("BASE64_DECODE_STRING");
25940 self.write("(");
25941 self.generate_expression(&e.this)?;
25942 if let Some(alphabet) = &e.alphabet {
25943 self.write(", ");
25944 self.generate_expression(alphabet)?;
25945 }
25946 self.write(")");
25947 Ok(())
25948 }
25949
25950 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
25951 self.write_keyword("BASE64_ENCODE");
25953 self.write("(");
25954 self.generate_expression(&e.this)?;
25955 if let Some(max_line_length) = &e.max_line_length {
25956 self.write(", ");
25957 self.generate_expression(max_line_length)?;
25958 }
25959 if let Some(alphabet) = &e.alphabet {
25960 self.write(", ");
25961 self.generate_expression(alphabet)?;
25962 }
25963 self.write(")");
25964 Ok(())
25965 }
25966
25967 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
25968 self.write_keyword("BLOCKCOMPRESSION");
25970 self.write("=");
25971 if let Some(autotemp) = &e.autotemp {
25972 self.write_keyword("AUTOTEMP");
25973 self.write("(");
25974 self.generate_expression(autotemp)?;
25975 self.write(")");
25976 }
25977 if let Some(always) = &e.always {
25978 self.generate_expression(always)?;
25979 }
25980 if let Some(default) = &e.default {
25981 self.generate_expression(default)?;
25982 }
25983 if let Some(manual) = &e.manual {
25984 self.generate_expression(manual)?;
25985 }
25986 if let Some(never) = &e.never {
25987 self.generate_expression(never)?;
25988 }
25989 Ok(())
25990 }
25991
25992 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
25993 self.write("((");
25995 self.generate_expression(&e.this)?;
25996 self.write(") ");
25997 self.write_keyword("AND");
25998 self.write(" (");
25999 self.generate_expression(&e.expression)?;
26000 self.write("))");
26001 Ok(())
26002 }
26003
26004 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
26005 self.write("((");
26007 self.generate_expression(&e.this)?;
26008 self.write(") ");
26009 self.write_keyword("OR");
26010 self.write(" (");
26011 self.generate_expression(&e.expression)?;
26012 self.write("))");
26013 Ok(())
26014 }
26015
26016 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
26017 self.write_keyword("BUILD");
26019 self.write_space();
26020 self.generate_expression(&e.this)?;
26021 Ok(())
26022 }
26023
26024 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
26025 self.generate_expression(&e.this)?;
26027 Ok(())
26028 }
26029
26030 fn generate_case_specific_column_constraint(
26031 &mut self,
26032 e: &CaseSpecificColumnConstraint,
26033 ) -> Result<()> {
26034 if e.not_.is_some() {
26036 self.write_keyword("NOT");
26037 self.write_space();
26038 }
26039 self.write_keyword("CASESPECIFIC");
26040 Ok(())
26041 }
26042
26043 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
26044 self.write_keyword("CAST");
26046 self.write("(");
26047 self.generate_expression(&e.this)?;
26048 if self.config.dialect == Some(DialectType::ClickHouse) {
26049 self.write(", ");
26051 } else {
26052 self.write_space();
26053 self.write_keyword("AS");
26054 self.write_space();
26055 }
26056 if let Some(to) = &e.to {
26057 self.generate_expression(to)?;
26058 }
26059 self.write(")");
26060 Ok(())
26061 }
26062
26063 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
26064 self.write_keyword("CHANGES");
26067 self.write(" (");
26068 if let Some(information) = &e.information {
26069 self.write_keyword("INFORMATION");
26070 self.write(" => ");
26071 self.generate_expression(information)?;
26072 }
26073 self.write(")");
26074 if let Some(at_before) = &e.at_before {
26076 self.write(" ");
26077 self.generate_expression(at_before)?;
26078 }
26079 if let Some(end) = &e.end {
26080 self.write(" ");
26081 self.generate_expression(end)?;
26082 }
26083 Ok(())
26084 }
26085
26086 fn generate_character_set_column_constraint(
26087 &mut self,
26088 e: &CharacterSetColumnConstraint,
26089 ) -> Result<()> {
26090 self.write_keyword("CHARACTER SET");
26092 self.write_space();
26093 self.generate_expression(&e.this)?;
26094 Ok(())
26095 }
26096
26097 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
26098 if e.default.is_some() {
26100 self.write_keyword("DEFAULT");
26101 self.write_space();
26102 }
26103 self.write_keyword("CHARACTER SET");
26104 self.write("=");
26105 self.generate_expression(&e.this)?;
26106 Ok(())
26107 }
26108
26109 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
26110 self.write_keyword("CHECK");
26112 self.write(" (");
26113 self.generate_expression(&e.this)?;
26114 self.write(")");
26115 if e.enforced.is_some() {
26116 self.write_space();
26117 self.write_keyword("ENFORCED");
26118 }
26119 Ok(())
26120 }
26121
26122 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
26123 self.write_keyword("ASSUME");
26125 self.write(" (");
26126 self.generate_expression(&e.this)?;
26127 self.write(")");
26128 Ok(())
26129 }
26130
26131 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
26132 self.write_keyword("CHECK_JSON");
26134 self.write("(");
26135 self.generate_expression(&e.this)?;
26136 self.write(")");
26137 Ok(())
26138 }
26139
26140 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
26141 self.write_keyword("CHECK_XML");
26143 self.write("(");
26144 self.generate_expression(&e.this)?;
26145 self.write(")");
26146 Ok(())
26147 }
26148
26149 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
26150 self.write_keyword("CHECKSUM");
26152 self.write("=");
26153 if e.on.is_some() {
26154 self.write_keyword("ON");
26155 } else if e.default.is_some() {
26156 self.write_keyword("DEFAULT");
26157 } else {
26158 self.write_keyword("OFF");
26159 }
26160 Ok(())
26161 }
26162
26163 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
26164 if e.shallow.is_some() {
26166 self.write_keyword("SHALLOW");
26167 self.write_space();
26168 }
26169 if e.copy.is_some() {
26170 self.write_keyword("COPY");
26171 } else {
26172 self.write_keyword("CLONE");
26173 }
26174 self.write_space();
26175 self.generate_expression(&e.this)?;
26176 Ok(())
26177 }
26178
26179 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
26180 self.write_keyword("CLUSTER BY");
26182 self.write(" (");
26183 for (i, ord) in e.expressions.iter().enumerate() {
26184 if i > 0 {
26185 self.write(", ");
26186 }
26187 self.generate_ordered(ord)?;
26188 }
26189 self.write(")");
26190 Ok(())
26191 }
26192
26193 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
26194 self.write_keyword("CLUSTER BY");
26196 self.write_space();
26197 for (i, col) in e.columns.iter().enumerate() {
26198 if i > 0 {
26199 self.write(", ");
26200 }
26201 self.generate_identifier(col)?;
26202 }
26203 Ok(())
26204 }
26205
26206 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
26207 self.write_keyword("CLUSTERED BY");
26209 self.write(" (");
26210 for (i, expr) in e.expressions.iter().enumerate() {
26211 if i > 0 {
26212 self.write(", ");
26213 }
26214 self.generate_expression(expr)?;
26215 }
26216 self.write(")");
26217 if let Some(sorted_by) = &e.sorted_by {
26218 self.write_space();
26219 self.write_keyword("SORTED BY");
26220 self.write(" (");
26221 if let Expression::Tuple(t) = sorted_by.as_ref() {
26223 for (i, expr) in t.expressions.iter().enumerate() {
26224 if i > 0 {
26225 self.write(", ");
26226 }
26227 self.generate_expression(expr)?;
26228 }
26229 } else {
26230 self.generate_expression(sorted_by)?;
26231 }
26232 self.write(")");
26233 }
26234 if let Some(buckets) = &e.buckets {
26235 self.write_space();
26236 self.write_keyword("INTO");
26237 self.write_space();
26238 self.generate_expression(buckets)?;
26239 self.write_space();
26240 self.write_keyword("BUCKETS");
26241 }
26242 Ok(())
26243 }
26244
26245 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
26246 if e.default.is_some() {
26250 self.write_keyword("DEFAULT");
26251 self.write_space();
26252 }
26253 self.write_keyword("COLLATE");
26254 match self.config.dialect {
26256 Some(DialectType::BigQuery) => self.write_space(),
26257 _ => self.write("="),
26258 }
26259 self.generate_expression(&e.this)?;
26260 Ok(())
26261 }
26262
26263 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
26264 match e {
26266 ColumnConstraint::NotNull => {
26267 self.write_keyword("NOT NULL");
26268 }
26269 ColumnConstraint::Null => {
26270 self.write_keyword("NULL");
26271 }
26272 ColumnConstraint::Unique => {
26273 self.write_keyword("UNIQUE");
26274 }
26275 ColumnConstraint::PrimaryKey => {
26276 self.write_keyword("PRIMARY KEY");
26277 }
26278 ColumnConstraint::Default(expr) => {
26279 self.write_keyword("DEFAULT");
26280 self.write_space();
26281 self.generate_expression(expr)?;
26282 }
26283 ColumnConstraint::Check(expr) => {
26284 self.write_keyword("CHECK");
26285 self.write(" (");
26286 self.generate_expression(expr)?;
26287 self.write(")");
26288 }
26289 ColumnConstraint::References(fk_ref) => {
26290 if fk_ref.has_foreign_key_keywords {
26291 self.write_keyword("FOREIGN KEY");
26292 self.write_space();
26293 }
26294 self.write_keyword("REFERENCES");
26295 self.write_space();
26296 self.generate_table(&fk_ref.table)?;
26297 if !fk_ref.columns.is_empty() {
26298 self.write(" (");
26299 for (i, col) in fk_ref.columns.iter().enumerate() {
26300 if i > 0 {
26301 self.write(", ");
26302 }
26303 self.generate_identifier(col)?;
26304 }
26305 self.write(")");
26306 }
26307 }
26308 ColumnConstraint::GeneratedAsIdentity(gen) => {
26309 self.write_keyword("GENERATED");
26310 self.write_space();
26311 if gen.always {
26312 self.write_keyword("ALWAYS");
26313 } else {
26314 self.write_keyword("BY DEFAULT");
26315 if gen.on_null {
26316 self.write_space();
26317 self.write_keyword("ON NULL");
26318 }
26319 }
26320 self.write_space();
26321 self.write_keyword("AS IDENTITY");
26322 }
26323 ColumnConstraint::Collate(collation) => {
26324 self.write_keyword("COLLATE");
26325 self.write_space();
26326 self.generate_identifier(collation)?;
26327 }
26328 ColumnConstraint::Comment(comment) => {
26329 self.write_keyword("COMMENT");
26330 self.write(" '");
26331 self.write(comment);
26332 self.write("'");
26333 }
26334 ColumnConstraint::ComputedColumn(cc) => {
26335 self.generate_computed_column_inline(cc)?;
26336 }
26337 ColumnConstraint::GeneratedAsRow(gar) => {
26338 self.generate_generated_as_row_inline(gar)?;
26339 }
26340 ColumnConstraint::Tags(tags) => {
26341 self.write_keyword("TAG");
26342 self.write(" (");
26343 for (i, expr) in tags.expressions.iter().enumerate() {
26344 if i > 0 {
26345 self.write(", ");
26346 }
26347 self.generate_expression(expr)?;
26348 }
26349 self.write(")");
26350 }
26351 ColumnConstraint::Path(path_expr) => {
26352 self.write_keyword("PATH");
26353 self.write_space();
26354 self.generate_expression(path_expr)?;
26355 }
26356 }
26357 Ok(())
26358 }
26359
26360 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
26361 match e {
26363 ColumnPosition::First => {
26364 self.write_keyword("FIRST");
26365 }
26366 ColumnPosition::After(ident) => {
26367 self.write_keyword("AFTER");
26368 self.write_space();
26369 self.generate_identifier(ident)?;
26370 }
26371 }
26372 Ok(())
26373 }
26374
26375 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
26376 self.generate_expression(&e.this)?;
26378 self.write("(");
26379 self.generate_expression(&e.expression)?;
26380 self.write(")");
26381 Ok(())
26382 }
26383
26384 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
26385 if let Some(ref unpack) = e.unpack {
26388 if let Expression::Boolean(b) = unpack.as_ref() {
26389 if b.value {
26390 self.write("*");
26391 }
26392 }
26393 }
26394 self.write_keyword("COLUMNS");
26395 self.write("(");
26396 self.generate_expression(&e.this)?;
26397 self.write(")");
26398 Ok(())
26399 }
26400
26401 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
26402 self.generate_expression(&e.this)?;
26404 self.write("(");
26405 for (i, expr) in e.expressions.iter().enumerate() {
26406 if i > 0 {
26407 self.write(", ");
26408 }
26409 self.generate_expression(expr)?;
26410 }
26411 self.write(")");
26412 Ok(())
26413 }
26414
26415 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
26416 self.generate_expression(&e.this)?;
26418 self.write("(");
26419 for (i, param) in e.params.iter().enumerate() {
26420 if i > 0 {
26421 self.write(", ");
26422 }
26423 self.generate_expression(param)?;
26424 }
26425 self.write(")(");
26426 for (i, expr) in e.expressions.iter().enumerate() {
26427 if i > 0 {
26428 self.write(", ");
26429 }
26430 self.generate_expression(expr)?;
26431 }
26432 self.write(")");
26433 Ok(())
26434 }
26435
26436 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
26437 self.write_keyword("COMMIT");
26439
26440 if e.this.is_none()
26442 && matches!(
26443 self.config.dialect,
26444 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26445 )
26446 {
26447 self.write_space();
26448 self.write_keyword("TRANSACTION");
26449 }
26450
26451 if let Some(this) = &e.this {
26453 let is_transaction_marker = matches!(
26455 this.as_ref(),
26456 Expression::Identifier(id) if id.name == "TRANSACTION"
26457 );
26458
26459 self.write_space();
26460 self.write_keyword("TRANSACTION");
26461
26462 if !is_transaction_marker {
26464 self.write_space();
26465 self.generate_expression(this)?;
26466 }
26467 }
26468
26469 if let Some(durability) = &e.durability {
26471 self.write_space();
26472 self.write_keyword("WITH");
26473 self.write(" (");
26474 self.write_keyword("DELAYED_DURABILITY");
26475 self.write(" = ");
26476 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
26477 self.write_keyword("ON");
26478 } else {
26479 self.write_keyword("OFF");
26480 }
26481 self.write(")");
26482 }
26483
26484 if let Some(chain) = &e.chain {
26486 self.write_space();
26487 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
26488 self.write_keyword("AND NO CHAIN");
26489 } else {
26490 self.write_keyword("AND CHAIN");
26491 }
26492 }
26493 Ok(())
26494 }
26495
26496 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
26497 self.write("[");
26499 self.generate_expression(&e.this)?;
26500 self.write_space();
26501 self.write_keyword("FOR");
26502 self.write_space();
26503 self.generate_expression(&e.expression)?;
26504 if let Some(pos) = &e.position {
26506 self.write(", ");
26507 self.generate_expression(pos)?;
26508 }
26509 if let Some(iterator) = &e.iterator {
26510 self.write_space();
26511 self.write_keyword("IN");
26512 self.write_space();
26513 self.generate_expression(iterator)?;
26514 }
26515 if let Some(condition) = &e.condition {
26516 self.write_space();
26517 self.write_keyword("IF");
26518 self.write_space();
26519 self.generate_expression(condition)?;
26520 }
26521 self.write("]");
26522 Ok(())
26523 }
26524
26525 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
26526 self.write_keyword("COMPRESS");
26528 self.write("(");
26529 self.generate_expression(&e.this)?;
26530 if let Some(method) = &e.method {
26531 self.write(", '");
26532 self.write(method);
26533 self.write("'");
26534 }
26535 self.write(")");
26536 Ok(())
26537 }
26538
26539 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
26540 self.write_keyword("COMPRESS");
26542 if let Some(this) = &e.this {
26543 self.write_space();
26544 self.generate_expression(this)?;
26545 }
26546 Ok(())
26547 }
26548
26549 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
26550 self.write_keyword("AS");
26552 self.write_space();
26553 self.generate_expression(&e.this)?;
26554 if e.not_null.is_some() {
26555 self.write_space();
26556 self.write_keyword("PERSISTED NOT NULL");
26557 } else if e.persisted.is_some() {
26558 self.write_space();
26559 self.write_keyword("PERSISTED");
26560 }
26561 Ok(())
26562 }
26563
26564 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
26568 let computed_expr = if matches!(
26569 self.config.dialect,
26570 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26571 ) {
26572 match &*cc.expression {
26573 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26574 {
26575 let wrapped = Expression::Cast(Box::new(Cast {
26576 this: y.this.clone(),
26577 to: DataType::Date,
26578 trailing_comments: Vec::new(),
26579 double_colon_syntax: false,
26580 format: None,
26581 default: None,
26582 inferred_type: None,
26583 }));
26584 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
26585 }
26586 Expression::Function(f)
26587 if f.name.eq_ignore_ascii_case("YEAR")
26588 && f.args.len() == 1
26589 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26590 {
26591 let wrapped = Expression::Cast(Box::new(Cast {
26592 this: f.args[0].clone(),
26593 to: DataType::Date,
26594 trailing_comments: Vec::new(),
26595 double_colon_syntax: false,
26596 format: None,
26597 default: None,
26598 inferred_type: None,
26599 }));
26600 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
26601 }
26602 _ => *cc.expression.clone(),
26603 }
26604 } else {
26605 *cc.expression.clone()
26606 };
26607
26608 match cc.persistence_kind.as_deref() {
26609 Some("STORED") | Some("VIRTUAL") => {
26610 self.write_keyword("GENERATED ALWAYS AS");
26612 self.write(" (");
26613 self.generate_expression(&computed_expr)?;
26614 self.write(")");
26615 self.write_space();
26616 if cc.persisted {
26617 self.write_keyword("STORED");
26618 } else {
26619 self.write_keyword("VIRTUAL");
26620 }
26621 }
26622 Some("PERSISTED") => {
26623 self.write_keyword("AS");
26625 self.write(" (");
26626 self.generate_expression(&computed_expr)?;
26627 self.write(")");
26628 self.write_space();
26629 self.write_keyword("PERSISTED");
26630 if let Some(ref dt) = cc.data_type {
26632 self.write_space();
26633 self.generate_data_type(dt)?;
26634 }
26635 if cc.not_null {
26636 self.write_space();
26637 self.write_keyword("NOT NULL");
26638 }
26639 }
26640 _ => {
26641 if matches!(
26644 self.config.dialect,
26645 Some(DialectType::Spark)
26646 | Some(DialectType::Databricks)
26647 | Some(DialectType::Hive)
26648 ) {
26649 self.write_keyword("GENERATED ALWAYS AS");
26650 self.write(" (");
26651 self.generate_expression(&computed_expr)?;
26652 self.write(")");
26653 } else if matches!(
26654 self.config.dialect,
26655 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26656 ) {
26657 self.write_keyword("AS");
26658 let omit_parens = matches!(computed_expr, Expression::Year(_))
26659 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
26660 if omit_parens {
26661 self.write_space();
26662 self.generate_expression(&computed_expr)?;
26663 } else {
26664 self.write(" (");
26665 self.generate_expression(&computed_expr)?;
26666 self.write(")");
26667 }
26668 } else {
26669 self.write_keyword("AS");
26670 self.write(" (");
26671 self.generate_expression(&computed_expr)?;
26672 self.write(")");
26673 }
26674 }
26675 }
26676 Ok(())
26677 }
26678
26679 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
26682 self.write_keyword("GENERATED ALWAYS AS ROW ");
26683 if gar.start {
26684 self.write_keyword("START");
26685 } else {
26686 self.write_keyword("END");
26687 }
26688 if gar.hidden {
26689 self.write_space();
26690 self.write_keyword("HIDDEN");
26691 }
26692 Ok(())
26693 }
26694
26695 fn generate_system_versioning_content(
26697 &mut self,
26698 e: &WithSystemVersioningProperty,
26699 ) -> Result<()> {
26700 let mut parts = Vec::new();
26701
26702 if let Some(this) = &e.this {
26703 let mut s = String::from("HISTORY_TABLE=");
26704 let mut gen = Generator::with_arc_config(self.config.clone());
26705 gen.generate_expression(this)?;
26706 s.push_str(&gen.output);
26707 parts.push(s);
26708 }
26709
26710 if let Some(data_consistency) = &e.data_consistency {
26711 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
26712 let mut gen = Generator::with_arc_config(self.config.clone());
26713 gen.generate_expression(data_consistency)?;
26714 s.push_str(&gen.output);
26715 parts.push(s);
26716 }
26717
26718 if let Some(retention_period) = &e.retention_period {
26719 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
26720 let mut gen = Generator::with_arc_config(self.config.clone());
26721 gen.generate_expression(retention_period)?;
26722 s.push_str(&gen.output);
26723 parts.push(s);
26724 }
26725
26726 self.write_keyword("SYSTEM_VERSIONING");
26727 self.write("=");
26728
26729 if !parts.is_empty() {
26730 self.write_keyword("ON");
26731 self.write("(");
26732 self.write(&parts.join(", "));
26733 self.write(")");
26734 } else if e.on.is_some() {
26735 self.write_keyword("ON");
26736 } else {
26737 self.write_keyword("OFF");
26738 }
26739
26740 Ok(())
26741 }
26742
26743 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
26744 if e.else_.is_some() {
26747 self.write_keyword("ELSE");
26748 self.write_space();
26749 } else if let Some(expression) = &e.expression {
26750 self.write_keyword("WHEN");
26751 self.write_space();
26752 self.generate_expression(expression)?;
26753 self.write_space();
26754 self.write_keyword("THEN");
26755 self.write_space();
26756 }
26757
26758 if let Expression::Insert(insert) = e.this.as_ref() {
26761 self.write_keyword("INTO");
26762 self.write_space();
26763 self.generate_table(&insert.table)?;
26764
26765 if !insert.columns.is_empty() {
26767 self.write(" (");
26768 for (i, col) in insert.columns.iter().enumerate() {
26769 if i > 0 {
26770 self.write(", ");
26771 }
26772 self.generate_identifier(col)?;
26773 }
26774 self.write(")");
26775 }
26776
26777 if !insert.values.is_empty() {
26779 self.write_space();
26780 self.write_keyword("VALUES");
26781 for (row_idx, row) in insert.values.iter().enumerate() {
26782 if row_idx > 0 {
26783 self.write(", ");
26784 }
26785 self.write(" (");
26786 for (i, val) in row.iter().enumerate() {
26787 if i > 0 {
26788 self.write(", ");
26789 }
26790 self.generate_expression(val)?;
26791 }
26792 self.write(")");
26793 }
26794 }
26795 } else {
26796 self.generate_expression(&e.this)?;
26798 }
26799 Ok(())
26800 }
26801
26802 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
26803 self.write_keyword("CONSTRAINT");
26805 self.write_space();
26806 self.generate_expression(&e.this)?;
26807 if !e.expressions.is_empty() {
26808 self.write_space();
26809 for (i, expr) in e.expressions.iter().enumerate() {
26810 if i > 0 {
26811 self.write_space();
26812 }
26813 self.generate_expression(expr)?;
26814 }
26815 }
26816 Ok(())
26817 }
26818
26819 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
26820 self.write_keyword("CONVERT_TIMEZONE");
26822 self.write("(");
26823 let mut first = true;
26824 if let Some(source_tz) = &e.source_tz {
26825 self.generate_expression(source_tz)?;
26826 first = false;
26827 }
26828 if let Some(target_tz) = &e.target_tz {
26829 if !first {
26830 self.write(", ");
26831 }
26832 self.generate_expression(target_tz)?;
26833 first = false;
26834 }
26835 if let Some(timestamp) = &e.timestamp {
26836 if !first {
26837 self.write(", ");
26838 }
26839 self.generate_expression(timestamp)?;
26840 }
26841 self.write(")");
26842 Ok(())
26843 }
26844
26845 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
26846 self.write_keyword("CONVERT");
26848 self.write("(");
26849 self.generate_expression(&e.this)?;
26850 if let Some(dest) = &e.dest {
26851 self.write_space();
26852 self.write_keyword("USING");
26853 self.write_space();
26854 self.generate_expression(dest)?;
26855 }
26856 self.write(")");
26857 Ok(())
26858 }
26859
26860 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
26861 self.write_keyword("COPY");
26862 if e.is_into {
26863 self.write_space();
26864 self.write_keyword("INTO");
26865 }
26866 self.write_space();
26867
26868 if let Expression::Literal(lit) = &e.this {
26870 if let Literal::String(s) = lit.as_ref() {
26871 if s.starts_with('@') {
26872 self.write(s);
26873 } else {
26874 self.generate_expression(&e.this)?;
26875 }
26876 }
26877 } else {
26878 self.generate_expression(&e.this)?;
26879 }
26880
26881 if e.kind {
26883 if self.config.pretty {
26885 self.write_newline();
26886 } else {
26887 self.write_space();
26888 }
26889 self.write_keyword("FROM");
26890 self.write_space();
26891 } else if !e.files.is_empty() {
26892 if self.config.pretty {
26894 self.write_newline();
26895 } else {
26896 self.write_space();
26897 }
26898 self.write_keyword("TO");
26899 self.write_space();
26900 }
26901
26902 for (i, file) in e.files.iter().enumerate() {
26904 if i > 0 {
26905 self.write_space();
26906 }
26907 if let Expression::Literal(lit) = file {
26909 if let Literal::String(s) = lit.as_ref() {
26910 if s.starts_with('@') {
26911 self.write(s);
26912 } else {
26913 self.generate_expression(file)?;
26914 }
26915 }
26916 } else if let Expression::Identifier(id) = file {
26917 if id.quoted {
26919 self.write("`");
26920 self.write(&id.name);
26921 self.write("`");
26922 } else {
26923 self.generate_expression(file)?;
26924 }
26925 } else {
26926 self.generate_expression(file)?;
26927 }
26928 }
26929
26930 if !e.with_wrapped {
26932 if let Some(ref creds) = e.credentials {
26933 if let Some(ref storage) = creds.storage {
26934 if self.config.pretty {
26935 self.write_newline();
26936 } else {
26937 self.write_space();
26938 }
26939 self.write_keyword("STORAGE_INTEGRATION");
26940 self.write(" = ");
26941 self.write(storage);
26942 }
26943 if creds.credentials.is_empty() {
26944 if self.config.pretty {
26946 self.write_newline();
26947 } else {
26948 self.write_space();
26949 }
26950 self.write_keyword("CREDENTIALS");
26951 self.write(" = ()");
26952 } else {
26953 if self.config.pretty {
26954 self.write_newline();
26955 } else {
26956 self.write_space();
26957 }
26958 self.write_keyword("CREDENTIALS");
26959 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
26962 self.write(" '");
26964 self.write(&creds.credentials[0].1);
26965 self.write("'");
26966 } else {
26967 self.write(" = (");
26969 for (i, (k, v)) in creds.credentials.iter().enumerate() {
26970 if i > 0 {
26971 self.write_space();
26972 }
26973 self.write(k);
26974 self.write("='");
26975 self.write(v);
26976 self.write("'");
26977 }
26978 self.write(")");
26979 }
26980 }
26981 if let Some(ref encryption) = creds.encryption {
26982 self.write_space();
26983 self.write_keyword("ENCRYPTION");
26984 self.write(" = ");
26985 self.write(encryption);
26986 }
26987 }
26988 }
26989
26990 if !e.params.is_empty() {
26992 if e.with_wrapped {
26993 self.write_space();
26995 self.write_keyword("WITH");
26996 self.write(" (");
26997 for (i, param) in e.params.iter().enumerate() {
26998 if i > 0 {
26999 self.write(", ");
27000 }
27001 self.generate_copy_param_with_format(param)?;
27002 }
27003 self.write(")");
27004 } else {
27005 for param in &e.params {
27009 if self.config.pretty {
27010 self.write_newline();
27011 } else {
27012 self.write_space();
27013 }
27014 self.write(¶m.name);
27016 if let Some(ref value) = param.value {
27017 if param.eq {
27019 self.write(" = ");
27020 } else {
27021 self.write(" ");
27022 }
27023 if !param.values.is_empty() {
27024 self.write("(");
27025 for (i, v) in param.values.iter().enumerate() {
27026 if i > 0 {
27027 self.write_space();
27028 }
27029 self.generate_copy_nested_param(v)?;
27030 }
27031 self.write(")");
27032 } else {
27033 self.generate_copy_param_value(value)?;
27035 }
27036 } else if !param.values.is_empty() {
27037 if param.eq {
27039 self.write(" = (");
27040 } else {
27041 self.write(" (");
27042 }
27043 let is_key_value_pairs = param
27048 .values
27049 .first()
27050 .map_or(false, |v| matches!(v, Expression::Eq(_)));
27051 let sep = if is_key_value_pairs && param.eq {
27052 " "
27053 } else {
27054 ", "
27055 };
27056 for (i, v) in param.values.iter().enumerate() {
27057 if i > 0 {
27058 self.write(sep);
27059 }
27060 self.generate_copy_nested_param(v)?;
27061 }
27062 self.write(")");
27063 }
27064 }
27065 }
27066 }
27067
27068 Ok(())
27069 }
27070
27071 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
27074 self.write_keyword(¶m.name);
27075 if !param.values.is_empty() {
27076 self.write(" = (");
27078 for (i, v) in param.values.iter().enumerate() {
27079 if i > 0 {
27080 self.write(", ");
27081 }
27082 self.generate_copy_nested_param(v)?;
27083 }
27084 self.write(")");
27085 } else if let Some(ref value) = param.value {
27086 if param.eq {
27087 self.write(" = ");
27088 } else {
27089 self.write(" ");
27090 }
27091 self.generate_expression(value)?;
27092 }
27093 Ok(())
27094 }
27095
27096 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
27098 match expr {
27099 Expression::Eq(eq) => {
27100 match &eq.left {
27102 Expression::Column(c) => self.write(&c.name.name),
27103 _ => self.generate_expression(&eq.left)?,
27104 }
27105 self.write("=");
27106 match &eq.right {
27108 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27109 let Literal::String(s) = lit.as_ref() else {
27110 unreachable!()
27111 };
27112 self.write("'");
27113 self.write(s);
27114 self.write("'");
27115 }
27116 Expression::Tuple(t) => {
27117 self.write("(");
27119 if self.config.pretty {
27120 self.write_newline();
27121 self.indent_level += 1;
27122 for (i, item) in t.expressions.iter().enumerate() {
27123 if i > 0 {
27124 self.write(", ");
27125 }
27126 self.write_indent();
27127 self.generate_expression(item)?;
27128 }
27129 self.write_newline();
27130 self.indent_level -= 1;
27131 } else {
27132 for (i, item) in t.expressions.iter().enumerate() {
27133 if i > 0 {
27134 self.write(", ");
27135 }
27136 self.generate_expression(item)?;
27137 }
27138 }
27139 self.write(")");
27140 }
27141 _ => self.generate_expression(&eq.right)?,
27142 }
27143 Ok(())
27144 }
27145 Expression::Column(c) => {
27146 self.write(&c.name.name);
27148 Ok(())
27149 }
27150 _ => self.generate_expression(expr),
27151 }
27152 }
27153
27154 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
27157 match expr {
27158 Expression::Column(c) => {
27159 if c.name.quoted {
27161 self.write("\"");
27162 self.write(&c.name.name);
27163 self.write("\"");
27164 } else {
27165 self.write(&c.name.name);
27166 }
27167 Ok(())
27168 }
27169 Expression::Identifier(id) => {
27170 if id.quoted {
27172 self.write("\"");
27173 self.write(&id.name);
27174 self.write("\"");
27175 } else {
27176 self.write(&id.name);
27177 }
27178 Ok(())
27179 }
27180 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27181 let Literal::String(s) = lit.as_ref() else {
27182 unreachable!()
27183 };
27184 self.write("'");
27186 self.write(s);
27187 self.write("'");
27188 Ok(())
27189 }
27190 _ => self.generate_expression(expr),
27191 }
27192 }
27193
27194 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
27195 self.write_keyword(&e.name);
27196 if let Some(ref value) = e.value {
27197 if e.eq {
27198 self.write(" = ");
27199 } else {
27200 self.write(" ");
27201 }
27202 self.generate_expression(value)?;
27203 }
27204 if !e.values.is_empty() {
27205 if e.eq {
27206 self.write(" = ");
27207 } else {
27208 self.write(" ");
27209 }
27210 self.write("(");
27211 for (i, v) in e.values.iter().enumerate() {
27212 if i > 0 {
27213 self.write(", ");
27214 }
27215 self.generate_expression(v)?;
27216 }
27217 self.write(")");
27218 }
27219 Ok(())
27220 }
27221
27222 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
27223 self.write_keyword("CORR");
27225 self.write("(");
27226 self.generate_expression(&e.this)?;
27227 self.write(", ");
27228 self.generate_expression(&e.expression)?;
27229 self.write(")");
27230 Ok(())
27231 }
27232
27233 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
27234 self.write_keyword("COSINE_DISTANCE");
27236 self.write("(");
27237 self.generate_expression(&e.this)?;
27238 self.write(", ");
27239 self.generate_expression(&e.expression)?;
27240 self.write(")");
27241 Ok(())
27242 }
27243
27244 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
27245 self.write_keyword("COVAR_POP");
27247 self.write("(");
27248 self.generate_expression(&e.this)?;
27249 self.write(", ");
27250 self.generate_expression(&e.expression)?;
27251 self.write(")");
27252 Ok(())
27253 }
27254
27255 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
27256 self.write_keyword("COVAR_SAMP");
27258 self.write("(");
27259 self.generate_expression(&e.this)?;
27260 self.write(", ");
27261 self.generate_expression(&e.expression)?;
27262 self.write(")");
27263 Ok(())
27264 }
27265
27266 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
27267 self.write_keyword("CREDENTIALS");
27269 self.write(" (");
27270 for (i, (key, value)) in e.credentials.iter().enumerate() {
27271 if i > 0 {
27272 self.write(", ");
27273 }
27274 self.write(key);
27275 self.write("='");
27276 self.write(value);
27277 self.write("'");
27278 }
27279 self.write(")");
27280 Ok(())
27281 }
27282
27283 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
27284 self.write_keyword("CREDENTIALS");
27286 self.write("=(");
27287 for (i, expr) in e.expressions.iter().enumerate() {
27288 if i > 0 {
27289 self.write(", ");
27290 }
27291 self.generate_expression(expr)?;
27292 }
27293 self.write(")");
27294 Ok(())
27295 }
27296
27297 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
27298 use crate::dialects::DialectType;
27299
27300 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
27303 self.generate_expression(&e.this)?;
27304 self.write_space();
27305 self.write_keyword("AS");
27306 self.write_space();
27307 self.generate_identifier(&e.alias)?;
27308 return Ok(());
27309 }
27310 self.write(&e.alias.name);
27311
27312 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
27314
27315 if !e.columns.is_empty() && !skip_cte_columns {
27316 self.write("(");
27317 for (i, col) in e.columns.iter().enumerate() {
27318 if i > 0 {
27319 self.write(", ");
27320 }
27321 self.write(&col.name);
27322 }
27323 self.write(")");
27324 }
27325 if !e.key_expressions.is_empty() {
27327 self.write_space();
27328 self.write_keyword("USING KEY");
27329 self.write(" (");
27330 for (i, key) in e.key_expressions.iter().enumerate() {
27331 if i > 0 {
27332 self.write(", ");
27333 }
27334 self.write(&key.name);
27335 }
27336 self.write(")");
27337 }
27338 self.write_space();
27339 self.write_keyword("AS");
27340 self.write_space();
27341 if let Some(materialized) = e.materialized {
27342 if materialized {
27343 self.write_keyword("MATERIALIZED");
27344 } else {
27345 self.write_keyword("NOT MATERIALIZED");
27346 }
27347 self.write_space();
27348 }
27349 self.write("(");
27350 self.generate_expression(&e.this)?;
27351 self.write(")");
27352 Ok(())
27353 }
27354
27355 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
27356 if e.expressions.is_empty() {
27358 self.write_keyword("WITH CUBE");
27359 } else {
27360 self.write_keyword("CUBE");
27361 self.write("(");
27362 for (i, expr) in e.expressions.iter().enumerate() {
27363 if i > 0 {
27364 self.write(", ");
27365 }
27366 self.generate_expression(expr)?;
27367 }
27368 self.write(")");
27369 }
27370 Ok(())
27371 }
27372
27373 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
27374 self.write_keyword("CURRENT_DATETIME");
27376 if let Some(this) = &e.this {
27377 self.write("(");
27378 self.generate_expression(this)?;
27379 self.write(")");
27380 }
27381 Ok(())
27382 }
27383
27384 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
27385 self.write_keyword("CURRENT_SCHEMA");
27387 Ok(())
27388 }
27389
27390 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
27391 self.write_keyword("CURRENT_SCHEMAS");
27393 self.write("(");
27394 if !matches!(
27396 self.config.dialect,
27397 Some(crate::dialects::DialectType::Snowflake)
27398 ) {
27399 if let Some(this) = &e.this {
27400 self.generate_expression(this)?;
27401 }
27402 }
27403 self.write(")");
27404 Ok(())
27405 }
27406
27407 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
27408 self.write_keyword("CURRENT_USER");
27410 let needs_parens = e.this.is_some()
27412 || matches!(
27413 self.config.dialect,
27414 Some(DialectType::Snowflake)
27415 | Some(DialectType::Spark)
27416 | Some(DialectType::Hive)
27417 | Some(DialectType::DuckDB)
27418 | Some(DialectType::BigQuery)
27419 | Some(DialectType::MySQL)
27420 | Some(DialectType::Databricks)
27421 );
27422 if needs_parens {
27423 self.write("()");
27424 }
27425 Ok(())
27426 }
27427
27428 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
27429 if self.config.dialect == Some(DialectType::Solr) {
27431 self.generate_expression(&e.this)?;
27432 self.write(" ");
27433 self.write_keyword("OR");
27434 self.write(" ");
27435 self.generate_expression(&e.expression)?;
27436 } else if self.config.dialect == Some(DialectType::MySQL) {
27437 self.generate_mysql_concat_from_dpipe(e)?;
27438 } else {
27439 self.generate_expression(&e.this)?;
27441 self.write(" || ");
27442 self.generate_expression(&e.expression)?;
27443 }
27444 Ok(())
27445 }
27446
27447 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
27448 self.write_keyword("DATABLOCKSIZE");
27450 self.write("=");
27451 if let Some(size) = e.size {
27452 self.write(&size.to_string());
27453 if let Some(units) = &e.units {
27454 self.write_space();
27455 self.generate_expression(units)?;
27456 }
27457 } else if e.minimum.is_some() {
27458 self.write_keyword("MINIMUM");
27459 } else if e.maximum.is_some() {
27460 self.write_keyword("MAXIMUM");
27461 } else if e.default.is_some() {
27462 self.write_keyword("DEFAULT");
27463 }
27464 Ok(())
27465 }
27466
27467 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
27468 self.write_keyword("DATA_DELETION");
27470 self.write("=");
27471
27472 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
27473 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
27474
27475 if is_on {
27476 self.write_keyword("ON");
27477 if has_options {
27478 self.write("(");
27479 let mut first = true;
27480 if let Some(filter_column) = &e.filter_column {
27481 self.write_keyword("FILTER_COLUMN");
27482 self.write("=");
27483 self.generate_expression(filter_column)?;
27484 first = false;
27485 }
27486 if let Some(retention_period) = &e.retention_period {
27487 if !first {
27488 self.write(", ");
27489 }
27490 self.write_keyword("RETENTION_PERIOD");
27491 self.write("=");
27492 self.generate_expression(retention_period)?;
27493 }
27494 self.write(")");
27495 }
27496 } else {
27497 self.write_keyword("OFF");
27498 }
27499 Ok(())
27500 }
27501
27502 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
27506 use crate::dialects::DialectType;
27507 use crate::expressions::Literal;
27508
27509 match self.config.dialect {
27510 Some(DialectType::Exasol) => {
27512 self.write_keyword("TO_DATE");
27513 self.write("(");
27514 match &e.this {
27516 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27517 let Literal::String(s) = lit.as_ref() else {
27518 unreachable!()
27519 };
27520 self.write("'");
27521 self.write(s);
27522 self.write("'");
27523 }
27524 _ => {
27525 self.generate_expression(&e.this)?;
27526 }
27527 }
27528 self.write(")");
27529 }
27530 _ => {
27532 self.write_keyword("DATE");
27533 self.write("(");
27534 self.generate_expression(&e.this)?;
27535 self.write(")");
27536 }
27537 }
27538 Ok(())
27539 }
27540
27541 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
27542 self.write_keyword("DATE_BIN");
27544 self.write("(");
27545 self.generate_expression(&e.this)?;
27546 self.write(", ");
27547 self.generate_expression(&e.expression)?;
27548 if let Some(origin) = &e.origin {
27549 self.write(", ");
27550 self.generate_expression(origin)?;
27551 }
27552 self.write(")");
27553 Ok(())
27554 }
27555
27556 fn generate_date_format_column_constraint(
27557 &mut self,
27558 e: &DateFormatColumnConstraint,
27559 ) -> Result<()> {
27560 self.write_keyword("FORMAT");
27562 self.write_space();
27563 self.generate_expression(&e.this)?;
27564 Ok(())
27565 }
27566
27567 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
27568 self.write_keyword("DATE_FROM_PARTS");
27570 self.write("(");
27571 let mut first = true;
27572 if let Some(year) = &e.year {
27573 self.generate_expression(year)?;
27574 first = false;
27575 }
27576 if let Some(month) = &e.month {
27577 if !first {
27578 self.write(", ");
27579 }
27580 self.generate_expression(month)?;
27581 first = false;
27582 }
27583 if let Some(day) = &e.day {
27584 if !first {
27585 self.write(", ");
27586 }
27587 self.generate_expression(day)?;
27588 }
27589 self.write(")");
27590 Ok(())
27591 }
27592
27593 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
27594 self.write_keyword("DATETIME");
27596 self.write("(");
27597 self.generate_expression(&e.this)?;
27598 if let Some(expr) = &e.expression {
27599 self.write(", ");
27600 self.generate_expression(expr)?;
27601 }
27602 self.write(")");
27603 Ok(())
27604 }
27605
27606 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
27607 self.write_keyword("DATETIME_ADD");
27609 self.write("(");
27610 self.generate_expression(&e.this)?;
27611 self.write(", ");
27612 self.generate_expression(&e.expression)?;
27613 if let Some(unit) = &e.unit {
27614 self.write(", ");
27615 self.write_keyword(unit);
27616 }
27617 self.write(")");
27618 Ok(())
27619 }
27620
27621 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
27622 self.write_keyword("DATETIME_DIFF");
27624 self.write("(");
27625 self.generate_expression(&e.this)?;
27626 self.write(", ");
27627 self.generate_expression(&e.expression)?;
27628 if let Some(unit) = &e.unit {
27629 self.write(", ");
27630 self.write_keyword(unit);
27631 }
27632 self.write(")");
27633 Ok(())
27634 }
27635
27636 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
27637 self.write_keyword("DATETIME_SUB");
27639 self.write("(");
27640 self.generate_expression(&e.this)?;
27641 self.write(", ");
27642 self.generate_expression(&e.expression)?;
27643 if let Some(unit) = &e.unit {
27644 self.write(", ");
27645 self.write_keyword(unit);
27646 }
27647 self.write(")");
27648 Ok(())
27649 }
27650
27651 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
27652 self.write_keyword("DATETIME_TRUNC");
27654 self.write("(");
27655 self.generate_expression(&e.this)?;
27656 self.write(", ");
27657 self.write_keyword(&e.unit);
27658 if let Some(zone) = &e.zone {
27659 self.write(", ");
27660 self.generate_expression(zone)?;
27661 }
27662 self.write(")");
27663 Ok(())
27664 }
27665
27666 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
27667 self.write_keyword("DAYNAME");
27669 self.write("(");
27670 self.generate_expression(&e.this)?;
27671 self.write(")");
27672 Ok(())
27673 }
27674
27675 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
27676 self.write_keyword("DECLARE");
27678 self.write_space();
27679 if e.replace {
27680 self.write_keyword("OR");
27681 self.write_space();
27682 self.write_keyword("REPLACE");
27683 self.write_space();
27684 }
27685 for (i, expr) in e.expressions.iter().enumerate() {
27686 if i > 0 {
27687 self.write(", ");
27688 }
27689 self.generate_expression(expr)?;
27690 }
27691 Ok(())
27692 }
27693
27694 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
27695 use crate::dialects::DialectType;
27696
27697 self.generate_expression(&e.this)?;
27699 for name in &e.additional_names {
27701 self.write(", ");
27702 self.generate_expression(name)?;
27703 }
27704 if let Some(kind) = &e.kind {
27705 self.write_space();
27706 match self.config.dialect {
27710 Some(DialectType::BigQuery) => {
27711 self.write(kind);
27712 }
27713 Some(DialectType::TSQL) => {
27714 let is_complex_table = kind.starts_with("TABLE")
27718 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
27719 if is_complex_table {
27720 self.write(kind);
27721 } else if kind == "INT" {
27722 self.write("INTEGER");
27723 } else if kind.starts_with("TABLE") {
27724 let normalized = kind
27726 .replace(" INT ", " INTEGER ")
27727 .replace(" INT,", " INTEGER,")
27728 .replace(" INT)", " INTEGER)")
27729 .replace("(INT ", "(INTEGER ");
27730 self.write(&normalized);
27731 } else {
27732 self.write(kind);
27733 }
27734 }
27735 _ => {
27736 if e.has_as {
27737 self.write_keyword("AS");
27738 self.write_space();
27739 }
27740 self.write(kind);
27741 }
27742 }
27743 }
27744 if let Some(default) = &e.default {
27745 match self.config.dialect {
27747 Some(DialectType::BigQuery) => {
27748 self.write_space();
27749 self.write_keyword("DEFAULT");
27750 self.write_space();
27751 }
27752 _ => {
27753 self.write(" = ");
27754 }
27755 }
27756 self.generate_expression(default)?;
27757 }
27758 Ok(())
27759 }
27760
27761 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
27762 self.write_keyword("DECODE");
27764 self.write("(");
27765 for (i, expr) in e.expressions.iter().enumerate() {
27766 if i > 0 {
27767 self.write(", ");
27768 }
27769 self.generate_expression(expr)?;
27770 }
27771 self.write(")");
27772 Ok(())
27773 }
27774
27775 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
27776 self.write_keyword("DECOMPRESS");
27778 self.write("(");
27779 self.generate_expression(&e.this)?;
27780 self.write(", '");
27781 self.write(&e.method);
27782 self.write("')");
27783 Ok(())
27784 }
27785
27786 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
27787 self.write_keyword("DECOMPRESS");
27789 self.write("(");
27790 self.generate_expression(&e.this)?;
27791 self.write(", '");
27792 self.write(&e.method);
27793 self.write("')");
27794 Ok(())
27795 }
27796
27797 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
27798 self.write_keyword("DECRYPT");
27800 self.write("(");
27801 self.generate_expression(&e.this)?;
27802 if let Some(passphrase) = &e.passphrase {
27803 self.write(", ");
27804 self.generate_expression(passphrase)?;
27805 }
27806 if let Some(aad) = &e.aad {
27807 self.write(", ");
27808 self.generate_expression(aad)?;
27809 }
27810 if let Some(method) = &e.encryption_method {
27811 self.write(", ");
27812 self.generate_expression(method)?;
27813 }
27814 self.write(")");
27815 Ok(())
27816 }
27817
27818 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
27819 self.write_keyword("DECRYPT_RAW");
27821 self.write("(");
27822 self.generate_expression(&e.this)?;
27823 if let Some(key) = &e.key {
27824 self.write(", ");
27825 self.generate_expression(key)?;
27826 }
27827 if let Some(iv) = &e.iv {
27828 self.write(", ");
27829 self.generate_expression(iv)?;
27830 }
27831 if let Some(aad) = &e.aad {
27832 self.write(", ");
27833 self.generate_expression(aad)?;
27834 }
27835 if let Some(method) = &e.encryption_method {
27836 self.write(", ");
27837 self.generate_expression(method)?;
27838 }
27839 self.write(")");
27840 Ok(())
27841 }
27842
27843 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
27844 self.write_keyword("DEFINER");
27846 self.write(" = ");
27847 self.generate_expression(&e.this)?;
27848 Ok(())
27849 }
27850
27851 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
27852 self.write_keyword("DETACH");
27854 if e.exists {
27855 self.write_keyword(" DATABASE IF EXISTS");
27856 }
27857 self.write_space();
27858 self.generate_expression(&e.this)?;
27859 Ok(())
27860 }
27861
27862 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
27863 let property_name = match e.this.as_ref() {
27864 Expression::Identifier(id) => id.name.as_str(),
27865 Expression::Var(v) => v.this.as_str(),
27866 _ => "DICTIONARY",
27867 };
27868 self.write_keyword(property_name);
27869 self.write("(");
27870 self.write(&e.kind);
27871 if let Some(settings) = &e.settings {
27872 self.write("(");
27873 if let Expression::Tuple(t) = settings.as_ref() {
27874 if self.config.pretty && !t.expressions.is_empty() {
27875 self.write_newline();
27876 self.indent_level += 1;
27877 for (i, pair) in t.expressions.iter().enumerate() {
27878 if i > 0 {
27879 self.write(",");
27880 self.write_newline();
27881 }
27882 self.write_indent();
27883 if let Expression::Tuple(pair_tuple) = pair {
27884 if let Some(k) = pair_tuple.expressions.first() {
27885 self.generate_expression(k)?;
27886 }
27887 if let Some(v) = pair_tuple.expressions.get(1) {
27888 self.write(" ");
27889 self.generate_expression(v)?;
27890 }
27891 } else {
27892 self.generate_expression(pair)?;
27893 }
27894 }
27895 self.indent_level -= 1;
27896 self.write_newline();
27897 self.write_indent();
27898 } else {
27899 for (i, pair) in t.expressions.iter().enumerate() {
27900 if i > 0 {
27901 self.write(" ");
27903 }
27904 if let Expression::Tuple(pair_tuple) = pair {
27905 if let Some(k) = pair_tuple.expressions.first() {
27906 self.generate_expression(k)?;
27907 }
27908 if let Some(v) = pair_tuple.expressions.get(1) {
27909 self.write(" ");
27910 self.generate_expression(v)?;
27911 }
27912 } else {
27913 self.generate_expression(pair)?;
27914 }
27915 }
27916 }
27917 } else {
27918 self.generate_expression(settings)?;
27919 }
27920 self.write(")");
27921 } else {
27922 self.write("()");
27924 }
27925 self.write(")");
27926 Ok(())
27927 }
27928
27929 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
27930 let property_name = match e.this.as_ref() {
27931 Expression::Identifier(id) => id.name.as_str(),
27932 Expression::Var(v) => v.this.as_str(),
27933 _ => "RANGE",
27934 };
27935 self.write_keyword(property_name);
27936 self.write("(");
27937 if let Some(min) = &e.min {
27938 self.write_keyword("MIN");
27939 self.write_space();
27940 self.generate_expression(min)?;
27941 }
27942 if let Some(max) = &e.max {
27943 self.write_space();
27944 self.write_keyword("MAX");
27945 self.write_space();
27946 self.generate_expression(max)?;
27947 }
27948 self.write(")");
27949 Ok(())
27950 }
27951
27952 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
27953 if e.local.is_some() {
27955 self.write_keyword("LOCAL ");
27956 }
27957 self.write_keyword("DIRECTORY");
27958 self.write_space();
27959 self.generate_expression(&e.this)?;
27960 if let Some(row_format) = &e.row_format {
27961 self.write_space();
27962 self.generate_expression(row_format)?;
27963 }
27964 Ok(())
27965 }
27966
27967 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
27968 self.write_keyword("DISTKEY");
27970 self.write("(");
27971 self.generate_expression(&e.this)?;
27972 self.write(")");
27973 Ok(())
27974 }
27975
27976 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
27977 self.write_keyword("DISTSTYLE");
27979 self.write_space();
27980 self.generate_expression(&e.this)?;
27981 Ok(())
27982 }
27983
27984 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
27985 self.write_keyword("DISTRIBUTE BY");
27987 self.write_space();
27988 for (i, expr) in e.expressions.iter().enumerate() {
27989 if i > 0 {
27990 self.write(", ");
27991 }
27992 self.generate_expression(expr)?;
27993 }
27994 Ok(())
27995 }
27996
27997 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
27998 self.write_keyword("DISTRIBUTED BY");
28000 self.write_space();
28001 self.write(&e.kind);
28002 if !e.expressions.is_empty() {
28003 self.write(" (");
28004 for (i, expr) in e.expressions.iter().enumerate() {
28005 if i > 0 {
28006 self.write(", ");
28007 }
28008 self.generate_expression(expr)?;
28009 }
28010 self.write(")");
28011 }
28012 if let Some(buckets) = &e.buckets {
28013 self.write_space();
28014 self.write_keyword("BUCKETS");
28015 self.write_space();
28016 self.generate_expression(buckets)?;
28017 }
28018 if let Some(order) = &e.order {
28019 self.write_space();
28020 self.generate_expression(order)?;
28021 }
28022 Ok(())
28023 }
28024
28025 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
28026 self.write_keyword("DOT_PRODUCT");
28028 self.write("(");
28029 self.generate_expression(&e.this)?;
28030 self.write(", ");
28031 self.generate_expression(&e.expression)?;
28032 self.write(")");
28033 Ok(())
28034 }
28035
28036 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
28037 self.write_keyword("DROP");
28039 if e.exists {
28040 self.write_keyword(" IF EXISTS ");
28041 } else {
28042 self.write_space();
28043 }
28044 for (i, expr) in e.expressions.iter().enumerate() {
28045 if i > 0 {
28046 self.write(", ");
28047 }
28048 self.generate_expression(expr)?;
28049 }
28050 Ok(())
28051 }
28052
28053 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
28054 self.write_keyword("DUPLICATE KEY");
28056 self.write(" (");
28057 for (i, expr) in e.expressions.iter().enumerate() {
28058 if i > 0 {
28059 self.write(", ");
28060 }
28061 self.generate_expression(expr)?;
28062 }
28063 self.write(")");
28064 Ok(())
28065 }
28066
28067 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
28068 self.write_keyword("ELT");
28070 self.write("(");
28071 self.generate_expression(&e.this)?;
28072 for expr in &e.expressions {
28073 self.write(", ");
28074 self.generate_expression(expr)?;
28075 }
28076 self.write(")");
28077 Ok(())
28078 }
28079
28080 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
28081 self.write_keyword("ENCODE");
28083 self.write("(");
28084 self.generate_expression(&e.this)?;
28085 if let Some(charset) = &e.charset {
28086 self.write(", ");
28087 self.generate_expression(charset)?;
28088 }
28089 self.write(")");
28090 Ok(())
28091 }
28092
28093 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
28094 if e.key.is_some() {
28096 self.write_keyword("KEY ");
28097 }
28098 self.write_keyword("ENCODE");
28099 self.write_space();
28100 self.generate_expression(&e.this)?;
28101 if !e.properties.is_empty() {
28102 self.write(" (");
28103 for (i, prop) in e.properties.iter().enumerate() {
28104 if i > 0 {
28105 self.write(", ");
28106 }
28107 self.generate_expression(prop)?;
28108 }
28109 self.write(")");
28110 }
28111 Ok(())
28112 }
28113
28114 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
28115 self.write_keyword("ENCRYPT");
28117 self.write("(");
28118 self.generate_expression(&e.this)?;
28119 if let Some(passphrase) = &e.passphrase {
28120 self.write(", ");
28121 self.generate_expression(passphrase)?;
28122 }
28123 if let Some(aad) = &e.aad {
28124 self.write(", ");
28125 self.generate_expression(aad)?;
28126 }
28127 if let Some(method) = &e.encryption_method {
28128 self.write(", ");
28129 self.generate_expression(method)?;
28130 }
28131 self.write(")");
28132 Ok(())
28133 }
28134
28135 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
28136 self.write_keyword("ENCRYPT_RAW");
28138 self.write("(");
28139 self.generate_expression(&e.this)?;
28140 if let Some(key) = &e.key {
28141 self.write(", ");
28142 self.generate_expression(key)?;
28143 }
28144 if let Some(iv) = &e.iv {
28145 self.write(", ");
28146 self.generate_expression(iv)?;
28147 }
28148 if let Some(aad) = &e.aad {
28149 self.write(", ");
28150 self.generate_expression(aad)?;
28151 }
28152 if let Some(method) = &e.encryption_method {
28153 self.write(", ");
28154 self.generate_expression(method)?;
28155 }
28156 self.write(")");
28157 Ok(())
28158 }
28159
28160 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
28161 self.write_keyword("ENGINE");
28163 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28164 self.write("=");
28165 } else {
28166 self.write(" = ");
28167 }
28168 self.generate_expression(&e.this)?;
28169 Ok(())
28170 }
28171
28172 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
28173 self.write_keyword("ENVIRONMENT");
28175 self.write(" (");
28176 for (i, expr) in e.expressions.iter().enumerate() {
28177 if i > 0 {
28178 self.write(", ");
28179 }
28180 self.generate_expression(expr)?;
28181 }
28182 self.write(")");
28183 Ok(())
28184 }
28185
28186 fn generate_ephemeral_column_constraint(
28187 &mut self,
28188 e: &EphemeralColumnConstraint,
28189 ) -> Result<()> {
28190 self.write_keyword("EPHEMERAL");
28192 if let Some(this) = &e.this {
28193 self.write_space();
28194 self.generate_expression(this)?;
28195 }
28196 Ok(())
28197 }
28198
28199 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
28200 self.write_keyword("EQUAL_NULL");
28202 self.write("(");
28203 self.generate_expression(&e.this)?;
28204 self.write(", ");
28205 self.generate_expression(&e.expression)?;
28206 self.write(")");
28207 Ok(())
28208 }
28209
28210 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
28211 use crate::dialects::DialectType;
28212
28213 match self.config.dialect {
28215 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
28216 self.generate_expression(&e.this)?;
28217 self.write(" <-> ");
28218 self.generate_expression(&e.expression)?;
28219 }
28220 _ => {
28221 self.write_keyword("EUCLIDEAN_DISTANCE");
28223 self.write("(");
28224 self.generate_expression(&e.this)?;
28225 self.write(", ");
28226 self.generate_expression(&e.expression)?;
28227 self.write(")");
28228 }
28229 }
28230 Ok(())
28231 }
28232
28233 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
28234 self.write_keyword("EXECUTE AS");
28236 self.write_space();
28237 self.generate_expression(&e.this)?;
28238 Ok(())
28239 }
28240
28241 fn generate_export(&mut self, e: &Export) -> Result<()> {
28242 self.write_keyword("EXPORT DATA");
28244 if let Some(connection) = &e.connection {
28245 self.write_space();
28246 self.write_keyword("WITH CONNECTION");
28247 self.write_space();
28248 self.generate_expression(connection)?;
28249 }
28250 if !e.options.is_empty() {
28251 self.write_space();
28252 self.generate_options_clause(&e.options)?;
28253 }
28254 self.write_space();
28255 self.write_keyword("AS");
28256 self.write_space();
28257 self.generate_expression(&e.this)?;
28258 Ok(())
28259 }
28260
28261 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
28262 self.write_keyword("EXTERNAL");
28264 if let Some(this) = &e.this {
28265 self.write_space();
28266 self.generate_expression(this)?;
28267 }
28268 Ok(())
28269 }
28270
28271 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
28272 if e.no.is_some() {
28274 self.write_keyword("NO ");
28275 }
28276 self.write_keyword("FALLBACK");
28277 if e.protection.is_some() {
28278 self.write_keyword(" PROTECTION");
28279 }
28280 Ok(())
28281 }
28282
28283 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
28284 self.write_keyword("FARM_FINGERPRINT");
28286 self.write("(");
28287 for (i, expr) in e.expressions.iter().enumerate() {
28288 if i > 0 {
28289 self.write(", ");
28290 }
28291 self.generate_expression(expr)?;
28292 }
28293 self.write(")");
28294 Ok(())
28295 }
28296
28297 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
28298 self.write_keyword("FEATURES_AT_TIME");
28300 self.write("(");
28301 self.generate_expression(&e.this)?;
28302 if let Some(time) = &e.time {
28303 self.write(", ");
28304 self.generate_expression(time)?;
28305 }
28306 if let Some(num_rows) = &e.num_rows {
28307 self.write(", ");
28308 self.generate_expression(num_rows)?;
28309 }
28310 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
28311 self.write(", ");
28312 self.generate_expression(ignore_nulls)?;
28313 }
28314 self.write(")");
28315 Ok(())
28316 }
28317
28318 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
28319 let use_limit = !e.percent
28321 && !e.with_ties
28322 && e.count.is_some()
28323 && matches!(
28324 self.config.dialect,
28325 Some(DialectType::Spark)
28326 | Some(DialectType::Hive)
28327 | Some(DialectType::DuckDB)
28328 | Some(DialectType::SQLite)
28329 | Some(DialectType::MySQL)
28330 | Some(DialectType::BigQuery)
28331 | Some(DialectType::Databricks)
28332 | Some(DialectType::StarRocks)
28333 | Some(DialectType::Doris)
28334 | Some(DialectType::Athena)
28335 | Some(DialectType::ClickHouse)
28336 );
28337
28338 if use_limit {
28339 self.write_keyword("LIMIT");
28340 self.write_space();
28341 self.generate_expression(e.count.as_ref().unwrap())?;
28342 return Ok(());
28343 }
28344
28345 self.write_keyword("FETCH");
28347 if !e.direction.is_empty() {
28348 self.write_space();
28349 self.write_keyword(&e.direction);
28350 }
28351 if let Some(count) = &e.count {
28352 self.write_space();
28353 self.generate_expression(count)?;
28354 }
28355 if e.percent {
28357 self.write_keyword(" PERCENT");
28358 }
28359 if e.rows {
28360 self.write_keyword(" ROWS");
28361 }
28362 if e.with_ties {
28363 self.write_keyword(" WITH TIES");
28364 } else if e.rows {
28365 self.write_keyword(" ONLY");
28366 } else {
28367 self.write_keyword(" ROWS ONLY");
28368 }
28369 Ok(())
28370 }
28371
28372 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
28373 if e.hive_format.is_some() {
28377 self.write_keyword("STORED AS");
28379 self.write_space();
28380 if let Some(this) = &e.this {
28381 if let Expression::Identifier(id) = this.as_ref() {
28383 self.write_keyword(&id.name.to_ascii_uppercase());
28384 } else {
28385 self.generate_expression(this)?;
28386 }
28387 }
28388 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
28389 self.write_keyword("STORED AS");
28391 self.write_space();
28392 if let Some(this) = &e.this {
28393 if let Expression::Identifier(id) = this.as_ref() {
28394 self.write_keyword(&id.name.to_ascii_uppercase());
28395 } else {
28396 self.generate_expression(this)?;
28397 }
28398 }
28399 } else if matches!(
28400 self.config.dialect,
28401 Some(DialectType::Spark) | Some(DialectType::Databricks)
28402 ) {
28403 self.write_keyword("USING");
28405 self.write_space();
28406 if let Some(this) = &e.this {
28407 self.generate_expression(this)?;
28408 }
28409 } else {
28410 self.write_keyword("FILE_FORMAT");
28412 self.write(" = ");
28413 if let Some(this) = &e.this {
28414 self.generate_expression(this)?;
28415 } else if !e.expressions.is_empty() {
28416 self.write("(");
28417 for (i, expr) in e.expressions.iter().enumerate() {
28418 if i > 0 {
28419 self.write(", ");
28420 }
28421 self.generate_expression(expr)?;
28422 }
28423 self.write(")");
28424 }
28425 }
28426 Ok(())
28427 }
28428
28429 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
28430 self.generate_expression(&e.this)?;
28432 self.write_space();
28433 self.write_keyword("FILTER");
28434 self.write("(");
28435 self.write_keyword("WHERE");
28436 self.write_space();
28437 self.generate_expression(&e.expression)?;
28438 self.write(")");
28439 Ok(())
28440 }
28441
28442 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
28443 self.write_keyword("FLOAT64");
28445 self.write("(");
28446 self.generate_expression(&e.this)?;
28447 if let Some(expr) = &e.expression {
28448 self.write(", ");
28449 self.generate_expression(expr)?;
28450 }
28451 self.write(")");
28452 Ok(())
28453 }
28454
28455 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
28456 self.write_keyword("FOR");
28458 self.write_space();
28459 self.generate_expression(&e.this)?;
28460 self.write_space();
28461 self.write_keyword("DO");
28462 self.write_space();
28463 self.generate_expression(&e.expression)?;
28464 Ok(())
28465 }
28466
28467 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
28468 self.write_keyword("FOREIGN KEY");
28470 if !e.expressions.is_empty() {
28471 self.write(" (");
28472 for (i, expr) in e.expressions.iter().enumerate() {
28473 if i > 0 {
28474 self.write(", ");
28475 }
28476 self.generate_expression(expr)?;
28477 }
28478 self.write(")");
28479 }
28480 if let Some(reference) = &e.reference {
28481 self.write_space();
28482 self.generate_expression(reference)?;
28483 }
28484 if let Some(delete) = &e.delete {
28485 self.write_space();
28486 self.write_keyword("ON DELETE");
28487 self.write_space();
28488 self.generate_expression(delete)?;
28489 }
28490 if let Some(update) = &e.update {
28491 self.write_space();
28492 self.write_keyword("ON UPDATE");
28493 self.write_space();
28494 self.generate_expression(update)?;
28495 }
28496 if !e.options.is_empty() {
28497 self.write_space();
28498 for (i, opt) in e.options.iter().enumerate() {
28499 if i > 0 {
28500 self.write_space();
28501 }
28502 self.generate_expression(opt)?;
28503 }
28504 }
28505 Ok(())
28506 }
28507
28508 fn generate_format(&mut self, e: &Format) -> Result<()> {
28509 self.write_keyword("FORMAT");
28511 self.write("(");
28512 self.generate_expression(&e.this)?;
28513 for expr in &e.expressions {
28514 self.write(", ");
28515 self.generate_expression(expr)?;
28516 }
28517 self.write(")");
28518 Ok(())
28519 }
28520
28521 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
28522 self.generate_expression(&e.this)?;
28524 self.write(" (");
28525 self.write_keyword("FORMAT");
28526 self.write(" '");
28527 self.write(&e.format);
28528 self.write("')");
28529 Ok(())
28530 }
28531
28532 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
28533 self.write_keyword("FREESPACE");
28535 self.write("=");
28536 self.generate_expression(&e.this)?;
28537 if e.percent.is_some() {
28538 self.write_keyword(" PERCENT");
28539 }
28540 Ok(())
28541 }
28542
28543 fn generate_from(&mut self, e: &From) -> Result<()> {
28544 self.write_keyword("FROM");
28546 self.write_space();
28547
28548 use crate::dialects::DialectType;
28552 let has_tablesample = e
28553 .expressions
28554 .iter()
28555 .any(|expr| matches!(expr, Expression::TableSample(_)));
28556 let is_cross_join_dialect = matches!(
28557 self.config.dialect,
28558 Some(DialectType::BigQuery)
28559 | Some(DialectType::Hive)
28560 | Some(DialectType::Spark)
28561 | Some(DialectType::Databricks)
28562 | Some(DialectType::SQLite)
28563 | Some(DialectType::ClickHouse)
28564 );
28565 let source_is_same_as_target2 = self.config.source_dialect.is_some()
28566 && self.config.source_dialect == self.config.dialect;
28567 let source_is_cross_join_dialect2 = matches!(
28568 self.config.source_dialect,
28569 Some(DialectType::BigQuery)
28570 | Some(DialectType::Hive)
28571 | Some(DialectType::Spark)
28572 | Some(DialectType::Databricks)
28573 | Some(DialectType::SQLite)
28574 | Some(DialectType::ClickHouse)
28575 );
28576 let use_cross_join = !has_tablesample
28577 && is_cross_join_dialect
28578 && (source_is_same_as_target2
28579 || source_is_cross_join_dialect2
28580 || self.config.source_dialect.is_none());
28581
28582 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
28584
28585 for (i, expr) in e.expressions.iter().enumerate() {
28586 if i > 0 {
28587 if use_cross_join {
28588 self.write(" CROSS JOIN ");
28589 } else {
28590 self.write(", ");
28591 }
28592 }
28593 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
28594 self.write("(");
28595 self.generate_expression(expr)?;
28596 self.write(")");
28597 } else {
28598 self.generate_expression(expr)?;
28599 }
28600 let leading = Self::extract_table_leading_comments(expr);
28603 for comment in &leading {
28604 self.write_space();
28605 self.write_formatted_comment(comment);
28606 }
28607 }
28608 Ok(())
28609 }
28610
28611 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
28613 match expr {
28614 Expression::Table(t) => t.leading_comments.clone(),
28615 Expression::Pivot(p) => {
28616 if let Expression::Table(t) = &p.this {
28617 t.leading_comments.clone()
28618 } else {
28619 Vec::new()
28620 }
28621 }
28622 _ => Vec::new(),
28623 }
28624 }
28625
28626 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
28627 self.write_keyword("FROM_BASE");
28629 self.write("(");
28630 self.generate_expression(&e.this)?;
28631 self.write(", ");
28632 self.generate_expression(&e.expression)?;
28633 self.write(")");
28634 Ok(())
28635 }
28636
28637 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
28638 self.generate_expression(&e.this)?;
28640 if let Some(zone) = &e.zone {
28641 self.write_space();
28642 self.write_keyword("AT TIME ZONE");
28643 self.write_space();
28644 self.generate_expression(zone)?;
28645 self.write_space();
28646 self.write_keyword("AT TIME ZONE");
28647 self.write(" 'UTC'");
28648 }
28649 Ok(())
28650 }
28651
28652 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
28653 self.write_keyword("GAP_FILL");
28655 self.write("(");
28656 self.generate_expression(&e.this)?;
28657 if let Some(ts_column) = &e.ts_column {
28658 self.write(", ");
28659 self.generate_expression(ts_column)?;
28660 }
28661 if let Some(bucket_width) = &e.bucket_width {
28662 self.write(", ");
28663 self.generate_expression(bucket_width)?;
28664 }
28665 if let Some(partitioning_columns) = &e.partitioning_columns {
28666 self.write(", ");
28667 self.generate_expression(partitioning_columns)?;
28668 }
28669 if let Some(value_columns) = &e.value_columns {
28670 self.write(", ");
28671 self.generate_expression(value_columns)?;
28672 }
28673 self.write(")");
28674 Ok(())
28675 }
28676
28677 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
28678 self.write_keyword("GENERATE_DATE_ARRAY");
28680 self.write("(");
28681 let mut first = true;
28682 if let Some(start) = &e.start {
28683 self.generate_expression(start)?;
28684 first = false;
28685 }
28686 if let Some(end) = &e.end {
28687 if !first {
28688 self.write(", ");
28689 }
28690 self.generate_expression(end)?;
28691 first = false;
28692 }
28693 if let Some(step) = &e.step {
28694 if !first {
28695 self.write(", ");
28696 }
28697 self.generate_expression(step)?;
28698 }
28699 self.write(")");
28700 Ok(())
28701 }
28702
28703 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
28704 self.write_keyword("ML.GENERATE_EMBEDDING");
28706 self.write("(");
28707 self.generate_expression(&e.this)?;
28708 self.write(", ");
28709 self.generate_expression(&e.expression)?;
28710 if let Some(params) = &e.params_struct {
28711 self.write(", ");
28712 self.generate_expression(params)?;
28713 }
28714 self.write(")");
28715 Ok(())
28716 }
28717
28718 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
28719 let fn_name = match self.config.dialect {
28721 Some(DialectType::Presto)
28722 | Some(DialectType::Trino)
28723 | Some(DialectType::Athena)
28724 | Some(DialectType::Spark)
28725 | Some(DialectType::Databricks)
28726 | Some(DialectType::Hive) => "SEQUENCE",
28727 _ => "GENERATE_SERIES",
28728 };
28729 self.write_keyword(fn_name);
28730 self.write("(");
28731 let mut first = true;
28732 if let Some(start) = &e.start {
28733 self.generate_expression(start)?;
28734 first = false;
28735 }
28736 if let Some(end) = &e.end {
28737 if !first {
28738 self.write(", ");
28739 }
28740 self.generate_expression(end)?;
28741 first = false;
28742 }
28743 if let Some(step) = &e.step {
28744 if !first {
28745 self.write(", ");
28746 }
28747 if matches!(
28750 self.config.dialect,
28751 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
28752 ) {
28753 if let Some(converted) = self.convert_week_interval_to_day(step) {
28754 self.generate_expression(&converted)?;
28755 } else {
28756 self.generate_expression(step)?;
28757 }
28758 } else {
28759 self.generate_expression(step)?;
28760 }
28761 }
28762 self.write(")");
28763 Ok(())
28764 }
28765
28766 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
28769 use crate::expressions::*;
28770 if let Expression::Interval(ref iv) = expr {
28771 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
28773 unit: IntervalUnit::Week,
28774 ..
28775 }) = &iv.unit
28776 {
28777 let count = match &iv.this {
28779 Some(Expression::Literal(lit)) => match lit.as_ref() {
28780 Literal::String(s) | Literal::Number(s) => s.clone(),
28781 _ => return None,
28782 },
28783 _ => return None,
28784 };
28785 (true, count)
28786 } else if iv.unit.is_none() {
28787 if let Some(Expression::Literal(lit)) = &iv.this {
28789 if let Literal::String(s) = lit.as_ref() {
28790 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
28791 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
28792 (true, parts[0].to_string())
28793 } else {
28794 (false, String::new())
28795 }
28796 } else {
28797 (false, String::new())
28798 }
28799 } else {
28800 (false, String::new())
28801 }
28802 } else {
28803 (false, String::new())
28804 };
28805
28806 if is_week {
28807 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
28809 let day_interval = Expression::Interval(Box::new(Interval {
28810 this: Some(Expression::Literal(Box::new(Literal::String(
28811 "7".to_string(),
28812 )))),
28813 unit: Some(IntervalUnitSpec::Simple {
28814 unit: IntervalUnit::Day,
28815 use_plural: false,
28816 }),
28817 }));
28818 let mul = Expression::Mul(Box::new(BinaryOp {
28819 left: count_expr,
28820 right: day_interval,
28821 left_comments: vec![],
28822 operator_comments: vec![],
28823 trailing_comments: vec![],
28824 inferred_type: None,
28825 }));
28826 return Some(Expression::Paren(Box::new(Paren {
28827 this: mul,
28828 trailing_comments: vec![],
28829 })));
28830 }
28831 }
28832 None
28833 }
28834
28835 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
28836 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
28838 self.write("(");
28839 let mut first = true;
28840 if let Some(start) = &e.start {
28841 self.generate_expression(start)?;
28842 first = false;
28843 }
28844 if let Some(end) = &e.end {
28845 if !first {
28846 self.write(", ");
28847 }
28848 self.generate_expression(end)?;
28849 first = false;
28850 }
28851 if let Some(step) = &e.step {
28852 if !first {
28853 self.write(", ");
28854 }
28855 self.generate_expression(step)?;
28856 }
28857 self.write(")");
28858 Ok(())
28859 }
28860
28861 fn generate_generated_as_identity_column_constraint(
28862 &mut self,
28863 e: &GeneratedAsIdentityColumnConstraint,
28864 ) -> Result<()> {
28865 use crate::dialects::DialectType;
28866
28867 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
28869 self.write_keyword("AUTOINCREMENT");
28870 if let Some(start) = &e.start {
28871 self.write_keyword(" START ");
28872 self.generate_expression(start)?;
28873 }
28874 if let Some(increment) = &e.increment {
28875 self.write_keyword(" INCREMENT ");
28876 self.generate_expression(increment)?;
28877 }
28878 return Ok(());
28879 }
28880
28881 self.write_keyword("GENERATED");
28883 if let Some(this) = &e.this {
28884 if let Expression::Boolean(b) = this.as_ref() {
28886 if b.value {
28887 self.write_keyword(" ALWAYS");
28888 } else {
28889 self.write_keyword(" BY DEFAULT");
28890 if e.on_null.is_some() {
28891 self.write_keyword(" ON NULL");
28892 }
28893 }
28894 } else {
28895 self.write_keyword(" ALWAYS");
28896 }
28897 }
28898 self.write_keyword(" AS IDENTITY");
28899 let has_options = e.start.is_some()
28901 || e.increment.is_some()
28902 || e.minvalue.is_some()
28903 || e.maxvalue.is_some();
28904 if has_options {
28905 self.write(" (");
28906 let mut first = true;
28907 if let Some(start) = &e.start {
28908 self.write_keyword("START WITH ");
28909 self.generate_expression(start)?;
28910 first = false;
28911 }
28912 if let Some(increment) = &e.increment {
28913 if !first {
28914 self.write(" ");
28915 }
28916 self.write_keyword("INCREMENT BY ");
28917 self.generate_expression(increment)?;
28918 first = false;
28919 }
28920 if let Some(minvalue) = &e.minvalue {
28921 if !first {
28922 self.write(" ");
28923 }
28924 self.write_keyword("MINVALUE ");
28925 self.generate_expression(minvalue)?;
28926 first = false;
28927 }
28928 if let Some(maxvalue) = &e.maxvalue {
28929 if !first {
28930 self.write(" ");
28931 }
28932 self.write_keyword("MAXVALUE ");
28933 self.generate_expression(maxvalue)?;
28934 }
28935 self.write(")");
28936 }
28937 Ok(())
28938 }
28939
28940 fn generate_generated_as_row_column_constraint(
28941 &mut self,
28942 e: &GeneratedAsRowColumnConstraint,
28943 ) -> Result<()> {
28944 self.write_keyword("GENERATED ALWAYS AS ROW ");
28946 if e.start.is_some() {
28947 self.write_keyword("START");
28948 } else {
28949 self.write_keyword("END");
28950 }
28951 if e.hidden.is_some() {
28952 self.write_keyword(" HIDDEN");
28953 }
28954 Ok(())
28955 }
28956
28957 fn generate_get(&mut self, e: &Get) -> Result<()> {
28958 self.write_keyword("GET");
28960 self.write_space();
28961 self.generate_expression(&e.this)?;
28962 if let Some(target) = &e.target {
28963 self.write_space();
28964 self.generate_expression(target)?;
28965 }
28966 for prop in &e.properties {
28967 self.write_space();
28968 self.generate_expression(prop)?;
28969 }
28970 Ok(())
28971 }
28972
28973 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
28974 self.generate_expression(&e.this)?;
28976 self.write("[");
28977 self.generate_expression(&e.expression)?;
28978 self.write("]");
28979 Ok(())
28980 }
28981
28982 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
28983 self.write_keyword("GETBIT");
28985 self.write("(");
28986 self.generate_expression(&e.this)?;
28987 self.write(", ");
28988 self.generate_expression(&e.expression)?;
28989 self.write(")");
28990 Ok(())
28991 }
28992
28993 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
28994 if e.is_role {
28996 self.write_keyword("ROLE");
28997 self.write_space();
28998 } else if e.is_group {
28999 self.write_keyword("GROUP");
29000 self.write_space();
29001 } else if e.is_share {
29002 self.write_keyword("SHARE");
29003 self.write_space();
29004 }
29005 self.write(&e.name.name);
29006 Ok(())
29007 }
29008
29009 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
29010 self.generate_expression(&e.this)?;
29012 if !e.expressions.is_empty() {
29013 self.write("(");
29014 for (i, expr) in e.expressions.iter().enumerate() {
29015 if i > 0 {
29016 self.write(", ");
29017 }
29018 self.generate_expression(expr)?;
29019 }
29020 self.write(")");
29021 }
29022 Ok(())
29023 }
29024
29025 fn generate_group(&mut self, e: &Group) -> Result<()> {
29026 self.write_keyword("GROUP BY");
29028 match e.all {
29030 Some(true) => {
29031 self.write_space();
29032 self.write_keyword("ALL");
29033 }
29034 Some(false) => {
29035 self.write_space();
29036 self.write_keyword("DISTINCT");
29037 }
29038 None => {}
29039 }
29040 if !e.expressions.is_empty() {
29041 self.write_space();
29042 for (i, expr) in e.expressions.iter().enumerate() {
29043 if i > 0 {
29044 self.write(", ");
29045 }
29046 self.generate_expression(expr)?;
29047 }
29048 }
29049 if let Some(cube) = &e.cube {
29051 if !e.expressions.is_empty() {
29052 self.write(", ");
29053 } else {
29054 self.write_space();
29055 }
29056 self.generate_expression(cube)?;
29057 }
29058 if let Some(rollup) = &e.rollup {
29059 if !e.expressions.is_empty() || e.cube.is_some() {
29060 self.write(", ");
29061 } else {
29062 self.write_space();
29063 }
29064 self.generate_expression(rollup)?;
29065 }
29066 if let Some(grouping_sets) = &e.grouping_sets {
29067 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
29068 self.write(", ");
29069 } else {
29070 self.write_space();
29071 }
29072 self.generate_expression(grouping_sets)?;
29073 }
29074 if let Some(totals) = &e.totals {
29075 self.write_space();
29076 self.write_keyword("WITH TOTALS");
29077 self.generate_expression(totals)?;
29078 }
29079 Ok(())
29080 }
29081
29082 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
29083 self.write_keyword("GROUP BY");
29085 match e.all {
29087 Some(true) => {
29088 self.write_space();
29089 self.write_keyword("ALL");
29090 }
29091 Some(false) => {
29092 self.write_space();
29093 self.write_keyword("DISTINCT");
29094 }
29095 None => {}
29096 }
29097
29098 let mut trailing_cube = false;
29101 let mut trailing_rollup = false;
29102 let mut regular_expressions: Vec<&Expression> = Vec::new();
29103
29104 for expr in &e.expressions {
29105 match expr {
29106 Expression::Cube(c) if c.expressions.is_empty() => {
29107 trailing_cube = true;
29108 }
29109 Expression::Rollup(r) if r.expressions.is_empty() => {
29110 trailing_rollup = true;
29111 }
29112 _ => {
29113 regular_expressions.push(expr);
29114 }
29115 }
29116 }
29117
29118 if self.config.pretty {
29120 self.write_newline();
29121 self.indent_level += 1;
29122 for (i, expr) in regular_expressions.iter().enumerate() {
29123 if i > 0 {
29124 self.write(",");
29125 self.write_newline();
29126 }
29127 self.write_indent();
29128 self.generate_expression(expr)?;
29129 }
29130 self.indent_level -= 1;
29131 } else {
29132 self.write_space();
29133 for (i, expr) in regular_expressions.iter().enumerate() {
29134 if i > 0 {
29135 self.write(", ");
29136 }
29137 self.generate_expression(expr)?;
29138 }
29139 }
29140
29141 if trailing_cube {
29143 self.write_space();
29144 self.write_keyword("WITH CUBE");
29145 } else if trailing_rollup {
29146 self.write_space();
29147 self.write_keyword("WITH ROLLUP");
29148 }
29149
29150 if e.totals {
29152 self.write_space();
29153 self.write_keyword("WITH TOTALS");
29154 }
29155
29156 Ok(())
29157 }
29158
29159 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
29160 self.write_keyword("GROUPING");
29162 self.write("(");
29163 for (i, expr) in e.expressions.iter().enumerate() {
29164 if i > 0 {
29165 self.write(", ");
29166 }
29167 self.generate_expression(expr)?;
29168 }
29169 self.write(")");
29170 Ok(())
29171 }
29172
29173 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
29174 self.write_keyword("GROUPING_ID");
29176 self.write("(");
29177 for (i, expr) in e.expressions.iter().enumerate() {
29178 if i > 0 {
29179 self.write(", ");
29180 }
29181 self.generate_expression(expr)?;
29182 }
29183 self.write(")");
29184 Ok(())
29185 }
29186
29187 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
29188 self.write_keyword("GROUPING SETS");
29190 self.write(" (");
29191 for (i, expr) in e.expressions.iter().enumerate() {
29192 if i > 0 {
29193 self.write(", ");
29194 }
29195 self.generate_expression(expr)?;
29196 }
29197 self.write(")");
29198 Ok(())
29199 }
29200
29201 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
29202 self.write_keyword("HASH_AGG");
29204 self.write("(");
29205 self.generate_expression(&e.this)?;
29206 for expr in &e.expressions {
29207 self.write(", ");
29208 self.generate_expression(expr)?;
29209 }
29210 self.write(")");
29211 Ok(())
29212 }
29213
29214 fn generate_having(&mut self, e: &Having) -> Result<()> {
29215 self.write_keyword("HAVING");
29217 self.write_space();
29218 self.generate_expression(&e.this)?;
29219 Ok(())
29220 }
29221
29222 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
29223 self.generate_expression(&e.this)?;
29225 self.write_space();
29226 self.write_keyword("HAVING");
29227 self.write_space();
29228 if e.max.is_some() {
29229 self.write_keyword("MAX");
29230 } else {
29231 self.write_keyword("MIN");
29232 }
29233 self.write_space();
29234 self.generate_expression(&e.expression)?;
29235 Ok(())
29236 }
29237
29238 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
29239 use crate::dialects::DialectType;
29240 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
29242 if let Expression::Literal(ref lit) = *e.this {
29244 if let Literal::String(ref s) = lit.as_ref() {
29245 return self.generate_string_literal(s);
29246 }
29247 }
29248 }
29249 if matches!(
29251 self.config.dialect,
29252 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29253 ) {
29254 self.write("$");
29255 if let Some(tag) = &e.tag {
29256 self.generate_expression(tag)?;
29257 }
29258 self.write("$");
29259 self.generate_expression(&e.this)?;
29260 self.write("$");
29261 if let Some(tag) = &e.tag {
29262 self.generate_expression(tag)?;
29263 }
29264 self.write("$");
29265 return Ok(());
29266 }
29267 self.write("$");
29269 if let Some(tag) = &e.tag {
29270 self.generate_expression(tag)?;
29271 }
29272 self.write("$");
29273 self.generate_expression(&e.this)?;
29274 self.write("$");
29275 if let Some(tag) = &e.tag {
29276 self.generate_expression(tag)?;
29277 }
29278 self.write("$");
29279 Ok(())
29280 }
29281
29282 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
29283 self.write_keyword("HEX_ENCODE");
29285 self.write("(");
29286 self.generate_expression(&e.this)?;
29287 self.write(")");
29288 Ok(())
29289 }
29290
29291 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
29292 match e.this.as_ref() {
29295 Expression::Identifier(id) => self.write(&id.name),
29296 other => self.generate_expression(other)?,
29297 }
29298 self.write(" (");
29299 self.write(&e.kind);
29300 self.write(" => ");
29301 self.generate_expression(&e.expression)?;
29302 self.write(")");
29303 Ok(())
29304 }
29305
29306 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
29307 self.write_keyword("HLL");
29309 self.write("(");
29310 self.generate_expression(&e.this)?;
29311 for expr in &e.expressions {
29312 self.write(", ");
29313 self.generate_expression(expr)?;
29314 }
29315 self.write(")");
29316 Ok(())
29317 }
29318
29319 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
29320 if e.input_.is_some() && e.output.is_some() {
29322 self.write_keyword("IN OUT");
29323 } else if e.input_.is_some() {
29324 self.write_keyword("IN");
29325 } else if e.output.is_some() {
29326 self.write_keyword("OUT");
29327 }
29328 Ok(())
29329 }
29330
29331 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
29332 self.write_keyword("INCLUDE");
29334 self.write_space();
29335 self.generate_expression(&e.this)?;
29336 if let Some(column_def) = &e.column_def {
29337 self.write_space();
29338 self.generate_expression(column_def)?;
29339 }
29340 if let Some(alias) = &e.alias {
29341 self.write_space();
29342 self.write_keyword("AS");
29343 self.write_space();
29344 self.write(alias);
29345 }
29346 Ok(())
29347 }
29348
29349 fn generate_index(&mut self, e: &Index) -> Result<()> {
29350 if e.unique {
29352 self.write_keyword("UNIQUE");
29353 self.write_space();
29354 }
29355 if e.primary.is_some() {
29356 self.write_keyword("PRIMARY");
29357 self.write_space();
29358 }
29359 if e.amp.is_some() {
29360 self.write_keyword("AMP");
29361 self.write_space();
29362 }
29363 if e.table.is_none() {
29364 self.write_keyword("INDEX");
29365 self.write_space();
29366 }
29367 if let Some(name) = &e.this {
29368 self.generate_expression(name)?;
29369 self.write_space();
29370 }
29371 if let Some(table) = &e.table {
29372 self.write_keyword("ON");
29373 self.write_space();
29374 self.generate_expression(table)?;
29375 }
29376 if !e.params.is_empty() {
29377 self.write("(");
29378 for (i, param) in e.params.iter().enumerate() {
29379 if i > 0 {
29380 self.write(", ");
29381 }
29382 self.generate_expression(param)?;
29383 }
29384 self.write(")");
29385 }
29386 Ok(())
29387 }
29388
29389 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
29390 if let Some(kind) = &e.kind {
29392 self.write(kind);
29393 self.write_space();
29394 }
29395 self.write_keyword("INDEX");
29396 if let Some(this) = &e.this {
29397 self.write_space();
29398 self.generate_expression(this)?;
29399 }
29400 if let Some(index_type) = &e.index_type {
29401 self.write_space();
29402 self.write_keyword("USING");
29403 self.write_space();
29404 self.generate_expression(index_type)?;
29405 }
29406 if !e.expressions.is_empty() {
29407 self.write(" (");
29408 for (i, expr) in e.expressions.iter().enumerate() {
29409 if i > 0 {
29410 self.write(", ");
29411 }
29412 self.generate_expression(expr)?;
29413 }
29414 self.write(")");
29415 }
29416 for opt in &e.options {
29417 self.write_space();
29418 self.generate_expression(opt)?;
29419 }
29420 Ok(())
29421 }
29422
29423 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
29424 if let Some(key_block_size) = &e.key_block_size {
29426 self.write_keyword("KEY_BLOCK_SIZE");
29427 self.write(" = ");
29428 self.generate_expression(key_block_size)?;
29429 } else if let Some(using) = &e.using {
29430 self.write_keyword("USING");
29431 self.write_space();
29432 self.generate_expression(using)?;
29433 } else if let Some(parser) = &e.parser {
29434 self.write_keyword("WITH PARSER");
29435 self.write_space();
29436 self.generate_expression(parser)?;
29437 } else if let Some(comment) = &e.comment {
29438 self.write_keyword("COMMENT");
29439 self.write_space();
29440 self.generate_expression(comment)?;
29441 } else if let Some(visible) = &e.visible {
29442 self.generate_expression(visible)?;
29443 } else if let Some(engine_attr) = &e.engine_attr {
29444 self.write_keyword("ENGINE_ATTRIBUTE");
29445 self.write(" = ");
29446 self.generate_expression(engine_attr)?;
29447 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
29448 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
29449 self.write(" = ");
29450 self.generate_expression(secondary_engine_attr)?;
29451 }
29452 Ok(())
29453 }
29454
29455 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
29456 if let Some(using) = &e.using {
29458 self.write_keyword("USING");
29459 self.write_space();
29460 self.generate_expression(using)?;
29461 }
29462 if !e.columns.is_empty() {
29463 self.write("(");
29464 for (i, col) in e.columns.iter().enumerate() {
29465 if i > 0 {
29466 self.write(", ");
29467 }
29468 self.generate_expression(col)?;
29469 }
29470 self.write(")");
29471 }
29472 if let Some(partition_by) = &e.partition_by {
29473 self.write_space();
29474 self.write_keyword("PARTITION BY");
29475 self.write_space();
29476 self.generate_expression(partition_by)?;
29477 }
29478 if let Some(where_) = &e.where_ {
29479 self.write_space();
29480 self.generate_expression(where_)?;
29481 }
29482 if let Some(include) = &e.include {
29483 self.write_space();
29484 self.write_keyword("INCLUDE");
29485 self.write(" (");
29486 self.generate_expression(include)?;
29487 self.write(")");
29488 }
29489 if let Some(with_storage) = &e.with_storage {
29490 self.write_space();
29491 self.write_keyword("WITH");
29492 self.write(" (");
29493 self.generate_expression(with_storage)?;
29494 self.write(")");
29495 }
29496 if let Some(tablespace) = &e.tablespace {
29497 self.write_space();
29498 self.write_keyword("USING INDEX TABLESPACE");
29499 self.write_space();
29500 self.generate_expression(tablespace)?;
29501 }
29502 Ok(())
29503 }
29504
29505 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
29506 if let Expression::Identifier(id) = &*e.this {
29510 self.write_keyword(&id.name);
29511 } else {
29512 self.generate_expression(&e.this)?;
29513 }
29514 self.write_space();
29515 self.write_keyword("INDEX");
29516 if let Some(target) = &e.target {
29517 self.write_space();
29518 self.write_keyword("FOR");
29519 self.write_space();
29520 if let Expression::Identifier(id) = &**target {
29521 self.write_keyword(&id.name);
29522 } else {
29523 self.generate_expression(target)?;
29524 }
29525 }
29526 self.write(" (");
29528 for (i, expr) in e.expressions.iter().enumerate() {
29529 if i > 0 {
29530 self.write(", ");
29531 }
29532 self.generate_expression(expr)?;
29533 }
29534 self.write(")");
29535 Ok(())
29536 }
29537
29538 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
29539 self.write_keyword("INHERITS");
29541 self.write(" (");
29542 for (i, expr) in e.expressions.iter().enumerate() {
29543 if i > 0 {
29544 self.write(", ");
29545 }
29546 self.generate_expression(expr)?;
29547 }
29548 self.write(")");
29549 Ok(())
29550 }
29551
29552 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
29553 self.write_keyword("INPUT");
29555 self.write("(");
29556 self.generate_expression(&e.this)?;
29557 self.write(")");
29558 Ok(())
29559 }
29560
29561 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
29562 if let Some(input_format) = &e.input_format {
29564 self.write_keyword("INPUTFORMAT");
29565 self.write_space();
29566 self.generate_expression(input_format)?;
29567 }
29568 if let Some(output_format) = &e.output_format {
29569 if e.input_format.is_some() {
29570 self.write(" ");
29571 }
29572 self.write_keyword("OUTPUTFORMAT");
29573 self.write_space();
29574 self.generate_expression(output_format)?;
29575 }
29576 Ok(())
29577 }
29578
29579 fn generate_install(&mut self, e: &Install) -> Result<()> {
29580 if e.force.is_some() {
29582 self.write_keyword("FORCE");
29583 self.write_space();
29584 }
29585 self.write_keyword("INSTALL");
29586 self.write_space();
29587 self.generate_expression(&e.this)?;
29588 if let Some(from) = &e.from_ {
29589 self.write_space();
29590 self.write_keyword("FROM");
29591 self.write_space();
29592 self.generate_expression(from)?;
29593 }
29594 Ok(())
29595 }
29596
29597 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
29598 self.write_keyword("INTERVAL");
29600 self.write_space();
29601 self.generate_expression(&e.expression)?;
29603 if let Some(unit) = &e.unit {
29604 self.write_space();
29605 self.write(unit);
29606 }
29607 Ok(())
29608 }
29609
29610 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
29611 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
29613 self.write_space();
29614 self.write_keyword("TO");
29615 self.write_space();
29616 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
29617 Ok(())
29618 }
29619
29620 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
29621 self.write_keyword("INTO");
29623 if e.temporary {
29624 self.write_keyword(" TEMPORARY");
29625 }
29626 if e.unlogged.is_some() {
29627 self.write_keyword(" UNLOGGED");
29628 }
29629 if let Some(this) = &e.this {
29630 self.write_space();
29631 self.generate_expression(this)?;
29632 }
29633 if !e.expressions.is_empty() {
29634 self.write(" (");
29635 for (i, expr) in e.expressions.iter().enumerate() {
29636 if i > 0 {
29637 self.write(", ");
29638 }
29639 self.generate_expression(expr)?;
29640 }
29641 self.write(")");
29642 }
29643 Ok(())
29644 }
29645
29646 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
29647 self.generate_expression(&e.this)?;
29649 self.write_space();
29650 self.generate_expression(&e.expression)?;
29651 Ok(())
29652 }
29653
29654 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
29655 self.write_keyword("WITH");
29657 if e.no.is_some() {
29658 self.write_keyword(" NO");
29659 }
29660 if e.concurrent.is_some() {
29661 self.write_keyword(" CONCURRENT");
29662 }
29663 self.write_keyword(" ISOLATED LOADING");
29664 if let Some(target) = &e.target {
29665 self.write_space();
29666 self.generate_expression(target)?;
29667 }
29668 Ok(())
29669 }
29670
29671 fn generate_json(&mut self, e: &JSON) -> Result<()> {
29672 self.write_keyword("JSON");
29674 if let Some(this) = &e.this {
29675 self.write_space();
29676 self.generate_expression(this)?;
29677 }
29678 if let Some(with_) = &e.with_ {
29679 if let Expression::Boolean(b) = with_.as_ref() {
29681 if b.value {
29682 self.write_keyword(" WITH");
29683 } else {
29684 self.write_keyword(" WITHOUT");
29685 }
29686 }
29687 }
29688 if e.unique {
29689 self.write_keyword(" UNIQUE KEYS");
29690 }
29691 Ok(())
29692 }
29693
29694 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
29695 self.write_keyword("JSON_ARRAY");
29697 self.write("(");
29698 for (i, expr) in e.expressions.iter().enumerate() {
29699 if i > 0 {
29700 self.write(", ");
29701 }
29702 self.generate_expression(expr)?;
29703 }
29704 if let Some(null_handling) = &e.null_handling {
29705 self.write_space();
29706 self.generate_expression(null_handling)?;
29707 }
29708 if let Some(return_type) = &e.return_type {
29709 self.write_space();
29710 self.write_keyword("RETURNING");
29711 self.write_space();
29712 self.generate_expression(return_type)?;
29713 }
29714 if e.strict.is_some() {
29715 self.write_space();
29716 self.write_keyword("STRICT");
29717 }
29718 self.write(")");
29719 Ok(())
29720 }
29721
29722 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
29723 self.write_keyword("JSON_ARRAYAGG");
29725 self.write("(");
29726 self.generate_expression(&e.this)?;
29727 if let Some(order) = &e.order {
29728 self.write_space();
29729 if let Expression::OrderBy(ob) = order.as_ref() {
29731 self.write_keyword("ORDER BY");
29732 self.write_space();
29733 for (i, ord) in ob.expressions.iter().enumerate() {
29734 if i > 0 {
29735 self.write(", ");
29736 }
29737 self.generate_ordered(ord)?;
29738 }
29739 } else {
29740 self.generate_expression(order)?;
29742 }
29743 }
29744 if let Some(null_handling) = &e.null_handling {
29745 self.write_space();
29746 self.generate_expression(null_handling)?;
29747 }
29748 if let Some(return_type) = &e.return_type {
29749 self.write_space();
29750 self.write_keyword("RETURNING");
29751 self.write_space();
29752 self.generate_expression(return_type)?;
29753 }
29754 if e.strict.is_some() {
29755 self.write_space();
29756 self.write_keyword("STRICT");
29757 }
29758 self.write(")");
29759 Ok(())
29760 }
29761
29762 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
29763 self.write_keyword("JSON_OBJECTAGG");
29765 self.write("(");
29766 for (i, expr) in e.expressions.iter().enumerate() {
29767 if i > 0 {
29768 self.write(", ");
29769 }
29770 self.generate_expression(expr)?;
29771 }
29772 if let Some(null_handling) = &e.null_handling {
29773 self.write_space();
29774 self.generate_expression(null_handling)?;
29775 }
29776 if let Some(unique_keys) = &e.unique_keys {
29777 self.write_space();
29778 if let Expression::Boolean(b) = unique_keys.as_ref() {
29779 if b.value {
29780 self.write_keyword("WITH UNIQUE KEYS");
29781 } else {
29782 self.write_keyword("WITHOUT UNIQUE KEYS");
29783 }
29784 }
29785 }
29786 if let Some(return_type) = &e.return_type {
29787 self.write_space();
29788 self.write_keyword("RETURNING");
29789 self.write_space();
29790 self.generate_expression(return_type)?;
29791 }
29792 self.write(")");
29793 Ok(())
29794 }
29795
29796 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
29797 self.write_keyword("JSON_ARRAY_APPEND");
29799 self.write("(");
29800 self.generate_expression(&e.this)?;
29801 for expr in &e.expressions {
29802 self.write(", ");
29803 self.generate_expression(expr)?;
29804 }
29805 self.write(")");
29806 Ok(())
29807 }
29808
29809 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
29810 self.write_keyword("JSON_ARRAY_CONTAINS");
29812 self.write("(");
29813 self.generate_expression(&e.this)?;
29814 self.write(", ");
29815 self.generate_expression(&e.expression)?;
29816 self.write(")");
29817 Ok(())
29818 }
29819
29820 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
29821 self.write_keyword("JSON_ARRAY_INSERT");
29823 self.write("(");
29824 self.generate_expression(&e.this)?;
29825 for expr in &e.expressions {
29826 self.write(", ");
29827 self.generate_expression(expr)?;
29828 }
29829 self.write(")");
29830 Ok(())
29831 }
29832
29833 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
29834 self.write_keyword("JSONB_EXISTS");
29836 self.write("(");
29837 self.generate_expression(&e.this)?;
29838 if let Some(path) = &e.path {
29839 self.write(", ");
29840 self.generate_expression(path)?;
29841 }
29842 self.write(")");
29843 Ok(())
29844 }
29845
29846 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
29847 self.write_keyword("JSONB_EXTRACT_SCALAR");
29849 self.write("(");
29850 self.generate_expression(&e.this)?;
29851 self.write(", ");
29852 self.generate_expression(&e.expression)?;
29853 self.write(")");
29854 Ok(())
29855 }
29856
29857 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
29858 self.write_keyword("JSONB_OBJECT_AGG");
29860 self.write("(");
29861 self.generate_expression(&e.this)?;
29862 self.write(", ");
29863 self.generate_expression(&e.expression)?;
29864 self.write(")");
29865 Ok(())
29866 }
29867
29868 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
29869 if let Some(nested_schema) = &e.nested_schema {
29871 self.write_keyword("NESTED");
29872 if let Some(path) = &e.path {
29873 self.write_space();
29874 self.write_keyword("PATH");
29875 self.write_space();
29876 self.generate_expression(path)?;
29877 }
29878 self.write_space();
29879 self.generate_expression(nested_schema)?;
29880 } else {
29881 if let Some(this) = &e.this {
29882 self.generate_expression(this)?;
29883 }
29884 if let Some(kind) = &e.kind {
29885 self.write_space();
29886 self.write(kind);
29887 }
29888 if let Some(path) = &e.path {
29889 self.write_space();
29890 self.write_keyword("PATH");
29891 self.write_space();
29892 self.generate_expression(path)?;
29893 }
29894 if e.ordinality.is_some() {
29895 self.write_keyword(" FOR ORDINALITY");
29896 }
29897 }
29898 Ok(())
29899 }
29900
29901 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
29902 self.write_keyword("JSON_EXISTS");
29904 self.write("(");
29905 self.generate_expression(&e.this)?;
29906 if let Some(path) = &e.path {
29907 self.write(", ");
29908 self.generate_expression(path)?;
29909 }
29910 if let Some(passing) = &e.passing {
29911 self.write_space();
29912 self.write_keyword("PASSING");
29913 self.write_space();
29914 self.generate_expression(passing)?;
29915 }
29916 if let Some(on_condition) = &e.on_condition {
29917 self.write_space();
29918 self.generate_expression(on_condition)?;
29919 }
29920 self.write(")");
29921 Ok(())
29922 }
29923
29924 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
29925 self.generate_expression(&e.this)?;
29926 self.write(".:");
29927 if Self::data_type_has_nested_expressions(&e.to) {
29931 let saved = std::mem::take(&mut self.output);
29933 self.generate_data_type(&e.to)?;
29934 let type_sql = std::mem::replace(&mut self.output, saved);
29935 self.write("\"");
29936 self.write(&type_sql);
29937 self.write("\"");
29938 } else {
29939 self.generate_data_type(&e.to)?;
29940 }
29941 Ok(())
29942 }
29943
29944 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
29947 matches!(
29948 dt,
29949 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
29950 )
29951 }
29952
29953 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
29954 self.write_keyword("JSON_EXTRACT_ARRAY");
29956 self.write("(");
29957 self.generate_expression(&e.this)?;
29958 if let Some(expr) = &e.expression {
29959 self.write(", ");
29960 self.generate_expression(expr)?;
29961 }
29962 self.write(")");
29963 Ok(())
29964 }
29965
29966 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
29967 if let Some(option) = &e.option {
29969 self.generate_expression(option)?;
29970 self.write_space();
29971 }
29972 self.write_keyword("QUOTES");
29973 if e.scalar.is_some() {
29974 self.write_keyword(" SCALAR_ONLY");
29975 }
29976 Ok(())
29977 }
29978
29979 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
29980 self.write_keyword("JSON_EXTRACT_SCALAR");
29982 self.write("(");
29983 self.generate_expression(&e.this)?;
29984 self.write(", ");
29985 self.generate_expression(&e.expression)?;
29986 self.write(")");
29987 Ok(())
29988 }
29989
29990 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
29991 if e.variant_extract.is_some() {
29995 use crate::dialects::DialectType;
29996 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
29997 self.generate_expression(&e.this)?;
30001 self.write(":");
30002 match e.expression.as_ref() {
30003 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
30004 let Literal::String(s) = lit.as_ref() else {
30005 unreachable!()
30006 };
30007 self.write_databricks_json_path(s);
30008 }
30009 _ => {
30010 self.generate_expression(&e.expression)?;
30012 }
30013 }
30014 } else {
30015 self.write_keyword("GET_PATH");
30017 self.write("(");
30018 self.generate_expression(&e.this)?;
30019 self.write(", ");
30020 self.generate_expression(&e.expression)?;
30021 self.write(")");
30022 }
30023 } else {
30024 self.write_keyword("JSON_EXTRACT");
30025 self.write("(");
30026 self.generate_expression(&e.this)?;
30027 self.write(", ");
30028 self.generate_expression(&e.expression)?;
30029 for expr in &e.expressions {
30030 self.write(", ");
30031 self.generate_expression(expr)?;
30032 }
30033 self.write(")");
30034 }
30035 Ok(())
30036 }
30037
30038 fn write_databricks_json_path(&mut self, path: &str) {
30042 if path.starts_with("[\"") || path.starts_with("['") {
30045 self.write(path);
30046 return;
30047 }
30048 let mut first = true;
30052 for segment in path.split('.') {
30053 if !first {
30054 self.write(".");
30055 }
30056 first = false;
30057 if let Some(bracket_pos) = segment.find('[') {
30059 let key = &segment[..bracket_pos];
30060 let subscript = &segment[bracket_pos..];
30061 if key.is_empty() {
30062 self.write(segment);
30064 } else if Self::is_safe_json_path_key(key) {
30065 self.write(key);
30066 self.write(subscript);
30067 } else {
30068 self.write("[\"");
30069 self.write(key);
30070 self.write("\"]");
30071 self.write(subscript);
30072 }
30073 } else if Self::is_safe_json_path_key(segment) {
30074 self.write(segment);
30075 } else {
30076 self.write("[\"");
30077 self.write(segment);
30078 self.write("\"]");
30079 }
30080 }
30081 }
30082
30083 fn is_safe_json_path_key(key: &str) -> bool {
30086 if key.is_empty() {
30087 return false;
30088 }
30089 let mut chars = key.chars();
30090 let first = chars.next().unwrap();
30091 if first != '_' && !first.is_ascii_alphabetic() {
30092 return false;
30093 }
30094 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
30095 }
30096
30097 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
30098 if let Some(this) = &e.this {
30101 self.generate_expression(this)?;
30102 self.write_space();
30103 }
30104 self.write_keyword("FORMAT JSON");
30105 Ok(())
30106 }
30107
30108 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
30109 self.generate_expression(&e.this)?;
30111 self.write(": ");
30112 self.generate_expression(&e.expression)?;
30113 Ok(())
30114 }
30115
30116 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
30117 self.write_keyword("JSON_KEYS");
30119 self.write("(");
30120 self.generate_expression(&e.this)?;
30121 if let Some(expr) = &e.expression {
30122 self.write(", ");
30123 self.generate_expression(expr)?;
30124 }
30125 for expr in &e.expressions {
30126 self.write(", ");
30127 self.generate_expression(expr)?;
30128 }
30129 self.write(")");
30130 Ok(())
30131 }
30132
30133 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
30134 self.write_keyword("JSON_KEYS");
30136 self.write("(");
30137 self.generate_expression(&e.this)?;
30138 if let Some(expr) = &e.expression {
30139 self.write(", ");
30140 self.generate_expression(expr)?;
30141 }
30142 self.write(")");
30143 Ok(())
30144 }
30145
30146 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
30147 let mut path_str = String::new();
30150 for expr in &e.expressions {
30151 match expr {
30152 Expression::JSONPathRoot(_) => {
30153 path_str.push('$');
30154 }
30155 Expression::JSONPathKey(k) => {
30156 if let Expression::Literal(lit) = k.this.as_ref() {
30158 if let crate::expressions::Literal::String(s) = lit.as_ref() {
30159 path_str.push('.');
30160 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
30162 if needs_quoting {
30163 path_str.push('"');
30164 path_str.push_str(s);
30165 path_str.push('"');
30166 } else {
30167 path_str.push_str(s);
30168 }
30169 }
30170 }
30171 }
30172 Expression::JSONPathSubscript(s) => {
30173 if let Expression::Literal(lit) = s.this.as_ref() {
30175 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
30176 path_str.push('[');
30177 path_str.push_str(n);
30178 path_str.push(']');
30179 }
30180 }
30181 }
30182 _ => {
30183 let mut temp_gen = Self::with_arc_config(self.config.clone());
30185 temp_gen.generate_expression(expr)?;
30186 path_str.push_str(&temp_gen.output);
30187 }
30188 }
30189 }
30190 self.write("'");
30192 self.write(&path_str);
30193 self.write("'");
30194 Ok(())
30195 }
30196
30197 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
30198 self.write("?(");
30200 self.generate_expression(&e.this)?;
30201 self.write(")");
30202 Ok(())
30203 }
30204
30205 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
30206 self.write(".");
30208 self.generate_expression(&e.this)?;
30209 Ok(())
30210 }
30211
30212 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
30213 self.write("..");
30215 if let Some(this) = &e.this {
30216 self.generate_expression(this)?;
30217 }
30218 Ok(())
30219 }
30220
30221 fn generate_json_path_root(&mut self) -> Result<()> {
30222 self.write("$");
30224 Ok(())
30225 }
30226
30227 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
30228 self.write("(");
30230 self.generate_expression(&e.this)?;
30231 self.write(")");
30232 Ok(())
30233 }
30234
30235 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
30236 self.generate_expression(&e.this)?;
30238 Ok(())
30239 }
30240
30241 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
30242 self.write("[");
30244 if let Some(start) = &e.start {
30245 self.generate_expression(start)?;
30246 }
30247 self.write(":");
30248 if let Some(end) = &e.end {
30249 self.generate_expression(end)?;
30250 }
30251 if let Some(step) = &e.step {
30252 self.write(":");
30253 self.generate_expression(step)?;
30254 }
30255 self.write("]");
30256 Ok(())
30257 }
30258
30259 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
30260 self.write("[");
30262 self.generate_expression(&e.this)?;
30263 self.write("]");
30264 Ok(())
30265 }
30266
30267 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
30268 self.write("[");
30270 for (i, expr) in e.expressions.iter().enumerate() {
30271 if i > 0 {
30272 self.write(", ");
30273 }
30274 self.generate_expression(expr)?;
30275 }
30276 self.write("]");
30277 Ok(())
30278 }
30279
30280 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
30281 self.write_keyword("JSON_REMOVE");
30283 self.write("(");
30284 self.generate_expression(&e.this)?;
30285 for expr in &e.expressions {
30286 self.write(", ");
30287 self.generate_expression(expr)?;
30288 }
30289 self.write(")");
30290 Ok(())
30291 }
30292
30293 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
30294 self.write_keyword("COLUMNS");
30297 self.write("(");
30298
30299 if self.config.pretty && !e.expressions.is_empty() {
30300 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
30302 for expr in &e.expressions {
30303 let mut temp_gen = Generator::with_arc_config(self.config.clone());
30304 temp_gen.generate_expression(expr)?;
30305 expr_strings.push(temp_gen.output);
30306 }
30307
30308 if self.too_wide(&expr_strings) {
30310 self.write_newline();
30312 self.indent_level += 1;
30313 for (i, expr_str) in expr_strings.iter().enumerate() {
30314 if i > 0 {
30315 self.write(",");
30316 self.write_newline();
30317 }
30318 self.write_indent();
30319 self.write(expr_str);
30320 }
30321 self.write_newline();
30322 self.indent_level -= 1;
30323 self.write_indent();
30324 } else {
30325 for (i, expr_str) in expr_strings.iter().enumerate() {
30327 if i > 0 {
30328 self.write(", ");
30329 }
30330 self.write(expr_str);
30331 }
30332 }
30333 } else {
30334 for (i, expr) in e.expressions.iter().enumerate() {
30336 if i > 0 {
30337 self.write(", ");
30338 }
30339 self.generate_expression(expr)?;
30340 }
30341 }
30342 self.write(")");
30343 Ok(())
30344 }
30345
30346 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
30347 self.write_keyword("JSON_SET");
30349 self.write("(");
30350 self.generate_expression(&e.this)?;
30351 for expr in &e.expressions {
30352 self.write(", ");
30353 self.generate_expression(expr)?;
30354 }
30355 self.write(")");
30356 Ok(())
30357 }
30358
30359 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
30360 self.write_keyword("JSON_STRIP_NULLS");
30362 self.write("(");
30363 self.generate_expression(&e.this)?;
30364 if let Some(expr) = &e.expression {
30365 self.write(", ");
30366 self.generate_expression(expr)?;
30367 }
30368 self.write(")");
30369 Ok(())
30370 }
30371
30372 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
30373 self.write_keyword("JSON_TABLE");
30375 self.write("(");
30376 self.generate_expression(&e.this)?;
30377 if let Some(path) = &e.path {
30378 self.write(", ");
30379 self.generate_expression(path)?;
30380 }
30381 if let Some(error_handling) = &e.error_handling {
30382 self.write_space();
30383 self.generate_expression(error_handling)?;
30384 }
30385 if let Some(empty_handling) = &e.empty_handling {
30386 self.write_space();
30387 self.generate_expression(empty_handling)?;
30388 }
30389 if let Some(schema) = &e.schema {
30390 self.write_space();
30391 self.generate_expression(schema)?;
30392 }
30393 self.write(")");
30394 Ok(())
30395 }
30396
30397 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
30398 self.write_keyword("JSON_TYPE");
30400 self.write("(");
30401 self.generate_expression(&e.this)?;
30402 self.write(")");
30403 Ok(())
30404 }
30405
30406 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
30407 self.write_keyword("JSON_VALUE");
30409 self.write("(");
30410 self.generate_expression(&e.this)?;
30411 if let Some(path) = &e.path {
30412 self.write(", ");
30413 self.generate_expression(path)?;
30414 }
30415 if let Some(returning) = &e.returning {
30416 self.write_space();
30417 self.write_keyword("RETURNING");
30418 self.write_space();
30419 self.generate_expression(returning)?;
30420 }
30421 if let Some(on_condition) = &e.on_condition {
30422 self.write_space();
30423 self.generate_expression(on_condition)?;
30424 }
30425 self.write(")");
30426 Ok(())
30427 }
30428
30429 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
30430 self.write_keyword("JSON_VALUE_ARRAY");
30432 self.write("(");
30433 self.generate_expression(&e.this)?;
30434 self.write(")");
30435 Ok(())
30436 }
30437
30438 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
30439 self.write_keyword("JAROWINKLER_SIMILARITY");
30441 self.write("(");
30442 self.generate_expression(&e.this)?;
30443 self.write(", ");
30444 self.generate_expression(&e.expression)?;
30445 self.write(")");
30446 Ok(())
30447 }
30448
30449 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
30450 self.generate_expression(&e.this)?;
30452 self.write("(");
30453 for (i, expr) in e.expressions.iter().enumerate() {
30454 if i > 0 {
30455 self.write(", ");
30456 }
30457 self.generate_expression(expr)?;
30458 }
30459 self.write(")");
30460 Ok(())
30461 }
30462
30463 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
30464 if e.no.is_some() {
30466 self.write_keyword("NO ");
30467 }
30468 if let Some(local) = &e.local {
30469 self.generate_expression(local)?;
30470 self.write_space();
30471 }
30472 if e.dual.is_some() {
30473 self.write_keyword("DUAL ");
30474 }
30475 if e.before.is_some() {
30476 self.write_keyword("BEFORE ");
30477 }
30478 if e.after.is_some() {
30479 self.write_keyword("AFTER ");
30480 }
30481 self.write_keyword("JOURNAL");
30482 Ok(())
30483 }
30484
30485 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
30486 self.write_keyword("LANGUAGE");
30488 self.write_space();
30489 self.generate_expression(&e.this)?;
30490 Ok(())
30491 }
30492
30493 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
30494 if e.view.is_some() {
30496 self.write_keyword("LATERAL VIEW");
30498 if e.outer.is_some() {
30499 self.write_space();
30500 self.write_keyword("OUTER");
30501 }
30502 self.write_space();
30503 self.generate_expression(&e.this)?;
30504 if let Some(alias) = &e.alias {
30505 self.write_space();
30506 self.write(alias);
30507 }
30508 } else {
30509 self.write_keyword("LATERAL");
30511 self.write_space();
30512 self.generate_expression(&e.this)?;
30513 if e.ordinality.is_some() {
30514 self.write_space();
30515 self.write_keyword("WITH ORDINALITY");
30516 }
30517 if let Some(alias) = &e.alias {
30518 self.write_space();
30519 self.write_keyword("AS");
30520 self.write_space();
30521 self.write(alias);
30522 if !e.column_aliases.is_empty() {
30523 self.write("(");
30524 for (i, col) in e.column_aliases.iter().enumerate() {
30525 if i > 0 {
30526 self.write(", ");
30527 }
30528 self.write(col);
30529 }
30530 self.write(")");
30531 }
30532 }
30533 }
30534 Ok(())
30535 }
30536
30537 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
30538 self.write_keyword("LIKE");
30540 self.write_space();
30541 self.generate_expression(&e.this)?;
30542 for expr in &e.expressions {
30543 self.write_space();
30544 self.generate_expression(expr)?;
30545 }
30546 Ok(())
30547 }
30548
30549 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
30550 self.write_keyword("LIMIT");
30551 self.write_space();
30552 self.write_limit_expr(&e.this)?;
30553 if e.percent {
30554 self.write_space();
30555 self.write_keyword("PERCENT");
30556 }
30557 for comment in &e.comments {
30559 self.write(" ");
30560 self.write_formatted_comment(comment);
30561 }
30562 Ok(())
30563 }
30564
30565 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
30566 if e.percent.is_some() {
30568 self.write_keyword(" PERCENT");
30569 }
30570 if e.rows.is_some() {
30571 self.write_keyword(" ROWS");
30572 }
30573 if e.with_ties.is_some() {
30574 self.write_keyword(" WITH TIES");
30575 } else if e.rows.is_some() {
30576 self.write_keyword(" ONLY");
30577 }
30578 Ok(())
30579 }
30580
30581 fn generate_list(&mut self, e: &List) -> Result<()> {
30582 use crate::dialects::DialectType;
30583 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
30584
30585 if e.expressions.len() == 1 {
30587 if let Expression::Select(_) = &e.expressions[0] {
30588 self.write_keyword("LIST");
30589 self.write("(");
30590 self.generate_expression(&e.expressions[0])?;
30591 self.write(")");
30592 return Ok(());
30593 }
30594 }
30595
30596 if is_materialize {
30598 self.write_keyword("LIST");
30599 self.write("[");
30600 for (i, expr) in e.expressions.iter().enumerate() {
30601 if i > 0 {
30602 self.write(", ");
30603 }
30604 self.generate_expression(expr)?;
30605 }
30606 self.write("]");
30607 } else {
30608 self.write_keyword("LIST");
30610 self.write("(");
30611 for (i, expr) in e.expressions.iter().enumerate() {
30612 if i > 0 {
30613 self.write(", ");
30614 }
30615 self.generate_expression(expr)?;
30616 }
30617 self.write(")");
30618 }
30619 Ok(())
30620 }
30621
30622 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
30623 if let Expression::Select(_) = &*e.this {
30625 self.write_keyword("MAP");
30626 self.write("(");
30627 self.generate_expression(&e.this)?;
30628 self.write(")");
30629 return Ok(());
30630 }
30631
30632 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
30633
30634 self.write_keyword("MAP");
30636 if is_duckdb {
30637 self.write(" {");
30638 } else {
30639 self.write("[");
30640 }
30641 if let Expression::Struct(s) = &*e.this {
30642 for (i, (_, expr)) in s.fields.iter().enumerate() {
30643 if i > 0 {
30644 self.write(", ");
30645 }
30646 if let Expression::PropertyEQ(op) = expr {
30647 self.generate_expression(&op.left)?;
30648 if is_duckdb {
30649 self.write(": ");
30650 } else {
30651 self.write(" => ");
30652 }
30653 self.generate_expression(&op.right)?;
30654 } else {
30655 self.generate_expression(expr)?;
30656 }
30657 }
30658 }
30659 if is_duckdb {
30660 self.write("}");
30661 } else {
30662 self.write("]");
30663 }
30664 Ok(())
30665 }
30666
30667 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
30668 self.write_keyword("LOCALTIME");
30670 if let Some(precision) = &e.this {
30671 self.write("(");
30672 self.generate_expression(precision)?;
30673 self.write(")");
30674 }
30675 Ok(())
30676 }
30677
30678 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
30679 self.write_keyword("LOCALTIMESTAMP");
30681 if let Some(precision) = &e.this {
30682 self.write("(");
30683 self.generate_expression(precision)?;
30684 self.write(")");
30685 }
30686 Ok(())
30687 }
30688
30689 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
30690 self.write_keyword("LOCATION");
30692 self.write_space();
30693 self.generate_expression(&e.this)?;
30694 Ok(())
30695 }
30696
30697 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
30698 if e.update.is_some() {
30700 if e.key.is_some() {
30701 self.write_keyword("FOR NO KEY UPDATE");
30702 } else {
30703 self.write_keyword("FOR UPDATE");
30704 }
30705 } else {
30706 if e.key.is_some() {
30707 self.write_keyword("FOR KEY SHARE");
30708 } else {
30709 self.write_keyword("FOR SHARE");
30710 }
30711 }
30712 if !e.expressions.is_empty() {
30713 self.write_keyword(" OF ");
30714 for (i, expr) in e.expressions.iter().enumerate() {
30715 if i > 0 {
30716 self.write(", ");
30717 }
30718 self.generate_expression(expr)?;
30719 }
30720 }
30721 if let Some(wait) = &e.wait {
30726 match wait.as_ref() {
30727 Expression::Boolean(b) => {
30728 if b.value {
30729 self.write_keyword(" NOWAIT");
30730 } else {
30731 self.write_keyword(" SKIP LOCKED");
30732 }
30733 }
30734 _ => {
30735 self.write_keyword(" WAIT ");
30737 self.generate_expression(wait)?;
30738 }
30739 }
30740 }
30741 Ok(())
30742 }
30743
30744 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
30745 self.write_keyword("LOCK");
30747 self.write_space();
30748 self.generate_expression(&e.this)?;
30749 Ok(())
30750 }
30751
30752 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
30753 self.write_keyword("LOCKING");
30755 self.write_space();
30756 self.write(&e.kind);
30757 if let Some(this) = &e.this {
30758 self.write_space();
30759 self.generate_expression(this)?;
30760 }
30761 if let Some(for_or_in) = &e.for_or_in {
30762 self.write_space();
30763 self.generate_expression(for_or_in)?;
30764 }
30765 if let Some(lock_type) = &e.lock_type {
30766 self.write_space();
30767 self.generate_expression(lock_type)?;
30768 }
30769 if e.override_.is_some() {
30770 self.write_keyword(" OVERRIDE");
30771 }
30772 Ok(())
30773 }
30774
30775 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
30776 self.generate_expression(&e.this)?;
30778 self.write_space();
30779 self.generate_expression(&e.expression)?;
30780 Ok(())
30781 }
30782
30783 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
30784 if e.no.is_some() {
30786 self.write_keyword("NO ");
30787 }
30788 self.write_keyword("LOG");
30789 Ok(())
30790 }
30791
30792 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
30793 self.write_keyword("MD5");
30795 self.write("(");
30796 self.generate_expression(&e.this)?;
30797 for expr in &e.expressions {
30798 self.write(", ");
30799 self.generate_expression(expr)?;
30800 }
30801 self.write(")");
30802 Ok(())
30803 }
30804
30805 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
30806 self.write_keyword("ML.FORECAST");
30808 self.write("(");
30809 self.generate_expression(&e.this)?;
30810 if let Some(expression) = &e.expression {
30811 self.write(", ");
30812 self.generate_expression(expression)?;
30813 }
30814 if let Some(params) = &e.params_struct {
30815 self.write(", ");
30816 self.generate_expression(params)?;
30817 }
30818 self.write(")");
30819 Ok(())
30820 }
30821
30822 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
30823 self.write_keyword("ML.TRANSLATE");
30825 self.write("(");
30826 self.generate_expression(&e.this)?;
30827 self.write(", ");
30828 self.generate_expression(&e.expression)?;
30829 if let Some(params) = &e.params_struct {
30830 self.write(", ");
30831 self.generate_expression(params)?;
30832 }
30833 self.write(")");
30834 Ok(())
30835 }
30836
30837 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
30838 self.write_keyword("MAKE_INTERVAL");
30840 self.write("(");
30841 let mut first = true;
30842 if let Some(year) = &e.year {
30843 self.write("years => ");
30844 self.generate_expression(year)?;
30845 first = false;
30846 }
30847 if let Some(month) = &e.month {
30848 if !first {
30849 self.write(", ");
30850 }
30851 self.write("months => ");
30852 self.generate_expression(month)?;
30853 first = false;
30854 }
30855 if let Some(week) = &e.week {
30856 if !first {
30857 self.write(", ");
30858 }
30859 self.write("weeks => ");
30860 self.generate_expression(week)?;
30861 first = false;
30862 }
30863 if let Some(day) = &e.day {
30864 if !first {
30865 self.write(", ");
30866 }
30867 self.write("days => ");
30868 self.generate_expression(day)?;
30869 first = false;
30870 }
30871 if let Some(hour) = &e.hour {
30872 if !first {
30873 self.write(", ");
30874 }
30875 self.write("hours => ");
30876 self.generate_expression(hour)?;
30877 first = false;
30878 }
30879 if let Some(minute) = &e.minute {
30880 if !first {
30881 self.write(", ");
30882 }
30883 self.write("mins => ");
30884 self.generate_expression(minute)?;
30885 first = false;
30886 }
30887 if let Some(second) = &e.second {
30888 if !first {
30889 self.write(", ");
30890 }
30891 self.write("secs => ");
30892 self.generate_expression(second)?;
30893 }
30894 self.write(")");
30895 Ok(())
30896 }
30897
30898 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
30899 self.write_keyword("MANHATTAN_DISTANCE");
30901 self.write("(");
30902 self.generate_expression(&e.this)?;
30903 self.write(", ");
30904 self.generate_expression(&e.expression)?;
30905 self.write(")");
30906 Ok(())
30907 }
30908
30909 fn generate_map(&mut self, e: &Map) -> Result<()> {
30910 self.write_keyword("MAP");
30912 self.write("(");
30913 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
30914 if i > 0 {
30915 self.write(", ");
30916 }
30917 self.generate_expression(key)?;
30918 self.write(", ");
30919 self.generate_expression(value)?;
30920 }
30921 self.write(")");
30922 Ok(())
30923 }
30924
30925 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
30926 self.write_keyword("MAP_CAT");
30928 self.write("(");
30929 self.generate_expression(&e.this)?;
30930 self.write(", ");
30931 self.generate_expression(&e.expression)?;
30932 self.write(")");
30933 Ok(())
30934 }
30935
30936 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
30937 self.write_keyword("MAP_DELETE");
30939 self.write("(");
30940 self.generate_expression(&e.this)?;
30941 for expr in &e.expressions {
30942 self.write(", ");
30943 self.generate_expression(expr)?;
30944 }
30945 self.write(")");
30946 Ok(())
30947 }
30948
30949 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
30950 self.write_keyword("MAP_INSERT");
30952 self.write("(");
30953 self.generate_expression(&e.this)?;
30954 if let Some(key) = &e.key {
30955 self.write(", ");
30956 self.generate_expression(key)?;
30957 }
30958 if let Some(value) = &e.value {
30959 self.write(", ");
30960 self.generate_expression(value)?;
30961 }
30962 if let Some(update_flag) = &e.update_flag {
30963 self.write(", ");
30964 self.generate_expression(update_flag)?;
30965 }
30966 self.write(")");
30967 Ok(())
30968 }
30969
30970 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
30971 self.write_keyword("MAP_PICK");
30973 self.write("(");
30974 self.generate_expression(&e.this)?;
30975 for expr in &e.expressions {
30976 self.write(", ");
30977 self.generate_expression(expr)?;
30978 }
30979 self.write(")");
30980 Ok(())
30981 }
30982
30983 fn generate_masking_policy_column_constraint(
30984 &mut self,
30985 e: &MaskingPolicyColumnConstraint,
30986 ) -> Result<()> {
30987 self.write_keyword("MASKING POLICY");
30989 self.write_space();
30990 self.generate_expression(&e.this)?;
30991 if !e.expressions.is_empty() {
30992 self.write_keyword(" USING");
30993 self.write(" (");
30994 for (i, expr) in e.expressions.iter().enumerate() {
30995 if i > 0 {
30996 self.write(", ");
30997 }
30998 self.generate_expression(expr)?;
30999 }
31000 self.write(")");
31001 }
31002 Ok(())
31003 }
31004
31005 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
31006 if matches!(
31007 self.config.dialect,
31008 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31009 ) {
31010 if e.expressions.len() > 1 {
31011 self.write("(");
31012 }
31013 for (i, expr) in e.expressions.iter().enumerate() {
31014 if i > 0 {
31015 self.write_keyword(" OR ");
31016 }
31017 self.generate_expression(expr)?;
31018 self.write_space();
31019 self.write("@@");
31020 self.write_space();
31021 self.generate_expression(&e.this)?;
31022 }
31023 if e.expressions.len() > 1 {
31024 self.write(")");
31025 }
31026 return Ok(());
31027 }
31028
31029 self.write_keyword("MATCH");
31031 self.write("(");
31032 for (i, expr) in e.expressions.iter().enumerate() {
31033 if i > 0 {
31034 self.write(", ");
31035 }
31036 self.generate_expression(expr)?;
31037 }
31038 self.write(")");
31039 self.write_keyword(" AGAINST");
31040 self.write("(");
31041 self.generate_expression(&e.this)?;
31042 if let Some(modifier) = &e.modifier {
31043 self.write_space();
31044 self.generate_expression(modifier)?;
31045 }
31046 self.write(")");
31047 Ok(())
31048 }
31049
31050 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
31051 if let Some(window_frame) = &e.window_frame {
31053 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
31054 self.write_space();
31055 }
31056 self.generate_expression(&e.this)?;
31057 Ok(())
31058 }
31059
31060 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
31061 self.write_keyword("MATERIALIZED");
31063 if let Some(this) = &e.this {
31064 self.write_space();
31065 self.generate_expression(this)?;
31066 }
31067 Ok(())
31068 }
31069
31070 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
31071 if let Some(with_) = &e.with_ {
31074 if let Expression::With(with_clause) = with_.as_ref() {
31075 self.generate_with(with_clause)?;
31076 self.write_space();
31077 } else {
31078 self.generate_expression(with_)?;
31079 self.write_space();
31080 }
31081 }
31082 self.write_keyword("MERGE INTO");
31083 self.write_space();
31084 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
31085 if let Expression::Alias(alias) = e.this.as_ref() {
31086 self.generate_expression(&alias.this)?;
31087 self.write_space();
31088 self.generate_identifier(&alias.alias)?;
31089 } else {
31090 self.generate_expression(&e.this)?;
31091 }
31092 } else {
31093 self.generate_expression(&e.this)?;
31094 }
31095
31096 if self.config.pretty {
31098 self.write_newline();
31099 self.write_indent();
31100 } else {
31101 self.write_space();
31102 }
31103 self.write_keyword("USING");
31104 self.write_space();
31105 self.generate_expression(&e.using)?;
31106
31107 if let Some(on) = &e.on {
31109 if self.config.pretty {
31110 self.write_newline();
31111 self.write_indent();
31112 } else {
31113 self.write_space();
31114 }
31115 self.write_keyword("ON");
31116 self.write_space();
31117 self.generate_expression(on)?;
31118 }
31119 if let Some(using_cond) = &e.using_cond {
31121 self.write_space();
31122 self.write_keyword("USING");
31123 self.write_space();
31124 self.write("(");
31125 if let Expression::Tuple(tuple) = using_cond.as_ref() {
31127 for (i, col) in tuple.expressions.iter().enumerate() {
31128 if i > 0 {
31129 self.write(", ");
31130 }
31131 self.generate_expression(col)?;
31132 }
31133 } else {
31134 self.generate_expression(using_cond)?;
31135 }
31136 self.write(")");
31137 }
31138 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
31140 if matches!(
31141 self.config.dialect,
31142 Some(crate::DialectType::PostgreSQL)
31143 | Some(crate::DialectType::Redshift)
31144 | Some(crate::DialectType::Trino)
31145 | Some(crate::DialectType::Presto)
31146 | Some(crate::DialectType::Athena)
31147 ) {
31148 let mut names = Vec::new();
31149 match e.this.as_ref() {
31150 Expression::Alias(a) => {
31151 if let Expression::Table(t) = &a.this {
31153 names.push(t.name.name.clone());
31154 } else if let Expression::Identifier(id) = &a.this {
31155 names.push(id.name.clone());
31156 }
31157 names.push(a.alias.name.clone());
31158 }
31159 Expression::Table(t) => {
31160 names.push(t.name.name.clone());
31161 }
31162 Expression::Identifier(id) => {
31163 names.push(id.name.clone());
31164 }
31165 _ => {}
31166 }
31167 self.merge_strip_qualifiers = names;
31168 }
31169
31170 if let Some(whens) = &e.whens {
31172 if self.config.pretty {
31173 self.write_newline();
31174 self.write_indent();
31175 } else {
31176 self.write_space();
31177 }
31178 self.generate_expression(whens)?;
31179 }
31180
31181 self.merge_strip_qualifiers = saved_merge_strip;
31183
31184 if let Some(returning) = &e.returning {
31186 if self.config.pretty {
31187 self.write_newline();
31188 self.write_indent();
31189 } else {
31190 self.write_space();
31191 }
31192 self.generate_expression(returning)?;
31193 }
31194 Ok(())
31195 }
31196
31197 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
31198 if e.no.is_some() {
31200 self.write_keyword("NO MERGEBLOCKRATIO");
31201 } else if e.default.is_some() {
31202 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
31203 } else {
31204 self.write_keyword("MERGEBLOCKRATIO");
31205 self.write("=");
31206 if let Some(this) = &e.this {
31207 self.generate_expression(this)?;
31208 }
31209 if e.percent.is_some() {
31210 self.write_keyword(" PERCENT");
31211 }
31212 }
31213 Ok(())
31214 }
31215
31216 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
31217 self.write_keyword("TTL");
31219 let pretty_clickhouse = self.config.pretty
31220 && matches!(
31221 self.config.dialect,
31222 Some(crate::dialects::DialectType::ClickHouse)
31223 );
31224
31225 if pretty_clickhouse {
31226 self.write_newline();
31227 self.indent_level += 1;
31228 for (i, expr) in e.expressions.iter().enumerate() {
31229 if i > 0 {
31230 self.write(",");
31231 self.write_newline();
31232 }
31233 self.write_indent();
31234 self.generate_expression(expr)?;
31235 }
31236 self.indent_level -= 1;
31237 } else {
31238 self.write_space();
31239 for (i, expr) in e.expressions.iter().enumerate() {
31240 if i > 0 {
31241 self.write(", ");
31242 }
31243 self.generate_expression(expr)?;
31244 }
31245 }
31246
31247 if let Some(where_) = &e.where_ {
31248 if pretty_clickhouse {
31249 self.write_newline();
31250 if let Expression::Where(w) = where_.as_ref() {
31251 self.write_indent();
31252 self.write_keyword("WHERE");
31253 self.write_newline();
31254 self.indent_level += 1;
31255 self.write_indent();
31256 self.generate_expression(&w.this)?;
31257 self.indent_level -= 1;
31258 } else {
31259 self.write_indent();
31260 self.generate_expression(where_)?;
31261 }
31262 } else {
31263 self.write_space();
31264 self.generate_expression(where_)?;
31265 }
31266 }
31267 if let Some(group) = &e.group {
31268 if pretty_clickhouse {
31269 self.write_newline();
31270 if let Expression::Group(g) = group.as_ref() {
31271 self.write_indent();
31272 self.write_keyword("GROUP BY");
31273 self.write_newline();
31274 self.indent_level += 1;
31275 for (i, expr) in g.expressions.iter().enumerate() {
31276 if i > 0 {
31277 self.write(",");
31278 self.write_newline();
31279 }
31280 self.write_indent();
31281 self.generate_expression(expr)?;
31282 }
31283 self.indent_level -= 1;
31284 } else {
31285 self.write_indent();
31286 self.generate_expression(group)?;
31287 }
31288 } else {
31289 self.write_space();
31290 self.generate_expression(group)?;
31291 }
31292 }
31293 if let Some(aggregates) = &e.aggregates {
31294 if pretty_clickhouse {
31295 self.write_newline();
31296 self.write_indent();
31297 self.write_keyword("SET");
31298 self.write_newline();
31299 self.indent_level += 1;
31300 if let Expression::Tuple(t) = aggregates.as_ref() {
31301 for (i, agg) in t.expressions.iter().enumerate() {
31302 if i > 0 {
31303 self.write(",");
31304 self.write_newline();
31305 }
31306 self.write_indent();
31307 self.generate_expression(agg)?;
31308 }
31309 } else {
31310 self.write_indent();
31311 self.generate_expression(aggregates)?;
31312 }
31313 self.indent_level -= 1;
31314 } else {
31315 self.write_space();
31316 self.write_keyword("SET");
31317 self.write_space();
31318 self.generate_expression(aggregates)?;
31319 }
31320 }
31321 Ok(())
31322 }
31323
31324 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
31325 self.generate_expression(&e.this)?;
31327 if e.delete.is_some() {
31328 self.write_keyword(" DELETE");
31329 }
31330 if let Some(recompress) = &e.recompress {
31331 self.write_keyword(" RECOMPRESS ");
31332 self.generate_expression(recompress)?;
31333 }
31334 if let Some(to_disk) = &e.to_disk {
31335 self.write_keyword(" TO DISK ");
31336 self.generate_expression(to_disk)?;
31337 }
31338 if let Some(to_volume) = &e.to_volume {
31339 self.write_keyword(" TO VOLUME ");
31340 self.generate_expression(to_volume)?;
31341 }
31342 Ok(())
31343 }
31344
31345 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
31346 self.write_keyword("MINHASH");
31348 self.write("(");
31349 self.generate_expression(&e.this)?;
31350 for expr in &e.expressions {
31351 self.write(", ");
31352 self.generate_expression(expr)?;
31353 }
31354 self.write(")");
31355 Ok(())
31356 }
31357
31358 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
31359 self.generate_expression(&e.this)?;
31361 self.write("!");
31362 self.generate_expression(&e.expression)?;
31363 Ok(())
31364 }
31365
31366 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
31367 self.write_keyword("MONTHNAME");
31369 self.write("(");
31370 self.generate_expression(&e.this)?;
31371 self.write(")");
31372 Ok(())
31373 }
31374
31375 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
31376 for comment in &e.leading_comments {
31378 self.write_formatted_comment(comment);
31379 if self.config.pretty {
31380 self.write_newline();
31381 self.write_indent();
31382 } else {
31383 self.write_space();
31384 }
31385 }
31386 self.write_keyword("INSERT");
31388 if e.overwrite {
31389 self.write_space();
31390 self.write_keyword("OVERWRITE");
31391 }
31392 self.write_space();
31393 self.write(&e.kind);
31394 if self.config.pretty {
31395 self.indent_level += 1;
31396 for expr in &e.expressions {
31397 self.write_newline();
31398 self.write_indent();
31399 self.generate_expression(expr)?;
31400 }
31401 self.indent_level -= 1;
31402 } else {
31403 for expr in &e.expressions {
31404 self.write_space();
31405 self.generate_expression(expr)?;
31406 }
31407 }
31408 if let Some(source) = &e.source {
31409 if self.config.pretty {
31410 self.write_newline();
31411 self.write_indent();
31412 } else {
31413 self.write_space();
31414 }
31415 self.generate_expression(source)?;
31416 }
31417 Ok(())
31418 }
31419
31420 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
31421 self.write_keyword("NEXT VALUE FOR");
31423 self.write_space();
31424 self.generate_expression(&e.this)?;
31425 if let Some(order) = &e.order {
31426 self.write_space();
31427 self.write_keyword("OVER");
31428 self.write(" (");
31429 self.generate_expression(order)?;
31430 self.write(")");
31431 }
31432 Ok(())
31433 }
31434
31435 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
31436 self.write_keyword("NORMAL");
31438 self.write("(");
31439 self.generate_expression(&e.this)?;
31440 if let Some(stddev) = &e.stddev {
31441 self.write(", ");
31442 self.generate_expression(stddev)?;
31443 }
31444 if let Some(gen) = &e.gen {
31445 self.write(", ");
31446 self.generate_expression(gen)?;
31447 }
31448 self.write(")");
31449 Ok(())
31450 }
31451
31452 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
31453 if e.is_casefold.is_some() {
31455 self.write_keyword("NORMALIZE_AND_CASEFOLD");
31456 } else {
31457 self.write_keyword("NORMALIZE");
31458 }
31459 self.write("(");
31460 self.generate_expression(&e.this)?;
31461 if let Some(form) = &e.form {
31462 self.write(", ");
31463 self.generate_expression(form)?;
31464 }
31465 self.write(")");
31466 Ok(())
31467 }
31468
31469 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
31470 if e.allow_null.is_none() {
31472 self.write_keyword("NOT ");
31473 }
31474 self.write_keyword("NULL");
31475 Ok(())
31476 }
31477
31478 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
31479 self.write_keyword("NULLIF");
31481 self.write("(");
31482 self.generate_expression(&e.this)?;
31483 self.write(", ");
31484 self.generate_expression(&e.expression)?;
31485 self.write(")");
31486 Ok(())
31487 }
31488
31489 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
31490 self.write_keyword("FORMAT");
31492 self.write("(");
31493 self.generate_expression(&e.this)?;
31494 self.write(", '");
31495 self.write(&e.format);
31496 self.write("'");
31497 if let Some(culture) = &e.culture {
31498 self.write(", ");
31499 self.generate_expression(culture)?;
31500 }
31501 self.write(")");
31502 Ok(())
31503 }
31504
31505 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
31506 self.write_keyword("OBJECT_AGG");
31508 self.write("(");
31509 self.generate_expression(&e.this)?;
31510 self.write(", ");
31511 self.generate_expression(&e.expression)?;
31512 self.write(")");
31513 Ok(())
31514 }
31515
31516 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
31517 self.generate_expression(&e.this)?;
31519 Ok(())
31520 }
31521
31522 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
31523 self.write_keyword("OBJECT_INSERT");
31525 self.write("(");
31526 self.generate_expression(&e.this)?;
31527 if let Some(key) = &e.key {
31528 self.write(", ");
31529 self.generate_expression(key)?;
31530 }
31531 if let Some(value) = &e.value {
31532 self.write(", ");
31533 self.generate_expression(value)?;
31534 }
31535 if let Some(update_flag) = &e.update_flag {
31536 self.write(", ");
31537 self.generate_expression(update_flag)?;
31538 }
31539 self.write(")");
31540 Ok(())
31541 }
31542
31543 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
31544 self.write_keyword("OFFSET");
31546 self.write_space();
31547 self.generate_expression(&e.this)?;
31548 if e.rows == Some(true)
31550 && matches!(
31551 self.config.dialect,
31552 Some(crate::dialects::DialectType::TSQL)
31553 | Some(crate::dialects::DialectType::Oracle)
31554 )
31555 {
31556 self.write_space();
31557 self.write_keyword("ROWS");
31558 }
31559 Ok(())
31560 }
31561
31562 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
31563 self.write_keyword("QUALIFY");
31565 self.write_space();
31566 self.generate_expression(&e.this)?;
31567 Ok(())
31568 }
31569
31570 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
31571 self.write_keyword("ON CLUSTER");
31573 self.write_space();
31574 self.generate_expression(&e.this)?;
31575 Ok(())
31576 }
31577
31578 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
31579 self.write_keyword("ON COMMIT");
31581 if e.delete.is_some() {
31582 self.write_keyword(" DELETE ROWS");
31583 } else {
31584 self.write_keyword(" PRESERVE ROWS");
31585 }
31586 Ok(())
31587 }
31588
31589 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
31590 if let Some(empty) = &e.empty {
31592 self.generate_expression(empty)?;
31593 self.write_keyword(" ON EMPTY");
31594 }
31595 if let Some(error) = &e.error {
31596 if e.empty.is_some() {
31597 self.write_space();
31598 }
31599 self.generate_expression(error)?;
31600 self.write_keyword(" ON ERROR");
31601 }
31602 if let Some(null) = &e.null {
31603 if e.empty.is_some() || e.error.is_some() {
31604 self.write_space();
31605 }
31606 self.generate_expression(null)?;
31607 self.write_keyword(" ON NULL");
31608 }
31609 Ok(())
31610 }
31611
31612 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
31613 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
31615 return Ok(());
31616 }
31617 if e.duplicate.is_some() {
31619 self.write_keyword("ON DUPLICATE KEY UPDATE");
31621 for (i, expr) in e.expressions.iter().enumerate() {
31622 if i > 0 {
31623 self.write(",");
31624 }
31625 self.write_space();
31626 self.generate_expression(expr)?;
31627 }
31628 return Ok(());
31629 } else {
31630 self.write_keyword("ON CONFLICT");
31631 }
31632 if let Some(constraint) = &e.constraint {
31633 self.write_keyword(" ON CONSTRAINT ");
31634 self.generate_expression(constraint)?;
31635 }
31636 if let Some(conflict_keys) = &e.conflict_keys {
31637 if let Expression::Tuple(t) = conflict_keys.as_ref() {
31639 self.write("(");
31640 for (i, expr) in t.expressions.iter().enumerate() {
31641 if i > 0 {
31642 self.write(", ");
31643 }
31644 self.generate_expression(expr)?;
31645 }
31646 self.write(")");
31647 } else {
31648 self.write("(");
31649 self.generate_expression(conflict_keys)?;
31650 self.write(")");
31651 }
31652 }
31653 if let Some(index_predicate) = &e.index_predicate {
31654 self.write_keyword(" WHERE ");
31655 self.generate_expression(index_predicate)?;
31656 }
31657 if let Some(action) = &e.action {
31658 if let Expression::Identifier(id) = action.as_ref() {
31660 if id.name.eq_ignore_ascii_case("NOTHING") {
31661 self.write_keyword(" DO NOTHING");
31662 } else {
31663 self.write_keyword(" DO ");
31664 self.generate_expression(action)?;
31665 }
31666 } else if let Expression::Tuple(t) = action.as_ref() {
31667 self.write_keyword(" DO UPDATE SET ");
31669 for (i, expr) in t.expressions.iter().enumerate() {
31670 if i > 0 {
31671 self.write(", ");
31672 }
31673 self.generate_expression(expr)?;
31674 }
31675 } else {
31676 self.write_keyword(" DO ");
31677 self.generate_expression(action)?;
31678 }
31679 }
31680 if let Some(where_) = &e.where_ {
31682 self.write_keyword(" WHERE ");
31683 self.generate_expression(where_)?;
31684 }
31685 Ok(())
31686 }
31687
31688 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
31689 self.write_keyword("ON");
31691 self.write_space();
31692 self.generate_expression(&e.this)?;
31693 Ok(())
31694 }
31695
31696 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
31697 self.generate_expression(&e.this)?;
31699 self.write_space();
31700 self.generate_expression(&e.expression)?;
31701 Ok(())
31702 }
31703
31704 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
31705 self.write_keyword("OPENJSON");
31707 self.write("(");
31708 self.generate_expression(&e.this)?;
31709 if let Some(path) = &e.path {
31710 self.write(", ");
31711 self.generate_expression(path)?;
31712 }
31713 self.write(")");
31714 if !e.expressions.is_empty() {
31715 self.write_keyword(" WITH");
31716 if self.config.pretty {
31717 self.write(" (\n");
31718 self.indent_level += 2;
31719 for (i, expr) in e.expressions.iter().enumerate() {
31720 if i > 0 {
31721 self.write(",\n");
31722 }
31723 self.write_indent();
31724 self.generate_expression(expr)?;
31725 }
31726 self.write("\n");
31727 self.indent_level -= 2;
31728 self.write(")");
31729 } else {
31730 self.write(" (");
31731 for (i, expr) in e.expressions.iter().enumerate() {
31732 if i > 0 {
31733 self.write(", ");
31734 }
31735 self.generate_expression(expr)?;
31736 }
31737 self.write(")");
31738 }
31739 }
31740 Ok(())
31741 }
31742
31743 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
31744 self.generate_expression(&e.this)?;
31746 self.write_space();
31747 if let Some(ref dt) = e.data_type {
31749 self.generate_data_type(dt)?;
31750 } else if !e.kind.is_empty() {
31751 self.write(&e.kind);
31752 }
31753 if let Some(path) = &e.path {
31754 self.write_space();
31755 self.generate_expression(path)?;
31756 }
31757 if e.as_json.is_some() {
31758 self.write_keyword(" AS JSON");
31759 }
31760 Ok(())
31761 }
31762
31763 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
31764 self.generate_expression(&e.this)?;
31766 self.write_space();
31767 if let Some(op) = &e.operator {
31768 self.write_keyword("OPERATOR");
31769 self.write("(");
31770 self.generate_expression(op)?;
31771 self.write(")");
31772 }
31773 for comment in &e.comments {
31775 self.write_space();
31776 self.write_formatted_comment(comment);
31777 }
31778 self.write_space();
31779 self.generate_expression(&e.expression)?;
31780 Ok(())
31781 }
31782
31783 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
31784 self.write_keyword("ORDER BY");
31786 let pretty_clickhouse_single_paren = self.config.pretty
31787 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
31788 && e.expressions.len() == 1
31789 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
31790 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
31791 && e.expressions.len() == 1
31792 && matches!(e.expressions[0].this, Expression::Tuple(_))
31793 && !e.expressions[0].desc
31794 && e.expressions[0].nulls_first.is_none();
31795
31796 if pretty_clickhouse_single_paren {
31797 self.write_space();
31798 if let Expression::Paren(p) = &e.expressions[0].this {
31799 self.write("(");
31800 self.write_newline();
31801 self.indent_level += 1;
31802 self.write_indent();
31803 self.generate_expression(&p.this)?;
31804 self.indent_level -= 1;
31805 self.write_newline();
31806 self.write(")");
31807 }
31808 return Ok(());
31809 }
31810
31811 if clickhouse_single_tuple {
31812 self.write_space();
31813 if let Expression::Tuple(t) = &e.expressions[0].this {
31814 self.write("(");
31815 for (i, expr) in t.expressions.iter().enumerate() {
31816 if i > 0 {
31817 self.write(", ");
31818 }
31819 self.generate_expression(expr)?;
31820 }
31821 self.write(")");
31822 }
31823 return Ok(());
31824 }
31825
31826 self.write_space();
31827 for (i, ordered) in e.expressions.iter().enumerate() {
31828 if i > 0 {
31829 self.write(", ");
31830 }
31831 self.generate_expression(&ordered.this)?;
31832 if ordered.desc {
31833 self.write_space();
31834 self.write_keyword("DESC");
31835 } else if ordered.explicit_asc {
31836 self.write_space();
31837 self.write_keyword("ASC");
31838 }
31839 if let Some(nulls_first) = ordered.nulls_first {
31840 let skip_nulls_last =
31842 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
31843 if !skip_nulls_last {
31844 self.write_space();
31845 self.write_keyword("NULLS");
31846 self.write_space();
31847 if nulls_first {
31848 self.write_keyword("FIRST");
31849 } else {
31850 self.write_keyword("LAST");
31851 }
31852 }
31853 }
31854 }
31855 Ok(())
31856 }
31857
31858 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
31859 self.write_keyword("OUTPUT");
31861 self.write("(");
31862 if self.config.pretty {
31863 self.indent_level += 1;
31864 self.write_newline();
31865 self.write_indent();
31866 self.generate_expression(&e.this)?;
31867 self.indent_level -= 1;
31868 self.write_newline();
31869 } else {
31870 self.generate_expression(&e.this)?;
31871 }
31872 self.write(")");
31873 Ok(())
31874 }
31875
31876 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
31877 self.write_keyword("TRUNCATE");
31879 if let Some(this) = &e.this {
31880 self.write_space();
31881 self.generate_expression(this)?;
31882 }
31883 if e.with_count.is_some() {
31884 self.write_keyword(" WITH COUNT");
31885 } else {
31886 self.write_keyword(" WITHOUT COUNT");
31887 }
31888 Ok(())
31889 }
31890
31891 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
31892 self.generate_expression(&e.this)?;
31894 self.write("(");
31895 for (i, expr) in e.expressions.iter().enumerate() {
31896 if i > 0 {
31897 self.write(", ");
31898 }
31899 self.generate_expression(expr)?;
31900 }
31901 self.write(")(");
31902 for (i, param) in e.params.iter().enumerate() {
31903 if i > 0 {
31904 self.write(", ");
31905 }
31906 self.generate_expression(param)?;
31907 }
31908 self.write(")");
31909 Ok(())
31910 }
31911
31912 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
31913 self.write_keyword("PARSE_DATETIME");
31915 self.write("(");
31916 if let Some(format) = &e.format {
31917 self.write("'");
31918 self.write(format);
31919 self.write("', ");
31920 }
31921 self.generate_expression(&e.this)?;
31922 if let Some(zone) = &e.zone {
31923 self.write(", ");
31924 self.generate_expression(zone)?;
31925 }
31926 self.write(")");
31927 Ok(())
31928 }
31929
31930 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
31931 self.write_keyword("PARSE_IP");
31933 self.write("(");
31934 self.generate_expression(&e.this)?;
31935 if let Some(type_) = &e.type_ {
31936 self.write(", ");
31937 self.generate_expression(type_)?;
31938 }
31939 if let Some(permissive) = &e.permissive {
31940 self.write(", ");
31941 self.generate_expression(permissive)?;
31942 }
31943 self.write(")");
31944 Ok(())
31945 }
31946
31947 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
31948 self.write_keyword("PARSE_JSON");
31950 self.write("(");
31951 self.generate_expression(&e.this)?;
31952 if let Some(expression) = &e.expression {
31953 self.write(", ");
31954 self.generate_expression(expression)?;
31955 }
31956 self.write(")");
31957 Ok(())
31958 }
31959
31960 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
31961 self.write_keyword("PARSE_TIME");
31963 self.write("(");
31964 self.write(&format!("'{}'", e.format));
31965 self.write(", ");
31966 self.generate_expression(&e.this)?;
31967 self.write(")");
31968 Ok(())
31969 }
31970
31971 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
31972 self.write_keyword("PARSE_URL");
31974 self.write("(");
31975 self.generate_expression(&e.this)?;
31976 if let Some(part) = &e.part_to_extract {
31977 self.write(", ");
31978 self.generate_expression(part)?;
31979 }
31980 if let Some(key) = &e.key {
31981 self.write(", ");
31982 self.generate_expression(key)?;
31983 }
31984 if let Some(permissive) = &e.permissive {
31985 self.write(", ");
31986 self.generate_expression(permissive)?;
31987 }
31988 self.write(")");
31989 Ok(())
31990 }
31991
31992 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
31993 if e.subpartition {
31995 self.write_keyword("SUBPARTITION");
31996 } else {
31997 self.write_keyword("PARTITION");
31998 }
31999 self.write("(");
32000 for (i, expr) in e.expressions.iter().enumerate() {
32001 if i > 0 {
32002 self.write(", ");
32003 }
32004 self.generate_expression(expr)?;
32005 }
32006 self.write(")");
32007 Ok(())
32008 }
32009
32010 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
32011 if let Some(this) = &e.this {
32013 if let Some(expression) = &e.expression {
32014 self.write_keyword("WITH");
32016 self.write(" (");
32017 self.write_keyword("MODULUS");
32018 self.write_space();
32019 self.generate_expression(this)?;
32020 self.write(", ");
32021 self.write_keyword("REMAINDER");
32022 self.write_space();
32023 self.generate_expression(expression)?;
32024 self.write(")");
32025 } else {
32026 self.write_keyword("IN");
32028 self.write(" (");
32029 self.generate_partition_bound_values(this)?;
32030 self.write(")");
32031 }
32032 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
32033 self.write_keyword("FROM");
32035 self.write(" (");
32036 self.generate_partition_bound_values(from)?;
32037 self.write(") ");
32038 self.write_keyword("TO");
32039 self.write(" (");
32040 self.generate_partition_bound_values(to)?;
32041 self.write(")");
32042 }
32043 Ok(())
32044 }
32045
32046 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
32049 if let Expression::Tuple(t) = expr {
32050 for (i, e) in t.expressions.iter().enumerate() {
32051 if i > 0 {
32052 self.write(", ");
32053 }
32054 self.generate_expression(e)?;
32055 }
32056 Ok(())
32057 } else {
32058 self.generate_expression(expr)
32059 }
32060 }
32061
32062 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
32063 self.write_keyword("PARTITION BY LIST");
32065 if let Some(partition_exprs) = &e.partition_expressions {
32066 self.write(" (");
32067 self.generate_doris_partition_expressions(partition_exprs)?;
32069 self.write(")");
32070 }
32071 if let Some(create_exprs) = &e.create_expressions {
32072 self.write(" (");
32073 self.generate_doris_partition_definitions(create_exprs)?;
32075 self.write(")");
32076 }
32077 Ok(())
32078 }
32079
32080 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
32081 self.write_keyword("PARTITION BY RANGE");
32083 if let Some(partition_exprs) = &e.partition_expressions {
32084 self.write(" (");
32085 self.generate_doris_partition_expressions(partition_exprs)?;
32087 self.write(")");
32088 }
32089 if let Some(create_exprs) = &e.create_expressions {
32090 self.write(" (");
32091 self.generate_doris_partition_definitions(create_exprs)?;
32093 self.write(")");
32094 }
32095 Ok(())
32096 }
32097
32098 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
32100 if let Expression::Tuple(t) = expr {
32101 for (i, e) in t.expressions.iter().enumerate() {
32102 if i > 0 {
32103 self.write(", ");
32104 }
32105 self.generate_expression(e)?;
32106 }
32107 } else {
32108 self.generate_expression(expr)?;
32109 }
32110 Ok(())
32111 }
32112
32113 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
32115 match expr {
32116 Expression::Tuple(t) => {
32117 for (i, part) in t.expressions.iter().enumerate() {
32119 if i > 0 {
32120 self.write(", ");
32121 }
32122 if let Expression::Partition(p) = part {
32124 for (j, inner) in p.expressions.iter().enumerate() {
32125 if j > 0 {
32126 self.write(", ");
32127 }
32128 self.generate_expression(inner)?;
32129 }
32130 } else {
32131 self.generate_expression(part)?;
32132 }
32133 }
32134 }
32135 Expression::PartitionByRangePropertyDynamic(_) => {
32136 self.generate_expression(expr)?;
32138 }
32139 _ => {
32140 self.generate_expression(expr)?;
32141 }
32142 }
32143 Ok(())
32144 }
32145
32146 fn generate_partition_by_range_property_dynamic(
32147 &mut self,
32148 e: &PartitionByRangePropertyDynamic,
32149 ) -> Result<()> {
32150 if e.use_start_end {
32151 if let Some(start) = &e.start {
32153 self.write_keyword("START");
32154 self.write(" (");
32155 self.generate_expression(start)?;
32156 self.write(")");
32157 }
32158 if let Some(end) = &e.end {
32159 self.write_space();
32160 self.write_keyword("END");
32161 self.write(" (");
32162 self.generate_expression(end)?;
32163 self.write(")");
32164 }
32165 if let Some(every) = &e.every {
32166 self.write_space();
32167 self.write_keyword("EVERY");
32168 self.write(" (");
32169 self.generate_doris_interval(every)?;
32171 self.write(")");
32172 }
32173 } else {
32174 if let Some(start) = &e.start {
32176 self.write_keyword("FROM");
32177 self.write(" (");
32178 self.generate_expression(start)?;
32179 self.write(")");
32180 }
32181 if let Some(end) = &e.end {
32182 self.write_space();
32183 self.write_keyword("TO");
32184 self.write(" (");
32185 self.generate_expression(end)?;
32186 self.write(")");
32187 }
32188 if let Some(every) = &e.every {
32189 self.write_space();
32190 self.generate_doris_interval(every)?;
32192 }
32193 }
32194 Ok(())
32195 }
32196
32197 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
32199 if let Expression::Interval(interval) = expr {
32200 self.write_keyword("INTERVAL");
32201 if let Some(ref value) = interval.this {
32202 self.write_space();
32203 match value {
32207 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()) => {
32208 if let Literal::String(s) = lit.as_ref() {
32209 self.write(s);
32210 }
32211 }
32212 _ => {
32213 self.generate_expression(value)?;
32214 }
32215 }
32216 }
32217 if let Some(ref unit_spec) = interval.unit {
32218 self.write_space();
32219 self.write_interval_unit_spec(unit_spec)?;
32220 }
32221 Ok(())
32222 } else {
32223 self.generate_expression(expr)
32224 }
32225 }
32226
32227 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
32228 self.write_keyword("TRUNCATE");
32230 self.write("(");
32231 self.generate_expression(&e.expression)?;
32232 self.write(", ");
32233 self.generate_expression(&e.this)?;
32234 self.write(")");
32235 Ok(())
32236 }
32237
32238 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
32239 self.write_keyword("PARTITION");
32241 self.write_space();
32242 self.generate_expression(&e.this)?;
32243 self.write_space();
32244 self.write_keyword("VALUES IN");
32245 self.write(" (");
32246 for (i, expr) in e.expressions.iter().enumerate() {
32247 if i > 0 {
32248 self.write(", ");
32249 }
32250 self.generate_expression(expr)?;
32251 }
32252 self.write(")");
32253 Ok(())
32254 }
32255
32256 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
32257 if e.expressions.is_empty() && e.expression.is_some() {
32260 self.generate_expression(&e.this)?;
32262 self.write_space();
32263 self.write_keyword("TO");
32264 self.write_space();
32265 self.generate_expression(e.expression.as_ref().unwrap())?;
32266 return Ok(());
32267 }
32268
32269 self.write_keyword("PARTITION");
32271 self.write_space();
32272 self.generate_expression(&e.this)?;
32273 self.write_space();
32274
32275 if e.expressions.len() == 1 {
32277 self.write_keyword("VALUES LESS THAN");
32279 self.write(" (");
32280 self.generate_expression(&e.expressions[0])?;
32281 self.write(")");
32282 } else if !e.expressions.is_empty() {
32283 self.write_keyword("VALUES");
32285 self.write(" [");
32286 for (i, expr) in e.expressions.iter().enumerate() {
32287 if i > 0 {
32288 self.write(", ");
32289 }
32290 if let Expression::Tuple(t) = expr {
32292 self.write("(");
32293 for (j, inner) in t.expressions.iter().enumerate() {
32294 if j > 0 {
32295 self.write(", ");
32296 }
32297 self.generate_expression(inner)?;
32298 }
32299 self.write(")");
32300 } else {
32301 self.write("(");
32302 self.generate_expression(expr)?;
32303 self.write(")");
32304 }
32305 }
32306 self.write(")");
32307 }
32308 Ok(())
32309 }
32310
32311 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
32312 self.write_keyword("BUCKET");
32314 self.write("(");
32315 self.generate_expression(&e.this)?;
32316 self.write(", ");
32317 self.generate_expression(&e.expression)?;
32318 self.write(")");
32319 Ok(())
32320 }
32321
32322 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
32323 self.write_keyword("PARTITION BY");
32325 self.write_space();
32326 for (i, expr) in e.expressions.iter().enumerate() {
32327 if i > 0 {
32328 self.write(", ");
32329 }
32330 self.generate_expression(expr)?;
32331 }
32332 Ok(())
32333 }
32334
32335 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
32336 if matches!(
32338 self.config.dialect,
32339 Some(crate::dialects::DialectType::Teradata)
32340 | Some(crate::dialects::DialectType::ClickHouse)
32341 ) {
32342 self.write_keyword("PARTITION BY");
32343 } else {
32344 self.write_keyword("PARTITIONED BY");
32345 }
32346 self.write_space();
32347 if self.config.pretty {
32349 if let Expression::Tuple(ref tuple) = *e.this {
32350 self.write("(");
32351 self.write_newline();
32352 self.indent_level += 1;
32353 for (i, expr) in tuple.expressions.iter().enumerate() {
32354 if i > 0 {
32355 self.write(",");
32356 self.write_newline();
32357 }
32358 self.write_indent();
32359 self.generate_expression(expr)?;
32360 }
32361 self.indent_level -= 1;
32362 self.write_newline();
32363 self.write(")");
32364 } else {
32365 self.generate_expression(&e.this)?;
32366 }
32367 } else {
32368 self.generate_expression(&e.this)?;
32369 }
32370 Ok(())
32371 }
32372
32373 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
32374 self.write_keyword("PARTITION OF");
32376 self.write_space();
32377 self.generate_expression(&e.this)?;
32378 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
32380 self.write_space();
32381 self.write_keyword("FOR VALUES");
32382 self.write_space();
32383 self.generate_expression(&e.expression)?;
32384 } else {
32385 self.write_space();
32386 self.write_keyword("DEFAULT");
32387 }
32388 Ok(())
32389 }
32390
32391 fn generate_period_for_system_time_constraint(
32392 &mut self,
32393 e: &PeriodForSystemTimeConstraint,
32394 ) -> Result<()> {
32395 self.write_keyword("PERIOD FOR SYSTEM_TIME");
32397 self.write(" (");
32398 self.generate_expression(&e.this)?;
32399 self.write(", ");
32400 self.generate_expression(&e.expression)?;
32401 self.write(")");
32402 Ok(())
32403 }
32404
32405 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
32406 self.generate_expression(&e.this)?;
32409 self.write_space();
32410 self.write_keyword("AS");
32411 self.write_space();
32412 if self.config.unpivot_aliases_are_identifiers {
32414 match &e.alias {
32415 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
32416 let Literal::String(s) = lit.as_ref() else {
32417 unreachable!()
32418 };
32419 self.generate_identifier(&Identifier::new(s.clone()))?;
32421 }
32422 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
32423 let Literal::Number(n) = lit.as_ref() else {
32424 unreachable!()
32425 };
32426 let mut id = Identifier::new(n.clone());
32428 id.quoted = true;
32429 self.generate_identifier(&id)?;
32430 }
32431 other => {
32432 self.generate_expression(other)?;
32433 }
32434 }
32435 } else {
32436 self.generate_expression(&e.alias)?;
32437 }
32438 Ok(())
32439 }
32440
32441 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
32442 self.write_keyword("ANY");
32444 if let Some(this) = &e.this {
32445 self.write_space();
32446 self.generate_expression(this)?;
32447 }
32448 Ok(())
32449 }
32450
32451 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
32452 self.write_keyword("ML.PREDICT");
32454 self.write("(");
32455 self.write_keyword("MODEL");
32456 self.write_space();
32457 self.generate_expression(&e.this)?;
32458 self.write(", ");
32459 self.generate_expression(&e.expression)?;
32460 if let Some(params) = &e.params_struct {
32461 self.write(", ");
32462 self.generate_expression(params)?;
32463 }
32464 self.write(")");
32465 Ok(())
32466 }
32467
32468 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
32469 self.write_keyword("PREVIOUS_DAY");
32471 self.write("(");
32472 self.generate_expression(&e.this)?;
32473 self.write(", ");
32474 self.generate_expression(&e.expression)?;
32475 self.write(")");
32476 Ok(())
32477 }
32478
32479 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
32480 self.write_keyword("PRIMARY KEY");
32482 if let Some(name) = &e.this {
32483 self.write_space();
32484 self.generate_expression(name)?;
32485 }
32486 if !e.expressions.is_empty() {
32487 self.write(" (");
32488 for (i, expr) in e.expressions.iter().enumerate() {
32489 if i > 0 {
32490 self.write(", ");
32491 }
32492 self.generate_expression(expr)?;
32493 }
32494 self.write(")");
32495 }
32496 if let Some(include) = &e.include {
32497 self.write_space();
32498 self.generate_expression(include)?;
32499 }
32500 if !e.options.is_empty() {
32501 self.write_space();
32502 for (i, opt) in e.options.iter().enumerate() {
32503 if i > 0 {
32504 self.write_space();
32505 }
32506 self.generate_expression(opt)?;
32507 }
32508 }
32509 Ok(())
32510 }
32511
32512 fn generate_primary_key_column_constraint(
32513 &mut self,
32514 _e: &PrimaryKeyColumnConstraint,
32515 ) -> Result<()> {
32516 self.write_keyword("PRIMARY KEY");
32518 Ok(())
32519 }
32520
32521 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
32522 self.write_keyword("PATH");
32524 self.write_space();
32525 self.generate_expression(&e.this)?;
32526 Ok(())
32527 }
32528
32529 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
32530 self.write_keyword("PROJECTION");
32532 self.write_space();
32533 self.generate_expression(&e.this)?;
32534 self.write(" (");
32535 self.generate_expression(&e.expression)?;
32536 self.write(")");
32537 Ok(())
32538 }
32539
32540 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
32541 for (i, prop) in e.expressions.iter().enumerate() {
32543 if i > 0 {
32544 self.write(", ");
32545 }
32546 self.generate_expression(prop)?;
32547 }
32548 Ok(())
32549 }
32550
32551 fn generate_property(&mut self, e: &Property) -> Result<()> {
32552 self.generate_expression(&e.this)?;
32554 if let Some(value) = &e.value {
32555 self.write("=");
32556 self.generate_expression(value)?;
32557 }
32558 Ok(())
32559 }
32560
32561 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
32562 self.write_keyword("OPTIONS");
32563 if e.entries.is_empty() {
32564 self.write(" ()");
32565 return Ok(());
32566 }
32567
32568 if self.config.pretty {
32569 self.write(" (");
32570 self.write_newline();
32571 self.indent_level += 1;
32572 for (i, entry) in e.entries.iter().enumerate() {
32573 if i > 0 {
32574 self.write(",");
32575 self.write_newline();
32576 }
32577 self.write_indent();
32578 self.generate_identifier(&entry.key)?;
32579 self.write("=");
32580 self.generate_expression(&entry.value)?;
32581 }
32582 self.indent_level -= 1;
32583 self.write_newline();
32584 self.write(")");
32585 } else {
32586 self.write(" (");
32587 for (i, entry) in e.entries.iter().enumerate() {
32588 if i > 0 {
32589 self.write(", ");
32590 }
32591 self.generate_identifier(&entry.key)?;
32592 self.write("=");
32593 self.generate_expression(&entry.value)?;
32594 }
32595 self.write(")");
32596 }
32597 Ok(())
32598 }
32599
32600 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
32602 self.write_keyword("OPTIONS");
32603 self.write(" (");
32604 for (i, opt) in options.iter().enumerate() {
32605 if i > 0 {
32606 self.write(", ");
32607 }
32608 self.generate_option_expression(opt)?;
32609 }
32610 self.write(")");
32611 Ok(())
32612 }
32613
32614 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
32616 self.write_keyword("PROPERTIES");
32617 self.write(" (");
32618 for (i, prop) in properties.iter().enumerate() {
32619 if i > 0 {
32620 self.write(", ");
32621 }
32622 self.generate_option_expression(prop)?;
32623 }
32624 self.write(")");
32625 Ok(())
32626 }
32627
32628 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
32630 self.write_keyword("ENVIRONMENT");
32631 self.write(" (");
32632 for (i, env_item) in environment.iter().enumerate() {
32633 if i > 0 {
32634 self.write(", ");
32635 }
32636 self.generate_environment_expression(env_item)?;
32637 }
32638 self.write(")");
32639 Ok(())
32640 }
32641
32642 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
32644 match expr {
32645 Expression::Eq(eq) => {
32646 self.generate_expression(&eq.left)?;
32648 self.write(" = ");
32649 self.generate_expression(&eq.right)?;
32650 Ok(())
32651 }
32652 _ => self.generate_expression(expr),
32653 }
32654 }
32655
32656 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
32658 self.write_keyword("TBLPROPERTIES");
32659 if self.config.pretty {
32660 self.write(" (");
32661 self.write_newline();
32662 self.indent_level += 1;
32663 for (i, opt) in options.iter().enumerate() {
32664 if i > 0 {
32665 self.write(",");
32666 self.write_newline();
32667 }
32668 self.write_indent();
32669 self.generate_option_expression(opt)?;
32670 }
32671 self.indent_level -= 1;
32672 self.write_newline();
32673 self.write(")");
32674 } else {
32675 self.write(" (");
32676 for (i, opt) in options.iter().enumerate() {
32677 if i > 0 {
32678 self.write(", ");
32679 }
32680 self.generate_option_expression(opt)?;
32681 }
32682 self.write(")");
32683 }
32684 Ok(())
32685 }
32686
32687 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
32689 match expr {
32690 Expression::Eq(eq) => {
32691 self.generate_expression(&eq.left)?;
32693 self.write("=");
32694 self.generate_expression(&eq.right)?;
32695 Ok(())
32696 }
32697 _ => self.generate_expression(expr),
32698 }
32699 }
32700
32701 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
32702 self.generate_expression(&e.this)?;
32704 Ok(())
32705 }
32706
32707 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
32708 self.write_keyword("PUT");
32710 self.write_space();
32711
32712 if e.source_quoted {
32714 self.write("'");
32715 self.write(&e.source);
32716 self.write("'");
32717 } else {
32718 self.write(&e.source);
32719 }
32720
32721 self.write_space();
32722
32723 if let Expression::Literal(lit) = &e.target {
32725 if let Literal::String(s) = lit.as_ref() {
32726 self.write(s);
32727 }
32728 } else {
32729 self.generate_expression(&e.target)?;
32730 }
32731
32732 for param in &e.params {
32734 self.write_space();
32735 self.write(¶m.name);
32736 if let Some(ref value) = param.value {
32737 self.write("=");
32738 self.generate_expression(value)?;
32739 }
32740 }
32741
32742 Ok(())
32743 }
32744
32745 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
32746 self.write_keyword("QUANTILE");
32748 self.write("(");
32749 self.generate_expression(&e.this)?;
32750 if let Some(quantile) = &e.quantile {
32751 self.write(", ");
32752 self.generate_expression(quantile)?;
32753 }
32754 self.write(")");
32755 Ok(())
32756 }
32757
32758 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
32759 if matches!(
32761 self.config.dialect,
32762 Some(crate::dialects::DialectType::Teradata)
32763 ) {
32764 self.write_keyword("SET");
32765 self.write_space();
32766 }
32767 self.write_keyword("QUERY_BAND");
32768 self.write(" = ");
32769 self.generate_expression(&e.this)?;
32770 if e.update.is_some() {
32771 self.write_space();
32772 self.write_keyword("UPDATE");
32773 }
32774 if let Some(scope) = &e.scope {
32775 self.write_space();
32776 self.write_keyword("FOR");
32777 self.write_space();
32778 self.generate_expression(scope)?;
32779 }
32780 Ok(())
32781 }
32782
32783 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
32784 self.generate_expression(&e.this)?;
32786 if let Some(expression) = &e.expression {
32787 self.write(" = ");
32788 self.generate_expression(expression)?;
32789 }
32790 Ok(())
32791 }
32792
32793 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
32794 self.write_keyword("TRANSFORM");
32796 self.write("(");
32797 for (i, expr) in e.expressions.iter().enumerate() {
32798 if i > 0 {
32799 self.write(", ");
32800 }
32801 self.generate_expression(expr)?;
32802 }
32803 self.write(")");
32804 if let Some(row_format_before) = &e.row_format_before {
32805 self.write_space();
32806 self.generate_expression(row_format_before)?;
32807 }
32808 if let Some(record_writer) = &e.record_writer {
32809 self.write_space();
32810 self.write_keyword("RECORDWRITER");
32811 self.write_space();
32812 self.generate_expression(record_writer)?;
32813 }
32814 if let Some(command_script) = &e.command_script {
32815 self.write_space();
32816 self.write_keyword("USING");
32817 self.write_space();
32818 self.generate_expression(command_script)?;
32819 }
32820 if let Some(schema) = &e.schema {
32821 self.write_space();
32822 self.write_keyword("AS");
32823 self.write_space();
32824 self.generate_expression(schema)?;
32825 }
32826 if let Some(row_format_after) = &e.row_format_after {
32827 self.write_space();
32828 self.generate_expression(row_format_after)?;
32829 }
32830 if let Some(record_reader) = &e.record_reader {
32831 self.write_space();
32832 self.write_keyword("RECORDREADER");
32833 self.write_space();
32834 self.generate_expression(record_reader)?;
32835 }
32836 Ok(())
32837 }
32838
32839 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
32840 self.write_keyword("RANDN");
32842 self.write("(");
32843 if let Some(this) = &e.this {
32844 self.generate_expression(this)?;
32845 }
32846 self.write(")");
32847 Ok(())
32848 }
32849
32850 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
32851 self.write_keyword("RANDSTR");
32853 self.write("(");
32854 self.generate_expression(&e.this)?;
32855 if let Some(generator) = &e.generator {
32856 self.write(", ");
32857 self.generate_expression(generator)?;
32858 }
32859 self.write(")");
32860 Ok(())
32861 }
32862
32863 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
32864 self.write_keyword("RANGE_BUCKET");
32866 self.write("(");
32867 self.generate_expression(&e.this)?;
32868 self.write(", ");
32869 self.generate_expression(&e.expression)?;
32870 self.write(")");
32871 Ok(())
32872 }
32873
32874 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
32875 self.write_keyword("RANGE_N");
32877 self.write("(");
32878 self.generate_expression(&e.this)?;
32879 self.write_space();
32880 self.write_keyword("BETWEEN");
32881 self.write_space();
32882 for (i, expr) in e.expressions.iter().enumerate() {
32883 if i > 0 {
32884 self.write(", ");
32885 }
32886 self.generate_expression(expr)?;
32887 }
32888 if let Some(each) = &e.each {
32889 self.write_space();
32890 self.write_keyword("EACH");
32891 self.write_space();
32892 self.generate_expression(each)?;
32893 }
32894 self.write(")");
32895 Ok(())
32896 }
32897
32898 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
32899 self.write_keyword("READ_CSV");
32901 self.write("(");
32902 self.generate_expression(&e.this)?;
32903 for expr in &e.expressions {
32904 self.write(", ");
32905 self.generate_expression(expr)?;
32906 }
32907 self.write(")");
32908 Ok(())
32909 }
32910
32911 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
32912 self.write_keyword("READ_PARQUET");
32914 self.write("(");
32915 for (i, expr) in e.expressions.iter().enumerate() {
32916 if i > 0 {
32917 self.write(", ");
32918 }
32919 self.generate_expression(expr)?;
32920 }
32921 self.write(")");
32922 Ok(())
32923 }
32924
32925 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
32926 if e.kind == "CYCLE" {
32929 self.write_keyword("CYCLE");
32930 } else {
32931 self.write_keyword("SEARCH");
32932 self.write_space();
32933 self.write(&e.kind);
32934 self.write_space();
32935 self.write_keyword("FIRST BY");
32936 }
32937 self.write_space();
32938 self.generate_expression(&e.this)?;
32939 self.write_space();
32940 self.write_keyword("SET");
32941 self.write_space();
32942 self.generate_expression(&e.expression)?;
32943 if let Some(using) = &e.using {
32944 self.write_space();
32945 self.write_keyword("USING");
32946 self.write_space();
32947 self.generate_expression(using)?;
32948 }
32949 Ok(())
32950 }
32951
32952 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
32953 self.write_keyword("REDUCE");
32955 self.write("(");
32956 self.generate_expression(&e.this)?;
32957 if let Some(initial) = &e.initial {
32958 self.write(", ");
32959 self.generate_expression(initial)?;
32960 }
32961 if let Some(merge) = &e.merge {
32962 self.write(", ");
32963 self.generate_expression(merge)?;
32964 }
32965 if let Some(finish) = &e.finish {
32966 self.write(", ");
32967 self.generate_expression(finish)?;
32968 }
32969 self.write(")");
32970 Ok(())
32971 }
32972
32973 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
32974 self.write_keyword("REFERENCES");
32976 self.write_space();
32977 self.generate_expression(&e.this)?;
32978 if !e.expressions.is_empty() {
32979 self.write(" (");
32980 for (i, expr) in e.expressions.iter().enumerate() {
32981 if i > 0 {
32982 self.write(", ");
32983 }
32984 self.generate_expression(expr)?;
32985 }
32986 self.write(")");
32987 }
32988 for opt in &e.options {
32989 self.write_space();
32990 self.generate_expression(opt)?;
32991 }
32992 Ok(())
32993 }
32994
32995 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
32996 self.write_keyword("REFRESH");
32998 if !e.kind.is_empty() {
32999 self.write_space();
33000 self.write_keyword(&e.kind);
33001 }
33002 self.write_space();
33003 self.generate_expression(&e.this)?;
33004 Ok(())
33005 }
33006
33007 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
33008 self.write_keyword("REFRESH");
33010 self.write_space();
33011 self.write_keyword(&e.method);
33012
33013 if let Some(ref kind) = e.kind {
33014 self.write_space();
33015 self.write_keyword("ON");
33016 self.write_space();
33017 self.write_keyword(kind);
33018
33019 if let Some(ref every) = e.every {
33021 self.write_space();
33022 self.write_keyword("EVERY");
33023 self.write_space();
33024 self.generate_expression(every)?;
33025 if let Some(ref unit) = e.unit {
33026 self.write_space();
33027 self.write_keyword(unit);
33028 }
33029 }
33030
33031 if let Some(ref starts) = e.starts {
33033 self.write_space();
33034 self.write_keyword("STARTS");
33035 self.write_space();
33036 self.generate_expression(starts)?;
33037 }
33038 }
33039 Ok(())
33040 }
33041
33042 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
33043 self.write_keyword("REGEXP_COUNT");
33045 self.write("(");
33046 self.generate_expression(&e.this)?;
33047 self.write(", ");
33048 self.generate_expression(&e.expression)?;
33049 if let Some(position) = &e.position {
33050 self.write(", ");
33051 self.generate_expression(position)?;
33052 }
33053 if let Some(parameters) = &e.parameters {
33054 self.write(", ");
33055 self.generate_expression(parameters)?;
33056 }
33057 self.write(")");
33058 Ok(())
33059 }
33060
33061 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
33062 self.write_keyword("REGEXP_EXTRACT_ALL");
33064 self.write("(");
33065 self.generate_expression(&e.this)?;
33066 self.write(", ");
33067 self.generate_expression(&e.expression)?;
33068 if let Some(group) = &e.group {
33069 self.write(", ");
33070 self.generate_expression(group)?;
33071 }
33072 self.write(")");
33073 Ok(())
33074 }
33075
33076 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
33077 self.write_keyword("REGEXP_FULL_MATCH");
33079 self.write("(");
33080 self.generate_expression(&e.this)?;
33081 self.write(", ");
33082 self.generate_expression(&e.expression)?;
33083 self.write(")");
33084 Ok(())
33085 }
33086
33087 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
33088 use crate::dialects::DialectType;
33089 if matches!(
33091 self.config.dialect,
33092 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
33093 ) && e.flag.is_none()
33094 {
33095 self.generate_expression(&e.this)?;
33096 self.write(" ~* ");
33097 self.generate_expression(&e.expression)?;
33098 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33099 self.write_keyword("REGEXP_LIKE");
33101 self.write("(");
33102 self.generate_expression(&e.this)?;
33103 self.write(", ");
33104 self.generate_expression(&e.expression)?;
33105 self.write(", ");
33106 if let Some(flag) = &e.flag {
33107 self.generate_expression(flag)?;
33108 } else {
33109 self.write("'i'");
33110 }
33111 self.write(")");
33112 } else {
33113 self.generate_expression(&e.this)?;
33115 self.write_space();
33116 self.write_keyword("REGEXP_ILIKE");
33117 self.write_space();
33118 self.generate_expression(&e.expression)?;
33119 if let Some(flag) = &e.flag {
33120 self.write(", ");
33121 self.generate_expression(flag)?;
33122 }
33123 }
33124 Ok(())
33125 }
33126
33127 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
33128 self.write_keyword("REGEXP_INSTR");
33130 self.write("(");
33131 self.generate_expression(&e.this)?;
33132 self.write(", ");
33133 self.generate_expression(&e.expression)?;
33134 if let Some(position) = &e.position {
33135 self.write(", ");
33136 self.generate_expression(position)?;
33137 }
33138 if let Some(occurrence) = &e.occurrence {
33139 self.write(", ");
33140 self.generate_expression(occurrence)?;
33141 }
33142 if let Some(option) = &e.option {
33143 self.write(", ");
33144 self.generate_expression(option)?;
33145 }
33146 if let Some(parameters) = &e.parameters {
33147 self.write(", ");
33148 self.generate_expression(parameters)?;
33149 }
33150 if let Some(group) = &e.group {
33151 self.write(", ");
33152 self.generate_expression(group)?;
33153 }
33154 self.write(")");
33155 Ok(())
33156 }
33157
33158 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
33159 self.write_keyword("REGEXP_SPLIT");
33161 self.write("(");
33162 self.generate_expression(&e.this)?;
33163 self.write(", ");
33164 self.generate_expression(&e.expression)?;
33165 if let Some(limit) = &e.limit {
33166 self.write(", ");
33167 self.generate_expression(limit)?;
33168 }
33169 self.write(")");
33170 Ok(())
33171 }
33172
33173 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
33174 self.write_keyword("REGR_AVGX");
33176 self.write("(");
33177 self.generate_expression(&e.this)?;
33178 self.write(", ");
33179 self.generate_expression(&e.expression)?;
33180 self.write(")");
33181 Ok(())
33182 }
33183
33184 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
33185 self.write_keyword("REGR_AVGY");
33187 self.write("(");
33188 self.generate_expression(&e.this)?;
33189 self.write(", ");
33190 self.generate_expression(&e.expression)?;
33191 self.write(")");
33192 Ok(())
33193 }
33194
33195 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
33196 self.write_keyword("REGR_COUNT");
33198 self.write("(");
33199 self.generate_expression(&e.this)?;
33200 self.write(", ");
33201 self.generate_expression(&e.expression)?;
33202 self.write(")");
33203 Ok(())
33204 }
33205
33206 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
33207 self.write_keyword("REGR_INTERCEPT");
33209 self.write("(");
33210 self.generate_expression(&e.this)?;
33211 self.write(", ");
33212 self.generate_expression(&e.expression)?;
33213 self.write(")");
33214 Ok(())
33215 }
33216
33217 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
33218 self.write_keyword("REGR_R2");
33220 self.write("(");
33221 self.generate_expression(&e.this)?;
33222 self.write(", ");
33223 self.generate_expression(&e.expression)?;
33224 self.write(")");
33225 Ok(())
33226 }
33227
33228 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
33229 self.write_keyword("REGR_SLOPE");
33231 self.write("(");
33232 self.generate_expression(&e.this)?;
33233 self.write(", ");
33234 self.generate_expression(&e.expression)?;
33235 self.write(")");
33236 Ok(())
33237 }
33238
33239 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
33240 self.write_keyword("REGR_SXX");
33242 self.write("(");
33243 self.generate_expression(&e.this)?;
33244 self.write(", ");
33245 self.generate_expression(&e.expression)?;
33246 self.write(")");
33247 Ok(())
33248 }
33249
33250 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
33251 self.write_keyword("REGR_SXY");
33253 self.write("(");
33254 self.generate_expression(&e.this)?;
33255 self.write(", ");
33256 self.generate_expression(&e.expression)?;
33257 self.write(")");
33258 Ok(())
33259 }
33260
33261 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
33262 self.write_keyword("REGR_SYY");
33264 self.write("(");
33265 self.generate_expression(&e.this)?;
33266 self.write(", ");
33267 self.generate_expression(&e.expression)?;
33268 self.write(")");
33269 Ok(())
33270 }
33271
33272 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
33273 self.write_keyword("REGR_VALX");
33275 self.write("(");
33276 self.generate_expression(&e.this)?;
33277 self.write(", ");
33278 self.generate_expression(&e.expression)?;
33279 self.write(")");
33280 Ok(())
33281 }
33282
33283 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
33284 self.write_keyword("REGR_VALY");
33286 self.write("(");
33287 self.generate_expression(&e.this)?;
33288 self.write(", ");
33289 self.generate_expression(&e.expression)?;
33290 self.write(")");
33291 Ok(())
33292 }
33293
33294 fn generate_remote_with_connection_model_property(
33295 &mut self,
33296 e: &RemoteWithConnectionModelProperty,
33297 ) -> Result<()> {
33298 self.write_keyword("REMOTE WITH CONNECTION");
33300 self.write_space();
33301 self.generate_expression(&e.this)?;
33302 Ok(())
33303 }
33304
33305 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
33306 self.write_keyword("RENAME COLUMN");
33308 if e.exists {
33309 self.write_space();
33310 self.write_keyword("IF EXISTS");
33311 }
33312 self.write_space();
33313 self.generate_expression(&e.this)?;
33314 if let Some(to) = &e.to {
33315 self.write_space();
33316 self.write_keyword("TO");
33317 self.write_space();
33318 self.generate_expression(to)?;
33319 }
33320 Ok(())
33321 }
33322
33323 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
33324 self.write_keyword("REPLACE PARTITION");
33326 self.write_space();
33327 self.generate_expression(&e.expression)?;
33328 if let Some(source) = &e.source {
33329 self.write_space();
33330 self.write_keyword("FROM");
33331 self.write_space();
33332 self.generate_expression(source)?;
33333 }
33334 Ok(())
33335 }
33336
33337 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
33338 let keyword = match self.config.dialect {
33341 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
33342 _ => "RETURNING",
33343 };
33344 self.write_keyword(keyword);
33345 self.write_space();
33346 for (i, expr) in e.expressions.iter().enumerate() {
33347 if i > 0 {
33348 self.write(", ");
33349 }
33350 self.generate_expression(expr)?;
33351 }
33352 if let Some(into) = &e.into {
33353 self.write_space();
33354 self.write_keyword("INTO");
33355 self.write_space();
33356 self.generate_expression(into)?;
33357 }
33358 Ok(())
33359 }
33360
33361 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
33362 self.write_space();
33364 self.write_keyword("OUTPUT");
33365 self.write_space();
33366 for (i, expr) in output.columns.iter().enumerate() {
33367 if i > 0 {
33368 self.write(", ");
33369 }
33370 self.generate_expression(expr)?;
33371 }
33372 if let Some(into_table) = &output.into_table {
33373 self.write_space();
33374 self.write_keyword("INTO");
33375 self.write_space();
33376 self.generate_expression(into_table)?;
33377 }
33378 Ok(())
33379 }
33380
33381 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
33382 self.write_keyword("RETURNS");
33384 if e.is_table.is_some() {
33385 self.write_space();
33386 self.write_keyword("TABLE");
33387 }
33388 if let Some(table) = &e.table {
33389 self.write_space();
33390 self.generate_expression(table)?;
33391 } else if let Some(this) = &e.this {
33392 self.write_space();
33393 self.generate_expression(this)?;
33394 }
33395 if e.null.is_some() {
33396 self.write_space();
33397 self.write_keyword("NULL ON NULL INPUT");
33398 }
33399 Ok(())
33400 }
33401
33402 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
33403 self.write_keyword("ROLLBACK");
33405
33406 if e.this.is_none()
33408 && matches!(
33409 self.config.dialect,
33410 Some(DialectType::TSQL) | Some(DialectType::Fabric)
33411 )
33412 {
33413 self.write_space();
33414 self.write_keyword("TRANSACTION");
33415 }
33416
33417 if let Some(this) = &e.this {
33419 let is_transaction_marker = matches!(
33421 this.as_ref(),
33422 Expression::Identifier(id) if id.name == "TRANSACTION"
33423 );
33424
33425 self.write_space();
33426 self.write_keyword("TRANSACTION");
33427
33428 if !is_transaction_marker {
33430 self.write_space();
33431 self.generate_expression(this)?;
33432 }
33433 }
33434
33435 if let Some(savepoint) = &e.savepoint {
33437 self.write_space();
33438 self.write_keyword("TO");
33439 self.write_space();
33440 self.generate_expression(savepoint)?;
33441 }
33442 Ok(())
33443 }
33444
33445 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
33446 if e.expressions.is_empty() {
33448 self.write_keyword("WITH ROLLUP");
33449 } else {
33450 self.write_keyword("ROLLUP");
33451 self.write("(");
33452 for (i, expr) in e.expressions.iter().enumerate() {
33453 if i > 0 {
33454 self.write(", ");
33455 }
33456 self.generate_expression(expr)?;
33457 }
33458 self.write(")");
33459 }
33460 Ok(())
33461 }
33462
33463 fn generate_row_format_delimited_property(
33464 &mut self,
33465 e: &RowFormatDelimitedProperty,
33466 ) -> Result<()> {
33467 self.write_keyword("ROW FORMAT DELIMITED");
33469 if let Some(fields) = &e.fields {
33470 self.write_space();
33471 self.write_keyword("FIELDS TERMINATED BY");
33472 self.write_space();
33473 self.generate_expression(fields)?;
33474 }
33475 if let Some(escaped) = &e.escaped {
33476 self.write_space();
33477 self.write_keyword("ESCAPED BY");
33478 self.write_space();
33479 self.generate_expression(escaped)?;
33480 }
33481 if let Some(items) = &e.collection_items {
33482 self.write_space();
33483 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
33484 self.write_space();
33485 self.generate_expression(items)?;
33486 }
33487 if let Some(keys) = &e.map_keys {
33488 self.write_space();
33489 self.write_keyword("MAP KEYS TERMINATED BY");
33490 self.write_space();
33491 self.generate_expression(keys)?;
33492 }
33493 if let Some(lines) = &e.lines {
33494 self.write_space();
33495 self.write_keyword("LINES TERMINATED BY");
33496 self.write_space();
33497 self.generate_expression(lines)?;
33498 }
33499 if let Some(null) = &e.null {
33500 self.write_space();
33501 self.write_keyword("NULL DEFINED AS");
33502 self.write_space();
33503 self.generate_expression(null)?;
33504 }
33505 if let Some(serde) = &e.serde {
33506 self.write_space();
33507 self.generate_expression(serde)?;
33508 }
33509 Ok(())
33510 }
33511
33512 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
33513 self.write_keyword("ROW FORMAT");
33515 self.write_space();
33516 self.generate_expression(&e.this)?;
33517 Ok(())
33518 }
33519
33520 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
33521 self.write_keyword("ROW FORMAT SERDE");
33523 self.write_space();
33524 self.generate_expression(&e.this)?;
33525 if let Some(props) = &e.serde_properties {
33526 self.write_space();
33527 self.generate_expression(props)?;
33529 }
33530 Ok(())
33531 }
33532
33533 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
33534 self.write_keyword("SHA2");
33536 self.write("(");
33537 self.generate_expression(&e.this)?;
33538 if let Some(length) = e.length {
33539 self.write(", ");
33540 self.write(&length.to_string());
33541 }
33542 self.write(")");
33543 Ok(())
33544 }
33545
33546 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
33547 self.write_keyword("SHA2_DIGEST");
33549 self.write("(");
33550 self.generate_expression(&e.this)?;
33551 if let Some(length) = e.length {
33552 self.write(", ");
33553 self.write(&length.to_string());
33554 }
33555 self.write(")");
33556 Ok(())
33557 }
33558
33559 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
33560 let name = if matches!(
33561 self.config.dialect,
33562 Some(crate::dialects::DialectType::Spark)
33563 | Some(crate::dialects::DialectType::Databricks)
33564 ) {
33565 "TRY_ADD"
33566 } else {
33567 "SAFE_ADD"
33568 };
33569 self.write_keyword(name);
33570 self.write("(");
33571 self.generate_expression(&e.this)?;
33572 self.write(", ");
33573 self.generate_expression(&e.expression)?;
33574 self.write(")");
33575 Ok(())
33576 }
33577
33578 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
33579 self.write_keyword("SAFE_DIVIDE");
33581 self.write("(");
33582 self.generate_expression(&e.this)?;
33583 self.write(", ");
33584 self.generate_expression(&e.expression)?;
33585 self.write(")");
33586 Ok(())
33587 }
33588
33589 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
33590 let name = if matches!(
33591 self.config.dialect,
33592 Some(crate::dialects::DialectType::Spark)
33593 | Some(crate::dialects::DialectType::Databricks)
33594 ) {
33595 "TRY_MULTIPLY"
33596 } else {
33597 "SAFE_MULTIPLY"
33598 };
33599 self.write_keyword(name);
33600 self.write("(");
33601 self.generate_expression(&e.this)?;
33602 self.write(", ");
33603 self.generate_expression(&e.expression)?;
33604 self.write(")");
33605 Ok(())
33606 }
33607
33608 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
33609 let name = if matches!(
33610 self.config.dialect,
33611 Some(crate::dialects::DialectType::Spark)
33612 | Some(crate::dialects::DialectType::Databricks)
33613 ) {
33614 "TRY_SUBTRACT"
33615 } else {
33616 "SAFE_SUBTRACT"
33617 };
33618 self.write_keyword(name);
33619 self.write("(");
33620 self.generate_expression(&e.this)?;
33621 self.write(", ");
33622 self.generate_expression(&e.expression)?;
33623 self.write(")");
33624 Ok(())
33625 }
33626
33627 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
33630 if matches!(sample.method, SampleMethod::Bucket) {
33632 self.write(" (");
33633 self.write_keyword("BUCKET");
33634 self.write_space();
33635 if let Some(ref num) = sample.bucket_numerator {
33636 self.generate_expression(num)?;
33637 }
33638 self.write_space();
33639 self.write_keyword("OUT OF");
33640 self.write_space();
33641 if let Some(ref denom) = sample.bucket_denominator {
33642 self.generate_expression(denom)?;
33643 }
33644 if let Some(ref field) = sample.bucket_field {
33645 self.write_space();
33646 self.write_keyword("ON");
33647 self.write_space();
33648 self.generate_expression(field)?;
33649 }
33650 self.write(")");
33651 return Ok(());
33652 }
33653
33654 let is_snowflake = matches!(
33656 self.config.dialect,
33657 Some(crate::dialects::DialectType::Snowflake)
33658 );
33659 let is_postgres = matches!(
33660 self.config.dialect,
33661 Some(crate::dialects::DialectType::PostgreSQL)
33662 | Some(crate::dialects::DialectType::Redshift)
33663 );
33664 let is_databricks = matches!(
33666 self.config.dialect,
33667 Some(crate::dialects::DialectType::Databricks)
33668 );
33669 let is_spark = matches!(
33670 self.config.dialect,
33671 Some(crate::dialects::DialectType::Spark)
33672 );
33673 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
33674 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
33676 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
33677 self.write_space();
33678 if !sample.explicit_method && (is_snowflake || force_method) {
33679 self.write_keyword("BERNOULLI");
33681 } else {
33682 match sample.method {
33683 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
33684 SampleMethod::System => self.write_keyword("SYSTEM"),
33685 SampleMethod::Block => self.write_keyword("BLOCK"),
33686 SampleMethod::Row => self.write_keyword("ROW"),
33687 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
33688 SampleMethod::Percent => self.write_keyword("SYSTEM"),
33689 SampleMethod::Bucket => {} }
33691 }
33692 }
33693
33694 let emit_size_no_parens = !self.config.tablesample_requires_parens;
33696 if emit_size_no_parens {
33697 self.write_space();
33698 match &sample.size {
33699 Expression::Tuple(tuple) => {
33700 for (i, expr) in tuple.expressions.iter().enumerate() {
33701 if i > 0 {
33702 self.write(", ");
33703 }
33704 self.generate_expression(expr)?;
33705 }
33706 }
33707 expr => self.generate_expression(expr)?,
33708 }
33709 } else {
33710 self.write(" (");
33711 self.generate_expression(&sample.size)?;
33712 }
33713
33714 let is_rows_method = matches!(
33716 sample.method,
33717 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
33718 );
33719 let is_percent = matches!(
33720 sample.method,
33721 SampleMethod::Percent
33722 | SampleMethod::System
33723 | SampleMethod::Bernoulli
33724 | SampleMethod::Block
33725 );
33726
33727 let is_presto = matches!(
33731 self.config.dialect,
33732 Some(crate::dialects::DialectType::Presto)
33733 | Some(crate::dialects::DialectType::Trino)
33734 | Some(crate::dialects::DialectType::Athena)
33735 );
33736 let should_output_unit = if is_databricks || is_spark {
33737 is_percent || is_rows_method || sample.unit_after_size
33739 } else if is_snowflake || is_postgres || is_presto {
33740 sample.unit_after_size
33741 } else {
33742 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
33743 };
33744
33745 if should_output_unit {
33746 self.write_space();
33747 if sample.is_percent {
33748 self.write_keyword("PERCENT");
33749 } else if is_rows_method && !sample.unit_after_size {
33750 self.write_keyword("ROWS");
33751 } else if sample.unit_after_size {
33752 match sample.method {
33753 SampleMethod::Percent
33754 | SampleMethod::System
33755 | SampleMethod::Bernoulli
33756 | SampleMethod::Block => {
33757 self.write_keyword("PERCENT");
33758 }
33759 SampleMethod::Row | SampleMethod::Reservoir => {
33760 self.write_keyword("ROWS");
33761 }
33762 _ => self.write_keyword("ROWS"),
33763 }
33764 } else {
33765 self.write_keyword("PERCENT");
33766 }
33767 }
33768
33769 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33770 if let Some(ref offset) = sample.offset {
33771 self.write_space();
33772 self.write_keyword("OFFSET");
33773 self.write_space();
33774 self.generate_expression(offset)?;
33775 }
33776 }
33777 if !emit_size_no_parens {
33778 self.write(")");
33779 }
33780
33781 Ok(())
33782 }
33783
33784 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
33785 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33787 self.write_keyword("SAMPLE BY");
33788 } else {
33789 self.write_keyword("SAMPLE");
33790 }
33791 self.write_space();
33792 self.generate_expression(&e.this)?;
33793 Ok(())
33794 }
33795
33796 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
33797 if let Some(this) = &e.this {
33799 self.generate_expression(this)?;
33800 }
33801 if !e.expressions.is_empty() {
33802 if e.this.is_some() {
33804 self.write_space();
33805 }
33806 self.write("(");
33807 for (i, expr) in e.expressions.iter().enumerate() {
33808 if i > 0 {
33809 self.write(", ");
33810 }
33811 self.generate_expression(expr)?;
33812 }
33813 self.write(")");
33814 }
33815 Ok(())
33816 }
33817
33818 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
33819 self.write_keyword("COMMENT");
33821 self.write_space();
33822 self.generate_expression(&e.this)?;
33823 Ok(())
33824 }
33825
33826 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
33827 if let Some(this) = &e.this {
33829 self.generate_expression(this)?;
33830 self.write("::");
33831 }
33832 self.generate_expression(&e.expression)?;
33833 Ok(())
33834 }
33835
33836 fn generate_search(&mut self, e: &Search) -> Result<()> {
33837 self.write_keyword("SEARCH");
33839 self.write("(");
33840 self.generate_expression(&e.this)?;
33841 self.write(", ");
33842 self.generate_expression(&e.expression)?;
33843 if let Some(json_scope) = &e.json_scope {
33844 self.write(", ");
33845 self.generate_expression(json_scope)?;
33846 }
33847 if let Some(analyzer) = &e.analyzer {
33848 self.write(", ");
33849 self.generate_expression(analyzer)?;
33850 }
33851 if let Some(analyzer_options) = &e.analyzer_options {
33852 self.write(", ");
33853 self.generate_expression(analyzer_options)?;
33854 }
33855 if let Some(search_mode) = &e.search_mode {
33856 self.write(", ");
33857 self.generate_expression(search_mode)?;
33858 }
33859 self.write(")");
33860 Ok(())
33861 }
33862
33863 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
33864 self.write_keyword("SEARCH_IP");
33866 self.write("(");
33867 self.generate_expression(&e.this)?;
33868 self.write(", ");
33869 self.generate_expression(&e.expression)?;
33870 self.write(")");
33871 Ok(())
33872 }
33873
33874 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
33875 self.write_keyword("SECURITY");
33877 self.write_space();
33878 self.generate_expression(&e.this)?;
33879 Ok(())
33880 }
33881
33882 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
33883 self.write("SEMANTIC_VIEW(");
33885
33886 if self.config.pretty {
33887 self.write_newline();
33889 self.indent_level += 1;
33890 self.write_indent();
33891 self.generate_expression(&e.this)?;
33892
33893 if let Some(metrics) = &e.metrics {
33894 self.write_newline();
33895 self.write_indent();
33896 self.write_keyword("METRICS");
33897 self.write_space();
33898 self.generate_semantic_view_tuple(metrics)?;
33899 }
33900 if let Some(dimensions) = &e.dimensions {
33901 self.write_newline();
33902 self.write_indent();
33903 self.write_keyword("DIMENSIONS");
33904 self.write_space();
33905 self.generate_semantic_view_tuple(dimensions)?;
33906 }
33907 if let Some(facts) = &e.facts {
33908 self.write_newline();
33909 self.write_indent();
33910 self.write_keyword("FACTS");
33911 self.write_space();
33912 self.generate_semantic_view_tuple(facts)?;
33913 }
33914 if let Some(where_) = &e.where_ {
33915 self.write_newline();
33916 self.write_indent();
33917 self.write_keyword("WHERE");
33918 self.write_space();
33919 self.generate_expression(where_)?;
33920 }
33921 self.write_newline();
33922 self.indent_level -= 1;
33923 self.write_indent();
33924 } else {
33925 self.generate_expression(&e.this)?;
33927 if let Some(metrics) = &e.metrics {
33928 self.write_space();
33929 self.write_keyword("METRICS");
33930 self.write_space();
33931 self.generate_semantic_view_tuple(metrics)?;
33932 }
33933 if let Some(dimensions) = &e.dimensions {
33934 self.write_space();
33935 self.write_keyword("DIMENSIONS");
33936 self.write_space();
33937 self.generate_semantic_view_tuple(dimensions)?;
33938 }
33939 if let Some(facts) = &e.facts {
33940 self.write_space();
33941 self.write_keyword("FACTS");
33942 self.write_space();
33943 self.generate_semantic_view_tuple(facts)?;
33944 }
33945 if let Some(where_) = &e.where_ {
33946 self.write_space();
33947 self.write_keyword("WHERE");
33948 self.write_space();
33949 self.generate_expression(where_)?;
33950 }
33951 }
33952 self.write(")");
33953 Ok(())
33954 }
33955
33956 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
33958 if let Expression::Tuple(t) = expr {
33959 for (i, e) in t.expressions.iter().enumerate() {
33960 if i > 0 {
33961 self.write(", ");
33962 }
33963 self.generate_expression(e)?;
33964 }
33965 } else {
33966 self.generate_expression(expr)?;
33967 }
33968 Ok(())
33969 }
33970
33971 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
33972 if let Some(start) = &e.start {
33974 self.write_keyword("START WITH");
33975 self.write_space();
33976 self.generate_expression(start)?;
33977 }
33978 if let Some(increment) = &e.increment {
33979 self.write_space();
33980 self.write_keyword("INCREMENT BY");
33981 self.write_space();
33982 self.generate_expression(increment)?;
33983 }
33984 if let Some(minvalue) = &e.minvalue {
33985 self.write_space();
33986 self.write_keyword("MINVALUE");
33987 self.write_space();
33988 self.generate_expression(minvalue)?;
33989 }
33990 if let Some(maxvalue) = &e.maxvalue {
33991 self.write_space();
33992 self.write_keyword("MAXVALUE");
33993 self.write_space();
33994 self.generate_expression(maxvalue)?;
33995 }
33996 if let Some(cache) = &e.cache {
33997 self.write_space();
33998 self.write_keyword("CACHE");
33999 self.write_space();
34000 self.generate_expression(cache)?;
34001 }
34002 if let Some(owned) = &e.owned {
34003 self.write_space();
34004 self.write_keyword("OWNED BY");
34005 self.write_space();
34006 self.generate_expression(owned)?;
34007 }
34008 for opt in &e.options {
34009 self.write_space();
34010 self.generate_expression(opt)?;
34011 }
34012 Ok(())
34013 }
34014
34015 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
34016 if e.with_.is_some() {
34018 self.write_keyword("WITH");
34019 self.write_space();
34020 }
34021 self.write_keyword("SERDEPROPERTIES");
34022 self.write(" (");
34023 for (i, expr) in e.expressions.iter().enumerate() {
34024 if i > 0 {
34025 self.write(", ");
34026 }
34027 match expr {
34029 Expression::Eq(eq) => {
34030 self.generate_expression(&eq.left)?;
34031 self.write("=");
34032 self.generate_expression(&eq.right)?;
34033 }
34034 _ => self.generate_expression(expr)?,
34035 }
34036 }
34037 self.write(")");
34038 Ok(())
34039 }
34040
34041 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
34042 self.write("@@");
34044 if let Some(kind) = &e.kind {
34045 self.write(kind);
34046 self.write(".");
34047 }
34048 self.generate_expression(&e.this)?;
34049 Ok(())
34050 }
34051
34052 fn generate_set(&mut self, e: &Set) -> Result<()> {
34053 if e.unset.is_some() {
34055 self.write_keyword("UNSET");
34056 } else {
34057 self.write_keyword("SET");
34058 }
34059 if e.tag.is_some() {
34060 self.write_space();
34061 self.write_keyword("TAG");
34062 }
34063 if !e.expressions.is_empty() {
34064 self.write_space();
34065 for (i, expr) in e.expressions.iter().enumerate() {
34066 if i > 0 {
34067 self.write(", ");
34068 }
34069 self.generate_expression(expr)?;
34070 }
34071 }
34072 Ok(())
34073 }
34074
34075 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
34076 self.write_keyword("SET");
34078 self.write_space();
34079 self.generate_expression(&e.this)?;
34080 Ok(())
34081 }
34082
34083 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
34084 if let Some(kind) = &e.kind {
34086 self.write_keyword(kind);
34087 self.write_space();
34088 }
34089 self.generate_expression(&e.name)?;
34090 self.write(" = ");
34091 self.generate_expression(&e.value)?;
34092 Ok(())
34093 }
34094
34095 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
34096 if let Some(with_) = &e.with_ {
34098 self.generate_expression(with_)?;
34099 self.write_space();
34100 }
34101 self.generate_expression(&e.this)?;
34102 self.write_space();
34103 if let Some(kind) = &e.kind {
34105 self.write_keyword(kind);
34106 }
34107 if e.distinct {
34108 self.write_space();
34109 self.write_keyword("DISTINCT");
34110 } else {
34111 self.write_space();
34112 self.write_keyword("ALL");
34113 }
34114 if e.by_name.is_some() {
34115 self.write_space();
34116 self.write_keyword("BY NAME");
34117 }
34118 self.write_space();
34119 self.generate_expression(&e.expression)?;
34120 Ok(())
34121 }
34122
34123 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
34124 if e.multi.is_some() {
34126 self.write_keyword("MULTISET");
34127 } else {
34128 self.write_keyword("SET");
34129 }
34130 Ok(())
34131 }
34132
34133 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
34134 self.write_keyword("SETTINGS");
34136 if self.config.pretty && e.expressions.len() > 1 {
34137 self.indent_level += 1;
34139 for (i, expr) in e.expressions.iter().enumerate() {
34140 if i > 0 {
34141 self.write(",");
34142 }
34143 self.write_newline();
34144 self.write_indent();
34145 self.generate_expression(expr)?;
34146 }
34147 self.indent_level -= 1;
34148 } else {
34149 self.write_space();
34150 for (i, expr) in e.expressions.iter().enumerate() {
34151 if i > 0 {
34152 self.write(", ");
34153 }
34154 self.generate_expression(expr)?;
34155 }
34156 }
34157 Ok(())
34158 }
34159
34160 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
34161 self.write_keyword("SHARING");
34163 if let Some(this) = &e.this {
34164 self.write(" = ");
34165 self.generate_expression(this)?;
34166 }
34167 Ok(())
34168 }
34169
34170 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
34171 if let Some(begin) = &e.this {
34173 self.generate_expression(begin)?;
34174 }
34175 self.write(":");
34176 if let Some(end) = &e.expression {
34177 self.generate_expression(end)?;
34178 }
34179 if let Some(step) = &e.step {
34180 self.write(":");
34181 self.generate_expression(step)?;
34182 }
34183 Ok(())
34184 }
34185
34186 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
34187 self.write_keyword("SORT_ARRAY");
34189 self.write("(");
34190 self.generate_expression(&e.this)?;
34191 if let Some(asc) = &e.asc {
34192 self.write(", ");
34193 self.generate_expression(asc)?;
34194 }
34195 self.write(")");
34196 Ok(())
34197 }
34198
34199 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
34200 self.write_keyword("SORT BY");
34202 self.write_space();
34203 for (i, expr) in e.expressions.iter().enumerate() {
34204 if i > 0 {
34205 self.write(", ");
34206 }
34207 self.generate_ordered(expr)?;
34208 }
34209 Ok(())
34210 }
34211
34212 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
34213 if e.compound.is_some() {
34215 self.write_keyword("COMPOUND");
34216 self.write_space();
34217 }
34218 self.write_keyword("SORTKEY");
34219 self.write("(");
34220 if let Expression::Tuple(t) = e.this.as_ref() {
34222 for (i, expr) in t.expressions.iter().enumerate() {
34223 if i > 0 {
34224 self.write(", ");
34225 }
34226 self.generate_expression(expr)?;
34227 }
34228 } else {
34229 self.generate_expression(&e.this)?;
34230 }
34231 self.write(")");
34232 Ok(())
34233 }
34234
34235 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
34236 self.write_keyword("SPLIT_PART");
34238 self.write("(");
34239 self.generate_expression(&e.this)?;
34240 if let Some(delimiter) = &e.delimiter {
34241 self.write(", ");
34242 self.generate_expression(delimiter)?;
34243 }
34244 if let Some(part_index) = &e.part_index {
34245 self.write(", ");
34246 self.generate_expression(part_index)?;
34247 }
34248 self.write(")");
34249 Ok(())
34250 }
34251
34252 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
34253 self.generate_expression(&e.this)?;
34255 Ok(())
34256 }
34257
34258 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
34259 self.write_keyword("SQL SECURITY");
34261 self.write_space();
34262 self.generate_expression(&e.this)?;
34263 Ok(())
34264 }
34265
34266 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
34267 self.write_keyword("ST_DISTANCE");
34269 self.write("(");
34270 self.generate_expression(&e.this)?;
34271 self.write(", ");
34272 self.generate_expression(&e.expression)?;
34273 if let Some(use_spheroid) = &e.use_spheroid {
34274 self.write(", ");
34275 self.generate_expression(use_spheroid)?;
34276 }
34277 self.write(")");
34278 Ok(())
34279 }
34280
34281 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
34282 self.write_keyword("ST_POINT");
34284 self.write("(");
34285 self.generate_expression(&e.this)?;
34286 self.write(", ");
34287 self.generate_expression(&e.expression)?;
34288 self.write(")");
34289 Ok(())
34290 }
34291
34292 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
34293 self.generate_expression(&e.this)?;
34295 Ok(())
34296 }
34297
34298 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
34299 self.write_keyword("STANDARD_HASH");
34301 self.write("(");
34302 self.generate_expression(&e.this)?;
34303 if let Some(expression) = &e.expression {
34304 self.write(", ");
34305 self.generate_expression(expression)?;
34306 }
34307 self.write(")");
34308 Ok(())
34309 }
34310
34311 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
34312 self.write_keyword("STORED BY");
34314 self.write_space();
34315 self.generate_expression(&e.this)?;
34316 Ok(())
34317 }
34318
34319 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
34320 use crate::dialects::DialectType;
34323 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34324 self.write_keyword("CHARINDEX");
34326 self.write("(");
34327 if let Some(substr) = &e.substr {
34328 self.generate_expression(substr)?;
34329 self.write(", ");
34330 }
34331 self.generate_expression(&e.this)?;
34332 if let Some(position) = &e.position {
34333 self.write(", ");
34334 self.generate_expression(position)?;
34335 }
34336 self.write(")");
34337 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34338 self.write_keyword("POSITION");
34339 self.write("(");
34340 self.generate_expression(&e.this)?;
34341 if let Some(substr) = &e.substr {
34342 self.write(", ");
34343 self.generate_expression(substr)?;
34344 }
34345 if let Some(position) = &e.position {
34346 self.write(", ");
34347 self.generate_expression(position)?;
34348 }
34349 if let Some(occurrence) = &e.occurrence {
34350 self.write(", ");
34351 self.generate_expression(occurrence)?;
34352 }
34353 self.write(")");
34354 } else if matches!(
34355 self.config.dialect,
34356 Some(DialectType::SQLite)
34357 | Some(DialectType::Oracle)
34358 | Some(DialectType::BigQuery)
34359 | Some(DialectType::Teradata)
34360 ) {
34361 self.write_keyword("INSTR");
34362 self.write("(");
34363 self.generate_expression(&e.this)?;
34364 if let Some(substr) = &e.substr {
34365 self.write(", ");
34366 self.generate_expression(substr)?;
34367 }
34368 if let Some(position) = &e.position {
34369 self.write(", ");
34370 self.generate_expression(position)?;
34371 } else if e.occurrence.is_some() {
34372 self.write(", 1");
34375 }
34376 if let Some(occurrence) = &e.occurrence {
34377 self.write(", ");
34378 self.generate_expression(occurrence)?;
34379 }
34380 self.write(")");
34381 } else if matches!(
34382 self.config.dialect,
34383 Some(DialectType::MySQL)
34384 | Some(DialectType::SingleStore)
34385 | Some(DialectType::Doris)
34386 | Some(DialectType::StarRocks)
34387 | Some(DialectType::Hive)
34388 | Some(DialectType::Spark)
34389 | Some(DialectType::Databricks)
34390 ) {
34391 self.write_keyword("LOCATE");
34393 self.write("(");
34394 if let Some(substr) = &e.substr {
34395 self.generate_expression(substr)?;
34396 self.write(", ");
34397 }
34398 self.generate_expression(&e.this)?;
34399 if let Some(position) = &e.position {
34400 self.write(", ");
34401 self.generate_expression(position)?;
34402 }
34403 self.write(")");
34404 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
34405 self.write_keyword("CHARINDEX");
34407 self.write("(");
34408 if let Some(substr) = &e.substr {
34409 self.generate_expression(substr)?;
34410 self.write(", ");
34411 }
34412 self.generate_expression(&e.this)?;
34413 if let Some(position) = &e.position {
34414 self.write(", ");
34415 self.generate_expression(position)?;
34416 }
34417 self.write(")");
34418 } else if matches!(
34419 self.config.dialect,
34420 Some(DialectType::PostgreSQL)
34421 | Some(DialectType::Materialize)
34422 | Some(DialectType::RisingWave)
34423 | Some(DialectType::Redshift)
34424 ) {
34425 self.write_keyword("POSITION");
34427 self.write("(");
34428 if let Some(substr) = &e.substr {
34429 self.generate_expression(substr)?;
34430 self.write(" IN ");
34431 }
34432 self.generate_expression(&e.this)?;
34433 self.write(")");
34434 } else {
34435 self.write_keyword("STRPOS");
34436 self.write("(");
34437 self.generate_expression(&e.this)?;
34438 if let Some(substr) = &e.substr {
34439 self.write(", ");
34440 self.generate_expression(substr)?;
34441 }
34442 if let Some(position) = &e.position {
34443 self.write(", ");
34444 self.generate_expression(position)?;
34445 }
34446 if let Some(occurrence) = &e.occurrence {
34447 self.write(", ");
34448 self.generate_expression(occurrence)?;
34449 }
34450 self.write(")");
34451 }
34452 Ok(())
34453 }
34454
34455 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
34456 match self.config.dialect {
34457 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
34458 self.write_keyword("TO_DATE");
34460 self.write("(");
34461 self.generate_expression(&e.this)?;
34462 if let Some(format) = &e.format {
34463 self.write(", '");
34464 self.write(&Self::strftime_to_java_format(format));
34465 self.write("'");
34466 }
34467 self.write(")");
34468 }
34469 Some(DialectType::DuckDB) => {
34470 self.write_keyword("CAST");
34472 self.write("(");
34473 self.write_keyword("STRPTIME");
34474 self.write("(");
34475 self.generate_expression(&e.this)?;
34476 if let Some(format) = &e.format {
34477 self.write(", '");
34478 self.write(format);
34479 self.write("'");
34480 }
34481 self.write(")");
34482 self.write_keyword(" AS ");
34483 self.write_keyword("DATE");
34484 self.write(")");
34485 }
34486 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
34487 self.write_keyword("TO_DATE");
34489 self.write("(");
34490 self.generate_expression(&e.this)?;
34491 if let Some(format) = &e.format {
34492 self.write(", '");
34493 self.write(&Self::strftime_to_postgres_format(format));
34494 self.write("'");
34495 }
34496 self.write(")");
34497 }
34498 Some(DialectType::BigQuery) => {
34499 self.write_keyword("PARSE_DATE");
34501 self.write("(");
34502 if let Some(format) = &e.format {
34503 self.write("'");
34504 self.write(format);
34505 self.write("'");
34506 self.write(", ");
34507 }
34508 self.generate_expression(&e.this)?;
34509 self.write(")");
34510 }
34511 Some(DialectType::Teradata) => {
34512 self.write_keyword("CAST");
34514 self.write("(");
34515 self.generate_expression(&e.this)?;
34516 self.write_keyword(" AS ");
34517 self.write_keyword("DATE");
34518 if let Some(format) = &e.format {
34519 self.write_keyword(" FORMAT ");
34520 self.write("'");
34521 self.write(&Self::strftime_to_teradata_format(format));
34522 self.write("'");
34523 }
34524 self.write(")");
34525 }
34526 _ => {
34527 self.write_keyword("STR_TO_DATE");
34529 self.write("(");
34530 self.generate_expression(&e.this)?;
34531 if let Some(format) = &e.format {
34532 self.write(", '");
34533 self.write(format);
34534 self.write("'");
34535 }
34536 self.write(")");
34537 }
34538 }
34539 Ok(())
34540 }
34541
34542 fn strftime_to_teradata_format(fmt: &str) -> String {
34544 let mut result = String::with_capacity(fmt.len() * 2);
34545 let bytes = fmt.as_bytes();
34546 let len = bytes.len();
34547 let mut i = 0;
34548 while i < len {
34549 if bytes[i] == b'%' && i + 1 < len {
34550 let replacement = match bytes[i + 1] {
34551 b'Y' => "YYYY",
34552 b'y' => "YY",
34553 b'm' => "MM",
34554 b'B' => "MMMM",
34555 b'b' => "MMM",
34556 b'd' => "DD",
34557 b'j' => "DDD",
34558 b'H' => "HH",
34559 b'M' => "MI",
34560 b'S' => "SS",
34561 b'f' => "SSSSSS",
34562 b'A' => "EEEE",
34563 b'a' => "EEE",
34564 _ => {
34565 result.push('%');
34566 i += 1;
34567 continue;
34568 }
34569 };
34570 result.push_str(replacement);
34571 i += 2;
34572 } else {
34573 result.push(bytes[i] as char);
34574 i += 1;
34575 }
34576 }
34577 result
34578 }
34579
34580 pub fn strftime_to_java_format_static(fmt: &str) -> String {
34583 Self::strftime_to_java_format(fmt)
34584 }
34585
34586 fn strftime_to_java_format(fmt: &str) -> String {
34588 let mut result = String::with_capacity(fmt.len() * 2);
34589 let bytes = fmt.as_bytes();
34590 let len = bytes.len();
34591 let mut i = 0;
34592 while i < len {
34593 if bytes[i] == b'%' && i + 1 < len {
34594 if bytes[i + 1] == b'-' && i + 2 < len {
34596 let replacement = match bytes[i + 2] {
34597 b'd' => "d",
34598 b'm' => "M",
34599 b'H' => "H",
34600 b'M' => "m",
34601 b'S' => "s",
34602 _ => {
34603 result.push('%');
34604 i += 1;
34605 continue;
34606 }
34607 };
34608 result.push_str(replacement);
34609 i += 3;
34610 } else {
34611 let replacement = match bytes[i + 1] {
34612 b'Y' => "yyyy",
34613 b'y' => "yy",
34614 b'm' => "MM",
34615 b'B' => "MMMM",
34616 b'b' => "MMM",
34617 b'd' => "dd",
34618 b'j' => "DDD",
34619 b'H' => "HH",
34620 b'M' => "mm",
34621 b'S' => "ss",
34622 b'f' => "SSSSSS",
34623 b'A' => "EEEE",
34624 b'a' => "EEE",
34625 _ => {
34626 result.push('%');
34627 i += 1;
34628 continue;
34629 }
34630 };
34631 result.push_str(replacement);
34632 i += 2;
34633 }
34634 } else {
34635 result.push(bytes[i] as char);
34636 i += 1;
34637 }
34638 }
34639 result
34640 }
34641
34642 fn strftime_to_tsql_format(fmt: &str) -> String {
34645 let mut result = String::with_capacity(fmt.len() * 2);
34646 let bytes = fmt.as_bytes();
34647 let len = bytes.len();
34648 let mut i = 0;
34649 while i < len {
34650 if bytes[i] == b'%' && i + 1 < len {
34651 if bytes[i + 1] == b'-' && i + 2 < len {
34653 let replacement = match bytes[i + 2] {
34654 b'd' => "d",
34655 b'm' => "M",
34656 b'H' => "H",
34657 b'M' => "m",
34658 b'S' => "s",
34659 _ => {
34660 result.push('%');
34661 i += 1;
34662 continue;
34663 }
34664 };
34665 result.push_str(replacement);
34666 i += 3;
34667 } else {
34668 let replacement = match bytes[i + 1] {
34669 b'Y' => "yyyy",
34670 b'y' => "yy",
34671 b'm' => "MM",
34672 b'B' => "MMMM",
34673 b'b' => "MMM",
34674 b'd' => "dd",
34675 b'j' => "DDD",
34676 b'H' => "HH",
34677 b'M' => "mm",
34678 b'S' => "ss",
34679 b'f' => "ffffff",
34680 b'A' => "dddd",
34681 b'a' => "ddd",
34682 _ => {
34683 result.push('%');
34684 i += 1;
34685 continue;
34686 }
34687 };
34688 result.push_str(replacement);
34689 i += 2;
34690 }
34691 } else {
34692 result.push(bytes[i] as char);
34693 i += 1;
34694 }
34695 }
34696 result
34697 }
34698
34699 fn decompose_json_path(path: &str) -> Vec<String> {
34702 let mut parts = Vec::new();
34703 let path = if path.starts_with("$.") {
34705 &path[2..]
34706 } else if path.starts_with('$') {
34707 &path[1..]
34708 } else {
34709 path
34710 };
34711 if path.is_empty() {
34712 return parts;
34713 }
34714 let mut current = String::new();
34715 let chars: Vec<char> = path.chars().collect();
34716 let mut i = 0;
34717 while i < chars.len() {
34718 match chars[i] {
34719 '.' => {
34720 if !current.is_empty() {
34721 parts.push(current.clone());
34722 current.clear();
34723 }
34724 i += 1;
34725 }
34726 '[' => {
34727 if !current.is_empty() {
34728 parts.push(current.clone());
34729 current.clear();
34730 }
34731 i += 1;
34732 let mut bracket_content = String::new();
34734 while i < chars.len() && chars[i] != ']' {
34735 if chars[i] == '"' || chars[i] == '\'' {
34737 let quote = chars[i];
34738 i += 1;
34739 while i < chars.len() && chars[i] != quote {
34740 bracket_content.push(chars[i]);
34741 i += 1;
34742 }
34743 if i < chars.len() {
34744 i += 1;
34745 } } else {
34747 bracket_content.push(chars[i]);
34748 i += 1;
34749 }
34750 }
34751 if i < chars.len() {
34752 i += 1;
34753 } if bracket_content != "*" {
34756 parts.push(bracket_content);
34757 }
34758 }
34759 _ => {
34760 current.push(chars[i]);
34761 i += 1;
34762 }
34763 }
34764 }
34765 if !current.is_empty() {
34766 parts.push(current);
34767 }
34768 parts
34769 }
34770
34771 fn strftime_to_postgres_format(fmt: &str) -> String {
34773 let mut result = String::with_capacity(fmt.len() * 2);
34774 let bytes = fmt.as_bytes();
34775 let len = bytes.len();
34776 let mut i = 0;
34777 while i < len {
34778 if bytes[i] == b'%' && i + 1 < len {
34779 if bytes[i + 1] == b'-' && i + 2 < len {
34781 let replacement = match bytes[i + 2] {
34782 b'd' => "FMDD",
34783 b'm' => "FMMM",
34784 b'H' => "FMHH24",
34785 b'M' => "FMMI",
34786 b'S' => "FMSS",
34787 _ => {
34788 result.push('%');
34789 i += 1;
34790 continue;
34791 }
34792 };
34793 result.push_str(replacement);
34794 i += 3;
34795 } else {
34796 let replacement = match bytes[i + 1] {
34797 b'Y' => "YYYY",
34798 b'y' => "YY",
34799 b'm' => "MM",
34800 b'B' => "Month",
34801 b'b' => "Mon",
34802 b'd' => "DD",
34803 b'j' => "DDD",
34804 b'H' => "HH24",
34805 b'M' => "MI",
34806 b'S' => "SS",
34807 b'f' => "US",
34808 b'A' => "Day",
34809 b'a' => "Dy",
34810 _ => {
34811 result.push('%');
34812 i += 1;
34813 continue;
34814 }
34815 };
34816 result.push_str(replacement);
34817 i += 2;
34818 }
34819 } else {
34820 result.push(bytes[i] as char);
34821 i += 1;
34822 }
34823 }
34824 result
34825 }
34826
34827 fn strftime_to_snowflake_format(fmt: &str) -> String {
34829 let mut result = String::with_capacity(fmt.len() * 2);
34830 let bytes = fmt.as_bytes();
34831 let len = bytes.len();
34832 let mut i = 0;
34833 while i < len {
34834 if bytes[i] == b'%' && i + 1 < len {
34835 if bytes[i + 1] == b'-' && i + 2 < len {
34837 let replacement = match bytes[i + 2] {
34838 b'd' => "dd",
34839 b'm' => "mm",
34840 _ => {
34841 result.push('%');
34842 i += 1;
34843 continue;
34844 }
34845 };
34846 result.push_str(replacement);
34847 i += 3;
34848 } else {
34849 let replacement = match bytes[i + 1] {
34850 b'Y' => "yyyy",
34851 b'y' => "yy",
34852 b'm' => "mm",
34853 b'd' => "DD",
34854 b'H' => "hh24",
34855 b'M' => "mi",
34856 b'S' => "ss",
34857 b'f' => "ff",
34858 _ => {
34859 result.push('%');
34860 i += 1;
34861 continue;
34862 }
34863 };
34864 result.push_str(replacement);
34865 i += 2;
34866 }
34867 } else {
34868 result.push(bytes[i] as char);
34869 i += 1;
34870 }
34871 }
34872 result
34873 }
34874
34875 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
34876 self.write_keyword("STR_TO_MAP");
34878 self.write("(");
34879 self.generate_expression(&e.this)?;
34880 let needs_defaults = matches!(
34882 self.config.dialect,
34883 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
34884 );
34885 if let Some(pair_delim) = &e.pair_delim {
34886 self.write(", ");
34887 self.generate_expression(pair_delim)?;
34888 } else if needs_defaults {
34889 self.write(", ','");
34890 }
34891 if let Some(key_value_delim) = &e.key_value_delim {
34892 self.write(", ");
34893 self.generate_expression(key_value_delim)?;
34894 } else if needs_defaults {
34895 self.write(", ':'");
34896 }
34897 self.write(")");
34898 Ok(())
34899 }
34900
34901 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
34902 let is_strftime = e.format.contains('%');
34904 let to_strftime = |f: &str| -> String {
34906 if is_strftime {
34907 f.to_string()
34908 } else {
34909 Self::snowflake_format_to_strftime(f)
34910 }
34911 };
34912 let to_java = |f: &str| -> String {
34914 if is_strftime {
34915 Self::strftime_to_java_format(f)
34916 } else {
34917 Self::snowflake_format_to_spark(f)
34918 }
34919 };
34920 let to_pg = |f: &str| -> String {
34922 if is_strftime {
34923 Self::strftime_to_postgres_format(f)
34924 } else {
34925 Self::convert_strptime_to_postgres_format(f)
34926 }
34927 };
34928
34929 match self.config.dialect {
34930 Some(DialectType::Exasol) => {
34931 self.write_keyword("TO_DATE");
34932 self.write("(");
34933 self.generate_expression(&e.this)?;
34934 self.write(", '");
34935 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34936 self.write("'");
34937 self.write(")");
34938 }
34939 Some(DialectType::BigQuery) => {
34940 let fmt = to_strftime(&e.format);
34942 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34944 self.write_keyword("PARSE_TIMESTAMP");
34945 self.write("('");
34946 self.write(&fmt);
34947 self.write("', ");
34948 self.generate_expression(&e.this)?;
34949 self.write(")");
34950 }
34951 Some(DialectType::Hive) => {
34952 let java_fmt = to_java(&e.format);
34955 if java_fmt == "yyyy-MM-dd HH:mm:ss"
34956 || java_fmt == "yyyy-MM-dd"
34957 || e.format == "yyyy-MM-dd HH:mm:ss"
34958 || e.format == "yyyy-MM-dd"
34959 {
34960 self.write_keyword("CAST");
34961 self.write("(");
34962 self.generate_expression(&e.this)?;
34963 self.write(" ");
34964 self.write_keyword("AS TIMESTAMP");
34965 self.write(")");
34966 } else {
34967 self.write_keyword("CAST");
34969 self.write("(");
34970 self.write_keyword("FROM_UNIXTIME");
34971 self.write("(");
34972 self.write_keyword("UNIX_TIMESTAMP");
34973 self.write("(");
34974 self.generate_expression(&e.this)?;
34975 self.write(", '");
34976 self.write(&java_fmt);
34977 self.write("')");
34978 self.write(") ");
34979 self.write_keyword("AS TIMESTAMP");
34980 self.write(")");
34981 }
34982 }
34983 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34984 let java_fmt = to_java(&e.format);
34986 self.write_keyword("TO_TIMESTAMP");
34987 self.write("(");
34988 self.generate_expression(&e.this)?;
34989 self.write(", '");
34990 self.write(&java_fmt);
34991 self.write("')");
34992 }
34993 Some(DialectType::MySQL) => {
34994 let mut fmt = to_strftime(&e.format);
34996 fmt = fmt.replace("%-d", "%e");
34998 fmt = fmt.replace("%-m", "%c");
34999 fmt = fmt.replace("%H:%M:%S", "%T");
35000 self.write_keyword("STR_TO_DATE");
35001 self.write("(");
35002 self.generate_expression(&e.this)?;
35003 self.write(", '");
35004 self.write(&fmt);
35005 self.write("')");
35006 }
35007 Some(DialectType::Drill) => {
35008 let java_fmt = to_java(&e.format);
35010 let java_fmt = java_fmt.replace('T', "''T''");
35012 self.write_keyword("TO_TIMESTAMP");
35013 self.write("(");
35014 self.generate_expression(&e.this)?;
35015 self.write(", '");
35016 self.write(&java_fmt);
35017 self.write("')");
35018 }
35019 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35020 let mut fmt = to_strftime(&e.format);
35022 fmt = fmt.replace("%-d", "%e");
35024 fmt = fmt.replace("%-m", "%c");
35025 fmt = fmt.replace("%H:%M:%S", "%T");
35026 self.write_keyword("DATE_PARSE");
35027 self.write("(");
35028 self.generate_expression(&e.this)?;
35029 self.write(", '");
35030 self.write(&fmt);
35031 self.write("')");
35032 }
35033 Some(DialectType::DuckDB) => {
35034 let fmt = to_strftime(&e.format);
35036 self.write_keyword("STRPTIME");
35037 self.write("(");
35038 self.generate_expression(&e.this)?;
35039 self.write(", '");
35040 self.write(&fmt);
35041 self.write("')");
35042 }
35043 Some(DialectType::PostgreSQL)
35044 | Some(DialectType::Redshift)
35045 | Some(DialectType::Materialize) => {
35046 let pg_fmt = to_pg(&e.format);
35048 self.write_keyword("TO_TIMESTAMP");
35049 self.write("(");
35050 self.generate_expression(&e.this)?;
35051 self.write(", '");
35052 self.write(&pg_fmt);
35053 self.write("')");
35054 }
35055 Some(DialectType::Oracle) => {
35056 let pg_fmt = to_pg(&e.format);
35058 self.write_keyword("TO_TIMESTAMP");
35059 self.write("(");
35060 self.generate_expression(&e.this)?;
35061 self.write(", '");
35062 self.write(&pg_fmt);
35063 self.write("')");
35064 }
35065 Some(DialectType::Snowflake) => {
35066 self.write_keyword("TO_TIMESTAMP");
35068 self.write("(");
35069 self.generate_expression(&e.this)?;
35070 self.write(", '");
35071 self.write(&e.format);
35072 self.write("')");
35073 }
35074 _ => {
35075 self.write_keyword("STR_TO_TIME");
35077 self.write("(");
35078 self.generate_expression(&e.this)?;
35079 self.write(", '");
35080 self.write(&e.format);
35081 self.write("'");
35082 self.write(")");
35083 }
35084 }
35085 Ok(())
35086 }
35087
35088 fn snowflake_format_to_strftime(format: &str) -> String {
35090 let mut result = String::new();
35091 let chars: Vec<char> = format.chars().collect();
35092 let mut i = 0;
35093 while i < chars.len() {
35094 let remaining = &format[i..];
35095 if remaining.starts_with("yyyy") {
35096 result.push_str("%Y");
35097 i += 4;
35098 } else if remaining.starts_with("yy") {
35099 result.push_str("%y");
35100 i += 2;
35101 } else if remaining.starts_with("mmmm") {
35102 result.push_str("%B"); i += 4;
35104 } else if remaining.starts_with("mon") {
35105 result.push_str("%b"); i += 3;
35107 } else if remaining.starts_with("mm") {
35108 result.push_str("%m");
35109 i += 2;
35110 } else if remaining.starts_with("DD") {
35111 result.push_str("%d");
35112 i += 2;
35113 } else if remaining.starts_with("dy") {
35114 result.push_str("%a"); i += 2;
35116 } else if remaining.starts_with("hh24") {
35117 result.push_str("%H");
35118 i += 4;
35119 } else if remaining.starts_with("hh12") {
35120 result.push_str("%I");
35121 i += 4;
35122 } else if remaining.starts_with("hh") {
35123 result.push_str("%H");
35124 i += 2;
35125 } else if remaining.starts_with("mi") {
35126 result.push_str("%M");
35127 i += 2;
35128 } else if remaining.starts_with("ss") {
35129 result.push_str("%S");
35130 i += 2;
35131 } else if remaining.starts_with("ff") {
35132 result.push_str("%f");
35134 i += 2;
35135 while i < chars.len() && chars[i].is_ascii_digit() {
35137 i += 1;
35138 }
35139 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
35140 result.push_str("%p");
35141 i += 2;
35142 } else if remaining.starts_with("tz") {
35143 result.push_str("%Z");
35144 i += 2;
35145 } else {
35146 result.push(chars[i]);
35147 i += 1;
35148 }
35149 }
35150 result
35151 }
35152
35153 fn snowflake_format_to_spark(format: &str) -> String {
35155 let mut result = String::new();
35156 let chars: Vec<char> = format.chars().collect();
35157 let mut i = 0;
35158 while i < chars.len() {
35159 let remaining = &format[i..];
35160 if remaining.starts_with("yyyy") {
35161 result.push_str("yyyy");
35162 i += 4;
35163 } else if remaining.starts_with("yy") {
35164 result.push_str("yy");
35165 i += 2;
35166 } else if remaining.starts_with("mmmm") {
35167 result.push_str("MMMM"); i += 4;
35169 } else if remaining.starts_with("mon") {
35170 result.push_str("MMM"); i += 3;
35172 } else if remaining.starts_with("mm") {
35173 result.push_str("MM");
35174 i += 2;
35175 } else if remaining.starts_with("DD") {
35176 result.push_str("dd");
35177 i += 2;
35178 } else if remaining.starts_with("dy") {
35179 result.push_str("EEE"); i += 2;
35181 } else if remaining.starts_with("hh24") {
35182 result.push_str("HH");
35183 i += 4;
35184 } else if remaining.starts_with("hh12") {
35185 result.push_str("hh");
35186 i += 4;
35187 } else if remaining.starts_with("hh") {
35188 result.push_str("HH");
35189 i += 2;
35190 } else if remaining.starts_with("mi") {
35191 result.push_str("mm");
35192 i += 2;
35193 } else if remaining.starts_with("ss") {
35194 result.push_str("ss");
35195 i += 2;
35196 } else if remaining.starts_with("ff") {
35197 result.push_str("SSS"); i += 2;
35199 while i < chars.len() && chars[i].is_ascii_digit() {
35201 i += 1;
35202 }
35203 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
35204 result.push_str("a");
35205 i += 2;
35206 } else if remaining.starts_with("tz") {
35207 result.push_str("z");
35208 i += 2;
35209 } else {
35210 result.push(chars[i]);
35211 i += 1;
35212 }
35213 }
35214 result
35215 }
35216
35217 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
35218 match self.config.dialect {
35219 Some(DialectType::DuckDB) => {
35220 self.write_keyword("EPOCH");
35222 self.write("(");
35223 self.write_keyword("STRPTIME");
35224 self.write("(");
35225 if let Some(this) = &e.this {
35226 self.generate_expression(this)?;
35227 }
35228 if let Some(format) = &e.format {
35229 self.write(", '");
35230 self.write(format);
35231 self.write("'");
35232 }
35233 self.write("))");
35234 }
35235 Some(DialectType::Hive) => {
35236 self.write_keyword("UNIX_TIMESTAMP");
35238 self.write("(");
35239 if let Some(this) = &e.this {
35240 self.generate_expression(this)?;
35241 }
35242 if let Some(format) = &e.format {
35243 let java_fmt = Self::strftime_to_java_format(format);
35244 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
35245 self.write(", '");
35246 self.write(&java_fmt);
35247 self.write("'");
35248 }
35249 }
35250 self.write(")");
35251 }
35252 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35253 self.write_keyword("UNIX_TIMESTAMP");
35255 self.write("(");
35256 if let Some(this) = &e.this {
35257 self.generate_expression(this)?;
35258 }
35259 if let Some(format) = &e.format {
35260 self.write(", '");
35261 self.write(format);
35262 self.write("'");
35263 }
35264 self.write(")");
35265 }
35266 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35267 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
35270 let java_fmt = Self::strftime_to_java_format(c_fmt);
35271 self.write_keyword("TO_UNIXTIME");
35272 self.write("(");
35273 self.write_keyword("COALESCE");
35274 self.write("(");
35275 self.write_keyword("TRY");
35276 self.write("(");
35277 self.write_keyword("DATE_PARSE");
35278 self.write("(");
35279 self.write_keyword("CAST");
35280 self.write("(");
35281 if let Some(this) = &e.this {
35282 self.generate_expression(this)?;
35283 }
35284 self.write(" ");
35285 self.write_keyword("AS VARCHAR");
35286 self.write("), '");
35287 self.write(c_fmt);
35288 self.write("')), ");
35289 self.write_keyword("PARSE_DATETIME");
35290 self.write("(");
35291 self.write_keyword("DATE_FORMAT");
35292 self.write("(");
35293 self.write_keyword("CAST");
35294 self.write("(");
35295 if let Some(this) = &e.this {
35296 self.generate_expression(this)?;
35297 }
35298 self.write(" ");
35299 self.write_keyword("AS TIMESTAMP");
35300 self.write("), '");
35301 self.write(c_fmt);
35302 self.write("'), '");
35303 self.write(&java_fmt);
35304 self.write("')))");
35305 }
35306 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35307 self.write_keyword("UNIX_TIMESTAMP");
35309 self.write("(");
35310 if let Some(this) = &e.this {
35311 self.generate_expression(this)?;
35312 }
35313 if let Some(format) = &e.format {
35314 let java_fmt = Self::strftime_to_java_format(format);
35315 self.write(", '");
35316 self.write(&java_fmt);
35317 self.write("'");
35318 }
35319 self.write(")");
35320 }
35321 _ => {
35322 self.write_keyword("STR_TO_UNIX");
35324 self.write("(");
35325 if let Some(this) = &e.this {
35326 self.generate_expression(this)?;
35327 }
35328 if let Some(format) = &e.format {
35329 self.write(", '");
35330 self.write(format);
35331 self.write("'");
35332 }
35333 self.write(")");
35334 }
35335 }
35336 Ok(())
35337 }
35338
35339 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
35340 self.write_keyword("STRING_TO_ARRAY");
35342 self.write("(");
35343 self.generate_expression(&e.this)?;
35344 if let Some(expression) = &e.expression {
35345 self.write(", ");
35346 self.generate_expression(expression)?;
35347 }
35348 if let Some(null_val) = &e.null {
35349 self.write(", ");
35350 self.generate_expression(null_val)?;
35351 }
35352 self.write(")");
35353 Ok(())
35354 }
35355
35356 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
35357 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35358 self.write_keyword("OBJECT_CONSTRUCT");
35360 self.write("(");
35361 for (i, (name, expr)) in e.fields.iter().enumerate() {
35362 if i > 0 {
35363 self.write(", ");
35364 }
35365 if let Some(name) = name {
35366 self.write("'");
35367 self.write(name);
35368 self.write("'");
35369 self.write(", ");
35370 } else {
35371 self.write("'_");
35372 self.write(&i.to_string());
35373 self.write("'");
35374 self.write(", ");
35375 }
35376 self.generate_expression(expr)?;
35377 }
35378 self.write(")");
35379 } else if self.config.struct_curly_brace_notation {
35380 self.write("{");
35382 for (i, (name, expr)) in e.fields.iter().enumerate() {
35383 if i > 0 {
35384 self.write(", ");
35385 }
35386 if let Some(name) = name {
35387 self.write("'");
35389 self.write(name);
35390 self.write("'");
35391 self.write(": ");
35392 } else {
35393 self.write("'_");
35395 self.write(&i.to_string());
35396 self.write("'");
35397 self.write(": ");
35398 }
35399 self.generate_expression(expr)?;
35400 }
35401 self.write("}");
35402 } else {
35403 let value_as_name = matches!(
35407 self.config.dialect,
35408 Some(DialectType::BigQuery)
35409 | Some(DialectType::Spark)
35410 | Some(DialectType::Databricks)
35411 | Some(DialectType::Hive)
35412 );
35413 self.write_keyword("STRUCT");
35414 self.write("(");
35415 for (i, (name, expr)) in e.fields.iter().enumerate() {
35416 if i > 0 {
35417 self.write(", ");
35418 }
35419 if let Some(name) = name {
35420 if value_as_name {
35421 self.generate_expression(expr)?;
35423 self.write_space();
35424 self.write_keyword("AS");
35425 self.write_space();
35426 let needs_quoting = name.contains(' ') || name.contains('-');
35428 if needs_quoting {
35429 if matches!(
35430 self.config.dialect,
35431 Some(DialectType::Spark)
35432 | Some(DialectType::Databricks)
35433 | Some(DialectType::Hive)
35434 ) {
35435 self.write("`");
35436 self.write(name);
35437 self.write("`");
35438 } else {
35439 self.write(name);
35440 }
35441 } else {
35442 self.write(name);
35443 }
35444 } else {
35445 self.write(name);
35447 self.write_space();
35448 self.write_keyword("AS");
35449 self.write_space();
35450 self.generate_expression(expr)?;
35451 }
35452 } else {
35453 self.generate_expression(expr)?;
35454 }
35455 }
35456 self.write(")");
35457 }
35458 Ok(())
35459 }
35460
35461 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
35462 self.write_keyword("STUFF");
35464 self.write("(");
35465 self.generate_expression(&e.this)?;
35466 if let Some(start) = &e.start {
35467 self.write(", ");
35468 self.generate_expression(start)?;
35469 }
35470 if let Some(length) = e.length {
35471 self.write(", ");
35472 self.write(&length.to_string());
35473 }
35474 self.write(", ");
35475 self.generate_expression(&e.expression)?;
35476 self.write(")");
35477 Ok(())
35478 }
35479
35480 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
35481 self.write_keyword("SUBSTRING_INDEX");
35483 self.write("(");
35484 self.generate_expression(&e.this)?;
35485 if let Some(delimiter) = &e.delimiter {
35486 self.write(", ");
35487 self.generate_expression(delimiter)?;
35488 }
35489 if let Some(count) = &e.count {
35490 self.write(", ");
35491 self.generate_expression(count)?;
35492 }
35493 self.write(")");
35494 Ok(())
35495 }
35496
35497 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
35498 self.write_keyword("SUMMARIZE");
35500 if e.table.is_some() {
35501 self.write_space();
35502 self.write_keyword("TABLE");
35503 }
35504 self.write_space();
35505 self.generate_expression(&e.this)?;
35506 Ok(())
35507 }
35508
35509 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
35510 self.write_keyword("SYSTIMESTAMP");
35512 Ok(())
35513 }
35514
35515 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
35516 if let Some(this) = &e.this {
35518 self.generate_expression(this)?;
35519 }
35520 if !e.columns.is_empty() {
35521 self.write("(");
35522 for (i, col) in e.columns.iter().enumerate() {
35523 if i > 0 {
35524 self.write(", ");
35525 }
35526 self.generate_expression(col)?;
35527 }
35528 self.write(")");
35529 }
35530 Ok(())
35531 }
35532
35533 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
35534 self.write_keyword("TABLE");
35536 self.write("(");
35537 self.generate_expression(&e.this)?;
35538 self.write(")");
35539 if let Some(alias) = &e.alias {
35540 self.write_space();
35541 self.write_keyword("AS");
35542 self.write_space();
35543 self.write(alias);
35544 }
35545 Ok(())
35546 }
35547
35548 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
35549 self.write_keyword("ROWS FROM");
35551 self.write(" (");
35552 for (i, expr) in e.expressions.iter().enumerate() {
35553 if i > 0 {
35554 self.write(", ");
35555 }
35556 match expr {
35560 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
35561 self.generate_expression(&tuple.expressions[0])?;
35563 self.write_space();
35564 self.write_keyword("AS");
35565 self.write_space();
35566 self.generate_expression(&tuple.expressions[1])?;
35567 }
35568 _ => {
35569 self.generate_expression(expr)?;
35570 }
35571 }
35572 }
35573 self.write(")");
35574 if e.ordinality {
35575 self.write_space();
35576 self.write_keyword("WITH ORDINALITY");
35577 }
35578 if let Some(alias) = &e.alias {
35579 self.write_space();
35580 self.write_keyword("AS");
35581 self.write_space();
35582 self.generate_expression(alias)?;
35583 }
35584 Ok(())
35585 }
35586
35587 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
35588 use crate::dialects::DialectType;
35589
35590 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
35592 if self.config.alias_post_tablesample {
35594 if let Expression::Subquery(ref s) = **this {
35596 if let Some(ref alias) = s.alias {
35597 let mut subquery_no_alias = (**s).clone();
35599 subquery_no_alias.alias = None;
35600 subquery_no_alias.column_aliases = Vec::new();
35601 self.generate_expression(&Expression::Subquery(Box::new(
35602 subquery_no_alias,
35603 )))?;
35604 self.write_space();
35605 self.write_keyword("TABLESAMPLE");
35606 self.generate_sample_body(sample)?;
35607 if let Some(ref seed) = sample.seed {
35608 self.write_space();
35609 let use_seed = sample.use_seed_keyword
35610 && !matches!(
35611 self.config.dialect,
35612 Some(crate::dialects::DialectType::Databricks)
35613 | Some(crate::dialects::DialectType::Spark)
35614 );
35615 if use_seed {
35616 self.write_keyword("SEED");
35617 } else {
35618 self.write_keyword("REPEATABLE");
35619 }
35620 self.write(" (");
35621 self.generate_expression(seed)?;
35622 self.write(")");
35623 }
35624 self.write_space();
35625 self.write_keyword("AS");
35626 self.write_space();
35627 self.generate_identifier(alias)?;
35628 return Ok(());
35629 }
35630 } else if let Expression::Alias(ref a) = **this {
35631 self.generate_expression(&a.this)?;
35633 self.write_space();
35634 self.write_keyword("TABLESAMPLE");
35635 self.generate_sample_body(sample)?;
35636 if let Some(ref seed) = sample.seed {
35637 self.write_space();
35638 let use_seed = sample.use_seed_keyword
35639 && !matches!(
35640 self.config.dialect,
35641 Some(crate::dialects::DialectType::Databricks)
35642 | Some(crate::dialects::DialectType::Spark)
35643 );
35644 if use_seed {
35645 self.write_keyword("SEED");
35646 } else {
35647 self.write_keyword("REPEATABLE");
35648 }
35649 self.write(" (");
35650 self.generate_expression(seed)?;
35651 self.write(")");
35652 }
35653 self.write_space();
35655 self.write_keyword("AS");
35656 self.write_space();
35657 self.generate_identifier(&a.alias)?;
35658 return Ok(());
35659 }
35660 }
35661 self.generate_expression(this)?;
35663 self.write_space();
35664 self.write_keyword("TABLESAMPLE");
35665 self.generate_sample_body(sample)?;
35666 if let Some(ref seed) = sample.seed {
35668 self.write_space();
35669 let use_seed = sample.use_seed_keyword
35671 && !matches!(
35672 self.config.dialect,
35673 Some(crate::dialects::DialectType::Databricks)
35674 | Some(crate::dialects::DialectType::Spark)
35675 );
35676 if use_seed {
35677 self.write_keyword("SEED");
35678 } else {
35679 self.write_keyword("REPEATABLE");
35680 }
35681 self.write(" (");
35682 self.generate_expression(seed)?;
35683 self.write(")");
35684 }
35685 return Ok(());
35686 }
35687
35688 self.write_keyword("TABLESAMPLE");
35690 if let Some(method) = &e.method {
35691 self.write_space();
35692 self.write_keyword(method);
35693 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35694 self.write_space();
35696 self.write_keyword("BERNOULLI");
35697 }
35698 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
35699 self.write_space();
35700 self.write_keyword("BUCKET");
35701 self.write_space();
35702 self.generate_expression(numerator)?;
35703 self.write_space();
35704 self.write_keyword("OUT OF");
35705 self.write_space();
35706 self.generate_expression(denominator)?;
35707 if let Some(field) = &e.bucket_field {
35708 self.write_space();
35709 self.write_keyword("ON");
35710 self.write_space();
35711 self.generate_expression(field)?;
35712 }
35713 } else if !e.expressions.is_empty() {
35714 self.write(" (");
35715 for (i, expr) in e.expressions.iter().enumerate() {
35716 if i > 0 {
35717 self.write(", ");
35718 }
35719 self.generate_expression(expr)?;
35720 }
35721 self.write(")");
35722 } else if let Some(percent) = &e.percent {
35723 self.write(" (");
35724 self.generate_expression(percent)?;
35725 self.write_space();
35726 self.write_keyword("PERCENT");
35727 self.write(")");
35728 }
35729 Ok(())
35730 }
35731
35732 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
35733 if let Some(prefix) = &e.prefix {
35735 self.generate_expression(prefix)?;
35736 }
35737 if let Some(this) = &e.this {
35738 self.generate_expression(this)?;
35739 }
35740 if let Some(postfix) = &e.postfix {
35741 self.generate_expression(postfix)?;
35742 }
35743 Ok(())
35744 }
35745
35746 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
35747 self.write_keyword("TAG");
35749 self.write(" (");
35750 for (i, expr) in e.expressions.iter().enumerate() {
35751 if i > 0 {
35752 self.write(", ");
35753 }
35754 self.generate_expression(expr)?;
35755 }
35756 self.write(")");
35757 Ok(())
35758 }
35759
35760 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
35761 if let Some(this) = &e.this {
35763 self.generate_expression(this)?;
35764 self.write_space();
35765 }
35766 self.write_keyword("TEMPORARY");
35767 Ok(())
35768 }
35769
35770 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
35773 self.write_keyword("TIME");
35775 self.write("(");
35776 self.generate_expression(&e.this)?;
35777 self.write(")");
35778 Ok(())
35779 }
35780
35781 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
35782 self.write_keyword("TIME_ADD");
35784 self.write("(");
35785 self.generate_expression(&e.this)?;
35786 self.write(", ");
35787 self.generate_expression(&e.expression)?;
35788 if let Some(unit) = &e.unit {
35789 self.write(", ");
35790 self.write_keyword(unit);
35791 }
35792 self.write(")");
35793 Ok(())
35794 }
35795
35796 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
35797 self.write_keyword("TIME_DIFF");
35799 self.write("(");
35800 self.generate_expression(&e.this)?;
35801 self.write(", ");
35802 self.generate_expression(&e.expression)?;
35803 if let Some(unit) = &e.unit {
35804 self.write(", ");
35805 self.write_keyword(unit);
35806 }
35807 self.write(")");
35808 Ok(())
35809 }
35810
35811 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
35812 self.write_keyword("TIME_FROM_PARTS");
35814 self.write("(");
35815 let mut first = true;
35816 if let Some(hour) = &e.hour {
35817 self.generate_expression(hour)?;
35818 first = false;
35819 }
35820 if let Some(minute) = &e.min {
35821 if !first {
35822 self.write(", ");
35823 }
35824 self.generate_expression(minute)?;
35825 first = false;
35826 }
35827 if let Some(second) = &e.sec {
35828 if !first {
35829 self.write(", ");
35830 }
35831 self.generate_expression(second)?;
35832 first = false;
35833 }
35834 if let Some(ns) = &e.nano {
35835 if !first {
35836 self.write(", ");
35837 }
35838 self.generate_expression(ns)?;
35839 }
35840 self.write(")");
35841 Ok(())
35842 }
35843
35844 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
35845 self.write_keyword("TIME_SLICE");
35847 self.write("(");
35848 self.generate_expression(&e.this)?;
35849 self.write(", ");
35850 self.generate_expression(&e.expression)?;
35851 self.write(", ");
35852 self.write_keyword(&e.unit);
35853 self.write(")");
35854 Ok(())
35855 }
35856
35857 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
35858 self.write_keyword("TIME_STR_TO_TIME");
35860 self.write("(");
35861 self.generate_expression(&e.this)?;
35862 self.write(")");
35863 Ok(())
35864 }
35865
35866 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
35867 self.write_keyword("TIME_SUB");
35869 self.write("(");
35870 self.generate_expression(&e.this)?;
35871 self.write(", ");
35872 self.generate_expression(&e.expression)?;
35873 if let Some(unit) = &e.unit {
35874 self.write(", ");
35875 self.write_keyword(unit);
35876 }
35877 self.write(")");
35878 Ok(())
35879 }
35880
35881 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
35882 match self.config.dialect {
35883 Some(DialectType::Exasol) => {
35884 self.write_keyword("TO_CHAR");
35886 self.write("(");
35887 self.generate_expression(&e.this)?;
35888 self.write(", '");
35889 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35890 self.write("'");
35891 self.write(")");
35892 }
35893 Some(DialectType::PostgreSQL)
35894 | Some(DialectType::Redshift)
35895 | Some(DialectType::Materialize) => {
35896 self.write_keyword("TO_CHAR");
35898 self.write("(");
35899 self.generate_expression(&e.this)?;
35900 self.write(", '");
35901 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
35902 self.write("'");
35903 self.write(")");
35904 }
35905 Some(DialectType::Oracle) => {
35906 self.write_keyword("TO_CHAR");
35908 self.write("(");
35909 self.generate_expression(&e.this)?;
35910 self.write(", '");
35911 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
35912 self.write("'");
35913 self.write(")");
35914 }
35915 Some(DialectType::Drill) => {
35916 self.write_keyword("TO_CHAR");
35918 self.write("(");
35919 self.generate_expression(&e.this)?;
35920 self.write(", '");
35921 self.write(&Self::strftime_to_java_format(&e.format));
35922 self.write("'");
35923 self.write(")");
35924 }
35925 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
35926 self.write_keyword("FORMAT");
35928 self.write("(");
35929 self.generate_expression(&e.this)?;
35930 self.write(", '");
35931 self.write(&Self::strftime_to_tsql_format(&e.format));
35932 self.write("'");
35933 self.write(")");
35934 }
35935 Some(DialectType::DuckDB) => {
35936 self.write_keyword("STRFTIME");
35938 self.write("(");
35939 self.generate_expression(&e.this)?;
35940 self.write(", '");
35941 self.write(&e.format);
35942 self.write("'");
35943 self.write(")");
35944 }
35945 Some(DialectType::BigQuery) => {
35946 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35949 self.write_keyword("FORMAT_DATE");
35950 self.write("('");
35951 self.write(&fmt);
35952 self.write("', ");
35953 self.generate_expression(&e.this)?;
35954 self.write(")");
35955 }
35956 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35957 self.write_keyword("DATE_FORMAT");
35959 self.write("(");
35960 self.generate_expression(&e.this)?;
35961 self.write(", '");
35962 self.write(&Self::strftime_to_java_format(&e.format));
35963 self.write("'");
35964 self.write(")");
35965 }
35966 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35967 self.write_keyword("DATE_FORMAT");
35969 self.write("(");
35970 self.generate_expression(&e.this)?;
35971 self.write(", '");
35972 self.write(&e.format);
35973 self.write("'");
35974 self.write(")");
35975 }
35976 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35977 self.write_keyword("DATE_FORMAT");
35979 self.write("(");
35980 self.generate_expression(&e.this)?;
35981 self.write(", '");
35982 self.write(&e.format);
35983 self.write("'");
35984 self.write(")");
35985 }
35986 _ => {
35987 self.write_keyword("TIME_TO_STR");
35989 self.write("(");
35990 self.generate_expression(&e.this)?;
35991 self.write(", '");
35992 self.write(&e.format);
35993 self.write("'");
35994 self.write(")");
35995 }
35996 }
35997 Ok(())
35998 }
35999
36000 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36001 match self.config.dialect {
36002 Some(DialectType::DuckDB) => {
36003 self.write_keyword("EPOCH");
36005 self.write("(");
36006 self.generate_expression(&e.this)?;
36007 self.write(")");
36008 }
36009 Some(DialectType::Hive)
36010 | Some(DialectType::Spark)
36011 | Some(DialectType::Databricks)
36012 | Some(DialectType::Doris)
36013 | Some(DialectType::StarRocks)
36014 | Some(DialectType::Drill) => {
36015 self.write_keyword("UNIX_TIMESTAMP");
36017 self.write("(");
36018 self.generate_expression(&e.this)?;
36019 self.write(")");
36020 }
36021 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36022 self.write_keyword("TO_UNIXTIME");
36024 self.write("(");
36025 self.generate_expression(&e.this)?;
36026 self.write(")");
36027 }
36028 _ => {
36029 self.write_keyword("TIME_TO_UNIX");
36031 self.write("(");
36032 self.generate_expression(&e.this)?;
36033 self.write(")");
36034 }
36035 }
36036 Ok(())
36037 }
36038
36039 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36040 match self.config.dialect {
36041 Some(DialectType::Hive) => {
36042 self.write_keyword("TO_DATE");
36044 self.write("(");
36045 self.generate_expression(&e.this)?;
36046 self.write(")");
36047 }
36048 _ => {
36049 self.write_keyword("TIME_STR_TO_DATE");
36051 self.write("(");
36052 self.generate_expression(&e.this)?;
36053 self.write(")");
36054 }
36055 }
36056 Ok(())
36057 }
36058
36059 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
36060 self.write_keyword("TIME_TRUNC");
36062 self.write("(");
36063 self.generate_expression(&e.this)?;
36064 self.write(", ");
36065 self.write_keyword(&e.unit);
36066 self.write(")");
36067 Ok(())
36068 }
36069
36070 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
36071 if let Some(unit) = &e.unit {
36073 self.write_keyword(unit);
36074 }
36075 Ok(())
36076 }
36077
36078 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
36082 use crate::dialects::DialectType;
36083 use crate::expressions::Literal;
36084
36085 match self.config.dialect {
36086 Some(DialectType::Exasol) => {
36088 self.write_keyword("TO_TIMESTAMP");
36089 self.write("(");
36090 if let Some(this) = &e.this {
36092 match this.as_ref() {
36093 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36094 let Literal::String(s) = lit.as_ref() else {
36095 unreachable!()
36096 };
36097 self.write("'");
36098 self.write(s);
36099 self.write("'");
36100 }
36101 _ => {
36102 self.generate_expression(this)?;
36103 }
36104 }
36105 }
36106 self.write(")");
36107 }
36108 _ => {
36110 self.write_keyword("TIMESTAMP");
36111 self.write("(");
36112 if let Some(this) = &e.this {
36113 self.generate_expression(this)?;
36114 }
36115 if let Some(zone) = &e.zone {
36116 self.write(", ");
36117 self.generate_expression(zone)?;
36118 }
36119 self.write(")");
36120 }
36121 }
36122 Ok(())
36123 }
36124
36125 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
36126 self.write_keyword("TIMESTAMP_ADD");
36128 self.write("(");
36129 self.generate_expression(&e.this)?;
36130 self.write(", ");
36131 self.generate_expression(&e.expression)?;
36132 if let Some(unit) = &e.unit {
36133 self.write(", ");
36134 self.write_keyword(unit);
36135 }
36136 self.write(")");
36137 Ok(())
36138 }
36139
36140 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
36141 self.write_keyword("TIMESTAMP_DIFF");
36143 self.write("(");
36144 self.generate_expression(&e.this)?;
36145 self.write(", ");
36146 self.generate_expression(&e.expression)?;
36147 if let Some(unit) = &e.unit {
36148 self.write(", ");
36149 self.write_keyword(unit);
36150 }
36151 self.write(")");
36152 Ok(())
36153 }
36154
36155 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
36156 self.write_keyword("TIMESTAMP_FROM_PARTS");
36158 self.write("(");
36159 if let Some(this) = &e.this {
36160 self.generate_expression(this)?;
36161 }
36162 if let Some(expression) = &e.expression {
36163 self.write(", ");
36164 self.generate_expression(expression)?;
36165 }
36166 if let Some(zone) = &e.zone {
36167 self.write(", ");
36168 self.generate_expression(zone)?;
36169 }
36170 if let Some(milli) = &e.milli {
36171 self.write(", ");
36172 self.generate_expression(milli)?;
36173 }
36174 self.write(")");
36175 Ok(())
36176 }
36177
36178 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
36179 self.write_keyword("TIMESTAMP_SUB");
36181 self.write("(");
36182 self.generate_expression(&e.this)?;
36183 self.write(", ");
36184 self.write_keyword("INTERVAL");
36185 self.write_space();
36186 self.generate_expression(&e.expression)?;
36187 if let Some(unit) = &e.unit {
36188 self.write_space();
36189 self.write_keyword(unit);
36190 }
36191 self.write(")");
36192 Ok(())
36193 }
36194
36195 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
36196 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
36198 self.write("(");
36199 if let Some(zone) = &e.zone {
36200 self.generate_expression(zone)?;
36201 }
36202 self.write(")");
36203 Ok(())
36204 }
36205
36206 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
36207 self.write_keyword("TO_BINARY");
36209 self.write("(");
36210 self.generate_expression(&e.this)?;
36211 if let Some(format) = &e.format {
36212 self.write(", '");
36213 self.write(format);
36214 self.write("'");
36215 }
36216 self.write(")");
36217 Ok(())
36218 }
36219
36220 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
36221 self.write_keyword("TO_BOOLEAN");
36223 self.write("(");
36224 self.generate_expression(&e.this)?;
36225 self.write(")");
36226 Ok(())
36227 }
36228
36229 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
36230 self.write_keyword("TO_CHAR");
36232 self.write("(");
36233 self.generate_expression(&e.this)?;
36234 if let Some(format) = &e.format {
36235 self.write(", '");
36236 self.write(format);
36237 self.write("'");
36238 }
36239 if let Some(nlsparam) = &e.nlsparam {
36240 self.write(", ");
36241 self.generate_expression(nlsparam)?;
36242 }
36243 self.write(")");
36244 Ok(())
36245 }
36246
36247 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
36248 self.write_keyword("TO_DECFLOAT");
36250 self.write("(");
36251 self.generate_expression(&e.this)?;
36252 if let Some(format) = &e.format {
36253 self.write(", '");
36254 self.write(format);
36255 self.write("'");
36256 }
36257 self.write(")");
36258 Ok(())
36259 }
36260
36261 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
36262 self.write_keyword("TO_DOUBLE");
36264 self.write("(");
36265 self.generate_expression(&e.this)?;
36266 if let Some(format) = &e.format {
36267 self.write(", '");
36268 self.write(format);
36269 self.write("'");
36270 }
36271 self.write(")");
36272 Ok(())
36273 }
36274
36275 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
36276 self.write_keyword("TO_FILE");
36278 self.write("(");
36279 self.generate_expression(&e.this)?;
36280 if let Some(path) = &e.path {
36281 self.write(", ");
36282 self.generate_expression(path)?;
36283 }
36284 self.write(")");
36285 Ok(())
36286 }
36287
36288 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
36289 let is_safe = e.safe.is_some();
36292 if is_safe {
36293 self.write_keyword("TRY_TO_NUMBER");
36294 } else {
36295 self.write_keyword("TO_NUMBER");
36296 }
36297 self.write("(");
36298 self.generate_expression(&e.this)?;
36299 let precision_is_snowflake_default = e.precision.is_none()
36300 || matches!(
36301 e.precision.as_deref(),
36302 Some(Expression::Literal(lit))
36303 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
36304 );
36305 let is_snowflake_default_precision =
36306 matches!(self.config.dialect, Some(DialectType::Snowflake))
36307 && e.nlsparam.is_none()
36308 && e.scale.is_none()
36309 && matches!(
36310 e.format.as_deref(),
36311 Some(Expression::Literal(lit))
36312 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
36313 )
36314 && precision_is_snowflake_default;
36315
36316 if !is_snowflake_default_precision {
36317 if let Some(format) = &e.format {
36318 self.write(", ");
36319 self.generate_expression(format)?;
36320 }
36321 if let Some(nlsparam) = &e.nlsparam {
36322 self.write(", ");
36323 self.generate_expression(nlsparam)?;
36324 }
36325 if let Some(precision) = &e.precision {
36326 self.write(", ");
36327 self.generate_expression(precision)?;
36328 }
36329 if let Some(scale) = &e.scale {
36330 self.write(", ");
36331 self.generate_expression(scale)?;
36332 }
36333 }
36334 self.write(")");
36335 Ok(())
36336 }
36337
36338 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
36339 self.write_keyword("TO_TABLE");
36341 self.write_space();
36342 self.generate_expression(&e.this)?;
36343 Ok(())
36344 }
36345
36346 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
36347 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
36349 Expression::Identifier(id) => id.name.clone(),
36350 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36351 let Literal::String(s) = lit.as_ref() else {
36352 unreachable!()
36353 };
36354 s.clone()
36355 }
36356 _ => String::new(),
36357 });
36358
36359 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
36360 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
36361 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
36362 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
36363 });
36364
36365 let use_start_transaction = matches!(
36367 self.config.dialect,
36368 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
36369 );
36370 let strip_transaction = matches!(
36372 self.config.dialect,
36373 Some(DialectType::Snowflake)
36374 | Some(DialectType::PostgreSQL)
36375 | Some(DialectType::Redshift)
36376 | Some(DialectType::MySQL)
36377 | Some(DialectType::Hive)
36378 | Some(DialectType::Spark)
36379 | Some(DialectType::Databricks)
36380 | Some(DialectType::DuckDB)
36381 | Some(DialectType::Oracle)
36382 | Some(DialectType::Doris)
36383 | Some(DialectType::StarRocks)
36384 | Some(DialectType::Materialize)
36385 | Some(DialectType::ClickHouse)
36386 );
36387
36388 if is_start || use_start_transaction {
36389 self.write_keyword("START TRANSACTION");
36391 if let Some(modes) = &e.modes {
36392 self.write_space();
36393 self.generate_expression(modes)?;
36394 }
36395 } else {
36396 self.write_keyword("BEGIN");
36398
36399 let is_kind = e.this.as_ref().map_or(false, |t| {
36401 if let Expression::Identifier(id) = t.as_ref() {
36402 id.name.eq_ignore_ascii_case("DEFERRED")
36403 || id.name.eq_ignore_ascii_case("IMMEDIATE")
36404 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
36405 } else {
36406 false
36407 }
36408 });
36409
36410 if is_kind {
36412 if let Some(this) = &e.this {
36413 self.write_space();
36414 if let Expression::Identifier(id) = this.as_ref() {
36415 self.write_keyword(&id.name);
36416 }
36417 }
36418 }
36419
36420 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
36422 self.write_space();
36423 self.write_keyword("TRANSACTION");
36424 }
36425
36426 if !is_kind {
36428 if let Some(this) = &e.this {
36429 self.write_space();
36430 self.generate_expression(this)?;
36431 }
36432 }
36433
36434 if has_with_mark {
36436 self.write_space();
36437 self.write_keyword("WITH MARK");
36438 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
36439 if let Literal::String(desc) = lit.as_ref() {
36440 if !desc.is_empty() {
36441 self.write_space();
36442 self.write(&format!("'{}'", desc));
36443 }
36444 }
36445 }
36446 }
36447
36448 if let Some(modes) = &e.modes {
36450 self.write_space();
36451 self.generate_expression(modes)?;
36452 }
36453 }
36454 Ok(())
36455 }
36456
36457 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
36458 self.write_keyword("TRANSFORM");
36460 self.write("(");
36461 self.generate_expression(&e.this)?;
36462 self.write(", ");
36463 self.generate_expression(&e.expression)?;
36464 self.write(")");
36465 Ok(())
36466 }
36467
36468 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
36469 self.write_keyword("TRANSFORM");
36471 self.write("(");
36472 if self.config.pretty && !e.expressions.is_empty() {
36473 self.indent_level += 1;
36474 for (i, expr) in e.expressions.iter().enumerate() {
36475 if i > 0 {
36476 self.write(",");
36477 }
36478 self.write_newline();
36479 self.write_indent();
36480 self.generate_expression(expr)?;
36481 }
36482 self.indent_level -= 1;
36483 self.write_newline();
36484 self.write(")");
36485 } else {
36486 for (i, expr) in e.expressions.iter().enumerate() {
36487 if i > 0 {
36488 self.write(", ");
36489 }
36490 self.generate_expression(expr)?;
36491 }
36492 self.write(")");
36493 }
36494 Ok(())
36495 }
36496
36497 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
36498 use crate::dialects::DialectType;
36499 if let Some(this) = &e.this {
36501 self.generate_expression(this)?;
36502 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36503 self.write_space();
36504 }
36505 }
36506 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36507 self.write_keyword("TRANSIENT");
36508 }
36509 Ok(())
36510 }
36511
36512 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
36513 self.write_keyword("TRANSLATE");
36515 self.write("(");
36516 self.generate_expression(&e.this)?;
36517 if let Some(from) = &e.from_ {
36518 self.write(", ");
36519 self.generate_expression(from)?;
36520 }
36521 if let Some(to) = &e.to {
36522 self.write(", ");
36523 self.generate_expression(to)?;
36524 }
36525 self.write(")");
36526 Ok(())
36527 }
36528
36529 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
36530 self.write_keyword("TRANSLATE");
36532 self.write("(");
36533 self.generate_expression(&e.this)?;
36534 self.write_space();
36535 self.write_keyword("USING");
36536 self.write_space();
36537 self.generate_expression(&e.expression)?;
36538 if e.with_error.is_some() {
36539 self.write_space();
36540 self.write_keyword("WITH ERROR");
36541 }
36542 self.write(")");
36543 Ok(())
36544 }
36545
36546 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
36547 self.write_keyword("TRUNCATE TABLE");
36549 self.write_space();
36550 for (i, expr) in e.expressions.iter().enumerate() {
36551 if i > 0 {
36552 self.write(", ");
36553 }
36554 self.generate_expression(expr)?;
36555 }
36556 Ok(())
36557 }
36558
36559 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
36560 self.write_keyword("TRY_BASE64_DECODE_BINARY");
36562 self.write("(");
36563 self.generate_expression(&e.this)?;
36564 if let Some(alphabet) = &e.alphabet {
36565 self.write(", ");
36566 self.generate_expression(alphabet)?;
36567 }
36568 self.write(")");
36569 Ok(())
36570 }
36571
36572 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
36573 self.write_keyword("TRY_BASE64_DECODE_STRING");
36575 self.write("(");
36576 self.generate_expression(&e.this)?;
36577 if let Some(alphabet) = &e.alphabet {
36578 self.write(", ");
36579 self.generate_expression(alphabet)?;
36580 }
36581 self.write(")");
36582 Ok(())
36583 }
36584
36585 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
36586 self.write_keyword("TRY_TO_DECFLOAT");
36588 self.write("(");
36589 self.generate_expression(&e.this)?;
36590 if let Some(format) = &e.format {
36591 self.write(", '");
36592 self.write(format);
36593 self.write("'");
36594 }
36595 self.write(")");
36596 Ok(())
36597 }
36598
36599 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
36600 self.write_keyword("TS_OR_DS_ADD");
36602 self.write("(");
36603 self.generate_expression(&e.this)?;
36604 self.write(", ");
36605 self.generate_expression(&e.expression)?;
36606 if let Some(unit) = &e.unit {
36607 self.write(", ");
36608 self.write_keyword(unit);
36609 }
36610 if let Some(return_type) = &e.return_type {
36611 self.write(", ");
36612 self.generate_expression(return_type)?;
36613 }
36614 self.write(")");
36615 Ok(())
36616 }
36617
36618 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
36619 self.write_keyword("TS_OR_DS_DIFF");
36621 self.write("(");
36622 self.generate_expression(&e.this)?;
36623 self.write(", ");
36624 self.generate_expression(&e.expression)?;
36625 if let Some(unit) = &e.unit {
36626 self.write(", ");
36627 self.write_keyword(unit);
36628 }
36629 self.write(")");
36630 Ok(())
36631 }
36632
36633 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
36634 let default_time_format = "%Y-%m-%d %H:%M:%S";
36635 let default_date_format = "%Y-%m-%d";
36636 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
36637 f != default_time_format && f != default_date_format
36638 });
36639
36640 if has_non_default_format {
36641 let fmt = e.format.as_ref().unwrap();
36643 match self.config.dialect {
36644 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
36645 let str_to_time = crate::expressions::StrToTime {
36648 this: Box::new((*e.this).clone()),
36649 format: fmt.clone(),
36650 zone: None,
36651 safe: None,
36652 target_type: None,
36653 };
36654 self.generate_str_to_time(&str_to_time)?;
36655 }
36656 Some(DialectType::Hive)
36657 | Some(DialectType::Spark)
36658 | Some(DialectType::Databricks) => {
36659 self.write_keyword("TO_DATE");
36661 self.write("(");
36662 self.generate_expression(&e.this)?;
36663 self.write(", '");
36664 self.write(&Self::strftime_to_java_format(fmt));
36665 self.write("')");
36666 }
36667 Some(DialectType::Snowflake) => {
36668 self.write_keyword("TO_DATE");
36670 self.write("(");
36671 self.generate_expression(&e.this)?;
36672 self.write(", '");
36673 self.write(&Self::strftime_to_snowflake_format(fmt));
36674 self.write("')");
36675 }
36676 Some(DialectType::Doris) => {
36677 self.write_keyword("TO_DATE");
36679 self.write("(");
36680 self.generate_expression(&e.this)?;
36681 self.write(")");
36682 }
36683 _ => {
36684 self.write_keyword("CAST");
36686 self.write("(");
36687 let str_to_time = crate::expressions::StrToTime {
36688 this: Box::new((*e.this).clone()),
36689 format: fmt.clone(),
36690 zone: None,
36691 safe: None,
36692 target_type: None,
36693 };
36694 self.generate_str_to_time(&str_to_time)?;
36695 self.write_keyword(" AS ");
36696 self.write_keyword("DATE");
36697 self.write(")");
36698 }
36699 }
36700 } else {
36701 match self.config.dialect {
36703 Some(DialectType::MySQL)
36704 | Some(DialectType::SQLite)
36705 | Some(DialectType::StarRocks) => {
36706 self.write_keyword("DATE");
36708 self.write("(");
36709 self.generate_expression(&e.this)?;
36710 self.write(")");
36711 }
36712 Some(DialectType::Hive)
36713 | Some(DialectType::Spark)
36714 | Some(DialectType::Databricks)
36715 | Some(DialectType::Snowflake)
36716 | Some(DialectType::Doris) => {
36717 self.write_keyword("TO_DATE");
36719 self.write("(");
36720 self.generate_expression(&e.this)?;
36721 self.write(")");
36722 }
36723 Some(DialectType::Presto)
36724 | Some(DialectType::Trino)
36725 | Some(DialectType::Athena) => {
36726 self.write_keyword("CAST");
36728 self.write("(");
36729 self.write_keyword("CAST");
36730 self.write("(");
36731 self.generate_expression(&e.this)?;
36732 self.write_keyword(" AS ");
36733 self.write_keyword("TIMESTAMP");
36734 self.write(")");
36735 self.write_keyword(" AS ");
36736 self.write_keyword("DATE");
36737 self.write(")");
36738 }
36739 Some(DialectType::ClickHouse) => {
36740 self.write_keyword("CAST");
36742 self.write("(");
36743 self.generate_expression(&e.this)?;
36744 self.write_keyword(" AS ");
36745 self.write("Nullable(DATE)");
36746 self.write(")");
36747 }
36748 _ => {
36749 self.write_keyword("CAST");
36751 self.write("(");
36752 self.generate_expression(&e.this)?;
36753 self.write_keyword(" AS ");
36754 self.write_keyword("DATE");
36755 self.write(")");
36756 }
36757 }
36758 }
36759 Ok(())
36760 }
36761
36762 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
36763 self.write_keyword("TS_OR_DS_TO_TIME");
36765 self.write("(");
36766 self.generate_expression(&e.this)?;
36767 if let Some(format) = &e.format {
36768 self.write(", '");
36769 self.write(format);
36770 self.write("'");
36771 }
36772 self.write(")");
36773 Ok(())
36774 }
36775
36776 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
36777 self.write_keyword("UNHEX");
36779 self.write("(");
36780 self.generate_expression(&e.this)?;
36781 if let Some(expression) = &e.expression {
36782 self.write(", ");
36783 self.generate_expression(expression)?;
36784 }
36785 self.write(")");
36786 Ok(())
36787 }
36788
36789 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
36790 self.write("U&");
36792 self.generate_expression(&e.this)?;
36793 if let Some(escape) = &e.escape {
36794 self.write_space();
36795 self.write_keyword("UESCAPE");
36796 self.write_space();
36797 self.generate_expression(escape)?;
36798 }
36799 Ok(())
36800 }
36801
36802 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
36803 self.write_keyword("UNIFORM");
36805 self.write("(");
36806 self.generate_expression(&e.this)?;
36807 self.write(", ");
36808 self.generate_expression(&e.expression)?;
36809 if let Some(gen) = &e.gen {
36810 self.write(", ");
36811 self.generate_expression(gen)?;
36812 }
36813 if let Some(seed) = &e.seed {
36814 self.write(", ");
36815 self.generate_expression(seed)?;
36816 }
36817 self.write(")");
36818 Ok(())
36819 }
36820
36821 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
36822 self.write_keyword("UNIQUE");
36824 if e.nulls.is_some() {
36826 self.write(" NULLS NOT DISTINCT");
36827 }
36828 if let Some(this) = &e.this {
36829 self.write_space();
36830 self.generate_expression(this)?;
36831 }
36832 if let Some(index_type) = &e.index_type {
36833 self.write(" USING ");
36834 self.generate_expression(index_type)?;
36835 }
36836 if let Some(on_conflict) = &e.on_conflict {
36837 self.write_space();
36838 self.generate_expression(on_conflict)?;
36839 }
36840 for opt in &e.options {
36841 self.write_space();
36842 self.generate_expression(opt)?;
36843 }
36844 Ok(())
36845 }
36846
36847 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
36848 self.write_keyword("UNIQUE KEY");
36850 self.write(" (");
36851 for (i, expr) in e.expressions.iter().enumerate() {
36852 if i > 0 {
36853 self.write(", ");
36854 }
36855 self.generate_expression(expr)?;
36856 }
36857 self.write(")");
36858 Ok(())
36859 }
36860
36861 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
36862 self.write_keyword("ROLLUP");
36864 self.write(" (");
36865 for (i, index) in e.expressions.iter().enumerate() {
36866 if i > 0 {
36867 self.write(", ");
36868 }
36869 self.generate_identifier(&index.name)?;
36870 self.write("(");
36871 for (j, col) in index.expressions.iter().enumerate() {
36872 if j > 0 {
36873 self.write(", ");
36874 }
36875 self.generate_identifier(col)?;
36876 }
36877 self.write(")");
36878 }
36879 self.write(")");
36880 Ok(())
36881 }
36882
36883 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
36884 match self.config.dialect {
36885 Some(DialectType::DuckDB) => {
36886 self.write_keyword("STRFTIME");
36888 self.write("(");
36889 self.write_keyword("TO_TIMESTAMP");
36890 self.write("(");
36891 self.generate_expression(&e.this)?;
36892 self.write("), '");
36893 if let Some(format) = &e.format {
36894 self.write(format);
36895 }
36896 self.write("')");
36897 }
36898 Some(DialectType::Hive) => {
36899 self.write_keyword("FROM_UNIXTIME");
36901 self.write("(");
36902 self.generate_expression(&e.this)?;
36903 if let Some(format) = &e.format {
36904 if format != "yyyy-MM-dd HH:mm:ss" {
36905 self.write(", '");
36906 self.write(format);
36907 self.write("'");
36908 }
36909 }
36910 self.write(")");
36911 }
36912 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36913 self.write_keyword("DATE_FORMAT");
36915 self.write("(");
36916 self.write_keyword("FROM_UNIXTIME");
36917 self.write("(");
36918 self.generate_expression(&e.this)?;
36919 self.write("), '");
36920 if let Some(format) = &e.format {
36921 self.write(format);
36922 }
36923 self.write("')");
36924 }
36925 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36926 self.write_keyword("FROM_UNIXTIME");
36928 self.write("(");
36929 self.generate_expression(&e.this)?;
36930 if let Some(format) = &e.format {
36931 self.write(", '");
36932 self.write(format);
36933 self.write("'");
36934 }
36935 self.write(")");
36936 }
36937 _ => {
36938 self.write_keyword("UNIX_TO_STR");
36940 self.write("(");
36941 self.generate_expression(&e.this)?;
36942 if let Some(format) = &e.format {
36943 self.write(", '");
36944 self.write(format);
36945 self.write("'");
36946 }
36947 self.write(")");
36948 }
36949 }
36950 Ok(())
36951 }
36952
36953 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
36954 use crate::dialects::DialectType;
36955 let scale = e.scale.unwrap_or(0); match self.config.dialect {
36958 Some(DialectType::Snowflake) => {
36959 self.write_keyword("TO_TIMESTAMP");
36961 self.write("(");
36962 self.generate_expression(&e.this)?;
36963 if let Some(s) = e.scale {
36964 if s > 0 {
36965 self.write(", ");
36966 self.write(&s.to_string());
36967 }
36968 }
36969 self.write(")");
36970 }
36971 Some(DialectType::BigQuery) => {
36972 match scale {
36975 0 => {
36976 self.write_keyword("TIMESTAMP_SECONDS");
36977 self.write("(");
36978 self.generate_expression(&e.this)?;
36979 self.write(")");
36980 }
36981 3 => {
36982 self.write_keyword("TIMESTAMP_MILLIS");
36983 self.write("(");
36984 self.generate_expression(&e.this)?;
36985 self.write(")");
36986 }
36987 6 => {
36988 self.write_keyword("TIMESTAMP_MICROS");
36989 self.write("(");
36990 self.generate_expression(&e.this)?;
36991 self.write(")");
36992 }
36993 _ => {
36994 self.write_keyword("TIMESTAMP_SECONDS");
36996 self.write("(CAST(");
36997 self.generate_expression(&e.this)?;
36998 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
36999 }
37000 }
37001 }
37002 Some(DialectType::Spark) => {
37003 match scale {
37008 0 => {
37009 self.write_keyword("CAST");
37010 self.write("(");
37011 self.write_keyword("FROM_UNIXTIME");
37012 self.write("(");
37013 self.generate_expression(&e.this)?;
37014 self.write(") ");
37015 self.write_keyword("AS TIMESTAMP");
37016 self.write(")");
37017 }
37018 3 => {
37019 self.write_keyword("TIMESTAMP_MILLIS");
37020 self.write("(");
37021 self.generate_expression(&e.this)?;
37022 self.write(")");
37023 }
37024 6 => {
37025 self.write_keyword("TIMESTAMP_MICROS");
37026 self.write("(");
37027 self.generate_expression(&e.this)?;
37028 self.write(")");
37029 }
37030 _ => {
37031 self.write_keyword("TIMESTAMP_SECONDS");
37032 self.write("(");
37033 self.generate_expression(&e.this)?;
37034 self.write(&format!(" / POWER(10, {}))", scale));
37035 }
37036 }
37037 }
37038 Some(DialectType::Databricks) => {
37039 match scale {
37043 0 => {
37044 self.write_keyword("CAST");
37045 self.write("(");
37046 self.write_keyword("FROM_UNIXTIME");
37047 self.write("(");
37048 self.generate_expression(&e.this)?;
37049 self.write(") ");
37050 self.write_keyword("AS TIMESTAMP");
37051 self.write(")");
37052 }
37053 3 => {
37054 self.write_keyword("TIMESTAMP_MILLIS");
37055 self.write("(");
37056 self.generate_expression(&e.this)?;
37057 self.write(")");
37058 }
37059 6 => {
37060 self.write_keyword("TIMESTAMP_MICROS");
37061 self.write("(");
37062 self.generate_expression(&e.this)?;
37063 self.write(")");
37064 }
37065 _ => {
37066 self.write_keyword("TIMESTAMP_SECONDS");
37067 self.write("(");
37068 self.generate_expression(&e.this)?;
37069 self.write(&format!(" / POWER(10, {}))", scale));
37070 }
37071 }
37072 }
37073 Some(DialectType::Hive) => {
37074 if scale == 0 {
37076 self.write_keyword("FROM_UNIXTIME");
37077 self.write("(");
37078 self.generate_expression(&e.this)?;
37079 self.write(")");
37080 } else {
37081 self.write_keyword("FROM_UNIXTIME");
37082 self.write("(");
37083 self.generate_expression(&e.this)?;
37084 self.write(&format!(" / POWER(10, {})", scale));
37085 self.write(")");
37086 }
37087 }
37088 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37089 if scale == 0 {
37092 self.write_keyword("FROM_UNIXTIME");
37093 self.write("(");
37094 self.generate_expression(&e.this)?;
37095 self.write(")");
37096 } else {
37097 self.write_keyword("FROM_UNIXTIME");
37098 self.write("(CAST(");
37099 self.generate_expression(&e.this)?;
37100 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
37101 }
37102 }
37103 Some(DialectType::DuckDB) => {
37104 match scale {
37108 0 => {
37109 self.write_keyword("TO_TIMESTAMP");
37110 self.write("(");
37111 self.generate_expression(&e.this)?;
37112 self.write(")");
37113 }
37114 3 => {
37115 self.write_keyword("EPOCH_MS");
37116 self.write("(");
37117 self.generate_expression(&e.this)?;
37118 self.write(")");
37119 }
37120 6 => {
37121 self.write_keyword("MAKE_TIMESTAMP");
37122 self.write("(");
37123 self.generate_expression(&e.this)?;
37124 self.write(")");
37125 }
37126 _ => {
37127 self.write_keyword("TO_TIMESTAMP");
37128 self.write("(");
37129 self.generate_expression(&e.this)?;
37130 self.write(&format!(" / POWER(10, {}))", scale));
37131 self.write_keyword(" AT TIME ZONE");
37132 self.write(" 'UTC'");
37133 }
37134 }
37135 }
37136 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
37137 self.write_keyword("FROM_UNIXTIME");
37139 self.write("(");
37140 self.generate_expression(&e.this)?;
37141 self.write(")");
37142 }
37143 Some(DialectType::Oracle) => {
37144 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
37146 self.generate_expression(&e.this)?;
37147 self.write(" / 86400)");
37148 }
37149 Some(DialectType::Redshift) => {
37150 self.write("(TIMESTAMP 'epoch' + ");
37153 if scale == 0 {
37154 self.generate_expression(&e.this)?;
37155 } else {
37156 self.write("(");
37157 self.generate_expression(&e.this)?;
37158 self.write(&format!(" / POWER(10, {}))", scale));
37159 }
37160 self.write(" * INTERVAL '1 SECOND')");
37161 }
37162 Some(DialectType::Exasol) => {
37163 self.write_keyword("FROM_POSIX_TIME");
37165 self.write("(");
37166 self.generate_expression(&e.this)?;
37167 self.write(")");
37168 }
37169 _ => {
37170 self.write_keyword("TO_TIMESTAMP");
37172 self.write("(");
37173 self.generate_expression(&e.this)?;
37174 if let Some(s) = e.scale {
37175 self.write(", ");
37176 self.write(&s.to_string());
37177 }
37178 self.write(")");
37179 }
37180 }
37181 Ok(())
37182 }
37183
37184 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
37185 if !matches!(&*e.this, Expression::Null(_)) {
37187 self.write_keyword("NAME");
37188 self.write_space();
37189 self.generate_expression(&e.this)?;
37190 }
37191 if !e.expressions.is_empty() {
37192 self.write_space();
37193 self.write_keyword("VALUE");
37194 self.write_space();
37195 for (i, expr) in e.expressions.iter().enumerate() {
37196 if i > 0 {
37197 self.write(", ");
37198 }
37199 self.generate_expression(expr)?;
37200 }
37201 }
37202 Ok(())
37203 }
37204
37205 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
37206 if e.wrapped.is_some() {
37208 self.write("(");
37209 }
37210 self.generate_expression(&e.this)?;
37211 if e.wrapped.is_some() {
37212 self.write(")");
37213 }
37214 self.write("(");
37215 for (i, expr) in e.expressions.iter().enumerate() {
37216 if i > 0 {
37217 self.write(", ");
37218 }
37219 self.generate_expression(expr)?;
37220 }
37221 self.write(")");
37222 Ok(())
37223 }
37224
37225 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
37226 self.write_keyword("USING TEMPLATE");
37228 self.write_space();
37229 self.generate_expression(&e.this)?;
37230 Ok(())
37231 }
37232
37233 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
37234 self.write_keyword("UTC_TIME");
37236 Ok(())
37237 }
37238
37239 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
37240 if matches!(
37241 self.config.dialect,
37242 Some(crate::dialects::DialectType::ClickHouse)
37243 ) {
37244 self.write_keyword("CURRENT_TIMESTAMP");
37245 self.write("('UTC')");
37246 } else {
37247 self.write_keyword("UTC_TIMESTAMP");
37248 }
37249 Ok(())
37250 }
37251
37252 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
37253 use crate::dialects::DialectType;
37254 let func_name = match self.config.dialect {
37256 Some(DialectType::Snowflake) => "UUID_STRING",
37257 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
37258 Some(DialectType::BigQuery) => "GENERATE_UUID",
37259 _ => {
37260 if let Some(name) = &e.name {
37261 name.as_str()
37262 } else {
37263 "UUID"
37264 }
37265 }
37266 };
37267 self.write_keyword(func_name);
37268 self.write("(");
37269 if let Some(this) = &e.this {
37270 self.generate_expression(this)?;
37271 }
37272 self.write(")");
37273 Ok(())
37274 }
37275
37276 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
37277 self.write_keyword("MAP");
37279 self.write("(");
37280 let mut first = true;
37281 for (k, v) in e.keys.iter().zip(e.values.iter()) {
37282 if !first {
37283 self.write(", ");
37284 }
37285 self.generate_expression(k)?;
37286 self.write(", ");
37287 self.generate_expression(v)?;
37288 first = false;
37289 }
37290 self.write(")");
37291 Ok(())
37292 }
37293
37294 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
37295 self.write_keyword("VECTOR_SEARCH");
37297 self.write("(");
37298 self.generate_expression(&e.this)?;
37299 if let Some(col) = &e.column_to_search {
37300 self.write(", ");
37301 self.generate_expression(col)?;
37302 }
37303 if let Some(query_table) = &e.query_table {
37304 self.write(", ");
37305 self.generate_expression(query_table)?;
37306 }
37307 if let Some(query_col) = &e.query_column_to_search {
37308 self.write(", ");
37309 self.generate_expression(query_col)?;
37310 }
37311 if let Some(top_k) = &e.top_k {
37312 self.write(", ");
37313 self.generate_expression(top_k)?;
37314 }
37315 if let Some(dist_type) = &e.distance_type {
37316 self.write(", ");
37317 self.generate_expression(dist_type)?;
37318 }
37319 self.write(")");
37320 Ok(())
37321 }
37322
37323 fn generate_version(&mut self, e: &Version) -> Result<()> {
37324 use crate::dialects::DialectType;
37330 let skip_for = matches!(
37331 self.config.dialect,
37332 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
37333 );
37334 if !skip_for {
37335 self.write_keyword("FOR");
37336 self.write_space();
37337 }
37338 match e.this.as_ref() {
37340 Expression::Identifier(ident) => {
37341 self.write_keyword(&ident.name);
37342 }
37343 _ => {
37344 self.generate_expression(&e.this)?;
37345 }
37346 }
37347 self.write_space();
37348 self.write_keyword(&e.kind);
37349 if let Some(expression) = &e.expression {
37350 self.write_space();
37351 self.generate_expression(expression)?;
37352 }
37353 Ok(())
37354 }
37355
37356 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
37357 self.generate_expression(&e.this)?;
37359 Ok(())
37360 }
37361
37362 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
37363 if e.this.is_some() {
37365 self.write_keyword("NOT VOLATILE");
37366 } else {
37367 self.write_keyword("VOLATILE");
37368 }
37369 Ok(())
37370 }
37371
37372 fn generate_watermark_column_constraint(
37373 &mut self,
37374 e: &WatermarkColumnConstraint,
37375 ) -> Result<()> {
37376 self.write_keyword("WATERMARK FOR");
37378 self.write_space();
37379 self.generate_expression(&e.this)?;
37380 self.write_space();
37381 self.write_keyword("AS");
37382 self.write_space();
37383 self.generate_expression(&e.expression)?;
37384 Ok(())
37385 }
37386
37387 fn generate_week(&mut self, e: &Week) -> Result<()> {
37388 self.write_keyword("WEEK");
37390 self.write("(");
37391 self.generate_expression(&e.this)?;
37392 if let Some(mode) = &e.mode {
37393 self.write(", ");
37394 self.generate_expression(mode)?;
37395 }
37396 self.write(")");
37397 Ok(())
37398 }
37399
37400 fn generate_when(&mut self, e: &When) -> Result<()> {
37401 self.write_keyword("WHEN");
37405 self.write_space();
37406
37407 if let Some(matched) = &e.matched {
37409 match matched.as_ref() {
37411 Expression::Boolean(b) if b.value => {
37412 self.write_keyword("MATCHED");
37413 }
37414 _ => {
37415 self.write_keyword("NOT MATCHED");
37416 }
37417 }
37418 } else {
37419 self.write_keyword("NOT MATCHED");
37420 }
37421
37422 if self.config.matched_by_source {
37427 if let Some(source) = &e.source {
37428 if let Expression::Boolean(b) = source.as_ref() {
37429 if b.value {
37430 self.write_space();
37432 self.write_keyword("BY SOURCE");
37433 }
37434 } else {
37436 self.write_space();
37438 self.write_keyword("BY SOURCE");
37439 }
37440 }
37441 }
37442
37443 if let Some(condition) = &e.condition {
37445 self.write_space();
37446 self.write_keyword("AND");
37447 self.write_space();
37448 self.generate_expression(condition)?;
37449 }
37450
37451 self.write_space();
37452 self.write_keyword("THEN");
37453 self.write_space();
37454
37455 self.generate_merge_action(&e.then)?;
37458
37459 Ok(())
37460 }
37461
37462 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
37463 match action {
37464 Expression::Tuple(tuple) => {
37465 let elements = &tuple.expressions;
37466 if elements.is_empty() {
37467 return self.generate_expression(action);
37468 }
37469 match &elements[0] {
37471 Expression::Var(v) if v.this == "INSERT" => {
37472 self.write_keyword("INSERT");
37473 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37475 self.write(" *");
37476 if let Some(Expression::Where(w)) = elements.get(2) {
37477 self.write_space();
37478 self.generate_where(w)?;
37479 }
37480 } else {
37481 let mut values_idx = 1;
37482 if elements.len() > 1 {
37484 if let Expression::Tuple(cols) = &elements[1] {
37485 if elements.len() > 2 {
37487 self.write(" (");
37489 for (i, col) in cols.expressions.iter().enumerate() {
37490 if i > 0 {
37491 self.write(", ");
37492 }
37493 if !self.merge_strip_qualifiers.is_empty() {
37495 let stripped = self.strip_merge_qualifier(col);
37496 self.generate_expression(&stripped)?;
37497 } else {
37498 self.generate_expression(col)?;
37499 }
37500 }
37501 self.write(")");
37502 values_idx = 2;
37503 } else {
37504 values_idx = 1;
37506 }
37507 }
37508 }
37509 let mut next_idx = values_idx;
37510 if values_idx < elements.len()
37512 && !matches!(&elements[values_idx], Expression::Where(_))
37513 {
37514 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
37516 if !is_row {
37517 self.write_space();
37518 self.write_keyword("VALUES");
37519 }
37520 self.write(" ");
37521 if let Expression::Tuple(vals) = &elements[values_idx] {
37522 self.write("(");
37523 for (i, val) in vals.expressions.iter().enumerate() {
37524 if i > 0 {
37525 self.write(", ");
37526 }
37527 self.generate_expression(val)?;
37528 }
37529 self.write(")");
37530 } else {
37531 self.generate_expression(&elements[values_idx])?;
37532 }
37533 next_idx += 1;
37534 }
37535 if let Some(Expression::Where(w)) = elements.get(next_idx) {
37536 self.write_space();
37537 self.generate_where(w)?;
37538 }
37539 } }
37541 Expression::Var(v) if v.this == "UPDATE" => {
37542 self.write_keyword("UPDATE");
37543 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37545 self.write(" *");
37546 if let Some(Expression::Where(w)) = elements.get(2) {
37547 self.write_space();
37548 self.generate_where(w)?;
37549 }
37550 } else if elements.len() > 1 {
37551 self.write_space();
37552 self.write_keyword("SET");
37553 if self.config.pretty {
37555 self.write_newline();
37556 self.indent_level += 1;
37557 self.write_indent();
37558 } else {
37559 self.write_space();
37560 }
37561 if let Expression::Tuple(assignments) = &elements[1] {
37562 for (i, assignment) in assignments.expressions.iter().enumerate() {
37563 if i > 0 {
37564 if self.config.pretty {
37565 self.write(",");
37566 self.write_newline();
37567 self.write_indent();
37568 } else {
37569 self.write(", ");
37570 }
37571 }
37572 if !self.merge_strip_qualifiers.is_empty() {
37574 self.generate_merge_set_assignment(assignment)?;
37575 } else {
37576 self.generate_expression(assignment)?;
37577 }
37578 }
37579 } else {
37580 self.generate_expression(&elements[1])?;
37581 }
37582 if self.config.pretty {
37583 self.indent_level -= 1;
37584 }
37585 if let Some(Expression::Where(w)) = elements.get(2) {
37586 self.write_space();
37587 self.generate_where(w)?;
37588 }
37589 }
37590 }
37591 Expression::Var(v) if v.this == "DELETE" => {
37592 self.write_keyword("DELETE");
37593 if let Some(Expression::Where(w)) = elements.get(1) {
37594 self.write_space();
37595 self.generate_where(w)?;
37596 }
37597 }
37598 _ => {
37599 self.generate_expression(action)?;
37601 }
37602 }
37603 }
37604 Expression::Var(v)
37605 if v.this == "INSERT"
37606 || v.this == "UPDATE"
37607 || v.this == "DELETE"
37608 || v.this == "DO NOTHING" =>
37609 {
37610 self.write_keyword(&v.this);
37611 }
37612 _ => {
37613 self.generate_expression(action)?;
37614 }
37615 }
37616 Ok(())
37617 }
37618
37619 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
37621 match assignment {
37622 Expression::Eq(eq) => {
37623 let stripped_left = self.strip_merge_qualifier(&eq.left);
37625 self.generate_expression(&stripped_left)?;
37626 self.write(" = ");
37627 self.generate_expression(&eq.right)?;
37628 Ok(())
37629 }
37630 other => self.generate_expression(other),
37631 }
37632 }
37633
37634 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
37636 match expr {
37637 Expression::Column(col) => {
37638 if let Some(ref table_ident) = col.table {
37639 if self
37640 .merge_strip_qualifiers
37641 .iter()
37642 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
37643 {
37644 let mut col = col.clone();
37646 col.table = None;
37647 return Expression::Column(col);
37648 }
37649 }
37650 expr.clone()
37651 }
37652 Expression::Dot(dot) => {
37653 if let Expression::Identifier(id) = &dot.this {
37655 if self
37656 .merge_strip_qualifiers
37657 .iter()
37658 .any(|n| n.eq_ignore_ascii_case(&id.name))
37659 {
37660 return Expression::Identifier(dot.field.clone());
37661 }
37662 }
37663 expr.clone()
37664 }
37665 _ => expr.clone(),
37666 }
37667 }
37668
37669 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
37670 for (i, expr) in e.expressions.iter().enumerate() {
37672 if i > 0 {
37673 if self.config.pretty {
37675 self.write_newline();
37676 self.write_indent();
37677 } else {
37678 self.write_space();
37679 }
37680 }
37681 self.generate_expression(expr)?;
37682 }
37683 Ok(())
37684 }
37685
37686 fn generate_where(&mut self, e: &Where) -> Result<()> {
37687 self.write_keyword("WHERE");
37689 self.write_space();
37690 self.generate_expression(&e.this)?;
37691 Ok(())
37692 }
37693
37694 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
37695 self.write_keyword("WIDTH_BUCKET");
37697 self.write("(");
37698 self.generate_expression(&e.this)?;
37699 if let Some(min_value) = &e.min_value {
37700 self.write(", ");
37701 self.generate_expression(min_value)?;
37702 }
37703 if let Some(max_value) = &e.max_value {
37704 self.write(", ");
37705 self.generate_expression(max_value)?;
37706 }
37707 if let Some(num_buckets) = &e.num_buckets {
37708 self.write(", ");
37709 self.generate_expression(num_buckets)?;
37710 }
37711 self.write(")");
37712 Ok(())
37713 }
37714
37715 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
37716 self.generate_window_spec(e)
37718 }
37719
37720 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
37721 let mut has_content = false;
37723
37724 if !e.partition_by.is_empty() {
37726 self.write_keyword("PARTITION BY");
37727 self.write_space();
37728 for (i, expr) in e.partition_by.iter().enumerate() {
37729 if i > 0 {
37730 self.write(", ");
37731 }
37732 self.generate_expression(expr)?;
37733 }
37734 has_content = true;
37735 }
37736
37737 if !e.order_by.is_empty() {
37739 if has_content {
37740 self.write_space();
37741 }
37742 self.write_keyword("ORDER BY");
37743 self.write_space();
37744 for (i, ordered) in e.order_by.iter().enumerate() {
37745 if i > 0 {
37746 self.write(", ");
37747 }
37748 self.generate_expression(&ordered.this)?;
37749 if ordered.desc {
37750 self.write_space();
37751 self.write_keyword("DESC");
37752 } else if ordered.explicit_asc {
37753 self.write_space();
37754 self.write_keyword("ASC");
37755 }
37756 if let Some(nulls_first) = ordered.nulls_first {
37757 self.write_space();
37758 self.write_keyword("NULLS");
37759 self.write_space();
37760 if nulls_first {
37761 self.write_keyword("FIRST");
37762 } else {
37763 self.write_keyword("LAST");
37764 }
37765 }
37766 }
37767 has_content = true;
37768 }
37769
37770 if let Some(frame) = &e.frame {
37772 if has_content {
37773 self.write_space();
37774 }
37775 self.generate_window_frame(frame)?;
37776 }
37777
37778 Ok(())
37779 }
37780
37781 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
37782 self.write_keyword("WITH");
37784 self.write_space();
37785 if e.no.is_some() {
37786 self.write_keyword("NO");
37787 self.write_space();
37788 }
37789 self.write_keyword("DATA");
37790
37791 if let Some(statistics) = &e.statistics {
37793 self.write_space();
37794 self.write_keyword("AND");
37795 self.write_space();
37796 match statistics.as_ref() {
37798 Expression::Boolean(b) if !b.value => {
37799 self.write_keyword("NO");
37800 self.write_space();
37801 }
37802 _ => {}
37803 }
37804 self.write_keyword("STATISTICS");
37805 }
37806 Ok(())
37807 }
37808
37809 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
37810 self.write_keyword("WITH FILL");
37812
37813 if let Some(from_) = &e.from_ {
37814 self.write_space();
37815 self.write_keyword("FROM");
37816 self.write_space();
37817 self.generate_expression(from_)?;
37818 }
37819
37820 if let Some(to) = &e.to {
37821 self.write_space();
37822 self.write_keyword("TO");
37823 self.write_space();
37824 self.generate_expression(to)?;
37825 }
37826
37827 if let Some(step) = &e.step {
37828 self.write_space();
37829 self.write_keyword("STEP");
37830 self.write_space();
37831 self.generate_expression(step)?;
37832 }
37833
37834 if let Some(staleness) = &e.staleness {
37835 self.write_space();
37836 self.write_keyword("STALENESS");
37837 self.write_space();
37838 self.generate_expression(staleness)?;
37839 }
37840
37841 if let Some(interpolate) = &e.interpolate {
37842 self.write_space();
37843 self.write_keyword("INTERPOLATE");
37844 self.write(" (");
37845 self.generate_interpolate_item(interpolate)?;
37847 self.write(")");
37848 }
37849
37850 Ok(())
37851 }
37852
37853 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
37855 match expr {
37856 Expression::Alias(alias) => {
37857 self.generate_identifier(&alias.alias)?;
37859 self.write_space();
37860 self.write_keyword("AS");
37861 self.write_space();
37862 self.generate_expression(&alias.this)?;
37863 }
37864 Expression::Tuple(tuple) => {
37865 for (i, item) in tuple.expressions.iter().enumerate() {
37866 if i > 0 {
37867 self.write(", ");
37868 }
37869 self.generate_interpolate_item(item)?;
37870 }
37871 }
37872 other => {
37873 self.generate_expression(other)?;
37874 }
37875 }
37876 Ok(())
37877 }
37878
37879 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
37880 self.write_keyword("WITH JOURNAL TABLE");
37882 self.write("=");
37883 self.generate_expression(&e.this)?;
37884 Ok(())
37885 }
37886
37887 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
37888 self.generate_expression(&e.this)?;
37890 self.write_space();
37891 self.write_keyword("WITH");
37892 self.write_space();
37893 self.write_keyword(&e.op);
37894 Ok(())
37895 }
37896
37897 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
37898 self.write_keyword("WITH");
37900 self.write_space();
37901 for (i, expr) in e.expressions.iter().enumerate() {
37902 if i > 0 {
37903 self.write(", ");
37904 }
37905 self.generate_expression(expr)?;
37906 }
37907 Ok(())
37908 }
37909
37910 fn generate_with_schema_binding_property(
37911 &mut self,
37912 e: &WithSchemaBindingProperty,
37913 ) -> Result<()> {
37914 self.write_keyword("WITH");
37916 self.write_space();
37917 self.generate_expression(&e.this)?;
37918 Ok(())
37919 }
37920
37921 fn generate_with_system_versioning_property(
37922 &mut self,
37923 e: &WithSystemVersioningProperty,
37924 ) -> Result<()> {
37925 let mut parts = Vec::new();
37931
37932 if let Some(this) = &e.this {
37933 let mut s = String::from("HISTORY_TABLE=");
37935 let mut gen = Generator::new();
37936 gen.generate_expression(this)?;
37937 s.push_str(&gen.output);
37938 parts.push(s);
37939 }
37940
37941 if let Some(data_consistency) = &e.data_consistency {
37942 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
37943 let mut gen = Generator::new();
37944 gen.generate_expression(data_consistency)?;
37945 s.push_str(&gen.output);
37946 parts.push(s);
37947 }
37948
37949 if let Some(retention_period) = &e.retention_period {
37950 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
37951 let mut gen = Generator::new();
37952 gen.generate_expression(retention_period)?;
37953 s.push_str(&gen.output);
37954 parts.push(s);
37955 }
37956
37957 self.write_keyword("SYSTEM_VERSIONING");
37958 self.write("=");
37959
37960 if !parts.is_empty() {
37961 self.write_keyword("ON");
37962 self.write("(");
37963 self.write(&parts.join(", "));
37964 self.write(")");
37965 } else if e.on.is_some() {
37966 self.write_keyword("ON");
37967 } else {
37968 self.write_keyword("OFF");
37969 }
37970
37971 if e.with_.is_some() {
37973 let inner = self.output.clone();
37974 self.output.clear();
37975 self.write("WITH(");
37976 self.write(&inner);
37977 self.write(")");
37978 }
37979
37980 Ok(())
37981 }
37982
37983 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
37984 self.write_keyword("WITH");
37986 self.write(" (");
37987 for (i, expr) in e.expressions.iter().enumerate() {
37988 if i > 0 {
37989 self.write(", ");
37990 }
37991 self.generate_expression(expr)?;
37992 }
37993 self.write(")");
37994 Ok(())
37995 }
37996
37997 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
37998 self.write_keyword("XMLELEMENT");
38001 self.write("(");
38002
38003 if e.evalname.is_some() {
38004 self.write_keyword("EVALNAME");
38005 } else {
38006 self.write_keyword("NAME");
38007 }
38008 self.write_space();
38009 self.generate_expression(&e.this)?;
38010
38011 for expr in &e.expressions {
38012 self.write(", ");
38013 self.generate_expression(expr)?;
38014 }
38015 self.write(")");
38016 Ok(())
38017 }
38018
38019 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
38020 self.write_keyword("XMLGET");
38022 self.write("(");
38023 self.generate_expression(&e.this)?;
38024 self.write(", ");
38025 self.generate_expression(&e.expression)?;
38026 if let Some(instance) = &e.instance {
38027 self.write(", ");
38028 self.generate_expression(instance)?;
38029 }
38030 self.write(")");
38031 Ok(())
38032 }
38033
38034 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
38035 self.generate_expression(&e.this)?;
38037 if let Some(expression) = &e.expression {
38038 self.write("(");
38039 self.generate_expression(expression)?;
38040 self.write(")");
38041 }
38042 Ok(())
38043 }
38044
38045 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
38046 self.write_keyword("XMLTABLE");
38048 self.write("(");
38049
38050 if self.config.pretty {
38051 self.indent_level += 1;
38052 self.write_newline();
38053 self.write_indent();
38054 self.generate_expression(&e.this)?;
38055
38056 if let Some(passing) = &e.passing {
38057 self.write_newline();
38058 self.write_indent();
38059 self.write_keyword("PASSING");
38060 if let Expression::Tuple(tuple) = passing.as_ref() {
38061 for expr in &tuple.expressions {
38062 self.write_newline();
38063 self.indent_level += 1;
38064 self.write_indent();
38065 self.generate_expression(expr)?;
38066 self.indent_level -= 1;
38067 }
38068 } else {
38069 self.write_newline();
38070 self.indent_level += 1;
38071 self.write_indent();
38072 self.generate_expression(passing)?;
38073 self.indent_level -= 1;
38074 }
38075 }
38076
38077 if e.by_ref.is_some() {
38078 self.write_newline();
38079 self.write_indent();
38080 self.write_keyword("RETURNING SEQUENCE BY REF");
38081 }
38082
38083 if !e.columns.is_empty() {
38084 self.write_newline();
38085 self.write_indent();
38086 self.write_keyword("COLUMNS");
38087 for (i, col) in e.columns.iter().enumerate() {
38088 self.write_newline();
38089 self.indent_level += 1;
38090 self.write_indent();
38091 self.generate_expression(col)?;
38092 self.indent_level -= 1;
38093 if i < e.columns.len() - 1 {
38094 self.write(",");
38095 }
38096 }
38097 }
38098
38099 self.indent_level -= 1;
38100 self.write_newline();
38101 self.write_indent();
38102 self.write(")");
38103 return Ok(());
38104 }
38105
38106 if let Some(namespaces) = &e.namespaces {
38108 self.write_keyword("XMLNAMESPACES");
38109 self.write("(");
38110 if let Expression::Tuple(tuple) = namespaces.as_ref() {
38112 for (i, expr) in tuple.expressions.iter().enumerate() {
38113 if i > 0 {
38114 self.write(", ");
38115 }
38116 if !matches!(expr, Expression::Alias(_)) {
38119 self.write_keyword("DEFAULT");
38120 self.write_space();
38121 }
38122 self.generate_expression(expr)?;
38123 }
38124 } else {
38125 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
38127 self.write_keyword("DEFAULT");
38128 self.write_space();
38129 }
38130 self.generate_expression(namespaces)?;
38131 }
38132 self.write("), ");
38133 }
38134
38135 self.generate_expression(&e.this)?;
38137
38138 if let Some(passing) = &e.passing {
38140 self.write_space();
38141 self.write_keyword("PASSING");
38142 self.write_space();
38143 if let Expression::Tuple(tuple) = passing.as_ref() {
38145 for (i, expr) in tuple.expressions.iter().enumerate() {
38146 if i > 0 {
38147 self.write(", ");
38148 }
38149 self.generate_expression(expr)?;
38150 }
38151 } else {
38152 self.generate_expression(passing)?;
38153 }
38154 }
38155
38156 if e.by_ref.is_some() {
38158 self.write_space();
38159 self.write_keyword("RETURNING SEQUENCE BY REF");
38160 }
38161
38162 if !e.columns.is_empty() {
38164 self.write_space();
38165 self.write_keyword("COLUMNS");
38166 self.write_space();
38167 for (i, col) in e.columns.iter().enumerate() {
38168 if i > 0 {
38169 self.write(", ");
38170 }
38171 self.generate_expression(col)?;
38172 }
38173 }
38174
38175 self.write(")");
38176 Ok(())
38177 }
38178
38179 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
38180 if let Some(this) = &e.this {
38183 self.generate_expression(this)?;
38184 if let Some(expression) = &e.expression {
38185 self.write_space();
38186 self.write_keyword("XOR");
38187 self.write_space();
38188 self.generate_expression(expression)?;
38189 }
38190 }
38191
38192 for (i, expr) in e.expressions.iter().enumerate() {
38194 if i > 0 || e.this.is_some() {
38195 self.write_space();
38196 self.write_keyword("XOR");
38197 self.write_space();
38198 }
38199 self.generate_expression(expr)?;
38200 }
38201 Ok(())
38202 }
38203
38204 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
38205 self.write_keyword("ZIPF");
38207 self.write("(");
38208 self.generate_expression(&e.this)?;
38209 if let Some(elementcount) = &e.elementcount {
38210 self.write(", ");
38211 self.generate_expression(elementcount)?;
38212 }
38213 if let Some(gen) = &e.gen {
38214 self.write(", ");
38215 self.generate_expression(gen)?;
38216 }
38217 self.write(")");
38218 Ok(())
38219 }
38220}
38221
38222impl Default for Generator {
38223 fn default() -> Self {
38224 Self::new()
38225 }
38226}
38227
38228#[cfg(test)]
38229mod tests {
38230 use super::*;
38231 use crate::parser::Parser;
38232
38233 fn roundtrip(sql: &str) -> String {
38234 let ast = Parser::parse_sql(sql).unwrap();
38235 Generator::sql(&ast[0]).unwrap()
38236 }
38237
38238 #[test]
38239 fn test_simple_select() {
38240 let result = roundtrip("SELECT 1");
38241 assert_eq!(result, "SELECT 1");
38242 }
38243
38244 #[test]
38245 fn test_select_from() {
38246 let result = roundtrip("SELECT a, b FROM t");
38247 assert_eq!(result, "SELECT a, b FROM t");
38248 }
38249
38250 #[test]
38251 fn test_select_where() {
38252 let result = roundtrip("SELECT * FROM t WHERE x = 1");
38253 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
38254 }
38255
38256 #[test]
38257 fn test_select_join() {
38258 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
38259 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
38260 }
38261
38262 #[test]
38263 fn test_insert() {
38264 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
38265 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
38266 }
38267
38268 #[test]
38269 fn test_pretty_print() {
38270 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
38271 let result = Generator::pretty_sql(&ast[0]).unwrap();
38272 assert!(result.contains('\n'));
38273 }
38274
38275 #[test]
38276 fn test_window_function() {
38277 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
38278 assert_eq!(
38279 result,
38280 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
38281 );
38282 }
38283
38284 #[test]
38285 fn test_window_function_with_frame() {
38286 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
38287 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
38288 }
38289
38290 #[test]
38291 fn test_aggregate_with_filter() {
38292 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
38293 assert_eq!(
38294 result,
38295 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
38296 );
38297 }
38298
38299 #[test]
38300 fn test_subscript() {
38301 let result = roundtrip("SELECT arr[0]");
38302 assert_eq!(result, "SELECT arr[0]");
38303 }
38304
38305 #[test]
38307 fn test_create_table() {
38308 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
38309 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
38310 }
38311
38312 #[test]
38313 fn test_create_table_with_constraints() {
38314 let result = roundtrip(
38315 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
38316 );
38317 assert_eq!(
38318 result,
38319 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
38320 );
38321 }
38322
38323 #[test]
38324 fn test_create_table_if_not_exists() {
38325 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
38326 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
38327 }
38328
38329 #[test]
38330 fn test_drop_table() {
38331 let result = roundtrip("DROP TABLE users");
38332 assert_eq!(result, "DROP TABLE users");
38333 }
38334
38335 #[test]
38336 fn test_drop_table_if_exists_cascade() {
38337 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
38338 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
38339 }
38340
38341 #[test]
38342 fn test_alter_table_add_column() {
38343 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38344 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38345 }
38346
38347 #[test]
38348 fn test_alter_table_drop_column() {
38349 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
38350 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
38351 }
38352
38353 #[test]
38354 fn test_create_index() {
38355 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
38356 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
38357 }
38358
38359 #[test]
38360 fn test_create_unique_index() {
38361 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
38362 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
38363 }
38364
38365 #[test]
38366 fn test_drop_index() {
38367 let result = roundtrip("DROP INDEX idx_name");
38368 assert_eq!(result, "DROP INDEX idx_name");
38369 }
38370
38371 #[test]
38372 fn test_create_view() {
38373 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
38374 assert_eq!(
38375 result,
38376 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
38377 );
38378 }
38379
38380 #[test]
38381 fn test_drop_view() {
38382 let result = roundtrip("DROP VIEW active_users");
38383 assert_eq!(result, "DROP VIEW active_users");
38384 }
38385
38386 #[test]
38387 fn test_truncate() {
38388 let result = roundtrip("TRUNCATE TABLE users");
38389 assert_eq!(result, "TRUNCATE TABLE users");
38390 }
38391
38392 #[test]
38393 fn test_string_literal_escaping_default() {
38394 let result = roundtrip("SELECT 'hello'");
38396 assert_eq!(result, "SELECT 'hello'");
38397
38398 let result = roundtrip("SELECT 'it''s a test'");
38400 assert_eq!(result, "SELECT 'it''s a test'");
38401 }
38402
38403 #[test]
38404 fn test_not_in_style_prefix_default_generic() {
38405 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
38406 assert_eq!(
38407 result,
38408 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
38409 );
38410 }
38411
38412 #[test]
38413 fn test_not_in_style_infix_generic_override() {
38414 let ast =
38415 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
38416 .unwrap();
38417 let config = GeneratorConfig {
38418 not_in_style: NotInStyle::Infix,
38419 ..Default::default()
38420 };
38421 let mut gen = Generator::with_config(config);
38422 let result = gen.generate(&ast[0]).unwrap();
38423 assert_eq!(
38424 result,
38425 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
38426 );
38427 }
38428
38429 #[test]
38430 fn test_string_literal_escaping_mysql() {
38431 use crate::dialects::DialectType;
38432
38433 let config = GeneratorConfig {
38434 dialect: Some(DialectType::MySQL),
38435 ..Default::default()
38436 };
38437
38438 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38439 let mut gen = Generator::with_config(config.clone());
38440 let result = gen.generate(&ast[0]).unwrap();
38441 assert_eq!(result, "SELECT 'hello'");
38442
38443 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38445 let mut gen = Generator::with_config(config.clone());
38446 let result = gen.generate(&ast[0]).unwrap();
38447 assert_eq!(result, "SELECT 'it''s'");
38448 }
38449
38450 #[test]
38451 fn test_string_literal_escaping_postgres() {
38452 use crate::dialects::DialectType;
38453
38454 let config = GeneratorConfig {
38455 dialect: Some(DialectType::PostgreSQL),
38456 ..Default::default()
38457 };
38458
38459 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38460 let mut gen = Generator::with_config(config.clone());
38461 let result = gen.generate(&ast[0]).unwrap();
38462 assert_eq!(result, "SELECT 'hello'");
38463
38464 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38466 let mut gen = Generator::with_config(config.clone());
38467 let result = gen.generate(&ast[0]).unwrap();
38468 assert_eq!(result, "SELECT 'it''s'");
38469 }
38470
38471 #[test]
38472 fn test_string_literal_escaping_bigquery() {
38473 use crate::dialects::DialectType;
38474
38475 let config = GeneratorConfig {
38476 dialect: Some(DialectType::BigQuery),
38477 ..Default::default()
38478 };
38479
38480 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38481 let mut gen = Generator::with_config(config.clone());
38482 let result = gen.generate(&ast[0]).unwrap();
38483 assert_eq!(result, "SELECT 'hello'");
38484
38485 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38487 let mut gen = Generator::with_config(config.clone());
38488 let result = gen.generate(&ast[0]).unwrap();
38489 assert_eq!(result, "SELECT 'it\\'s'");
38490 }
38491
38492 #[test]
38493 fn test_generate_deep_and_chain_without_stack_growth() {
38494 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38495 Expression::column("c0"),
38496 Expression::number(0),
38497 )));
38498
38499 for i in 1..2500 {
38500 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38501 Expression::column(format!("c{i}")),
38502 Expression::number(i as i64),
38503 )));
38504 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
38505 }
38506
38507 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
38508 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38509 }
38510
38511 #[test]
38512 fn test_generate_deep_or_chain_without_stack_growth() {
38513 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38514 Expression::column("c0"),
38515 Expression::number(0),
38516 )));
38517
38518 for i in 1..2500 {
38519 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38520 Expression::column(format!("c{i}")),
38521 Expression::number(i as i64),
38522 )));
38523 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
38524 }
38525
38526 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
38527 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38528 }
38529}