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 alias_explicit_as: false,
2207 alias_keyword: None,
2208 pre_alias_comments: Vec::new(),
2209 trailing_comments: Vec::new(),
2210 inferred_type: None,
2211 })),
2212
2213 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2215 this: expr.clone(),
2216 alias: ident.clone(),
2217 column_aliases: Vec::new(),
2218 alias_explicit_as: false,
2219 alias_keyword: None,
2220 pre_alias_comments: Vec::new(),
2221 trailing_comments: Vec::new(),
2222 inferred_type: None,
2223 })),
2224
2225 Expression::Subquery(sq) => {
2227 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2228 if sq.alias.is_some() {
2230 processed
2231 } else {
2232 processed
2234 }
2235 }
2236
2237 Expression::Star(_) => expr,
2239
2240 _ => expr,
2243 }
2244 }
2245
2246 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2250 match expr {
2251 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
2252 let Literal::Number(n) = lit.as_ref() else {
2253 unreachable!()
2254 };
2255 n.parse::<i64>().ok()
2256 }
2257 Expression::Add(op) => {
2258 let left = Self::try_evaluate_constant(&op.left)?;
2259 let right = Self::try_evaluate_constant(&op.right)?;
2260 Some(left + right)
2261 }
2262 Expression::Sub(op) => {
2263 let left = Self::try_evaluate_constant(&op.left)?;
2264 let right = Self::try_evaluate_constant(&op.right)?;
2265 Some(left - right)
2266 }
2267 Expression::Mul(op) => {
2268 let left = Self::try_evaluate_constant(&op.left)?;
2269 let right = Self::try_evaluate_constant(&op.right)?;
2270 Some(left * right)
2271 }
2272 Expression::Div(op) => {
2273 let left = Self::try_evaluate_constant(&op.left)?;
2274 let right = Self::try_evaluate_constant(&op.right)?;
2275 if right != 0 {
2276 Some(left / right)
2277 } else {
2278 None
2279 }
2280 }
2281 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2282 _ => None,
2283 }
2284 }
2285
2286 fn is_reserved_keyword(&self, name: &str) -> bool {
2288 use crate::dialects::DialectType;
2289 let mut buf = [0u8; 128];
2290 let lower_ref: &str = if name.len() <= 128 {
2291 for (i, b) in name.bytes().enumerate() {
2292 buf[i] = b.to_ascii_lowercase();
2293 }
2294 std::str::from_utf8(&buf[..name.len()]).unwrap_or(name)
2296 } else {
2297 return false;
2298 };
2299
2300 match self.config.dialect {
2301 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2302 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2303 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2304 }
2305 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2306 Some(DialectType::SingleStore) => {
2307 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2308 }
2309 Some(DialectType::StarRocks) => {
2310 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2311 }
2312 Some(DialectType::PostgreSQL)
2313 | Some(DialectType::CockroachDB)
2314 | Some(DialectType::Materialize)
2315 | Some(DialectType::RisingWave) => {
2316 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2317 }
2318 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2319 Some(DialectType::Snowflake) => false,
2322 Some(DialectType::ClickHouse) => false,
2324 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2325 Some(DialectType::Teradata) => false,
2327 Some(DialectType::TSQL)
2329 | Some(DialectType::Fabric)
2330 | Some(DialectType::Oracle)
2331 | Some(DialectType::Spark)
2332 | Some(DialectType::Databricks)
2333 | Some(DialectType::Hive)
2334 | Some(DialectType::Solr) => false,
2335 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2336 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2337 }
2338 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2339 Some(DialectType::Generic) | None => false,
2341 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2343 }
2344 }
2345
2346 fn normalize_func_name<'a>(&self, name: &'a str) -> Cow<'a, str> {
2348 match self.config.normalize_functions {
2349 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
2350 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
2351 NormalizeFunctions::None => Cow::Borrowed(name),
2352 }
2353 }
2354
2355 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2364 self.output.clear();
2365 self.unsupported_messages.clear();
2366 self.generate_expression(expr)?;
2367 if self.config.unsupported_level == UnsupportedLevel::Raise
2368 && !self.unsupported_messages.is_empty()
2369 {
2370 return Err(crate::error::Error::generate(
2371 self.format_unsupported_messages(),
2372 ));
2373 }
2374 Ok(std::mem::take(&mut self.output))
2375 }
2376
2377 pub fn unsupported_messages(&self) -> &[String] {
2379 &self.unsupported_messages
2380 }
2381
2382 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2383 let message = message.into();
2384 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2385 return Err(crate::error::Error::generate(message));
2386 }
2387 self.unsupported_messages.push(message);
2388 Ok(())
2389 }
2390
2391 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2392 self.unsupported(message.to_string())?;
2393 self.write("/* ");
2394 self.write(message);
2395 self.write(" */");
2396 Ok(())
2397 }
2398
2399 fn format_unsupported_messages(&self) -> String {
2400 let limit = self.config.max_unsupported.max(1);
2401 if self.unsupported_messages.len() <= limit {
2402 return self.unsupported_messages.join("; ");
2403 }
2404
2405 let mut messages = self
2406 .unsupported_messages
2407 .iter()
2408 .take(limit)
2409 .cloned()
2410 .collect::<Vec<_>>();
2411 messages.push(format!(
2412 "... and {} more",
2413 self.unsupported_messages.len() - limit
2414 ));
2415 messages.join("; ")
2416 }
2417
2418 pub fn sql(expr: &Expression) -> Result<String> {
2424 let mut gen = Generator::new();
2425 gen.generate(expr)
2426 }
2427
2428 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2433 let config = GeneratorConfig {
2434 pretty: true,
2435 ..Default::default()
2436 };
2437 let mut gen = Generator::with_config(config);
2438 let mut sql = gen.generate(expr)?;
2439 if !sql.ends_with(';') {
2441 sql.push(';');
2442 }
2443 Ok(sql)
2444 }
2445
2446 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2447 #[cfg(feature = "stacker")]
2448 {
2449 let red_zone = if cfg!(debug_assertions) {
2450 4 * 1024 * 1024
2451 } else {
2452 1024 * 1024
2453 };
2454 stacker::maybe_grow(red_zone, 8 * 1024 * 1024, || {
2455 self.generate_expression_inner(expr)
2456 })
2457 }
2458 #[cfg(not(feature = "stacker"))]
2459 {
2460 self.generate_expression_inner(expr)
2461 }
2462 }
2463
2464 fn generate_expression_inner(&mut self, expr: &Expression) -> Result<()> {
2465 match expr {
2466 Expression::Select(select) => self.generate_select(select),
2467 Expression::Union(union) => self.generate_union(union),
2468 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2469 Expression::Except(except) => self.generate_except(except),
2470 Expression::Insert(insert) => self.generate_insert(insert),
2471 Expression::Update(update) => self.generate_update(update),
2472 Expression::Delete(delete) => self.generate_delete(delete),
2473 Expression::Literal(lit) => self.generate_literal(lit),
2474 Expression::Boolean(b) => self.generate_boolean(b),
2475 Expression::Null(_) => {
2476 self.write_keyword("NULL");
2477 Ok(())
2478 }
2479 Expression::Identifier(id) => self.generate_identifier(id),
2480 Expression::Column(col) => self.generate_column(col),
2481 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2482 Expression::Connect(c) => self.generate_connect_expr(c),
2483 Expression::Prior(p) => self.generate_prior(p),
2484 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2485 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2486 Expression::Table(table) => self.generate_table(table),
2487 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2488 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2489 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2490 Expression::Star(star) => self.generate_star(star),
2491 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2492 Expression::Alias(alias) => self.generate_alias(alias),
2493 Expression::Cast(cast) => self.generate_cast(cast),
2494 Expression::Collation(coll) => self.generate_collation(coll),
2495 Expression::Case(case) => self.generate_case(case),
2496 Expression::Function(func) => self.generate_function(func),
2497 Expression::FunctionEmits(fe) => self.generate_function_emits(fe),
2498 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2499 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2500 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2501 Expression::Interval(interval) => self.generate_interval(interval),
2502
2503 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2505 Expression::Substring(f) => self.generate_substring(f),
2506 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2507 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2508 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2509 Expression::Trim(f) => self.generate_trim(f),
2510 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2511 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2512 Expression::Replace(f) => self.generate_replace(f),
2513 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2514 Expression::Left(f) => self.generate_left_right("LEFT", f),
2515 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2516 Expression::Repeat(f) => self.generate_repeat(f),
2517 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2518 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2519 Expression::Split(f) => self.generate_split(f),
2520 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2521 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2522 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2523 Expression::Overlay(f) => self.generate_overlay(f),
2524
2525 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2527 Expression::Round(f) => self.generate_round(f),
2528 Expression::Floor(f) => self.generate_floor(f),
2529 Expression::Ceil(f) => self.generate_ceil(f),
2530 Expression::Power(f) => self.generate_power(f),
2531 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2532 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2533 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2534 Expression::Log(f) => self.generate_log(f),
2535 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2536 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2537 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2538 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2539
2540 Expression::CurrentDate(_) => {
2542 self.write_keyword("CURRENT_DATE");
2543 Ok(())
2544 }
2545 Expression::CurrentTime(f) => self.generate_current_time(f),
2546 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2547 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2548 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2549 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2550 Expression::DateDiff(f) => self.generate_datediff(f),
2551 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2552 Expression::Extract(f) => self.generate_extract(f),
2553 Expression::ToDate(f) => self.generate_to_date(f),
2554 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2555
2556 Expression::Coalesce(f) => {
2558 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2560 self.generate_vararg_func(func_name, &f.expressions)
2561 }
2562 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2563 Expression::IfFunc(f) => self.generate_if_func(f),
2564 Expression::IfNull(f) => self.generate_ifnull(f),
2565 Expression::Nvl(f) => self.generate_nvl(f),
2566 Expression::Nvl2(f) => self.generate_nvl2(f),
2567
2568 Expression::TryCast(cast) => self.generate_try_cast(cast),
2570 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2571
2572 Expression::Count(f) => self.generate_count(f),
2574 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2575 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2576 Expression::Min(f) => self.generate_agg_func("MIN", f),
2577 Expression::Max(f) => self.generate_agg_func("MAX", f),
2578 Expression::GroupConcat(f) => self.generate_group_concat(f),
2579 Expression::StringAgg(f) => self.generate_string_agg(f),
2580 Expression::ListAgg(f) => self.generate_listagg(f),
2581 Expression::ArrayAgg(f) => {
2582 let override_name = f
2585 .name
2586 .as_ref()
2587 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2588 .map(|n| n.to_ascii_uppercase());
2589 match override_name {
2590 Some(name) => self.generate_agg_func(&name, f),
2591 None => self.generate_agg_func("ARRAY_AGG", f),
2592 }
2593 }
2594 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2595 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2596 Expression::SumIf(f) => self.generate_sum_if(f),
2597 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2598 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2599 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2600 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2601 Expression::VarPop(f) => {
2602 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2603 "VARIANCE_POP"
2604 } else {
2605 "VAR_POP"
2606 };
2607 self.generate_agg_func(name, f)
2608 }
2609 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2610 Expression::Skewness(f) => {
2611 let name = match self.config.dialect {
2612 Some(DialectType::Snowflake) => "SKEW",
2613 _ => "SKEWNESS",
2614 };
2615 self.generate_agg_func(name, f)
2616 }
2617 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2618 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2619 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2620 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2621 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2622 Expression::ApproxDistinct(f) => {
2623 match self.config.dialect {
2624 Some(DialectType::Hive)
2625 | Some(DialectType::Spark)
2626 | Some(DialectType::Databricks)
2627 | Some(DialectType::BigQuery) => {
2628 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2630 }
2631 Some(DialectType::Redshift) => {
2632 self.write_keyword("APPROXIMATE COUNT");
2634 self.write("(");
2635 self.write_keyword("DISTINCT");
2636 self.write(" ");
2637 self.generate_expression(&f.this)?;
2638 self.write(")");
2639 Ok(())
2640 }
2641 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2642 }
2643 }
2644 Expression::ApproxCountDistinct(f) => {
2645 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2646 }
2647 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2648 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2649 Expression::LogicalAnd(f) => {
2650 let name = match self.config.dialect {
2651 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2652 Some(DialectType::Spark)
2653 | Some(DialectType::Databricks)
2654 | Some(DialectType::PostgreSQL)
2655 | Some(DialectType::DuckDB)
2656 | Some(DialectType::Redshift) => "BOOL_AND",
2657 Some(DialectType::Oracle)
2658 | Some(DialectType::SQLite)
2659 | Some(DialectType::MySQL) => "MIN",
2660 _ => "BOOL_AND",
2661 };
2662 self.generate_agg_func(name, f)
2663 }
2664 Expression::LogicalOr(f) => {
2665 let name = match self.config.dialect {
2666 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2667 Some(DialectType::Spark)
2668 | Some(DialectType::Databricks)
2669 | Some(DialectType::PostgreSQL)
2670 | Some(DialectType::DuckDB)
2671 | Some(DialectType::Redshift) => "BOOL_OR",
2672 Some(DialectType::Oracle)
2673 | Some(DialectType::SQLite)
2674 | Some(DialectType::MySQL) => "MAX",
2675 _ => "BOOL_OR",
2676 };
2677 self.generate_agg_func(name, f)
2678 }
2679
2680 Expression::RowNumber(_) => {
2682 if self.config.dialect == Some(DialectType::ClickHouse) {
2683 self.write("row_number");
2684 } else {
2685 self.write_keyword("ROW_NUMBER");
2686 }
2687 self.write("()");
2688 Ok(())
2689 }
2690 Expression::Rank(r) => {
2691 self.write_keyword("RANK");
2692 self.write("(");
2693 if !r.args.is_empty() {
2695 for (i, arg) in r.args.iter().enumerate() {
2696 if i > 0 {
2697 self.write(", ");
2698 }
2699 self.generate_expression(arg)?;
2700 }
2701 } else if let Some(order_by) = &r.order_by {
2702 self.write_keyword(" ORDER BY ");
2704 for (i, ob) in order_by.iter().enumerate() {
2705 if i > 0 {
2706 self.write(", ");
2707 }
2708 self.generate_ordered(ob)?;
2709 }
2710 }
2711 self.write(")");
2712 Ok(())
2713 }
2714 Expression::DenseRank(dr) => {
2715 self.write_keyword("DENSE_RANK");
2716 self.write("(");
2717 for (i, arg) in dr.args.iter().enumerate() {
2719 if i > 0 {
2720 self.write(", ");
2721 }
2722 self.generate_expression(arg)?;
2723 }
2724 self.write(")");
2725 Ok(())
2726 }
2727 Expression::NTile(f) => self.generate_ntile(f),
2728 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2729 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2730 Expression::FirstValue(f) => {
2731 self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f)
2732 }
2733 Expression::LastValue(f) => {
2734 self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f)
2735 }
2736 Expression::NthValue(f) => self.generate_nth_value(f),
2737 Expression::PercentRank(pr) => {
2738 self.write_keyword("PERCENT_RANK");
2739 self.write("(");
2740 if !pr.args.is_empty() {
2742 for (i, arg) in pr.args.iter().enumerate() {
2743 if i > 0 {
2744 self.write(", ");
2745 }
2746 self.generate_expression(arg)?;
2747 }
2748 } else if let Some(order_by) = &pr.order_by {
2749 self.write_keyword(" ORDER BY ");
2751 for (i, ob) in order_by.iter().enumerate() {
2752 if i > 0 {
2753 self.write(", ");
2754 }
2755 self.generate_ordered(ob)?;
2756 }
2757 }
2758 self.write(")");
2759 Ok(())
2760 }
2761 Expression::CumeDist(cd) => {
2762 self.write_keyword("CUME_DIST");
2763 self.write("(");
2764 if !cd.args.is_empty() {
2766 for (i, arg) in cd.args.iter().enumerate() {
2767 if i > 0 {
2768 self.write(", ");
2769 }
2770 self.generate_expression(arg)?;
2771 }
2772 } else if let Some(order_by) = &cd.order_by {
2773 self.write_keyword(" ORDER BY ");
2775 for (i, ob) in order_by.iter().enumerate() {
2776 if i > 0 {
2777 self.write(", ");
2778 }
2779 self.generate_ordered(ob)?;
2780 }
2781 }
2782 self.write(")");
2783 Ok(())
2784 }
2785 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2786 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2787
2788 Expression::Contains(f) => {
2790 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2791 }
2792 Expression::StartsWith(f) => {
2793 let name = match self.config.dialect {
2794 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2795 _ => "STARTS_WITH",
2796 };
2797 self.generate_binary_func(name, &f.this, &f.expression)
2798 }
2799 Expression::EndsWith(f) => {
2800 let name = match self.config.dialect {
2801 Some(DialectType::Snowflake) => "ENDSWITH",
2802 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2803 Some(DialectType::ClickHouse) => "endsWith",
2804 _ => "ENDS_WITH",
2805 };
2806 self.generate_binary_func(name, &f.this, &f.expression)
2807 }
2808 Expression::Position(f) => self.generate_position(f),
2809 Expression::Initcap(f) => match self.config.dialect {
2810 Some(DialectType::Presto)
2811 | Some(DialectType::Trino)
2812 | Some(DialectType::Athena) => {
2813 self.write_keyword("REGEXP_REPLACE");
2814 self.write("(");
2815 self.generate_expression(&f.this)?;
2816 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2817 Ok(())
2818 }
2819 _ => self.generate_simple_func("INITCAP", &f.this),
2820 },
2821 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2822 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2823 Expression::CharFunc(f) => self.generate_char_func(f),
2824 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2825 Expression::Levenshtein(f) => {
2826 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2827 }
2828
2829 Expression::ModFunc(f) => self.generate_mod_func(f),
2831 Expression::Random(_) => {
2832 self.write_keyword("RANDOM");
2833 self.write("()");
2834 Ok(())
2835 }
2836 Expression::Rand(f) => self.generate_rand(f),
2837 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2838 Expression::Pi(_) => {
2839 self.write_keyword("PI");
2840 self.write("()");
2841 Ok(())
2842 }
2843 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2844 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2845 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2846 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2847 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2848 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2849 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2850 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2851 Expression::Atan2(f) => {
2852 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2853 self.generate_binary_func(name, &f.this, &f.expression)
2854 }
2855
2856 Expression::Decode(f) => self.generate_decode(f),
2858
2859 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2861 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2862 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2863 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2864 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2865 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2866 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2867 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2868 Expression::DayOfWeek(f) => {
2869 let name = match self.config.dialect {
2870 Some(DialectType::Presto)
2871 | Some(DialectType::Trino)
2872 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2873 Some(DialectType::DuckDB) => "ISODOW",
2874 _ => "DAYOFWEEK",
2875 };
2876 self.generate_simple_func(name, &f.this)
2877 }
2878 Expression::DayOfMonth(f) => {
2879 let name = match self.config.dialect {
2880 Some(DialectType::Presto)
2881 | Some(DialectType::Trino)
2882 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2883 _ => "DAYOFMONTH",
2884 };
2885 self.generate_simple_func(name, &f.this)
2886 }
2887 Expression::DayOfYear(f) => {
2888 let name = match self.config.dialect {
2889 Some(DialectType::Presto)
2890 | Some(DialectType::Trino)
2891 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2892 _ => "DAYOFYEAR",
2893 };
2894 self.generate_simple_func(name, &f.this)
2895 }
2896 Expression::WeekOfYear(f) => {
2897 let name = match self.config.dialect {
2899 Some(DialectType::Hive)
2900 | Some(DialectType::DuckDB)
2901 | Some(DialectType::Spark)
2902 | Some(DialectType::Databricks)
2903 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2904 _ => "WEEK_OF_YEAR",
2905 };
2906 self.generate_simple_func(name, &f.this)
2907 }
2908 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2909 Expression::AddMonths(f) => {
2910 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2911 }
2912 Expression::MonthsBetween(f) => {
2913 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2914 }
2915 Expression::LastDay(f) => self.generate_last_day(f),
2916 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2917 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2918 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2919 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2920 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2921 Expression::MakeDate(f) => self.generate_make_date(f),
2922 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2923 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2924
2925 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2927 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2928 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2929 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2930 Expression::ArrayContains(f) => {
2931 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2932 }
2933 Expression::ArrayPosition(f) => {
2934 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2935 }
2936 Expression::ArrayAppend(f) => {
2937 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2938 }
2939 Expression::ArrayPrepend(f) => {
2940 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2941 }
2942 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2943 Expression::ArraySort(f) => self.generate_array_sort(f),
2944 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2945 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2946 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2947 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2948 Expression::Unnest(f) => self.generate_unnest(f),
2949 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2950 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2951 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2952 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2953 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2954 Expression::ArrayCompact(f) => {
2955 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2956 self.write("LIST_FILTER(");
2958 self.generate_expression(&f.this)?;
2959 self.write(", _u -> NOT _u IS NULL)");
2960 Ok(())
2961 } else {
2962 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2963 }
2964 }
2965 Expression::ArrayIntersect(f) => {
2966 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2967 self.generate_vararg_func(func_name, &f.expressions)
2968 }
2969 Expression::ArrayUnion(f) => {
2970 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2971 }
2972 Expression::ArrayExcept(f) => {
2973 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2974 }
2975 Expression::ArrayRemove(f) => {
2976 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2977 }
2978 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2979 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2980 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2981
2982 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2984 Expression::StructExtract(f) => self.generate_struct_extract(f),
2985 Expression::NamedStruct(f) => self.generate_named_struct(f),
2986
2987 Expression::MapFunc(f) => self.generate_map_constructor(f),
2989 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2990 Expression::MapFromArrays(f) => {
2991 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2992 }
2993 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2994 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2995 Expression::MapContainsKey(f) => {
2996 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2997 }
2998 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2999 Expression::ElementAt(f) => {
3000 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
3001 }
3002 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
3003 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
3004
3005 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
3007 Expression::JsonExtractScalar(f) => {
3008 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
3009 }
3010 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
3011 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
3012 Expression::JsonObject(f) => self.generate_json_object(f),
3013 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
3014 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
3015 Expression::JsonArrayLength(f) => {
3016 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
3017 }
3018 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
3019 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
3020 Expression::ParseJson(f) => {
3021 let name = match self.config.dialect {
3022 Some(DialectType::Presto)
3023 | Some(DialectType::Trino)
3024 | Some(DialectType::Athena) => "JSON_PARSE",
3025 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
3026 self.write_keyword("CAST");
3028 self.write("(");
3029 self.generate_expression(&f.this)?;
3030 self.write_keyword(" AS ");
3031 self.write_keyword("JSON");
3032 self.write(")");
3033 return Ok(());
3034 }
3035 Some(DialectType::Hive)
3036 | Some(DialectType::Spark)
3037 | Some(DialectType::MySQL)
3038 | Some(DialectType::SingleStore)
3039 | Some(DialectType::TiDB)
3040 | Some(DialectType::TSQL) => {
3041 self.generate_expression(&f.this)?;
3043 return Ok(());
3044 }
3045 Some(DialectType::DuckDB) => "JSON",
3046 _ => "PARSE_JSON",
3047 };
3048 self.generate_simple_func(name, &f.this)
3049 }
3050 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3051 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3052 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3053 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3054 Expression::JsonMergePatch(f) => {
3055 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3056 }
3057 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3058 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3059
3060 Expression::Convert(f) => self.generate_convert(f),
3062 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3063
3064 Expression::Lambda(f) => self.generate_lambda(f),
3066 Expression::Parameter(f) => self.generate_parameter(f),
3067 Expression::Placeholder(f) => self.generate_placeholder(f),
3068 Expression::NamedArgument(f) => self.generate_named_argument(f),
3069 Expression::TableArgument(f) => self.generate_table_argument(f),
3070 Expression::SqlComment(f) => self.generate_sql_comment(f),
3071
3072 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3074 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3075 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3076 Expression::SimilarTo(f) => self.generate_similar_to(f),
3077 Expression::Any(f) => self.generate_quantified("ANY", f),
3078 Expression::All(f) => self.generate_quantified("ALL", f),
3079 Expression::Overlaps(f) => self.generate_overlaps(f),
3080
3081 Expression::BitwiseLeftShift(op) => {
3083 if matches!(
3084 self.config.dialect,
3085 Some(DialectType::Presto) | Some(DialectType::Trino)
3086 ) {
3087 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
3088 self.write("(");
3089 self.generate_expression(&op.left)?;
3090 self.write(", ");
3091 self.generate_expression(&op.right)?;
3092 self.write(")");
3093 Ok(())
3094 } else if matches!(
3095 self.config.dialect,
3096 Some(DialectType::Spark) | Some(DialectType::Databricks)
3097 ) {
3098 self.write_keyword("SHIFTLEFT");
3099 self.write("(");
3100 self.generate_expression(&op.left)?;
3101 self.write(", ");
3102 self.generate_expression(&op.right)?;
3103 self.write(")");
3104 Ok(())
3105 } else {
3106 self.generate_binary_op(op, "<<")
3107 }
3108 }
3109 Expression::BitwiseRightShift(op) => {
3110 if matches!(
3111 self.config.dialect,
3112 Some(DialectType::Presto) | Some(DialectType::Trino)
3113 ) {
3114 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
3115 self.write("(");
3116 self.generate_expression(&op.left)?;
3117 self.write(", ");
3118 self.generate_expression(&op.right)?;
3119 self.write(")");
3120 Ok(())
3121 } else if matches!(
3122 self.config.dialect,
3123 Some(DialectType::Spark) | Some(DialectType::Databricks)
3124 ) {
3125 self.write_keyword("SHIFTRIGHT");
3126 self.write("(");
3127 self.generate_expression(&op.left)?;
3128 self.write(", ");
3129 self.generate_expression(&op.right)?;
3130 self.write(")");
3131 Ok(())
3132 } else {
3133 self.generate_binary_op(op, ">>")
3134 }
3135 }
3136 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3137 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3138 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3139
3140 Expression::Subscript(s) => self.generate_subscript(s),
3142 Expression::Dot(d) => self.generate_dot_access(d),
3143 Expression::MethodCall(m) => self.generate_method_call(m),
3144 Expression::ArraySlice(s) => self.generate_array_slice(s),
3145
3146 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3147 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3148 Expression::Add(op) => self.generate_binary_op(op, "+"),
3149 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3150 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3151 Expression::Div(op) => self.generate_binary_op(op, "/"),
3152 Expression::IntDiv(f) => {
3153 use crate::dialects::DialectType;
3154 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3155 self.generate_expression(&f.this)?;
3157 self.write(" // ");
3158 self.generate_expression(&f.expression)?;
3159 Ok(())
3160 } else if matches!(
3161 self.config.dialect,
3162 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3163 ) {
3164 self.generate_expression(&f.this)?;
3166 self.write(" ");
3167 self.write_keyword("DIV");
3168 self.write(" ");
3169 self.generate_expression(&f.expression)?;
3170 Ok(())
3171 } else {
3172 self.write_keyword("DIV");
3174 self.write("(");
3175 self.generate_expression(&f.this)?;
3176 self.write(", ");
3177 self.generate_expression(&f.expression)?;
3178 self.write(")");
3179 Ok(())
3180 }
3181 }
3182 Expression::Mod(op) => {
3183 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3184 self.generate_binary_op(op, "MOD")
3185 } else {
3186 self.generate_binary_op(op, "%")
3187 }
3188 }
3189 Expression::Eq(op) => self.generate_binary_op(op, "="),
3190 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3191 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3192 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3193 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3194 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3195 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3196 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3197 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3198 Expression::Concat(op) => {
3199 if self.config.dialect == Some(DialectType::Solr) {
3201 self.generate_binary_op(op, "OR")
3202 } else if self.config.dialect == Some(DialectType::MySQL) {
3203 self.generate_mysql_concat_from_concat(op)
3204 } else {
3205 self.generate_binary_op(op, "||")
3206 }
3207 }
3208 Expression::BitwiseAnd(op) => {
3209 if matches!(
3211 self.config.dialect,
3212 Some(DialectType::Presto) | Some(DialectType::Trino)
3213 ) {
3214 self.write_keyword("BITWISE_AND");
3215 self.write("(");
3216 self.generate_expression(&op.left)?;
3217 self.write(", ");
3218 self.generate_expression(&op.right)?;
3219 self.write(")");
3220 Ok(())
3221 } else {
3222 self.generate_binary_op(op, "&")
3223 }
3224 }
3225 Expression::BitwiseOr(op) => {
3226 if matches!(
3228 self.config.dialect,
3229 Some(DialectType::Presto) | Some(DialectType::Trino)
3230 ) {
3231 self.write_keyword("BITWISE_OR");
3232 self.write("(");
3233 self.generate_expression(&op.left)?;
3234 self.write(", ");
3235 self.generate_expression(&op.right)?;
3236 self.write(")");
3237 Ok(())
3238 } else {
3239 self.generate_binary_op(op, "|")
3240 }
3241 }
3242 Expression::BitwiseXor(op) => {
3243 if matches!(
3245 self.config.dialect,
3246 Some(DialectType::Presto) | Some(DialectType::Trino)
3247 ) {
3248 self.write_keyword("BITWISE_XOR");
3249 self.write("(");
3250 self.generate_expression(&op.left)?;
3251 self.write(", ");
3252 self.generate_expression(&op.right)?;
3253 self.write(")");
3254 Ok(())
3255 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3256 self.generate_binary_op(op, "#")
3257 } else {
3258 self.generate_binary_op(op, "^")
3259 }
3260 }
3261 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3262 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3263 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3264 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3265 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3266 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3267 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3268 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3269 Expression::JSONBContains(f) => {
3270 self.generate_expression(&f.this)?;
3272 self.write_space();
3273 self.write("?");
3274 self.write_space();
3275 self.generate_expression(&f.expression)
3276 }
3277 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3278 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3279 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3280 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3281 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3282 Expression::BitwiseNot(op) => {
3283 if matches!(
3285 self.config.dialect,
3286 Some(DialectType::Presto) | Some(DialectType::Trino)
3287 ) {
3288 self.write_keyword("BITWISE_NOT");
3289 self.write("(");
3290 self.generate_expression(&op.this)?;
3291 self.write(")");
3292 Ok(())
3293 } else {
3294 self.generate_unary_op(op, "~")
3295 }
3296 }
3297 Expression::In(in_expr) => self.generate_in(in_expr),
3298 Expression::Between(between) => self.generate_between(between),
3299 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3300 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3301 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3302 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3303 Expression::Is(is_expr) => self.generate_is(is_expr),
3304 Expression::Exists(exists) => self.generate_exists(exists),
3305 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3306 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3307 Expression::Paren(paren) => {
3308 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3310
3311 if !skip_parens {
3312 self.write("(");
3313 if self.config.pretty {
3314 self.write_newline();
3315 self.indent_level += 1;
3316 self.write_indent();
3317 }
3318 }
3319 self.generate_expression(&paren.this)?;
3320 if !skip_parens {
3321 if self.config.pretty {
3322 self.write_newline();
3323 self.indent_level -= 1;
3324 self.write_indent();
3325 }
3326 self.write(")");
3327 }
3328 for comment in &paren.trailing_comments {
3330 self.write(" ");
3331 self.write_formatted_comment(comment);
3332 }
3333 Ok(())
3334 }
3335 Expression::Array(arr) => self.generate_array(arr),
3336 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3337 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3338 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3339 Expression::DataType(dt) => self.generate_data_type(dt),
3340 Expression::Raw(raw) => {
3341 self.write(&raw.sql);
3342 Ok(())
3343 }
3344 Expression::CreateTask(task) => self.generate_create_task(task),
3345 Expression::Command(cmd) => {
3346 self.write(&cmd.this);
3347 Ok(())
3348 }
3349 Expression::Kill(kill) => {
3350 self.write_keyword("KILL");
3351 if let Some(kind) = &kill.kind {
3352 self.write_space();
3353 self.write_keyword(kind);
3354 }
3355 self.write_space();
3356 self.generate_expression(&kill.this)?;
3357 Ok(())
3358 }
3359 Expression::Execute(exec) => {
3360 self.write_keyword("EXECUTE");
3361 self.write_space();
3362 self.generate_expression(&exec.this)?;
3363 for (i, param) in exec.parameters.iter().enumerate() {
3364 if i == 0 {
3365 self.write_space();
3366 } else {
3367 self.write(", ");
3368 }
3369 self.write(¶m.name);
3370 if !param.positional {
3372 self.write(" = ");
3373 self.generate_expression(¶m.value)?;
3374 }
3375 if param.output {
3376 self.write_space();
3377 self.write_keyword("OUTPUT");
3378 }
3379 }
3380 if let Some(ref suffix) = exec.suffix {
3381 self.write_space();
3382 self.write(suffix);
3383 }
3384 Ok(())
3385 }
3386 Expression::Annotated(annotated) => {
3387 self.generate_expression(&annotated.this)?;
3388 for comment in &annotated.trailing_comments {
3389 self.write(" ");
3390 self.write_formatted_comment(comment);
3391 }
3392 Ok(())
3393 }
3394
3395 Expression::CreateTable(ct) => self.generate_create_table(ct),
3397 Expression::DropTable(dt) => self.generate_drop_table(dt),
3398 Expression::Undrop(u) => self.generate_undrop(u),
3399 Expression::AlterTable(at) => self.generate_alter_table(at),
3400 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3401 Expression::DropIndex(di) => self.generate_drop_index(di),
3402 Expression::CreateView(cv) => self.generate_create_view(cv),
3403 Expression::DropView(dv) => self.generate_drop_view(dv),
3404 Expression::AlterView(av) => self.generate_alter_view(av),
3405 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3406 Expression::Truncate(tr) => self.generate_truncate(tr),
3407 Expression::Use(u) => self.generate_use(u),
3408 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3410 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3411 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3412 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3413 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3414 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3415 Expression::DropFunction(df) => self.generate_drop_function(df),
3416 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3417 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3418 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3419 Expression::CreateSynonym(cs) => {
3420 self.write_keyword("CREATE SYNONYM");
3421 self.write_space();
3422 self.generate_table(&cs.name)?;
3423 self.write_space();
3424 self.write_keyword("FOR");
3425 self.write_space();
3426 self.generate_table(&cs.target)?;
3427 Ok(())
3428 }
3429 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3430 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3431 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3432 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3433 Expression::CreateType(ct) => self.generate_create_type(ct),
3434 Expression::DropType(dt) => self.generate_drop_type(dt),
3435 Expression::Describe(d) => self.generate_describe(d),
3436 Expression::Show(s) => self.generate_show(s),
3437
3438 Expression::Cache(c) => self.generate_cache(c),
3440 Expression::Uncache(u) => self.generate_uncache(u),
3441 Expression::LoadData(l) => self.generate_load_data(l),
3442 Expression::Pragma(p) => self.generate_pragma(p),
3443 Expression::Grant(g) => self.generate_grant(g),
3444 Expression::Revoke(r) => self.generate_revoke(r),
3445 Expression::Comment(c) => self.generate_comment(c),
3446 Expression::SetStatement(s) => self.generate_set_statement(s),
3447
3448 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3450 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3451
3452 Expression::Values(values) => self.generate_values(values),
3454
3455 Expression::AIAgg(e) => self.generate_ai_agg(e),
3457 Expression::AIClassify(e) => self.generate_ai_classify(e),
3458 Expression::AddPartition(e) => self.generate_add_partition(e),
3459 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3460 Expression::Aliases(e) => self.generate_aliases(e),
3461 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3462 Expression::AlterColumn(e) => self.generate_alter_column(e),
3463 Expression::AlterSession(e) => self.generate_alter_session(e),
3464 Expression::AlterSet(e) => self.generate_alter_set(e),
3465 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3466 Expression::Analyze(e) => self.generate_analyze(e),
3467 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3468 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3469 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3470 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3471 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3472 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3473 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3474 Expression::Anonymous(e) => self.generate_anonymous(e),
3475 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3476 Expression::Apply(e) => self.generate_apply(e),
3477 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3478 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3479 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3480 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3481 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3482 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3483 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3484 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3485 Expression::ArgMax(e) => self.generate_arg_max(e),
3486 Expression::ArgMin(e) => self.generate_arg_min(e),
3487 Expression::ArrayAll(e) => self.generate_array_all(e),
3488 Expression::ArrayAny(e) => self.generate_array_any(e),
3489 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3490 Expression::ArraySum(e) => self.generate_array_sum(e),
3491 Expression::AtIndex(e) => self.generate_at_index(e),
3492 Expression::Attach(e) => self.generate_attach(e),
3493 Expression::AttachOption(e) => self.generate_attach_option(e),
3494 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3495 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3496 Expression::BackupProperty(e) => self.generate_backup_property(e),
3497 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3498 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3499 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3500 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3501 Expression::Booland(e) => self.generate_booland(e),
3502 Expression::Boolor(e) => self.generate_boolor(e),
3503 Expression::BuildProperty(e) => self.generate_build_property(e),
3504 Expression::ByteString(e) => self.generate_byte_string(e),
3505 Expression::CaseSpecificColumnConstraint(e) => {
3506 self.generate_case_specific_column_constraint(e)
3507 }
3508 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3509 Expression::Changes(e) => self.generate_changes(e),
3510 Expression::CharacterSetColumnConstraint(e) => {
3511 self.generate_character_set_column_constraint(e)
3512 }
3513 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3514 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3515 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3516 Expression::CheckJson(e) => self.generate_check_json(e),
3517 Expression::CheckXml(e) => self.generate_check_xml(e),
3518 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3519 Expression::Clone(e) => self.generate_clone(e),
3520 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3521 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3522 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3523 Expression::CollateProperty(e) => self.generate_collate_property(e),
3524 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3525 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3526 Expression::ColumnPosition(e) => self.generate_column_position(e),
3527 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3528 Expression::Columns(e) => self.generate_columns(e),
3529 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3530 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3531 Expression::Commit(e) => self.generate_commit(e),
3532 Expression::Comprehension(e) => self.generate_comprehension(e),
3533 Expression::Compress(e) => self.generate_compress(e),
3534 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3535 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3536 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3537 Expression::Constraint(e) => self.generate_constraint(e),
3538 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3539 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3540 Expression::Copy(e) => self.generate_copy(e),
3541 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3542 Expression::Corr(e) => self.generate_corr(e),
3543 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3544 Expression::CovarPop(e) => self.generate_covar_pop(e),
3545 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3546 Expression::Credentials(e) => self.generate_credentials(e),
3547 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3548 Expression::Cte(e) => self.generate_cte(e),
3549 Expression::Cube(e) => self.generate_cube(e),
3550 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3551 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3552 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3553 Expression::CurrentUser(e) => self.generate_current_user(e),
3554 Expression::DPipe(e) => self.generate_d_pipe(e),
3555 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3556 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3557 Expression::Date(e) => self.generate_date_func(e),
3558 Expression::DateBin(e) => self.generate_date_bin(e),
3559 Expression::DateFormatColumnConstraint(e) => {
3560 self.generate_date_format_column_constraint(e)
3561 }
3562 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3563 Expression::Datetime(e) => self.generate_datetime(e),
3564 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3565 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3566 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3567 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3568 Expression::Dayname(e) => self.generate_dayname(e),
3569 Expression::Declare(e) => self.generate_declare(e),
3570 Expression::DeclareItem(e) => self.generate_declare_item(e),
3571 Expression::DecodeCase(e) => self.generate_decode_case(e),
3572 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3573 Expression::DecompressString(e) => self.generate_decompress_string(e),
3574 Expression::Decrypt(e) => self.generate_decrypt(e),
3575 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3576 Expression::DefaultColumnConstraint(e) => {
3577 self.write_keyword("DEFAULT");
3578 self.write_space();
3579 self.generate_expression(&e.this)?;
3580 if let Some(ref col) = e.for_column {
3581 self.write_space();
3582 self.write_keyword("FOR");
3583 self.write_space();
3584 self.generate_identifier(col)?;
3585 }
3586 Ok(())
3587 }
3588 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3589 Expression::Detach(e) => self.generate_detach(e),
3590 Expression::DictProperty(e) => self.generate_dict_property(e),
3591 Expression::DictRange(e) => self.generate_dict_range(e),
3592 Expression::Directory(e) => self.generate_directory(e),
3593 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3594 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3595 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3596 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3597 Expression::DotProduct(e) => self.generate_dot_product(e),
3598 Expression::DropPartition(e) => self.generate_drop_partition(e),
3599 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3600 Expression::Elt(e) => self.generate_elt(e),
3601 Expression::Encode(e) => self.generate_encode(e),
3602 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3603 Expression::Encrypt(e) => self.generate_encrypt(e),
3604 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3605 Expression::EngineProperty(e) => self.generate_engine_property(e),
3606 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3607 Expression::EphemeralColumnConstraint(e) => {
3608 self.generate_ephemeral_column_constraint(e)
3609 }
3610 Expression::EqualNull(e) => self.generate_equal_null(e),
3611 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3612 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3613 Expression::Export(e) => self.generate_export(e),
3614 Expression::ExternalProperty(e) => self.generate_external_property(e),
3615 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3616 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3617 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3618 Expression::Fetch(e) => self.generate_fetch(e),
3619 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3620 Expression::Filter(e) => self.generate_filter(e),
3621 Expression::Float64(e) => self.generate_float64(e),
3622 Expression::ForIn(e) => self.generate_for_in(e),
3623 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3624 Expression::Format(e) => self.generate_format(e),
3625 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3626 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3627 Expression::From(e) => self.generate_from(e),
3628 Expression::FromBase(e) => self.generate_from_base(e),
3629 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3630 Expression::GapFill(e) => self.generate_gap_fill(e),
3631 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3632 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3633 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3634 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3635 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3636 self.generate_generated_as_identity_column_constraint(e)
3637 }
3638 Expression::GeneratedAsRowColumnConstraint(e) => {
3639 self.generate_generated_as_row_column_constraint(e)
3640 }
3641 Expression::Get(e) => self.generate_get(e),
3642 Expression::GetExtract(e) => self.generate_get_extract(e),
3643 Expression::Getbit(e) => self.generate_getbit(e),
3644 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3645 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3646 Expression::Group(e) => self.generate_group(e),
3647 Expression::GroupBy(e) => self.generate_group_by(e),
3648 Expression::Grouping(e) => self.generate_grouping(e),
3649 Expression::GroupingId(e) => self.generate_grouping_id(e),
3650 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3651 Expression::HashAgg(e) => self.generate_hash_agg(e),
3652 Expression::Having(e) => self.generate_having(e),
3653 Expression::HavingMax(e) => self.generate_having_max(e),
3654 Expression::Heredoc(e) => self.generate_heredoc(e),
3655 Expression::HexEncode(e) => self.generate_hex_encode(e),
3656 Expression::Hll(e) => self.generate_hll(e),
3657 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3658 Expression::IncludeProperty(e) => self.generate_include_property(e),
3659 Expression::Index(e) => self.generate_index(e),
3660 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3661 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3662 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3663 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3664 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3665 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3666 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3667 Expression::Install(e) => self.generate_install(e),
3668 Expression::IntervalOp(e) => self.generate_interval_op(e),
3669 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3670 Expression::IntoClause(e) => self.generate_into_clause(e),
3671 Expression::Introducer(e) => self.generate_introducer(e),
3672 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3673 Expression::JSON(e) => self.generate_json(e),
3674 Expression::JSONArray(e) => self.generate_json_array(e),
3675 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3676 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3677 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3678 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3679 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3680 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3681 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3682 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3683 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3684 Expression::JSONExists(e) => self.generate_json_exists(e),
3685 Expression::JSONCast(e) => self.generate_json_cast(e),
3686 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3687 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3688 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3689 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3690 Expression::JSONFormat(e) => self.generate_json_format(e),
3691 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3692 Expression::JSONKeys(e) => self.generate_json_keys(e),
3693 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3694 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3695 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3696 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3697 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3698 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3699 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3700 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3701 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3702 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3703 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3704 Expression::JSONRemove(e) => self.generate_json_remove(e),
3705 Expression::JSONSchema(e) => self.generate_json_schema(e),
3706 Expression::JSONSet(e) => self.generate_json_set(e),
3707 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3708 Expression::JSONTable(e) => self.generate_json_table(e),
3709 Expression::JSONType(e) => self.generate_json_type(e),
3710 Expression::JSONValue(e) => self.generate_json_value(e),
3711 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3712 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3713 Expression::JoinHint(e) => self.generate_join_hint(e),
3714 Expression::JournalProperty(e) => self.generate_journal_property(e),
3715 Expression::LanguageProperty(e) => self.generate_language_property(e),
3716 Expression::Lateral(e) => self.generate_lateral(e),
3717 Expression::LikeProperty(e) => self.generate_like_property(e),
3718 Expression::Limit(e) => self.generate_limit(e),
3719 Expression::LimitOptions(e) => self.generate_limit_options(e),
3720 Expression::List(e) => self.generate_list(e),
3721 Expression::ToMap(e) => self.generate_tomap(e),
3722 Expression::Localtime(e) => self.generate_localtime(e),
3723 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3724 Expression::LocationProperty(e) => self.generate_location_property(e),
3725 Expression::Lock(e) => self.generate_lock(e),
3726 Expression::LockProperty(e) => self.generate_lock_property(e),
3727 Expression::LockingProperty(e) => self.generate_locking_property(e),
3728 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3729 Expression::LogProperty(e) => self.generate_log_property(e),
3730 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3731 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3732 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3733 Expression::MakeInterval(e) => self.generate_make_interval(e),
3734 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3735 Expression::Map(e) => self.generate_map(e),
3736 Expression::MapCat(e) => self.generate_map_cat(e),
3737 Expression::MapDelete(e) => self.generate_map_delete(e),
3738 Expression::MapInsert(e) => self.generate_map_insert(e),
3739 Expression::MapPick(e) => self.generate_map_pick(e),
3740 Expression::MaskingPolicyColumnConstraint(e) => {
3741 self.generate_masking_policy_column_constraint(e)
3742 }
3743 Expression::MatchAgainst(e) => self.generate_match_against(e),
3744 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3745 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3746 Expression::Merge(e) => self.generate_merge(e),
3747 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3748 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3749 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3750 Expression::Minhash(e) => self.generate_minhash(e),
3751 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3752 Expression::Monthname(e) => self.generate_monthname(e),
3753 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3754 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3755 Expression::Normal(e) => self.generate_normal(e),
3756 Expression::Normalize(e) => self.generate_normalize(e),
3757 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3758 Expression::Nullif(e) => self.generate_nullif(e),
3759 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3760 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3761 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3762 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3763 Expression::Offset(e) => self.generate_offset(e),
3764 Expression::Qualify(e) => self.generate_qualify(e),
3765 Expression::OnCluster(e) => self.generate_on_cluster(e),
3766 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3767 Expression::OnCondition(e) => self.generate_on_condition(e),
3768 Expression::OnConflict(e) => self.generate_on_conflict(e),
3769 Expression::OnProperty(e) => self.generate_on_property(e),
3770 Expression::Opclass(e) => self.generate_opclass(e),
3771 Expression::OpenJSON(e) => self.generate_open_json(e),
3772 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3773 Expression::Operator(e) => self.generate_operator(e),
3774 Expression::OrderBy(e) => self.generate_order_by(e),
3775 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3776 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3777 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3778 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3779 Expression::ParseIp(e) => self.generate_parse_ip(e),
3780 Expression::ParseJSON(e) => self.generate_parse_json(e),
3781 Expression::ParseTime(e) => self.generate_parse_time(e),
3782 Expression::ParseUrl(e) => self.generate_parse_url(e),
3783 Expression::Partition(e) => self.generate_partition_expr(e),
3784 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3785 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3786 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3787 Expression::PartitionByRangePropertyDynamic(e) => {
3788 self.generate_partition_by_range_property_dynamic(e)
3789 }
3790 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3791 Expression::PartitionList(e) => self.generate_partition_list(e),
3792 Expression::PartitionRange(e) => self.generate_partition_range(e),
3793 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3794 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3795 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3796 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3797 Expression::PeriodForSystemTimeConstraint(e) => {
3798 self.generate_period_for_system_time_constraint(e)
3799 }
3800 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3801 Expression::PivotAny(e) => self.generate_pivot_any(e),
3802 Expression::Predict(e) => self.generate_predict(e),
3803 Expression::PreviousDay(e) => self.generate_previous_day(e),
3804 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3805 Expression::PrimaryKeyColumnConstraint(e) => {
3806 self.generate_primary_key_column_constraint(e)
3807 }
3808 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3809 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3810 Expression::OptionsProperty(e) => self.generate_options_property(e),
3811 Expression::Properties(e) => self.generate_properties(e),
3812 Expression::Property(e) => self.generate_property(e),
3813 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3814 Expression::Put(e) => self.generate_put(e),
3815 Expression::Quantile(e) => self.generate_quantile(e),
3816 Expression::QueryBand(e) => self.generate_query_band(e),
3817 Expression::QueryOption(e) => self.generate_query_option(e),
3818 Expression::QueryTransform(e) => self.generate_query_transform(e),
3819 Expression::Randn(e) => self.generate_randn(e),
3820 Expression::Randstr(e) => self.generate_randstr(e),
3821 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3822 Expression::RangeN(e) => self.generate_range_n(e),
3823 Expression::ReadCSV(e) => self.generate_read_csv(e),
3824 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3825 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3826 Expression::Reduce(e) => self.generate_reduce(e),
3827 Expression::Reference(e) => self.generate_reference(e),
3828 Expression::Refresh(e) => self.generate_refresh(e),
3829 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3830 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3831 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3832 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3833 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3834 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3835 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3836 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3837 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3838 Expression::RegrCount(e) => self.generate_regr_count(e),
3839 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3840 Expression::RegrR2(e) => self.generate_regr_r2(e),
3841 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3842 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3843 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3844 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3845 Expression::RegrValx(e) => self.generate_regr_valx(e),
3846 Expression::RegrValy(e) => self.generate_regr_valy(e),
3847 Expression::RemoteWithConnectionModelProperty(e) => {
3848 self.generate_remote_with_connection_model_property(e)
3849 }
3850 Expression::RenameColumn(e) => self.generate_rename_column(e),
3851 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3852 Expression::Returning(e) => self.generate_returning(e),
3853 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3854 Expression::Rollback(e) => self.generate_rollback(e),
3855 Expression::Rollup(e) => self.generate_rollup(e),
3856 Expression::RowFormatDelimitedProperty(e) => {
3857 self.generate_row_format_delimited_property(e)
3858 }
3859 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3860 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3861 Expression::SHA2(e) => self.generate_sha2(e),
3862 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3863 Expression::SafeAdd(e) => self.generate_safe_add(e),
3864 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3865 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3866 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3867 Expression::SampleProperty(e) => self.generate_sample_property(e),
3868 Expression::Schema(e) => self.generate_schema(e),
3869 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3870 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3871 Expression::Search(e) => self.generate_search(e),
3872 Expression::SearchIp(e) => self.generate_search_ip(e),
3873 Expression::SecurityProperty(e) => self.generate_security_property(e),
3874 Expression::SemanticView(e) => self.generate_semantic_view(e),
3875 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3876 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3877 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3878 Expression::Set(e) => self.generate_set(e),
3879 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3880 Expression::SetItem(e) => self.generate_set_item(e),
3881 Expression::SetOperation(e) => self.generate_set_operation(e),
3882 Expression::SetProperty(e) => self.generate_set_property(e),
3883 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3884 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3885 Expression::Slice(e) => self.generate_slice(e),
3886 Expression::SortArray(e) => self.generate_sort_array(e),
3887 Expression::SortBy(e) => self.generate_sort_by(e),
3888 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3889 Expression::SplitPart(e) => self.generate_split_part(e),
3890 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3891 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3892 Expression::StDistance(e) => self.generate_st_distance(e),
3893 Expression::StPoint(e) => self.generate_st_point(e),
3894 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3895 Expression::StandardHash(e) => self.generate_standard_hash(e),
3896 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3897 Expression::StrPosition(e) => self.generate_str_position(e),
3898 Expression::StrToDate(e) => self.generate_str_to_date(e),
3899 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3900 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3901 Expression::StrToMap(e) => self.generate_str_to_map(e),
3902 Expression::StrToTime(e) => self.generate_str_to_time(e),
3903 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3904 Expression::StringToArray(e) => self.generate_string_to_array(e),
3905 Expression::Struct(e) => self.generate_struct(e),
3906 Expression::Stuff(e) => self.generate_stuff(e),
3907 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3908 Expression::Summarize(e) => self.generate_summarize(e),
3909 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3910 Expression::TableAlias(e) => self.generate_table_alias(e),
3911 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3912 Expression::RowsFrom(e) => self.generate_rows_from(e),
3913 Expression::TableSample(e) => self.generate_table_sample(e),
3914 Expression::Tag(e) => self.generate_tag(e),
3915 Expression::Tags(e) => self.generate_tags(e),
3916 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3917 Expression::Time(e) => self.generate_time_func(e),
3918 Expression::TimeAdd(e) => self.generate_time_add(e),
3919 Expression::TimeDiff(e) => self.generate_time_diff(e),
3920 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3921 Expression::TimeSlice(e) => self.generate_time_slice(e),
3922 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3923 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3924 Expression::TimeSub(e) => self.generate_time_sub(e),
3925 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3926 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3927 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3928 Expression::TimeUnit(e) => self.generate_time_unit(e),
3929 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3930 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3931 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3932 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3933 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3934 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3935 Expression::ToBinary(e) => self.generate_to_binary(e),
3936 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3937 Expression::ToChar(e) => self.generate_to_char(e),
3938 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3939 Expression::ToDouble(e) => self.generate_to_double(e),
3940 Expression::ToFile(e) => self.generate_to_file(e),
3941 Expression::ToNumber(e) => self.generate_to_number(e),
3942 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3943 Expression::Transaction(e) => self.generate_transaction(e),
3944 Expression::Transform(e) => self.generate_transform(e),
3945 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3946 Expression::TransientProperty(e) => self.generate_transient_property(e),
3947 Expression::Translate(e) => self.generate_translate(e),
3948 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3949 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3950 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3951 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3952 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3953 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3954 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3955 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3956 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3957 Expression::Unhex(e) => self.generate_unhex(e),
3958 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3959 Expression::Uniform(e) => self.generate_uniform(e),
3960 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3961 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3962 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3963 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3964 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3965 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3966 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3967 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3968 Expression::UtcTime(e) => self.generate_utc_time(e),
3969 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3970 Expression::Uuid(e) => self.generate_uuid(e),
3971 Expression::Var(v) => {
3972 if matches!(self.config.dialect, Some(DialectType::MySQL))
3973 && v.this.len() > 2
3974 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3975 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3976 {
3977 return self.generate_identifier(&Identifier {
3978 name: v.this.clone(),
3979 quoted: true,
3980 trailing_comments: Vec::new(),
3981 span: None,
3982 });
3983 }
3984 self.write(&v.this);
3985 Ok(())
3986 }
3987 Expression::Variadic(e) => {
3988 self.write_keyword("VARIADIC");
3989 self.write_space();
3990 self.generate_expression(&e.this)?;
3991 Ok(())
3992 }
3993 Expression::VarMap(e) => self.generate_var_map(e),
3994 Expression::VectorSearch(e) => self.generate_vector_search(e),
3995 Expression::Version(e) => self.generate_version(e),
3996 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3997 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3998 Expression::WatermarkColumnConstraint(e) => {
3999 self.generate_watermark_column_constraint(e)
4000 }
4001 Expression::Week(e) => self.generate_week(e),
4002 Expression::When(e) => self.generate_when(e),
4003 Expression::Whens(e) => self.generate_whens(e),
4004 Expression::Where(e) => self.generate_where(e),
4005 Expression::WidthBucket(e) => self.generate_width_bucket(e),
4006 Expression::Window(e) => self.generate_window(e),
4007 Expression::WindowSpec(e) => self.generate_window_spec(e),
4008 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
4009 Expression::WithFill(e) => self.generate_with_fill(e),
4010 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
4011 Expression::WithOperator(e) => self.generate_with_operator(e),
4012 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
4013 Expression::WithSchemaBindingProperty(e) => {
4014 self.generate_with_schema_binding_property(e)
4015 }
4016 Expression::WithSystemVersioningProperty(e) => {
4017 self.generate_with_system_versioning_property(e)
4018 }
4019 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
4020 Expression::XMLElement(e) => self.generate_xml_element(e),
4021 Expression::XMLGet(e) => self.generate_xml_get(e),
4022 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
4023 Expression::XMLTable(e) => self.generate_xml_table(e),
4024 Expression::Xor(e) => self.generate_xor(e),
4025 Expression::Zipf(e) => self.generate_zipf(e),
4026 _ => self.write_unsupported_comment("unsupported expression"),
4027 }
4028 }
4029
4030 fn generate_select(&mut self, select: &Select) -> Result<()> {
4031 use crate::dialects::DialectType;
4032
4033 if let Some(exclude) = &select.exclude {
4037 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4038 let mut inner_select = select.clone();
4040 inner_select.exclude = None;
4041 let inner_expr = Expression::Select(Box::new(inner_select));
4042
4043 let subquery = crate::expressions::Subquery {
4045 this: inner_expr,
4046 alias: None,
4047 column_aliases: Vec::new(),
4048 alias_explicit_as: false,
4049 alias_keyword: None,
4050 order_by: None,
4051 limit: None,
4052 offset: None,
4053 distribute_by: None,
4054 sort_by: None,
4055 cluster_by: None,
4056 lateral: false,
4057 modifiers_inside: false,
4058 trailing_comments: Vec::new(),
4059 inferred_type: None,
4060 };
4061
4062 let star = Expression::Star(crate::expressions::Star {
4064 table: None,
4065 except: Some(
4066 exclude
4067 .iter()
4068 .map(|e| match e {
4069 Expression::Column(col) => col.name.clone(),
4070 Expression::Identifier(id) => id.clone(),
4071 _ => crate::expressions::Identifier::new("unknown".to_string()),
4072 })
4073 .collect(),
4074 ),
4075 replace: None,
4076 rename: None,
4077 trailing_comments: Vec::new(),
4078 span: None,
4079 });
4080
4081 let outer_select = Select {
4082 expressions: vec![star],
4083 from: Some(crate::expressions::From {
4084 expressions: vec![Expression::Subquery(Box::new(subquery))],
4085 }),
4086 ..Select::new()
4087 };
4088
4089 return self.generate_select(&outer_select);
4090 }
4091 }
4092
4093 for comment in &select.leading_comments {
4095 self.write_formatted_comment(comment);
4096 self.write(" ");
4097 }
4098
4099 if let Some(with) = &select.with {
4101 self.generate_with(with)?;
4102 if self.config.pretty {
4103 self.write_newline();
4104 self.write_indent();
4105 } else {
4106 self.write_space();
4107 }
4108 }
4109
4110 for comment in &select.post_select_comments {
4113 self.write_formatted_comment(comment);
4114 self.write(" ");
4115 }
4116
4117 self.write_keyword("SELECT");
4118
4119 if let Some(hint) = &select.hint {
4121 self.generate_hint(hint)?;
4122 }
4123
4124 let use_top_from_limit = matches!(
4128 self.config.dialect,
4129 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4130 ) && select.top.is_none()
4131 && select.limit.is_some()
4132 && select.offset.is_none(); let is_top_dialect = matches!(
4137 self.config.dialect,
4138 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4139 );
4140 let keep_top_verbatim = !is_top_dialect
4141 && select.limit.is_none()
4142 && select
4143 .top
4144 .as_ref()
4145 .map_or(false, |top| top.percent || top.with_ties);
4146
4147 if select.distinct && (is_top_dialect || select.top.is_some()) {
4148 self.write_space();
4149 self.write_keyword("DISTINCT");
4150 }
4151
4152 if is_top_dialect || keep_top_verbatim {
4153 if let Some(top) = &select.top {
4154 self.write_space();
4155 self.write_keyword("TOP");
4156 if top.parenthesized {
4157 if matches!(&top.this, Expression::Subquery(_) | Expression::Paren(_)) {
4158 self.write_space();
4159 self.generate_expression(&top.this)?;
4160 } else {
4161 self.write(" (");
4162 self.generate_expression(&top.this)?;
4163 self.write(")");
4164 }
4165 } else {
4166 self.write_space();
4167 self.generate_expression(&top.this)?;
4168 }
4169 if top.percent {
4170 self.write_space();
4171 self.write_keyword("PERCENT");
4172 }
4173 if top.with_ties {
4174 self.write_space();
4175 self.write_keyword("WITH TIES");
4176 }
4177 } else if use_top_from_limit {
4178 if let Some(limit) = &select.limit {
4180 self.write_space();
4181 self.write_keyword("TOP");
4182 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4184 if is_simple_literal {
4185 self.write_space();
4186 self.generate_expression(&limit.this)?;
4187 } else {
4188 self.write(" (");
4189 self.generate_expression(&limit.this)?;
4190 self.write(")");
4191 }
4192 }
4193 }
4194 }
4195
4196 if select.distinct && !is_top_dialect && select.top.is_none() {
4197 self.write_space();
4198 self.write_keyword("DISTINCT");
4199 }
4200
4201 if let Some(distinct_on) = &select.distinct_on {
4203 self.write_space();
4204 self.write_keyword("ON");
4205 self.write(" (");
4206 for (i, expr) in distinct_on.iter().enumerate() {
4207 if i > 0 {
4208 self.write(", ");
4209 }
4210 self.generate_expression(expr)?;
4211 }
4212 self.write(")");
4213 }
4214
4215 for modifier in &select.operation_modifiers {
4217 self.write_space();
4218 self.write_keyword(modifier);
4219 }
4220
4221 if let Some(kind) = &select.kind {
4223 self.write_space();
4224 self.write_keyword("AS");
4225 self.write_space();
4226 self.write_keyword(kind);
4227 }
4228
4229 if !select.expressions.is_empty() {
4231 if self.config.pretty {
4232 self.write_newline();
4233 self.indent_level += 1;
4234 } else {
4235 self.write_space();
4236 }
4237 }
4238
4239 for (i, expr) in select.expressions.iter().enumerate() {
4240 if i > 0 {
4241 self.write(",");
4242 if self.config.pretty {
4243 self.write_newline();
4244 } else {
4245 self.write_space();
4246 }
4247 }
4248 if self.config.pretty {
4249 self.write_indent();
4250 }
4251 self.generate_expression(expr)?;
4252 }
4253
4254 if self.config.pretty && !select.expressions.is_empty() {
4255 self.indent_level -= 1;
4256 }
4257
4258 if let Some(exclude) = &select.exclude {
4263 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4264 self.write_space();
4265 self.write_keyword("EXCLUDE");
4266 self.write(" (");
4267 for (i, col) in exclude.iter().enumerate() {
4268 if i > 0 {
4269 self.write(", ");
4270 }
4271 self.generate_expression(col)?;
4272 }
4273 self.write(")");
4274 }
4275 }
4276
4277 if let Some(into) = &select.into {
4280 if self.config.pretty {
4281 self.write_newline();
4282 self.write_indent();
4283 } else {
4284 self.write_space();
4285 }
4286 if into.bulk_collect {
4287 self.write_keyword("BULK COLLECT INTO");
4288 } else {
4289 self.write_keyword("INTO");
4290 }
4291 if into.temporary {
4292 self.write_space();
4293 self.write_keyword("TEMPORARY");
4294 }
4295 if into.unlogged {
4296 self.write_space();
4297 self.write_keyword("UNLOGGED");
4298 }
4299 self.write_space();
4300 if !into.expressions.is_empty() {
4302 for (i, expr) in into.expressions.iter().enumerate() {
4303 if i > 0 {
4304 self.write(", ");
4305 }
4306 self.generate_expression(expr)?;
4307 }
4308 } else {
4309 self.generate_expression(&into.this)?;
4310 }
4311 }
4312
4313 if let Some(from) = &select.from {
4315 if self.config.pretty {
4316 self.write_newline();
4317 self.write_indent();
4318 } else {
4319 self.write_space();
4320 }
4321 self.write_keyword("FROM");
4322 self.write_space();
4323
4324 let has_tablesample = from
4329 .expressions
4330 .iter()
4331 .any(|e| matches!(e, Expression::TableSample(_)));
4332 let is_cross_join_dialect = matches!(
4333 self.config.dialect,
4334 Some(DialectType::BigQuery)
4335 | Some(DialectType::Hive)
4336 | Some(DialectType::Spark)
4337 | Some(DialectType::Databricks)
4338 | Some(DialectType::SQLite)
4339 | Some(DialectType::ClickHouse)
4340 );
4341 let source_is_same_as_target = self.config.source_dialect.is_some()
4344 && self.config.source_dialect == self.config.dialect;
4345 let source_is_cross_join_dialect = matches!(
4346 self.config.source_dialect,
4347 Some(DialectType::BigQuery)
4348 | Some(DialectType::Hive)
4349 | Some(DialectType::Spark)
4350 | Some(DialectType::Databricks)
4351 | Some(DialectType::SQLite)
4352 | Some(DialectType::ClickHouse)
4353 );
4354 let use_cross_join = !has_tablesample
4355 && is_cross_join_dialect
4356 && (source_is_same_as_target
4357 || source_is_cross_join_dialect
4358 || self.config.source_dialect.is_none());
4359
4360 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4362
4363 for (i, expr) in from.expressions.iter().enumerate() {
4364 if i > 0 {
4365 if use_cross_join {
4366 self.write(" CROSS JOIN ");
4367 } else {
4368 self.write(", ");
4369 }
4370 }
4371 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4372 self.write("(");
4373 self.generate_expression(expr)?;
4374 self.write(")");
4375 } else {
4376 self.generate_expression(expr)?;
4377 }
4378 let leading = Self::extract_table_leading_comments(expr);
4381 for comment in &leading {
4382 self.write_space();
4383 self.write_formatted_comment(comment);
4384 }
4385 }
4386 }
4387
4388 if self.config.pretty {
4392 self.generate_joins_with_nesting(&select.joins)?;
4393 } else {
4394 for join in &select.joins {
4395 self.generate_join(join)?;
4396 }
4397 for join in select.joins.iter().rev() {
4399 if join.deferred_condition {
4400 self.generate_join_condition(join)?;
4401 }
4402 }
4403 }
4404
4405 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4407 self.generate_lateral_view(lateral_view, lv_idx)?;
4408 }
4409
4410 if let Some(prewhere) = &select.prewhere {
4412 self.write_clause_condition("PREWHERE", prewhere)?;
4413 }
4414
4415 if let Some(where_clause) = &select.where_clause {
4417 self.write_clause_condition("WHERE", &where_clause.this)?;
4418 }
4419
4420 if let Some(connect) = &select.connect {
4422 self.generate_connect(connect)?;
4423 }
4424
4425 if let Some(group_by) = &select.group_by {
4427 if self.config.pretty {
4428 for comment in &group_by.comments {
4430 self.write_newline();
4431 self.write_indent();
4432 self.write_formatted_comment(comment);
4433 }
4434 self.write_newline();
4435 self.write_indent();
4436 } else {
4437 self.write_space();
4438 for comment in &group_by.comments {
4440 self.write_formatted_comment(comment);
4441 self.write_space();
4442 }
4443 }
4444 let clickhouse_bare_modifiers =
4445 matches!(self.config.dialect, Some(DialectType::ClickHouse))
4446 && group_by.all.is_none()
4447 && (group_by.totals || !group_by.expressions.is_empty())
4448 && group_by.expressions.iter().all(|expr| match expr {
4449 Expression::Cube(c) => c.expressions.is_empty(),
4450 Expression::Rollup(r) => r.expressions.is_empty(),
4451 _ => false,
4452 });
4453
4454 if clickhouse_bare_modifiers {
4455 let trailing_cube = group_by
4456 .expressions
4457 .iter()
4458 .any(|expr| matches!(expr, Expression::Cube(c) if c.expressions.is_empty()));
4459 let trailing_rollup = group_by
4460 .expressions
4461 .iter()
4462 .any(|expr| matches!(expr, Expression::Rollup(r) if r.expressions.is_empty()));
4463
4464 if trailing_cube {
4465 self.write_keyword("WITH CUBE");
4466 } else if trailing_rollup {
4467 self.write_keyword("WITH ROLLUP");
4468 }
4469
4470 if group_by.totals {
4471 if trailing_cube || trailing_rollup {
4472 self.write_space();
4473 }
4474 self.write_keyword("WITH TOTALS");
4475 }
4476 } else {
4477 self.write_keyword("GROUP BY");
4478 match group_by.all {
4480 Some(true) => {
4481 self.write_space();
4482 self.write_keyword("ALL");
4483 }
4484 Some(false) => {
4485 self.write_space();
4486 self.write_keyword("DISTINCT");
4487 }
4488 None => {}
4489 }
4490 if !group_by.expressions.is_empty() {
4491 let mut trailing_cube = false;
4494 let mut trailing_rollup = false;
4495 let mut plain_expressions: Vec<&Expression> = Vec::new();
4496 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4497 let mut cube_expressions: Vec<&Expression> = Vec::new();
4498 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4499
4500 for expr in &group_by.expressions {
4501 match expr {
4502 Expression::Cube(c) if c.expressions.is_empty() => {
4503 trailing_cube = true;
4504 }
4505 Expression::Rollup(r) if r.expressions.is_empty() => {
4506 trailing_rollup = true;
4507 }
4508 Expression::Function(f) if f.name == "CUBE" => {
4509 cube_expressions.push(expr);
4510 }
4511 Expression::Function(f) if f.name == "ROLLUP" => {
4512 rollup_expressions.push(expr);
4513 }
4514 Expression::Function(f) if f.name == "GROUPING SETS" => {
4515 grouping_sets_expressions.push(expr);
4516 }
4517 _ => {
4518 plain_expressions.push(expr);
4519 }
4520 }
4521 }
4522
4523 let mut regular_expressions: Vec<&Expression> = Vec::new();
4525 regular_expressions.extend(plain_expressions);
4526 regular_expressions.extend(grouping_sets_expressions);
4527 regular_expressions.extend(cube_expressions);
4528 regular_expressions.extend(rollup_expressions);
4529
4530 if self.config.pretty {
4531 self.write_newline();
4532 self.indent_level += 1;
4533 self.write_indent();
4534 } else {
4535 self.write_space();
4536 }
4537
4538 for (i, expr) in regular_expressions.iter().enumerate() {
4539 if i > 0 {
4540 if self.config.pretty {
4541 self.write(",");
4542 self.write_newline();
4543 self.write_indent();
4544 } else {
4545 self.write(", ");
4546 }
4547 }
4548 self.generate_expression(expr)?;
4549 }
4550
4551 if self.config.pretty {
4552 self.indent_level -= 1;
4553 }
4554
4555 if trailing_cube {
4557 self.write_space();
4558 self.write_keyword("WITH CUBE");
4559 } else if trailing_rollup {
4560 self.write_space();
4561 self.write_keyword("WITH ROLLUP");
4562 }
4563 }
4564
4565 if group_by.totals {
4567 self.write_space();
4568 self.write_keyword("WITH TOTALS");
4569 }
4570 }
4571 }
4572
4573 if let Some(having) = &select.having {
4575 if self.config.pretty {
4576 for comment in &having.comments {
4578 self.write_newline();
4579 self.write_indent();
4580 self.write_formatted_comment(comment);
4581 }
4582 } else {
4583 for comment in &having.comments {
4584 self.write_space();
4585 self.write_formatted_comment(comment);
4586 }
4587 }
4588 self.write_clause_condition("HAVING", &having.this)?;
4589 }
4590
4591 if select.qualify_after_window {
4593 if let Some(windows) = &select.windows {
4595 self.write_window_clause(windows)?;
4596 }
4597 if let Some(qualify) = &select.qualify {
4598 self.write_clause_condition("QUALIFY", &qualify.this)?;
4599 }
4600 } else {
4601 if let Some(qualify) = &select.qualify {
4603 self.write_clause_condition("QUALIFY", &qualify.this)?;
4604 }
4605 if let Some(windows) = &select.windows {
4606 self.write_window_clause(windows)?;
4607 }
4608 }
4609
4610 if let Some(distribute_by) = &select.distribute_by {
4612 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4613 }
4614
4615 if let Some(cluster_by) = &select.cluster_by {
4617 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4618 }
4619
4620 if let Some(sort_by) = &select.sort_by {
4622 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4623 }
4624
4625 if let Some(order_by) = &select.order_by {
4627 if self.config.pretty {
4628 for comment in &order_by.comments {
4630 self.write_newline();
4631 self.write_indent();
4632 self.write_formatted_comment(comment);
4633 }
4634 } else {
4635 for comment in &order_by.comments {
4636 self.write_space();
4637 self.write_formatted_comment(comment);
4638 }
4639 }
4640 let keyword = if order_by.siblings {
4641 "ORDER SIBLINGS BY"
4642 } else {
4643 "ORDER BY"
4644 };
4645 self.write_order_clause(keyword, &order_by.expressions)?;
4646 }
4647
4648 if select.order_by.is_none()
4650 && select.fetch.is_some()
4651 && matches!(
4652 self.config.dialect,
4653 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4654 )
4655 {
4656 if self.config.pretty {
4657 self.write_newline();
4658 self.write_indent();
4659 } else {
4660 self.write_space();
4661 }
4662 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4663 }
4664
4665 let is_presto_like = matches!(
4670 self.config.dialect,
4671 Some(DialectType::Presto) | Some(DialectType::Trino)
4672 );
4673
4674 if is_presto_like && select.offset.is_some() {
4675 if let Some(offset) = &select.offset {
4677 if self.config.pretty {
4678 self.write_newline();
4679 self.write_indent();
4680 } else {
4681 self.write_space();
4682 }
4683 self.write_keyword("OFFSET");
4684 self.write_space();
4685 self.write_limit_expr(&offset.this)?;
4686 if offset.rows == Some(true) {
4687 self.write_space();
4688 self.write_keyword("ROWS");
4689 }
4690 }
4691 if let Some(limit) = &select.limit {
4692 if self.config.pretty {
4693 self.write_newline();
4694 self.write_indent();
4695 } else {
4696 self.write_space();
4697 }
4698 self.write_keyword("LIMIT");
4699 self.write_space();
4700 self.write_limit_expr(&limit.this)?;
4701 if limit.percent {
4702 self.write_space();
4703 self.write_keyword("PERCENT");
4704 }
4705 for comment in &limit.comments {
4707 self.write(" ");
4708 self.write_formatted_comment(comment);
4709 }
4710 }
4711 } else {
4712 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4714 !fetch.percent
4715 && !fetch.with_ties
4716 && fetch.count.is_some()
4717 && matches!(
4718 self.config.dialect,
4719 Some(DialectType::Spark)
4720 | Some(DialectType::Hive)
4721 | Some(DialectType::DuckDB)
4722 | Some(DialectType::SQLite)
4723 | Some(DialectType::MySQL)
4724 | Some(DialectType::BigQuery)
4725 | Some(DialectType::Databricks)
4726 | Some(DialectType::StarRocks)
4727 | Some(DialectType::Doris)
4728 | Some(DialectType::Athena)
4729 | Some(DialectType::ClickHouse)
4730 | Some(DialectType::Redshift)
4731 )
4732 });
4733
4734 if let Some(limit) = &select.limit {
4736 if !matches!(
4738 self.config.dialect,
4739 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4740 ) {
4741 if self.config.pretty {
4742 self.write_newline();
4743 self.write_indent();
4744 } else {
4745 self.write_space();
4746 }
4747 self.write_keyword("LIMIT");
4748 self.write_space();
4749 self.write_limit_expr(&limit.this)?;
4750 if limit.percent {
4751 self.write_space();
4752 self.write_keyword("PERCENT");
4753 }
4754 for comment in &limit.comments {
4756 self.write(" ");
4757 self.write_formatted_comment(comment);
4758 }
4759 }
4760 }
4761
4762 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4764 if let Some(top) = &select.top {
4765 if !top.percent && !top.with_ties {
4766 if self.config.pretty {
4767 self.write_newline();
4768 self.write_indent();
4769 } else {
4770 self.write_space();
4771 }
4772 self.write_keyword("LIMIT");
4773 self.write_space();
4774 self.generate_expression(&top.this)?;
4775 }
4776 }
4777 }
4778
4779 if fetch_as_limit && select.offset.is_some() {
4782 if let Some(fetch) = &select.fetch {
4783 if self.config.pretty {
4784 self.write_newline();
4785 self.write_indent();
4786 } else {
4787 self.write_space();
4788 }
4789 self.write_keyword("LIMIT");
4790 self.write_space();
4791 self.generate_expression(fetch.count.as_ref().unwrap())?;
4792 }
4793 }
4794
4795 if let Some(offset) = &select.offset {
4799 if self.config.pretty {
4800 self.write_newline();
4801 self.write_indent();
4802 } else {
4803 self.write_space();
4804 }
4805 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4806 self.write_keyword("OFFSET");
4808 self.write_space();
4809 self.write_limit_expr(&offset.this)?;
4810 self.write_space();
4811 self.write_keyword("ROWS");
4812 if let Some(limit) = &select.limit {
4814 self.write_space();
4815 self.write_keyword("FETCH NEXT");
4816 self.write_space();
4817 self.write_limit_expr(&limit.this)?;
4818 self.write_space();
4819 self.write_keyword("ROWS ONLY");
4820 }
4821 } else {
4822 self.write_keyword("OFFSET");
4823 self.write_space();
4824 self.write_limit_expr(&offset.this)?;
4825 if offset.rows == Some(true) {
4827 self.write_space();
4828 self.write_keyword("ROWS");
4829 }
4830 }
4831 }
4832 }
4833
4834 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4836 if let Some(limit_by) = &select.limit_by {
4837 if !limit_by.is_empty() {
4838 self.write_space();
4839 self.write_keyword("BY");
4840 self.write_space();
4841 for (i, expr) in limit_by.iter().enumerate() {
4842 if i > 0 {
4843 self.write(", ");
4844 }
4845 self.generate_expression(expr)?;
4846 }
4847 }
4848 }
4849 }
4850
4851 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4853 if let Some(settings) = &select.settings {
4854 if self.config.pretty {
4855 self.write_newline();
4856 self.write_indent();
4857 } else {
4858 self.write_space();
4859 }
4860 self.write_keyword("SETTINGS");
4861 self.write_space();
4862 for (i, expr) in settings.iter().enumerate() {
4863 if i > 0 {
4864 self.write(", ");
4865 }
4866 self.generate_expression(expr)?;
4867 }
4868 }
4869
4870 if let Some(format_expr) = &select.format {
4871 if self.config.pretty {
4872 self.write_newline();
4873 self.write_indent();
4874 } else {
4875 self.write_space();
4876 }
4877 self.write_keyword("FORMAT");
4878 self.write_space();
4879 self.generate_expression(format_expr)?;
4880 }
4881 }
4882
4883 if let Some(fetch) = &select.fetch {
4885 let fetch_already_as_limit = select.offset.is_some()
4887 && !fetch.percent
4888 && !fetch.with_ties
4889 && fetch.count.is_some()
4890 && matches!(
4891 self.config.dialect,
4892 Some(DialectType::Spark)
4893 | Some(DialectType::Hive)
4894 | Some(DialectType::DuckDB)
4895 | Some(DialectType::SQLite)
4896 | Some(DialectType::MySQL)
4897 | Some(DialectType::BigQuery)
4898 | Some(DialectType::Databricks)
4899 | Some(DialectType::StarRocks)
4900 | Some(DialectType::Doris)
4901 | Some(DialectType::Athena)
4902 | Some(DialectType::ClickHouse)
4903 | Some(DialectType::Redshift)
4904 );
4905
4906 if fetch_already_as_limit {
4907 } else {
4909 if self.config.pretty {
4910 self.write_newline();
4911 self.write_indent();
4912 } else {
4913 self.write_space();
4914 }
4915
4916 let use_limit = !fetch.percent
4918 && !fetch.with_ties
4919 && fetch.count.is_some()
4920 && matches!(
4921 self.config.dialect,
4922 Some(DialectType::Spark)
4923 | Some(DialectType::Hive)
4924 | Some(DialectType::DuckDB)
4925 | Some(DialectType::SQLite)
4926 | Some(DialectType::MySQL)
4927 | Some(DialectType::BigQuery)
4928 | Some(DialectType::Databricks)
4929 | Some(DialectType::StarRocks)
4930 | Some(DialectType::Doris)
4931 | Some(DialectType::Athena)
4932 | Some(DialectType::ClickHouse)
4933 | Some(DialectType::Redshift)
4934 );
4935
4936 if use_limit {
4937 self.write_keyword("LIMIT");
4938 self.write_space();
4939 self.generate_expression(fetch.count.as_ref().unwrap())?;
4940 } else {
4941 self.write_keyword("FETCH");
4942 self.write_space();
4943 self.write_keyword(&fetch.direction);
4944 if let Some(ref count) = fetch.count {
4945 self.write_space();
4946 self.generate_expression(count)?;
4947 }
4948 if fetch.percent {
4949 self.write_space();
4950 self.write_keyword("PERCENT");
4951 }
4952 if fetch.rows {
4953 self.write_space();
4954 self.write_keyword("ROWS");
4955 }
4956 if fetch.with_ties {
4957 self.write_space();
4958 self.write_keyword("WITH TIES");
4959 } else {
4960 self.write_space();
4961 self.write_keyword("ONLY");
4962 }
4963 }
4964 } }
4966
4967 if let Some(sample) = &select.sample {
4969 use crate::dialects::DialectType;
4970 if self.config.pretty {
4971 self.write_newline();
4972 } else {
4973 self.write_space();
4974 }
4975
4976 if sample.is_using_sample {
4977 self.write_keyword("USING SAMPLE");
4979 self.generate_sample_body(sample)?;
4980 } else {
4981 self.write_keyword("TABLESAMPLE");
4982
4983 let snowflake_bernoulli =
4985 matches!(self.config.dialect, Some(DialectType::Snowflake))
4986 && !sample.explicit_method;
4987 if snowflake_bernoulli {
4988 self.write_space();
4989 self.write_keyword("BERNOULLI");
4990 }
4991
4992 if matches!(sample.method, SampleMethod::Bucket) {
4994 self.write_space();
4995 self.write("(");
4996 self.write_keyword("BUCKET");
4997 self.write_space();
4998 if let Some(ref num) = sample.bucket_numerator {
4999 self.generate_expression(num)?;
5000 }
5001 self.write_space();
5002 self.write_keyword("OUT OF");
5003 self.write_space();
5004 if let Some(ref denom) = sample.bucket_denominator {
5005 self.generate_expression(denom)?;
5006 }
5007 if let Some(ref field) = sample.bucket_field {
5008 self.write_space();
5009 self.write_keyword("ON");
5010 self.write_space();
5011 self.generate_expression(field)?;
5012 }
5013 self.write(")");
5014 } else if sample.unit_after_size {
5015 if sample.explicit_method && sample.method_before_size {
5017 self.write_space();
5018 match sample.method {
5019 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5020 SampleMethod::System => self.write_keyword("SYSTEM"),
5021 SampleMethod::Block => self.write_keyword("BLOCK"),
5022 SampleMethod::Row => self.write_keyword("ROW"),
5023 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5024 _ => {}
5025 }
5026 }
5027 self.write(" (");
5028 self.generate_expression(&sample.size)?;
5029 self.write_space();
5030 match sample.method {
5031 SampleMethod::Percent => self.write_keyword("PERCENT"),
5032 SampleMethod::Row => self.write_keyword("ROWS"),
5033 SampleMethod::Reservoir => self.write_keyword("ROWS"),
5034 _ => {
5035 self.write_keyword("PERCENT");
5036 }
5037 }
5038 self.write(")");
5039 } else {
5040 self.write_space();
5042 match sample.method {
5043 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
5044 SampleMethod::System => self.write_keyword("SYSTEM"),
5045 SampleMethod::Block => self.write_keyword("BLOCK"),
5046 SampleMethod::Row => self.write_keyword("ROW"),
5047 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
5048 SampleMethod::Bucket => {}
5049 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
5050 }
5051 self.write(" (");
5052 self.generate_expression(&sample.size)?;
5053 if matches!(sample.method, SampleMethod::Percent) {
5054 self.write_space();
5055 self.write_keyword("PERCENT");
5056 }
5057 self.write(")");
5058 }
5059 }
5060
5061 if let Some(seed) = &sample.seed {
5062 self.write_space();
5063 let use_seed = sample.use_seed_keyword
5065 && !matches!(
5066 self.config.dialect,
5067 Some(crate::dialects::DialectType::Databricks)
5068 | Some(crate::dialects::DialectType::Spark)
5069 );
5070 if use_seed {
5071 self.write_keyword("SEED");
5072 } else {
5073 self.write_keyword("REPEATABLE");
5074 }
5075 self.write(" (");
5076 self.generate_expression(seed)?;
5077 self.write(")");
5078 }
5079 }
5080
5081 if self.config.locking_reads_supported {
5084 for lock in &select.locks {
5085 if self.config.pretty {
5086 self.write_newline();
5087 self.write_indent();
5088 } else {
5089 self.write_space();
5090 }
5091 self.generate_lock(lock)?;
5092 }
5093 }
5094
5095 if !select.for_xml.is_empty() {
5097 if self.config.pretty {
5098 self.write_newline();
5099 self.write_indent();
5100 } else {
5101 self.write_space();
5102 }
5103 self.write_keyword("FOR XML");
5104 for (i, opt) in select.for_xml.iter().enumerate() {
5105 if self.config.pretty {
5106 if i > 0 {
5107 self.write(",");
5108 }
5109 self.write_newline();
5110 self.write_indent();
5111 self.write(" "); } else {
5113 if i > 0 {
5114 self.write(",");
5115 }
5116 self.write_space();
5117 }
5118 self.generate_for_xml_option(opt)?;
5119 }
5120 }
5121
5122 if !select.for_json.is_empty() {
5124 if self.config.pretty {
5125 self.write_newline();
5126 self.write_indent();
5127 } else {
5128 self.write_space();
5129 }
5130 self.write_keyword("FOR JSON");
5131 for (i, opt) in select.for_json.iter().enumerate() {
5132 if self.config.pretty {
5133 if i > 0 {
5134 self.write(",");
5135 }
5136 self.write_newline();
5137 self.write_indent();
5138 self.write(" "); } else {
5140 if i > 0 {
5141 self.write(",");
5142 }
5143 self.write_space();
5144 }
5145 self.generate_for_xml_option(opt)?;
5146 }
5147 }
5148
5149 if let Some(ref option) = select.option {
5151 if matches!(
5152 self.config.dialect,
5153 Some(crate::dialects::DialectType::TSQL)
5154 | Some(crate::dialects::DialectType::Fabric)
5155 ) {
5156 self.write_space();
5157 self.write(option);
5158 }
5159 }
5160
5161 Ok(())
5162 }
5163
5164 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5166 match opt {
5167 Expression::QueryOption(qo) => {
5168 if let Expression::Var(var) = &*qo.this {
5170 self.write(&var.this);
5171 } else {
5172 self.generate_expression(&qo.this)?;
5173 }
5174 if let Some(expr) = &qo.expression {
5176 self.write("(");
5177 self.generate_expression(expr)?;
5178 self.write(")");
5179 }
5180 }
5181 _ => {
5182 self.generate_expression(opt)?;
5183 }
5184 }
5185 Ok(())
5186 }
5187
5188 fn generate_with(&mut self, with: &With) -> Result<()> {
5189 use crate::dialects::DialectType;
5190
5191 for comment in &with.leading_comments {
5193 self.write_formatted_comment(comment);
5194 self.write(" ");
5195 }
5196 self.write_keyword("WITH");
5197 if with.recursive && self.config.cte_recursive_keyword_required {
5198 self.write_space();
5199 self.write_keyword("RECURSIVE");
5200 }
5201 self.write_space();
5202
5203 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5205
5206 for (i, cte) in with.ctes.iter().enumerate() {
5207 if i > 0 {
5208 self.write(",");
5209 if self.config.pretty {
5210 self.write_space();
5211 } else {
5212 self.write(" ");
5213 }
5214 }
5215 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5216 self.generate_expression(&cte.this)?;
5217 self.write_space();
5218 self.write_keyword("AS");
5219 self.write_space();
5220 self.generate_identifier(&cte.alias)?;
5221 continue;
5222 }
5223 self.generate_identifier(&cte.alias)?;
5224 for comment in &cte.comments {
5226 self.write_space();
5227 self.write_formatted_comment(comment);
5228 }
5229 if !cte.columns.is_empty() && !skip_cte_columns {
5230 self.write("(");
5231 for (j, col) in cte.columns.iter().enumerate() {
5232 if j > 0 {
5233 self.write(", ");
5234 }
5235 self.generate_identifier(col)?;
5236 }
5237 self.write(")");
5238 }
5239 if !cte.key_expressions.is_empty() {
5241 self.write_space();
5242 self.write_keyword("USING KEY");
5243 self.write(" (");
5244 for (i, key) in cte.key_expressions.iter().enumerate() {
5245 if i > 0 {
5246 self.write(", ");
5247 }
5248 self.generate_identifier(key)?;
5249 }
5250 self.write(")");
5251 }
5252 self.write_space();
5253 self.write_keyword("AS");
5254 if let Some(materialized) = cte.materialized {
5256 self.write_space();
5257 if materialized {
5258 self.write_keyword("MATERIALIZED");
5259 } else {
5260 self.write_keyword("NOT MATERIALIZED");
5261 }
5262 }
5263 self.write(" (");
5264 if self.config.pretty {
5265 self.write_newline();
5266 self.indent_level += 1;
5267 self.write_indent();
5268 }
5269 let wrap_values_in_select = matches!(
5272 self.config.dialect,
5273 Some(DialectType::Spark) | Some(DialectType::Databricks)
5274 ) && matches!(&cte.this, Expression::Values(_));
5275
5276 if wrap_values_in_select {
5277 self.write_keyword("SELECT");
5278 self.write(" * ");
5279 self.write_keyword("FROM");
5280 self.write_space();
5281 }
5282 self.generate_expression(&cte.this)?;
5283 if self.config.pretty {
5284 self.write_newline();
5285 self.indent_level -= 1;
5286 self.write_indent();
5287 }
5288 self.write(")");
5289 }
5290
5291 if let Some(search) = &with.search {
5293 self.write_space();
5294 self.generate_expression(search)?;
5295 }
5296
5297 Ok(())
5298 }
5299
5300 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5304 let mut i = 0;
5305 while i < joins.len() {
5306 if joins[i].deferred_condition {
5307 let parent_group = joins[i].nesting_group;
5308
5309 self.generate_join_without_condition(&joins[i])?;
5312
5313 let child_start = i + 1;
5315 let mut child_end = child_start;
5316 while child_end < joins.len()
5317 && !joins[child_end].deferred_condition
5318 && joins[child_end].nesting_group == parent_group
5319 {
5320 child_end += 1;
5321 }
5322
5323 if child_start < child_end {
5325 self.indent_level += 1;
5326 for j in child_start..child_end {
5327 self.generate_join(&joins[j])?;
5328 }
5329 self.indent_level -= 1;
5330 }
5331
5332 self.generate_join_condition(&joins[i])?;
5334
5335 i = child_end;
5336 } else {
5337 self.generate_join(&joins[i])?;
5339 i += 1;
5340 }
5341 }
5342 Ok(())
5343 }
5344
5345 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5348 let mut join_copy = join.clone();
5351 join_copy.on = None;
5352 join_copy.using = Vec::new();
5353 join_copy.deferred_condition = false;
5354 self.generate_join(&join_copy)
5355 }
5356
5357 fn generate_join(&mut self, join: &Join) -> Result<()> {
5358 if join.kind == JoinKind::Implicit {
5360 self.write(",");
5361 if self.config.pretty {
5362 self.write_newline();
5363 self.write_indent();
5364 } else {
5365 self.write_space();
5366 }
5367 self.generate_expression(&join.this)?;
5368 return Ok(());
5369 }
5370
5371 if self.config.pretty {
5372 self.write_newline();
5373 self.write_indent();
5374 } else {
5375 self.write_space();
5376 }
5377
5378 let hint_str = if self.config.join_hints {
5381 join.join_hint
5382 .as_ref()
5383 .map(|h| format!(" {}", h))
5384 .unwrap_or_default()
5385 } else {
5386 String::new()
5387 };
5388
5389 let clickhouse_join_keyword =
5390 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5391 if let Some(hint) = &join.join_hint {
5392 let mut global = false;
5393 let mut strictness: Option<&'static str> = None;
5394 for part in hint.split_whitespace() {
5395 if part.eq_ignore_ascii_case("GLOBAL") {
5396 global = true;
5397 } else if part.eq_ignore_ascii_case("ALL") {
5398 strictness = Some("ALL");
5399 } else if part.eq_ignore_ascii_case("ANY") {
5400 strictness = Some("ANY");
5401 } else if part.eq_ignore_ascii_case("ASOF") {
5402 strictness = Some("ASOF");
5403 } else if part.eq_ignore_ascii_case("SEMI") {
5404 strictness = Some("SEMI");
5405 } else if part.eq_ignore_ascii_case("ANTI") {
5406 strictness = Some("ANTI");
5407 }
5408 }
5409
5410 if global || strictness.is_some() {
5411 let join_type = match join.kind {
5412 JoinKind::Left => {
5413 if join.use_outer_keyword {
5414 "LEFT OUTER"
5415 } else if join.use_inner_keyword {
5416 "LEFT INNER"
5417 } else {
5418 "LEFT"
5419 }
5420 }
5421 JoinKind::Right => {
5422 if join.use_outer_keyword {
5423 "RIGHT OUTER"
5424 } else if join.use_inner_keyword {
5425 "RIGHT INNER"
5426 } else {
5427 "RIGHT"
5428 }
5429 }
5430 JoinKind::Full => {
5431 if join.use_outer_keyword {
5432 "FULL OUTER"
5433 } else {
5434 "FULL"
5435 }
5436 }
5437 JoinKind::Inner => {
5438 if join.use_inner_keyword {
5439 "INNER"
5440 } else {
5441 ""
5442 }
5443 }
5444 _ => "",
5445 };
5446
5447 let mut parts = Vec::new();
5448 if global {
5449 parts.push("GLOBAL");
5450 }
5451 if !join_type.is_empty() {
5452 parts.push(join_type);
5453 }
5454 if let Some(strict) = strictness {
5455 parts.push(strict);
5456 }
5457 parts.push("JOIN");
5458 Some(parts.join(" "))
5459 } else {
5460 None
5461 }
5462 } else {
5463 None
5464 }
5465 } else {
5466 None
5467 };
5468
5469 if !join.comments.is_empty() {
5473 if self.config.pretty {
5474 let trimmed = self.output.trim_end().len();
5479 self.output.truncate(trimmed);
5480 for comment in &join.comments {
5481 self.write_newline();
5482 self.write_indent();
5483 self.write_formatted_comment(comment);
5484 }
5485 self.write_newline();
5486 self.write_indent();
5487 } else {
5488 for comment in &join.comments {
5489 self.write_formatted_comment(comment);
5490 self.write_space();
5491 }
5492 }
5493 }
5494
5495 let directed_str = if join.directed { " DIRECTED" } else { "" };
5496
5497 if let Some(keyword) = clickhouse_join_keyword {
5498 self.write_keyword(&keyword);
5499 } else {
5500 match join.kind {
5501 JoinKind::Inner => {
5502 if join.use_inner_keyword {
5503 if hint_str.is_empty() && directed_str.is_empty() {
5504 self.write_keyword("INNER JOIN");
5505 } else {
5506 self.write_keyword("INNER");
5507 if !hint_str.is_empty() {
5508 self.write_keyword(&hint_str);
5509 }
5510 if !directed_str.is_empty() {
5511 self.write_keyword(directed_str);
5512 }
5513 self.write_keyword(" JOIN");
5514 }
5515 } else {
5516 if !hint_str.is_empty() {
5517 self.write_keyword(hint_str.trim());
5518 self.write_keyword(" ");
5519 }
5520 if !directed_str.is_empty() {
5521 self.write_keyword("DIRECTED ");
5522 }
5523 self.write_keyword("JOIN");
5524 }
5525 }
5526 JoinKind::Left => {
5527 if join.use_outer_keyword {
5528 if hint_str.is_empty() && directed_str.is_empty() {
5529 self.write_keyword("LEFT OUTER JOIN");
5530 } else {
5531 self.write_keyword("LEFT 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("LEFT INNER JOIN");
5543 } else {
5544 self.write_keyword("LEFT 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("LEFT JOIN");
5556 } else {
5557 self.write_keyword("LEFT");
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::Right => {
5569 if join.use_outer_keyword {
5570 if hint_str.is_empty() && directed_str.is_empty() {
5571 self.write_keyword("RIGHT OUTER JOIN");
5572 } else {
5573 self.write_keyword("RIGHT 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 if join.use_inner_keyword {
5583 if hint_str.is_empty() && directed_str.is_empty() {
5584 self.write_keyword("RIGHT INNER JOIN");
5585 } else {
5586 self.write_keyword("RIGHT INNER");
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 } else {
5596 if hint_str.is_empty() && directed_str.is_empty() {
5597 self.write_keyword("RIGHT JOIN");
5598 } else {
5599 self.write_keyword("RIGHT");
5600 if !hint_str.is_empty() {
5601 self.write_keyword(&hint_str);
5602 }
5603 if !directed_str.is_empty() {
5604 self.write_keyword(directed_str);
5605 }
5606 self.write_keyword(" JOIN");
5607 }
5608 }
5609 }
5610 JoinKind::Full => {
5611 if join.use_outer_keyword {
5612 if hint_str.is_empty() && directed_str.is_empty() {
5613 self.write_keyword("FULL OUTER JOIN");
5614 } else {
5615 self.write_keyword("FULL OUTER");
5616 if !hint_str.is_empty() {
5617 self.write_keyword(&hint_str);
5618 }
5619 if !directed_str.is_empty() {
5620 self.write_keyword(directed_str);
5621 }
5622 self.write_keyword(" JOIN");
5623 }
5624 } else {
5625 if hint_str.is_empty() && directed_str.is_empty() {
5626 self.write_keyword("FULL JOIN");
5627 } else {
5628 self.write_keyword("FULL");
5629 if !hint_str.is_empty() {
5630 self.write_keyword(&hint_str);
5631 }
5632 if !directed_str.is_empty() {
5633 self.write_keyword(directed_str);
5634 }
5635 self.write_keyword(" JOIN");
5636 }
5637 }
5638 }
5639 JoinKind::Outer => {
5640 if directed_str.is_empty() {
5641 self.write_keyword("OUTER JOIN");
5642 } else {
5643 self.write_keyword("OUTER");
5644 self.write_keyword(directed_str);
5645 self.write_keyword(" JOIN");
5646 }
5647 }
5648 JoinKind::Cross => {
5649 if directed_str.is_empty() {
5650 self.write_keyword("CROSS JOIN");
5651 } else {
5652 self.write_keyword("CROSS");
5653 self.write_keyword(directed_str);
5654 self.write_keyword(" JOIN");
5655 }
5656 }
5657 JoinKind::Natural => {
5658 if join.use_inner_keyword {
5659 if directed_str.is_empty() {
5660 self.write_keyword("NATURAL INNER JOIN");
5661 } else {
5662 self.write_keyword("NATURAL INNER");
5663 self.write_keyword(directed_str);
5664 self.write_keyword(" JOIN");
5665 }
5666 } else {
5667 if directed_str.is_empty() {
5668 self.write_keyword("NATURAL JOIN");
5669 } else {
5670 self.write_keyword("NATURAL");
5671 self.write_keyword(directed_str);
5672 self.write_keyword(" JOIN");
5673 }
5674 }
5675 }
5676 JoinKind::NaturalLeft => {
5677 if join.use_outer_keyword {
5678 if directed_str.is_empty() {
5679 self.write_keyword("NATURAL LEFT OUTER JOIN");
5680 } else {
5681 self.write_keyword("NATURAL LEFT OUTER");
5682 self.write_keyword(directed_str);
5683 self.write_keyword(" JOIN");
5684 }
5685 } else {
5686 if directed_str.is_empty() {
5687 self.write_keyword("NATURAL LEFT JOIN");
5688 } else {
5689 self.write_keyword("NATURAL LEFT");
5690 self.write_keyword(directed_str);
5691 self.write_keyword(" JOIN");
5692 }
5693 }
5694 }
5695 JoinKind::NaturalRight => {
5696 if join.use_outer_keyword {
5697 if directed_str.is_empty() {
5698 self.write_keyword("NATURAL RIGHT OUTER JOIN");
5699 } else {
5700 self.write_keyword("NATURAL RIGHT OUTER");
5701 self.write_keyword(directed_str);
5702 self.write_keyword(" JOIN");
5703 }
5704 } else {
5705 if directed_str.is_empty() {
5706 self.write_keyword("NATURAL RIGHT JOIN");
5707 } else {
5708 self.write_keyword("NATURAL RIGHT");
5709 self.write_keyword(directed_str);
5710 self.write_keyword(" JOIN");
5711 }
5712 }
5713 }
5714 JoinKind::NaturalFull => {
5715 if join.use_outer_keyword {
5716 if directed_str.is_empty() {
5717 self.write_keyword("NATURAL FULL OUTER JOIN");
5718 } else {
5719 self.write_keyword("NATURAL FULL OUTER");
5720 self.write_keyword(directed_str);
5721 self.write_keyword(" JOIN");
5722 }
5723 } else {
5724 if directed_str.is_empty() {
5725 self.write_keyword("NATURAL FULL JOIN");
5726 } else {
5727 self.write_keyword("NATURAL FULL");
5728 self.write_keyword(directed_str);
5729 self.write_keyword(" JOIN");
5730 }
5731 }
5732 }
5733 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5734 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5735 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5736 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5737 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5738 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5739 JoinKind::CrossApply => {
5740 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5742 self.write_keyword("CROSS APPLY");
5743 } else {
5744 self.write_keyword("INNER JOIN LATERAL");
5745 }
5746 }
5747 JoinKind::OuterApply => {
5748 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5750 self.write_keyword("OUTER APPLY");
5751 } else {
5752 self.write_keyword("LEFT JOIN LATERAL");
5753 }
5754 }
5755 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5756 JoinKind::AsOfLeft => {
5757 if join.use_outer_keyword {
5758 self.write_keyword("ASOF LEFT OUTER JOIN");
5759 } else {
5760 self.write_keyword("ASOF LEFT JOIN");
5761 }
5762 }
5763 JoinKind::AsOfRight => {
5764 if join.use_outer_keyword {
5765 self.write_keyword("ASOF RIGHT OUTER JOIN");
5766 } else {
5767 self.write_keyword("ASOF RIGHT JOIN");
5768 }
5769 }
5770 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5771 JoinKind::LeftLateral => {
5772 if join.use_outer_keyword {
5773 self.write_keyword("LEFT OUTER LATERAL JOIN");
5774 } else {
5775 self.write_keyword("LEFT LATERAL JOIN");
5776 }
5777 }
5778 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5779 JoinKind::Implicit => {
5780 use crate::dialects::DialectType;
5784 let is_cj_dialect = matches!(
5785 self.config.dialect,
5786 Some(DialectType::BigQuery)
5787 | Some(DialectType::Hive)
5788 | Some(DialectType::Spark)
5789 | Some(DialectType::Databricks)
5790 );
5791 let source_is_same = self.config.source_dialect.is_some()
5792 && self.config.source_dialect == self.config.dialect;
5793 let source_is_cj = matches!(
5794 self.config.source_dialect,
5795 Some(DialectType::BigQuery)
5796 | Some(DialectType::Hive)
5797 | Some(DialectType::Spark)
5798 | Some(DialectType::Databricks)
5799 );
5800 if is_cj_dialect
5801 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5802 {
5803 self.write_keyword("CROSS JOIN");
5804 } else {
5805 self.output.truncate(self.output.trim_end().len());
5809 self.write(",");
5810 }
5811 }
5812 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5813 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5814 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5815 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
5816 }
5817 }
5818
5819 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5821 match &join.this {
5822 Expression::Tuple(t) if t.expressions.is_empty() => {}
5823 Expression::Tuple(t) => {
5824 self.write_space();
5825 for (i, item) in t.expressions.iter().enumerate() {
5826 if i > 0 {
5827 self.write(", ");
5828 }
5829 self.generate_expression(item)?;
5830 }
5831 }
5832 other => {
5833 self.write_space();
5834 self.generate_expression(other)?;
5835 }
5836 }
5837 } else {
5838 self.write_space();
5839 self.generate_expression(&join.this)?;
5840 }
5841
5842 if !join.deferred_condition {
5844 if let Some(match_cond) = &join.match_condition {
5846 self.write_space();
5847 self.write_keyword("MATCH_CONDITION");
5848 self.write(" (");
5849 self.generate_expression(match_cond)?;
5850 self.write(")");
5851 }
5852
5853 if let Some(on) = &join.on {
5854 if self.config.pretty {
5855 self.write_newline();
5856 self.indent_level += 1;
5857 self.write_indent();
5858 self.write_keyword("ON");
5859 self.write_space();
5860 self.generate_join_on_condition(on)?;
5861 self.indent_level -= 1;
5862 } else {
5863 self.write_space();
5864 self.write_keyword("ON");
5865 self.write_space();
5866 self.generate_expression(on)?;
5867 }
5868 }
5869
5870 if !join.using.is_empty() {
5871 if self.config.pretty {
5872 self.write_newline();
5873 self.indent_level += 1;
5874 self.write_indent();
5875 self.write_keyword("USING");
5876 self.write(" (");
5877 for (i, col) in join.using.iter().enumerate() {
5878 if i > 0 {
5879 self.write(", ");
5880 }
5881 self.generate_identifier(col)?;
5882 }
5883 self.write(")");
5884 self.indent_level -= 1;
5885 } else {
5886 self.write_space();
5887 self.write_keyword("USING");
5888 self.write(" (");
5889 for (i, col) in join.using.iter().enumerate() {
5890 if i > 0 {
5891 self.write(", ");
5892 }
5893 self.generate_identifier(col)?;
5894 }
5895 self.write(")");
5896 }
5897 }
5898 }
5899
5900 for pivot in &join.pivots {
5902 self.write_space();
5903 self.generate_expression(pivot)?;
5904 }
5905
5906 Ok(())
5907 }
5908
5909 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5911 if let Some(match_cond) = &join.match_condition {
5913 self.write_space();
5914 self.write_keyword("MATCH_CONDITION");
5915 self.write(" (");
5916 self.generate_expression(match_cond)?;
5917 self.write(")");
5918 }
5919
5920 if let Some(on) = &join.on {
5921 if self.config.pretty {
5922 self.write_newline();
5923 self.indent_level += 1;
5924 self.write_indent();
5925 self.write_keyword("ON");
5926 self.write_space();
5927 self.generate_join_on_condition(on)?;
5929 self.indent_level -= 1;
5930 } else {
5931 self.write_space();
5932 self.write_keyword("ON");
5933 self.write_space();
5934 self.generate_expression(on)?;
5935 }
5936 }
5937
5938 if !join.using.is_empty() {
5939 if self.config.pretty {
5940 self.write_newline();
5941 self.indent_level += 1;
5942 self.write_indent();
5943 self.write_keyword("USING");
5944 self.write(" (");
5945 for (i, col) in join.using.iter().enumerate() {
5946 if i > 0 {
5947 self.write(", ");
5948 }
5949 self.generate_identifier(col)?;
5950 }
5951 self.write(")");
5952 self.indent_level -= 1;
5953 } else {
5954 self.write_space();
5955 self.write_keyword("USING");
5956 self.write(" (");
5957 for (i, col) in join.using.iter().enumerate() {
5958 if i > 0 {
5959 self.write(", ");
5960 }
5961 self.generate_identifier(col)?;
5962 }
5963 self.write(")");
5964 }
5965 }
5966
5967 for pivot in &join.pivots {
5969 self.write_space();
5970 self.generate_expression(pivot)?;
5971 }
5972
5973 Ok(())
5974 }
5975
5976 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5978 if let Expression::And(and_op) = expr {
5979 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5980 self.generate_expression(conditions[0])?;
5981 for condition in conditions.iter().skip(1) {
5982 self.write_newline();
5983 self.write_indent();
5984 self.write_keyword("AND");
5985 self.write_space();
5986 self.generate_expression(condition)?;
5987 }
5988 return Ok(());
5989 }
5990 }
5991
5992 self.generate_expression(expr)
5993 }
5994
5995 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5996 self.write("(");
5998 self.generate_expression(&jt.left)?;
5999
6000 for join in &jt.joins {
6002 self.generate_join(join)?;
6003 }
6004
6005 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
6007 self.generate_lateral_view(lv, lv_idx)?;
6008 }
6009
6010 self.write(")");
6011
6012 if let Some(alias) = &jt.alias {
6014 self.write_space();
6015 self.write_keyword("AS");
6016 self.write_space();
6017 self.generate_identifier(alias)?;
6018 }
6019
6020 Ok(())
6021 }
6022
6023 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
6024 use crate::dialects::DialectType;
6025
6026 if self.config.pretty {
6027 self.write_newline();
6028 self.write_indent();
6029 } else {
6030 self.write_space();
6031 }
6032
6033 let use_lateral_join = matches!(
6036 self.config.dialect,
6037 Some(DialectType::PostgreSQL)
6038 | Some(DialectType::DuckDB)
6039 | Some(DialectType::Snowflake)
6040 | Some(DialectType::TSQL)
6041 | Some(DialectType::Presto)
6042 | Some(DialectType::Trino)
6043 | Some(DialectType::Athena)
6044 );
6045
6046 let use_unnest = matches!(
6048 self.config.dialect,
6049 Some(DialectType::DuckDB)
6050 | Some(DialectType::Presto)
6051 | Some(DialectType::Trino)
6052 | Some(DialectType::Athena)
6053 );
6054
6055 let (is_posexplode, is_inline, func_args) = match &lv.this {
6057 Expression::Explode(uf) => {
6058 (false, false, vec![uf.this.clone()])
6060 }
6061 Expression::Unnest(uf) => {
6062 let mut args = vec![uf.this.clone()];
6063 args.extend(uf.expressions.clone());
6064 (false, false, args)
6065 }
6066 Expression::Function(func) => {
6067 if func.name.eq_ignore_ascii_case("POSEXPLODE")
6068 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
6069 {
6070 (true, false, func.args.clone())
6071 } else if func.name.eq_ignore_ascii_case("INLINE") {
6072 (false, true, func.args.clone())
6073 } else if func.name.eq_ignore_ascii_case("EXPLODE")
6074 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
6075 {
6076 (false, false, func.args.clone())
6077 } else {
6078 (false, false, vec![])
6079 }
6080 }
6081 _ => (false, false, vec![]),
6082 };
6083
6084 if use_lateral_join {
6085 if lv.outer {
6087 self.write_keyword("LEFT JOIN LATERAL");
6088 } else {
6089 self.write_keyword("CROSS JOIN");
6090 }
6091 self.write_space();
6092
6093 if use_unnest && !func_args.is_empty() {
6094 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6097 func_args
6099 .iter()
6100 .map(|a| {
6101 if let Expression::Function(ref f) = a {
6102 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6103 return Expression::ArrayFunc(Box::new(
6104 crate::expressions::ArrayConstructor {
6105 expressions: f.args.clone(),
6106 bracket_notation: true,
6107 use_list_keyword: false,
6108 },
6109 ));
6110 }
6111 }
6112 a.clone()
6113 })
6114 .collect::<Vec<_>>()
6115 } else if matches!(
6116 self.config.dialect,
6117 Some(DialectType::Presto)
6118 | Some(DialectType::Trino)
6119 | Some(DialectType::Athena)
6120 ) {
6121 func_args
6123 .iter()
6124 .map(|a| {
6125 if let Expression::Function(ref f) = a {
6126 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6127 return Expression::ArrayFunc(Box::new(
6128 crate::expressions::ArrayConstructor {
6129 expressions: f.args.clone(),
6130 bracket_notation: true,
6131 use_list_keyword: false,
6132 },
6133 ));
6134 }
6135 }
6136 a.clone()
6137 })
6138 .collect::<Vec<_>>()
6139 } else {
6140 func_args
6141 };
6142
6143 if is_posexplode {
6145 self.write_keyword("LATERAL");
6146 self.write(" (");
6147 self.write_keyword("SELECT");
6148 self.write_space();
6149
6150 let pos_alias = if !lv.column_aliases.is_empty() {
6153 lv.column_aliases[0].clone()
6154 } else {
6155 Identifier::new("pos")
6156 };
6157 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6158 lv.column_aliases[1..].to_vec()
6159 } else {
6160 vec![Identifier::new("col")]
6161 };
6162
6163 self.generate_identifier(&pos_alias)?;
6165 self.write(" - 1");
6166 self.write_space();
6167 self.write_keyword("AS");
6168 self.write_space();
6169 self.generate_identifier(&pos_alias)?;
6170
6171 for data_col in &data_aliases {
6173 self.write(", ");
6174 self.generate_identifier(data_col)?;
6175 }
6176
6177 self.write_space();
6178 self.write_keyword("FROM");
6179 self.write_space();
6180 self.write_keyword("UNNEST");
6181 self.write("(");
6182 for (i, arg) in unnest_args.iter().enumerate() {
6183 if i > 0 {
6184 self.write(", ");
6185 }
6186 self.generate_expression(arg)?;
6187 }
6188 self.write(")");
6189 self.write_space();
6190 self.write_keyword("WITH ORDINALITY");
6191 self.write_space();
6192 self.write_keyword("AS");
6193 self.write_space();
6194
6195 let table_alias_ident = lv
6197 .table_alias
6198 .clone()
6199 .unwrap_or_else(|| Identifier::new("t"));
6200 self.generate_identifier(&table_alias_ident)?;
6201 self.write("(");
6202 for (i, data_col) in data_aliases.iter().enumerate() {
6203 if i > 0 {
6204 self.write(", ");
6205 }
6206 self.generate_identifier(data_col)?;
6207 }
6208 self.write(", ");
6209 self.generate_identifier(&pos_alias)?;
6210 self.write("))");
6211 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6212 self.write_keyword("LATERAL");
6214 self.write(" (");
6215 self.write_keyword("SELECT");
6216 self.write_space();
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 self.write_keyword("max_depth");
6227 self.write(" => 2))");
6228
6229 if let Some(alias) = &lv.table_alias {
6231 self.write_space();
6232 self.write_keyword("AS");
6233 self.write_space();
6234 self.generate_identifier(alias)?;
6235 if !lv.column_aliases.is_empty() {
6236 self.write("(");
6237 for (i, col) in lv.column_aliases.iter().enumerate() {
6238 if i > 0 {
6239 self.write(", ");
6240 }
6241 self.generate_identifier(col)?;
6242 }
6243 self.write(")");
6244 }
6245 } else if !lv.column_aliases.is_empty() {
6246 self.write_space();
6248 self.write_keyword("AS");
6249 self.write_space();
6250 self.write(&format!("_u_{}", lv_index));
6251 self.write("(");
6252 for (i, col) in lv.column_aliases.iter().enumerate() {
6253 if i > 0 {
6254 self.write(", ");
6255 }
6256 self.generate_identifier(col)?;
6257 }
6258 self.write(")");
6259 }
6260 } else {
6261 self.write_keyword("UNNEST");
6262 self.write("(");
6263 for (i, arg) in unnest_args.iter().enumerate() {
6264 if i > 0 {
6265 self.write(", ");
6266 }
6267 self.generate_expression(arg)?;
6268 }
6269 self.write(")");
6270
6271 if let Some(alias) = &lv.table_alias {
6273 self.write_space();
6274 self.write_keyword("AS");
6275 self.write_space();
6276 self.generate_identifier(alias)?;
6277 if !lv.column_aliases.is_empty() {
6278 self.write("(");
6279 for (i, col) in lv.column_aliases.iter().enumerate() {
6280 if i > 0 {
6281 self.write(", ");
6282 }
6283 self.generate_identifier(col)?;
6284 }
6285 self.write(")");
6286 }
6287 } else if !lv.column_aliases.is_empty() {
6288 self.write_space();
6289 self.write_keyword("AS");
6290 self.write(" t(");
6291 for (i, col) in lv.column_aliases.iter().enumerate() {
6292 if i > 0 {
6293 self.write(", ");
6294 }
6295 self.generate_identifier(col)?;
6296 }
6297 self.write(")");
6298 }
6299 }
6300 } else {
6301 if !lv.outer {
6303 self.write_keyword("LATERAL");
6304 self.write_space();
6305 }
6306 self.generate_expression(&lv.this)?;
6307
6308 if let Some(alias) = &lv.table_alias {
6310 self.write_space();
6311 self.write_keyword("AS");
6312 self.write_space();
6313 self.generate_identifier(alias)?;
6314 if !lv.column_aliases.is_empty() {
6315 self.write("(");
6316 for (i, col) in lv.column_aliases.iter().enumerate() {
6317 if i > 0 {
6318 self.write(", ");
6319 }
6320 self.generate_identifier(col)?;
6321 }
6322 self.write(")");
6323 }
6324 } else if !lv.column_aliases.is_empty() {
6325 self.write_space();
6326 self.write_keyword("AS");
6327 self.write(" t(");
6328 for (i, col) in lv.column_aliases.iter().enumerate() {
6329 if i > 0 {
6330 self.write(", ");
6331 }
6332 self.generate_identifier(col)?;
6333 }
6334 self.write(")");
6335 }
6336 }
6337
6338 if lv.outer {
6340 self.write_space();
6341 self.write_keyword("ON TRUE");
6342 }
6343 } else {
6344 self.write_keyword("LATERAL VIEW");
6346 if lv.outer {
6347 self.write_space();
6348 self.write_keyword("OUTER");
6349 }
6350 if self.config.pretty {
6351 self.write_newline();
6352 self.write_indent();
6353 } else {
6354 self.write_space();
6355 }
6356 self.generate_expression(&lv.this)?;
6357
6358 if let Some(alias) = &lv.table_alias {
6360 self.write_space();
6361 self.generate_identifier(alias)?;
6362 }
6363
6364 if !lv.column_aliases.is_empty() {
6366 self.write_space();
6367 self.write_keyword("AS");
6368 self.write_space();
6369 for (i, col) in lv.column_aliases.iter().enumerate() {
6370 if i > 0 {
6371 self.write(", ");
6372 }
6373 self.generate_identifier(col)?;
6374 }
6375 }
6376 }
6377
6378 Ok(())
6379 }
6380
6381 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
6382 let mut chain: Vec<&Union> = vec![outermost];
6387 let mut leftmost: &Expression = &outermost.left;
6388 while let Expression::Union(inner) = leftmost {
6389 chain.push(inner);
6390 leftmost = &inner.left;
6391 }
6392 if let Some(with) = &outermost.with {
6397 self.generate_with(with)?;
6398 self.write_space();
6399 }
6400
6401 self.generate_expression(leftmost)?;
6403
6404 for union in chain.iter().rev() {
6406 self.generate_union_step(union)?;
6407 }
6408 Ok(())
6409 }
6410
6411 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
6413 if self.config.pretty {
6414 self.write_newline();
6415 self.write_indent();
6416 } else {
6417 self.write_space();
6418 }
6419
6420 if let Some(side) = &union.side {
6422 self.write_keyword(side);
6423 self.write_space();
6424 }
6425 if let Some(kind) = &union.kind {
6426 self.write_keyword(kind);
6427 self.write_space();
6428 }
6429
6430 self.write_keyword("UNION");
6431 if union.all {
6432 self.write_space();
6433 self.write_keyword("ALL");
6434 } else if union.distinct {
6435 self.write_space();
6436 self.write_keyword("DISTINCT");
6437 }
6438
6439 if union.corresponding || union.by_name {
6442 self.write_space();
6443 self.write_keyword("BY NAME");
6444 }
6445 if !union.on_columns.is_empty() {
6446 self.write_space();
6447 self.write_keyword("ON");
6448 self.write(" (");
6449 for (i, col) in union.on_columns.iter().enumerate() {
6450 if i > 0 {
6451 self.write(", ");
6452 }
6453 self.generate_expression(col)?;
6454 }
6455 self.write(")");
6456 }
6457
6458 if self.config.pretty {
6459 self.write_newline();
6460 self.write_indent();
6461 } else {
6462 self.write_space();
6463 }
6464 self.generate_expression(&union.right)?;
6465 if let Some(order_by) = &union.order_by {
6467 if self.config.pretty {
6468 self.write_newline();
6469 } else {
6470 self.write_space();
6471 }
6472 self.write_keyword("ORDER BY");
6473 self.write_space();
6474 for (i, ordered) in order_by.expressions.iter().enumerate() {
6475 if i > 0 {
6476 self.write(", ");
6477 }
6478 self.generate_ordered(ordered)?;
6479 }
6480 }
6481 if let Some(limit) = &union.limit {
6482 if self.config.pretty {
6483 self.write_newline();
6484 } else {
6485 self.write_space();
6486 }
6487 self.write_keyword("LIMIT");
6488 self.write_space();
6489 self.generate_expression(limit)?;
6490 }
6491 if let Some(offset) = &union.offset {
6492 if self.config.pretty {
6493 self.write_newline();
6494 } else {
6495 self.write_space();
6496 }
6497 self.write_keyword("OFFSET");
6498 self.write_space();
6499 self.generate_expression(offset)?;
6500 }
6501 if let Some(distribute_by) = &union.distribute_by {
6503 self.write_space();
6504 self.write_keyword("DISTRIBUTE BY");
6505 self.write_space();
6506 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6507 if i > 0 {
6508 self.write(", ");
6509 }
6510 self.generate_expression(expr)?;
6511 }
6512 }
6513 if let Some(sort_by) = &union.sort_by {
6515 self.write_space();
6516 self.write_keyword("SORT BY");
6517 self.write_space();
6518 for (i, ord) in sort_by.expressions.iter().enumerate() {
6519 if i > 0 {
6520 self.write(", ");
6521 }
6522 self.generate_ordered(ord)?;
6523 }
6524 }
6525 if let Some(cluster_by) = &union.cluster_by {
6527 self.write_space();
6528 self.write_keyword("CLUSTER BY");
6529 self.write_space();
6530 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6531 if i > 0 {
6532 self.write(", ");
6533 }
6534 self.generate_ordered(ord)?;
6535 }
6536 }
6537 Ok(())
6538 }
6539
6540 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
6541 let mut chain: Vec<&Intersect> = vec![outermost];
6543 let mut leftmost: &Expression = &outermost.left;
6544 while let Expression::Intersect(inner) = leftmost {
6545 chain.push(inner);
6546 leftmost = &inner.left;
6547 }
6548
6549 if let Some(with) = &outermost.with {
6550 self.generate_with(with)?;
6551 self.write_space();
6552 }
6553
6554 self.generate_expression(leftmost)?;
6555
6556 for intersect in chain.iter().rev() {
6557 self.generate_intersect_step(intersect)?;
6558 }
6559 Ok(())
6560 }
6561
6562 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
6564 if self.config.pretty {
6565 self.write_newline();
6566 self.write_indent();
6567 } else {
6568 self.write_space();
6569 }
6570
6571 if let Some(side) = &intersect.side {
6573 self.write_keyword(side);
6574 self.write_space();
6575 }
6576 if let Some(kind) = &intersect.kind {
6577 self.write_keyword(kind);
6578 self.write_space();
6579 }
6580
6581 self.write_keyword("INTERSECT");
6582 if intersect.all {
6583 self.write_space();
6584 self.write_keyword("ALL");
6585 } else if intersect.distinct {
6586 self.write_space();
6587 self.write_keyword("DISTINCT");
6588 }
6589
6590 if intersect.corresponding || intersect.by_name {
6593 self.write_space();
6594 self.write_keyword("BY NAME");
6595 }
6596 if !intersect.on_columns.is_empty() {
6597 self.write_space();
6598 self.write_keyword("ON");
6599 self.write(" (");
6600 for (i, col) in intersect.on_columns.iter().enumerate() {
6601 if i > 0 {
6602 self.write(", ");
6603 }
6604 self.generate_expression(col)?;
6605 }
6606 self.write(")");
6607 }
6608
6609 if self.config.pretty {
6610 self.write_newline();
6611 self.write_indent();
6612 } else {
6613 self.write_space();
6614 }
6615 self.generate_expression(&intersect.right)?;
6616 if let Some(order_by) = &intersect.order_by {
6618 if self.config.pretty {
6619 self.write_newline();
6620 } else {
6621 self.write_space();
6622 }
6623 self.write_keyword("ORDER BY");
6624 self.write_space();
6625 for (i, ordered) in order_by.expressions.iter().enumerate() {
6626 if i > 0 {
6627 self.write(", ");
6628 }
6629 self.generate_ordered(ordered)?;
6630 }
6631 }
6632 if let Some(limit) = &intersect.limit {
6633 if self.config.pretty {
6634 self.write_newline();
6635 } else {
6636 self.write_space();
6637 }
6638 self.write_keyword("LIMIT");
6639 self.write_space();
6640 self.generate_expression(limit)?;
6641 }
6642 if let Some(offset) = &intersect.offset {
6643 if self.config.pretty {
6644 self.write_newline();
6645 } else {
6646 self.write_space();
6647 }
6648 self.write_keyword("OFFSET");
6649 self.write_space();
6650 self.generate_expression(offset)?;
6651 }
6652 if let Some(distribute_by) = &intersect.distribute_by {
6654 self.write_space();
6655 self.write_keyword("DISTRIBUTE BY");
6656 self.write_space();
6657 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6658 if i > 0 {
6659 self.write(", ");
6660 }
6661 self.generate_expression(expr)?;
6662 }
6663 }
6664 if let Some(sort_by) = &intersect.sort_by {
6666 self.write_space();
6667 self.write_keyword("SORT BY");
6668 self.write_space();
6669 for (i, ord) in sort_by.expressions.iter().enumerate() {
6670 if i > 0 {
6671 self.write(", ");
6672 }
6673 self.generate_ordered(ord)?;
6674 }
6675 }
6676 if let Some(cluster_by) = &intersect.cluster_by {
6678 self.write_space();
6679 self.write_keyword("CLUSTER BY");
6680 self.write_space();
6681 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6682 if i > 0 {
6683 self.write(", ");
6684 }
6685 self.generate_ordered(ord)?;
6686 }
6687 }
6688 Ok(())
6689 }
6690
6691 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
6692 let mut chain: Vec<&Except> = vec![outermost];
6694 let mut leftmost: &Expression = &outermost.left;
6695 while let Expression::Except(inner) = leftmost {
6696 chain.push(inner);
6697 leftmost = &inner.left;
6698 }
6699
6700 if let Some(with) = &outermost.with {
6701 self.generate_with(with)?;
6702 self.write_space();
6703 }
6704
6705 self.generate_expression(leftmost)?;
6706
6707 for except in chain.iter().rev() {
6708 self.generate_except_step(except)?;
6709 }
6710 Ok(())
6711 }
6712
6713 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
6715 use crate::dialects::DialectType;
6716
6717 if self.config.pretty {
6718 self.write_newline();
6719 self.write_indent();
6720 } else {
6721 self.write_space();
6722 }
6723
6724 if let Some(side) = &except.side {
6726 self.write_keyword(side);
6727 self.write_space();
6728 }
6729 if let Some(kind) = &except.kind {
6730 self.write_keyword(kind);
6731 self.write_space();
6732 }
6733
6734 match self.config.dialect {
6736 Some(DialectType::Oracle) if !except.all => {
6737 self.write_keyword("MINUS");
6738 }
6739 Some(DialectType::ClickHouse) => {
6740 self.write_keyword("EXCEPT");
6741 let preserve_all = self.config.source_dialect.is_none()
6742 || matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
6743 if except.all && preserve_all {
6744 self.write_space();
6745 self.write_keyword("ALL");
6746 }
6747 if except.distinct {
6748 self.write_space();
6749 self.write_keyword("DISTINCT");
6750 }
6751 }
6752 Some(DialectType::BigQuery) => {
6753 self.write_keyword("EXCEPT");
6755 if except.all {
6756 self.write_space();
6757 self.write_keyword("ALL");
6758 } else {
6759 self.write_space();
6760 self.write_keyword("DISTINCT");
6761 }
6762 }
6763 _ => {
6764 self.write_keyword("EXCEPT");
6765 if except.all {
6766 self.write_space();
6767 self.write_keyword("ALL");
6768 } else if except.distinct {
6769 self.write_space();
6770 self.write_keyword("DISTINCT");
6771 }
6772 }
6773 }
6774
6775 if except.corresponding || except.by_name {
6778 self.write_space();
6779 self.write_keyword("BY NAME");
6780 }
6781 if !except.on_columns.is_empty() {
6782 self.write_space();
6783 self.write_keyword("ON");
6784 self.write(" (");
6785 for (i, col) in except.on_columns.iter().enumerate() {
6786 if i > 0 {
6787 self.write(", ");
6788 }
6789 self.generate_expression(col)?;
6790 }
6791 self.write(")");
6792 }
6793
6794 if self.config.pretty {
6795 self.write_newline();
6796 self.write_indent();
6797 } else {
6798 self.write_space();
6799 }
6800 self.generate_expression(&except.right)?;
6801 if let Some(order_by) = &except.order_by {
6803 if self.config.pretty {
6804 self.write_newline();
6805 } else {
6806 self.write_space();
6807 }
6808 self.write_keyword("ORDER BY");
6809 self.write_space();
6810 for (i, ordered) in order_by.expressions.iter().enumerate() {
6811 if i > 0 {
6812 self.write(", ");
6813 }
6814 self.generate_ordered(ordered)?;
6815 }
6816 }
6817 if let Some(limit) = &except.limit {
6818 if self.config.pretty {
6819 self.write_newline();
6820 } else {
6821 self.write_space();
6822 }
6823 self.write_keyword("LIMIT");
6824 self.write_space();
6825 self.generate_expression(limit)?;
6826 }
6827 if let Some(offset) = &except.offset {
6828 if self.config.pretty {
6829 self.write_newline();
6830 } else {
6831 self.write_space();
6832 }
6833 self.write_keyword("OFFSET");
6834 self.write_space();
6835 self.generate_expression(offset)?;
6836 }
6837 if let Some(distribute_by) = &except.distribute_by {
6839 self.write_space();
6840 self.write_keyword("DISTRIBUTE BY");
6841 self.write_space();
6842 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6843 if i > 0 {
6844 self.write(", ");
6845 }
6846 self.generate_expression(expr)?;
6847 }
6848 }
6849 if let Some(sort_by) = &except.sort_by {
6851 self.write_space();
6852 self.write_keyword("SORT BY");
6853 self.write_space();
6854 for (i, ord) in sort_by.expressions.iter().enumerate() {
6855 if i > 0 {
6856 self.write(", ");
6857 }
6858 self.generate_ordered(ord)?;
6859 }
6860 }
6861 if let Some(cluster_by) = &except.cluster_by {
6863 self.write_space();
6864 self.write_keyword("CLUSTER BY");
6865 self.write_space();
6866 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6867 if i > 0 {
6868 self.write(", ");
6869 }
6870 self.generate_ordered(ord)?;
6871 }
6872 }
6873 Ok(())
6874 }
6875
6876 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6877 let prepend_query_cte = if insert.with.is_none() {
6879 use crate::dialects::DialectType;
6880 let should_prepend = matches!(
6881 self.config.dialect,
6882 Some(DialectType::TSQL)
6883 | Some(DialectType::Fabric)
6884 | Some(DialectType::Spark)
6885 | Some(DialectType::Databricks)
6886 | Some(DialectType::Hive)
6887 );
6888 if should_prepend {
6889 if let Some(Expression::Select(select)) = &insert.query {
6890 select.with.clone()
6891 } else {
6892 None
6893 }
6894 } else {
6895 None
6896 }
6897 } else {
6898 None
6899 };
6900
6901 if let Some(with) = &insert.with {
6903 self.generate_with(with)?;
6904 self.write_space();
6905 } else if let Some(with) = &prepend_query_cte {
6906 self.generate_with(with)?;
6907 self.write_space();
6908 }
6909
6910 for comment in &insert.leading_comments {
6912 self.write_formatted_comment(comment);
6913 self.write(" ");
6914 }
6915
6916 if let Some(dir) = &insert.directory {
6918 self.write_keyword("INSERT OVERWRITE");
6919 if dir.local {
6920 self.write_space();
6921 self.write_keyword("LOCAL");
6922 }
6923 self.write_space();
6924 self.write_keyword("DIRECTORY");
6925 self.write_space();
6926 self.write("'");
6927 self.write(&dir.path);
6928 self.write("'");
6929
6930 if let Some(row_format) = &dir.row_format {
6932 self.write_space();
6933 self.write_keyword("ROW FORMAT");
6934 if row_format.delimited {
6935 self.write_space();
6936 self.write_keyword("DELIMITED");
6937 }
6938 if let Some(val) = &row_format.fields_terminated_by {
6939 self.write_space();
6940 self.write_keyword("FIELDS TERMINATED BY");
6941 self.write_space();
6942 self.generate_string_literal(val)?;
6943 }
6944 if let Some(val) = &row_format.collection_items_terminated_by {
6945 self.write_space();
6946 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6947 self.write_space();
6948 self.write("'");
6949 self.write(val);
6950 self.write("'");
6951 }
6952 if let Some(val) = &row_format.map_keys_terminated_by {
6953 self.write_space();
6954 self.write_keyword("MAP KEYS TERMINATED BY");
6955 self.write_space();
6956 self.write("'");
6957 self.write(val);
6958 self.write("'");
6959 }
6960 if let Some(val) = &row_format.lines_terminated_by {
6961 self.write_space();
6962 self.write_keyword("LINES TERMINATED BY");
6963 self.write_space();
6964 self.write("'");
6965 self.write(val);
6966 self.write("'");
6967 }
6968 if let Some(val) = &row_format.null_defined_as {
6969 self.write_space();
6970 self.write_keyword("NULL DEFINED AS");
6971 self.write_space();
6972 self.write("'");
6973 self.write(val);
6974 self.write("'");
6975 }
6976 }
6977
6978 if let Some(format) = &dir.stored_as {
6980 self.write_space();
6981 self.write_keyword("STORED AS");
6982 self.write_space();
6983 self.write_keyword(format);
6984 }
6985
6986 if let Some(query) = &insert.query {
6988 self.write_space();
6989 self.generate_expression(query)?;
6990 }
6991
6992 return Ok(());
6993 }
6994
6995 if insert.is_replace {
6996 self.write_keyword("REPLACE INTO");
6998 } else if insert.overwrite {
6999 self.write_keyword("INSERT");
7001 if let Some(ref hint) = insert.hint {
7003 self.generate_hint(hint)?;
7004 }
7005 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
7006 } else if let Some(ref action) = insert.conflict_action {
7007 self.write_keyword("INSERT OR");
7009 self.write_space();
7010 self.write_keyword(action);
7011 self.write_space();
7012 self.write_keyword("INTO");
7013 } else if insert.ignore {
7014 self.write_keyword("INSERT IGNORE INTO");
7016 } else {
7017 self.write_keyword("INSERT");
7018 if let Some(ref hint) = insert.hint {
7020 self.generate_hint(hint)?;
7021 }
7022 self.write_space();
7023 self.write_keyword("INTO");
7024 }
7025 if let Some(ref func) = insert.function_target {
7027 self.write_space();
7028 self.write_keyword("FUNCTION");
7029 self.write_space();
7030 self.generate_expression(func)?;
7031 } else {
7032 self.write_space();
7033 self.generate_table(&insert.table)?;
7034 }
7035
7036 if let Some(ref alias) = insert.alias {
7038 self.write_space();
7039 if insert.alias_explicit_as {
7040 self.write_keyword("AS");
7041 self.write_space();
7042 }
7043 self.generate_identifier(alias)?;
7044 }
7045
7046 if insert.if_exists {
7048 self.write_space();
7049 self.write_keyword("IF EXISTS");
7050 }
7051
7052 if let Some(ref replace_where) = insert.replace_where {
7054 if self.config.pretty {
7055 self.write_newline();
7056 self.write_indent();
7057 } else {
7058 self.write_space();
7059 }
7060 self.write_keyword("REPLACE WHERE");
7061 self.write_space();
7062 self.generate_expression(replace_where)?;
7063 }
7064
7065 if !insert.partition.is_empty() {
7067 self.write_space();
7068 self.write_keyword("PARTITION");
7069 self.write("(");
7070 for (i, (col, val)) in insert.partition.iter().enumerate() {
7071 if i > 0 {
7072 self.write(", ");
7073 }
7074 self.generate_identifier(col)?;
7075 if let Some(v) = val {
7076 self.write(" = ");
7077 self.generate_expression(v)?;
7078 }
7079 }
7080 self.write(")");
7081 }
7082
7083 if let Some(ref partition_by) = insert.partition_by {
7085 self.write_space();
7086 self.write_keyword("PARTITION BY");
7087 self.write_space();
7088 self.generate_expression(partition_by)?;
7089 }
7090
7091 if !insert.settings.is_empty() {
7093 self.write_space();
7094 self.write_keyword("SETTINGS");
7095 self.write_space();
7096 for (i, setting) in insert.settings.iter().enumerate() {
7097 if i > 0 {
7098 self.write(", ");
7099 }
7100 self.generate_expression(setting)?;
7101 }
7102 }
7103
7104 if !insert.columns.is_empty() {
7105 if insert.alias.is_some() && insert.alias_explicit_as {
7106 self.write("(");
7108 } else {
7109 self.write(" (");
7111 }
7112 for (i, col) in insert.columns.iter().enumerate() {
7113 if i > 0 {
7114 self.write(", ");
7115 }
7116 self.generate_identifier(col)?;
7117 }
7118 self.write(")");
7119 }
7120
7121 if let Some(ref output) = insert.output {
7123 self.generate_output_clause(output)?;
7124 }
7125
7126 if insert.by_name {
7128 self.write_space();
7129 self.write_keyword("BY NAME");
7130 }
7131
7132 if insert.default_values {
7133 self.write_space();
7134 self.write_keyword("DEFAULT VALUES");
7135 } else if let Some(query) = &insert.query {
7136 if self.config.pretty {
7137 self.write_newline();
7138 } else {
7139 self.write_space();
7140 }
7141 if prepend_query_cte.is_some() {
7143 if let Expression::Select(select) = query {
7144 let mut select_no_with = select.clone();
7145 select_no_with.with = None;
7146 self.generate_select(&select_no_with)?;
7147 } else {
7148 self.generate_expression(query)?;
7149 }
7150 } else {
7151 self.generate_expression(query)?;
7152 }
7153 } else if !insert.values.is_empty() {
7154 if self.config.pretty {
7155 self.write_newline();
7157 self.write_keyword("VALUES");
7158 self.write_newline();
7159 self.indent_level += 1;
7160 for (i, row) in insert.values.iter().enumerate() {
7161 if i > 0 {
7162 self.write(",");
7163 self.write_newline();
7164 }
7165 self.write_indent();
7166 self.write("(");
7167 for (j, val) in row.iter().enumerate() {
7168 if j > 0 {
7169 self.write(", ");
7170 }
7171 self.generate_expression(val)?;
7172 }
7173 self.write(")");
7174 }
7175 self.indent_level -= 1;
7176 } else {
7177 self.write_space();
7179 self.write_keyword("VALUES");
7180 for (i, row) in insert.values.iter().enumerate() {
7181 if i > 0 {
7182 self.write(",");
7183 }
7184 self.write(" (");
7185 for (j, val) in row.iter().enumerate() {
7186 if j > 0 {
7187 self.write(", ");
7188 }
7189 self.generate_expression(val)?;
7190 }
7191 self.write(")");
7192 }
7193 }
7194 }
7195
7196 if let Some(ref source) = insert.source {
7198 self.write_space();
7199 self.write_keyword("TABLE");
7200 self.write_space();
7201 self.generate_expression(source)?;
7202 }
7203
7204 if let Some(alias) = &insert.source_alias {
7206 self.write_space();
7207 self.write_keyword("AS");
7208 self.write_space();
7209 self.generate_identifier(alias)?;
7210 }
7211
7212 if let Some(on_conflict) = &insert.on_conflict {
7214 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7215 self.write_space();
7216 self.generate_expression(on_conflict)?;
7217 }
7218 }
7219
7220 if !insert.returning.is_empty() {
7222 self.write_space();
7223 self.write_keyword("RETURNING");
7224 self.write_space();
7225 for (i, expr) in insert.returning.iter().enumerate() {
7226 if i > 0 {
7227 self.write(", ");
7228 }
7229 self.generate_expression(expr)?;
7230 }
7231 }
7232
7233 Ok(())
7234 }
7235
7236 fn generate_update(&mut self, update: &Update) -> Result<()> {
7237 for comment in &update.leading_comments {
7239 self.write_formatted_comment(comment);
7240 self.write(" ");
7241 }
7242
7243 if let Some(ref with) = update.with {
7245 self.generate_with(with)?;
7246 self.write_space();
7247 }
7248
7249 self.write_keyword("UPDATE");
7250 if let Some(hint) = &update.hint {
7251 self.generate_hint(hint)?;
7252 }
7253 self.write_space();
7254 self.generate_table(&update.table)?;
7255
7256 let mysql_like_update_from = matches!(
7257 self.config.dialect,
7258 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
7259 ) && update.from_clause.is_some();
7260
7261 let mut set_pairs = update.set.clone();
7262
7263 let mut pre_set_joins = update.table_joins.clone();
7265 if mysql_like_update_from {
7266 let target_name = update
7267 .table
7268 .alias
7269 .as_ref()
7270 .map(|a| a.name.clone())
7271 .unwrap_or_else(|| update.table.name.name.clone());
7272
7273 for (col, _) in &mut set_pairs {
7274 if !col.name.contains('.') {
7275 col.name = format!("{}.{}", target_name, col.name);
7276 }
7277 }
7278
7279 if let Some(from_clause) = &update.from_clause {
7280 for table_expr in &from_clause.expressions {
7281 pre_set_joins.push(crate::expressions::Join {
7282 this: table_expr.clone(),
7283 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7284 value: true,
7285 })),
7286 using: Vec::new(),
7287 kind: crate::expressions::JoinKind::Inner,
7288 use_inner_keyword: false,
7289 use_outer_keyword: false,
7290 deferred_condition: false,
7291 join_hint: None,
7292 match_condition: None,
7293 pivots: Vec::new(),
7294 comments: Vec::new(),
7295 nesting_group: 0,
7296 directed: false,
7297 });
7298 }
7299 }
7300 for join in &update.from_joins {
7301 let mut join = join.clone();
7302 if join.on.is_none() && join.using.is_empty() {
7303 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7304 value: true,
7305 }));
7306 }
7307 pre_set_joins.push(join);
7308 }
7309 }
7310
7311 for extra_table in &update.extra_tables {
7313 self.write(", ");
7314 self.generate_table(extra_table)?;
7315 }
7316
7317 for join in &pre_set_joins {
7319 self.generate_join(join)?;
7321 }
7322
7323 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
7325 if teradata_from_before_set && !mysql_like_update_from {
7326 if let Some(ref from_clause) = update.from_clause {
7327 self.write_space();
7328 self.write_keyword("FROM");
7329 self.write_space();
7330 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7331 if i > 0 {
7332 self.write(", ");
7333 }
7334 self.generate_expression(table_expr)?;
7335 }
7336 }
7337 for join in &update.from_joins {
7338 self.generate_join(join)?;
7339 }
7340 }
7341
7342 self.write_space();
7343 self.write_keyword("SET");
7344 self.write_space();
7345
7346 for (i, (col, val)) in set_pairs.iter().enumerate() {
7347 if i > 0 {
7348 self.write(", ");
7349 }
7350 self.generate_identifier(col)?;
7351 self.write(" = ");
7352 self.generate_expression(val)?;
7353 }
7354
7355 if let Some(ref output) = update.output {
7357 self.generate_output_clause(output)?;
7358 }
7359
7360 if !mysql_like_update_from && !teradata_from_before_set {
7362 if let Some(ref from_clause) = update.from_clause {
7363 self.write_space();
7364 self.write_keyword("FROM");
7365 self.write_space();
7366 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7368 if i > 0 {
7369 self.write(", ");
7370 }
7371 self.generate_expression(table_expr)?;
7372 }
7373 }
7374 }
7375
7376 if !mysql_like_update_from && !teradata_from_before_set {
7377 for join in &update.from_joins {
7379 self.generate_join(join)?;
7380 }
7381 }
7382
7383 if let Some(where_clause) = &update.where_clause {
7384 self.write_space();
7385 self.write_keyword("WHERE");
7386 self.write_space();
7387 self.generate_expression(&where_clause.this)?;
7388 }
7389
7390 if !update.returning.is_empty() {
7392 self.write_space();
7393 self.write_keyword("RETURNING");
7394 self.write_space();
7395 for (i, expr) in update.returning.iter().enumerate() {
7396 if i > 0 {
7397 self.write(", ");
7398 }
7399 self.generate_expression(expr)?;
7400 }
7401 }
7402
7403 if let Some(ref order_by) = update.order_by {
7405 self.write_space();
7406 self.generate_order_by(order_by)?;
7407 }
7408
7409 if let Some(ref limit) = update.limit {
7411 self.write_space();
7412 self.write_keyword("LIMIT");
7413 self.write_space();
7414 self.generate_expression(limit)?;
7415 }
7416
7417 Ok(())
7418 }
7419
7420 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
7421 if let Some(with) = &delete.with {
7423 self.generate_with(with)?;
7424 self.write_space();
7425 }
7426
7427 for comment in &delete.leading_comments {
7429 self.write_formatted_comment(comment);
7430 self.write(" ");
7431 }
7432
7433 if !delete.tables.is_empty() && !delete.tables_from_using {
7435 self.write_keyword("DELETE");
7437 if let Some(hint) = &delete.hint {
7438 self.generate_hint(hint)?;
7439 }
7440 self.write_space();
7441 for (i, tbl) in delete.tables.iter().enumerate() {
7442 if i > 0 {
7443 self.write(", ");
7444 }
7445 self.generate_table(tbl)?;
7446 }
7447 if let Some(ref output) = delete.output {
7449 self.generate_output_clause(output)?;
7450 }
7451 self.write_space();
7452 self.write_keyword("FROM");
7453 self.write_space();
7454 self.generate_table(&delete.table)?;
7455 } else if !delete.tables.is_empty() && delete.tables_from_using {
7456 self.write_keyword("DELETE");
7458 if let Some(hint) = &delete.hint {
7459 self.generate_hint(hint)?;
7460 }
7461 self.write_space();
7462 self.write_keyword("FROM");
7463 self.write_space();
7464 for (i, tbl) in delete.tables.iter().enumerate() {
7465 if i > 0 {
7466 self.write(", ");
7467 }
7468 self.generate_table(tbl)?;
7469 }
7470 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
7471 self.write_keyword("DELETE");
7473 if let Some(hint) = &delete.hint {
7474 self.generate_hint(hint)?;
7475 }
7476 self.write_space();
7477 self.generate_table(&delete.table)?;
7478 } else {
7479 self.write_keyword("DELETE");
7480 if let Some(hint) = &delete.hint {
7481 self.generate_hint(hint)?;
7482 }
7483 self.write_space();
7484 self.write_keyword("FROM");
7485 self.write_space();
7486 self.generate_table(&delete.table)?;
7487 }
7488
7489 if let Some(ref on_cluster) = delete.on_cluster {
7491 self.write_space();
7492 self.generate_on_cluster(on_cluster)?;
7493 }
7494
7495 if let Some(ref idx) = delete.force_index {
7497 self.write_space();
7498 self.write_keyword("FORCE INDEX");
7499 self.write(" (");
7500 self.write(idx);
7501 self.write(")");
7502 }
7503
7504 if let Some(ref alias) = delete.alias {
7506 self.write_space();
7507 if delete.alias_explicit_as
7508 || matches!(self.config.dialect, Some(DialectType::BigQuery))
7509 {
7510 self.write_keyword("AS");
7511 self.write_space();
7512 }
7513 self.generate_identifier(alias)?;
7514 }
7515
7516 if !delete.tables_from_using {
7518 for join in &delete.joins {
7519 self.generate_join(join)?;
7520 }
7521 }
7522
7523 if !delete.using.is_empty() {
7525 self.write_space();
7526 self.write_keyword("USING");
7527 for (i, table) in delete.using.iter().enumerate() {
7528 if i > 0 {
7529 self.write(",");
7530 }
7531 self.write_space();
7532 if !table.hints.is_empty() && table.name.is_empty() {
7534 self.generate_expression(&table.hints[0])?;
7536 if let Some(ref alias) = table.alias {
7537 self.write_space();
7538 if table.alias_explicit_as {
7539 self.write_keyword("AS");
7540 self.write_space();
7541 }
7542 self.generate_identifier(alias)?;
7543 if !table.column_aliases.is_empty() {
7544 self.write("(");
7545 for (j, col_alias) in table.column_aliases.iter().enumerate() {
7546 if j > 0 {
7547 self.write(", ");
7548 }
7549 self.generate_identifier(col_alias)?;
7550 }
7551 self.write(")");
7552 }
7553 }
7554 } else {
7555 self.generate_table(table)?;
7556 }
7557 }
7558 }
7559
7560 if delete.tables_from_using {
7562 for join in &delete.joins {
7563 self.generate_join(join)?;
7564 }
7565 }
7566
7567 let output_already_emitted =
7569 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
7570 if !output_already_emitted {
7571 if let Some(ref output) = delete.output {
7572 self.generate_output_clause(output)?;
7573 }
7574 }
7575
7576 if let Some(where_clause) = &delete.where_clause {
7577 self.write_space();
7578 self.write_keyword("WHERE");
7579 self.write_space();
7580 self.generate_expression(&where_clause.this)?;
7581 }
7582
7583 if let Some(ref order_by) = delete.order_by {
7585 self.write_space();
7586 self.generate_order_by(order_by)?;
7587 }
7588
7589 if let Some(ref limit) = delete.limit {
7591 self.write_space();
7592 self.write_keyword("LIMIT");
7593 self.write_space();
7594 self.generate_expression(limit)?;
7595 }
7596
7597 if !delete.returning.is_empty() {
7599 self.write_space();
7600 self.write_keyword("RETURNING");
7601 self.write_space();
7602 for (i, expr) in delete.returning.iter().enumerate() {
7603 if i > 0 {
7604 self.write(", ");
7605 }
7606 self.generate_expression(expr)?;
7607 }
7608 }
7609
7610 Ok(())
7611 }
7612
7613 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7616 let saved_athena_hive_context = self.athena_hive_context;
7620 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7621 if matches!(
7622 self.config.dialect,
7623 Some(crate::dialects::DialectType::Athena)
7624 ) {
7625 let is_external = ct
7629 .table_modifier
7630 .as_ref()
7631 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7632 .unwrap_or(false);
7633 let has_as_select = ct.as_select.is_some();
7634 self.athena_hive_context = is_external || !has_as_select;
7635 }
7636
7637 if matches!(
7639 self.config.dialect,
7640 Some(crate::dialects::DialectType::TSQL)
7641 ) {
7642 if let Some(ref query) = ct.as_select {
7643 if let Some(with_cte) = &ct.with_cte {
7645 self.generate_with(with_cte)?;
7646 self.write_space();
7647 }
7648
7649 self.write_keyword("SELECT");
7651 self.write(" * ");
7652 self.write_keyword("INTO");
7653 self.write_space();
7654
7655 if ct.temporary {
7657 self.write("#");
7658 }
7659 self.generate_table(&ct.name)?;
7660
7661 self.write_space();
7662 self.write_keyword("FROM");
7663 self.write(" (");
7664 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7666 self.generate_expression(&aliased_query)?;
7667 self.write(") ");
7668 self.write_keyword("AS");
7669 self.write(" temp");
7670 return Ok(());
7671 }
7672 }
7673
7674 if let Some(with_cte) = &ct.with_cte {
7676 self.generate_with(with_cte)?;
7677 self.write_space();
7678 }
7679
7680 for comment in &ct.leading_comments {
7682 self.write_formatted_comment(comment);
7683 self.write(" ");
7684 }
7685 self.write_keyword("CREATE");
7686
7687 if ct.or_replace {
7688 self.write_space();
7689 self.write_keyword("OR REPLACE");
7690 }
7691
7692 if ct.temporary {
7693 self.write_space();
7694 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7696 self.write_keyword("GLOBAL TEMPORARY");
7697 } else {
7698 self.write_keyword("TEMPORARY");
7699 }
7700 }
7701
7702 let is_dictionary = ct
7704 .table_modifier
7705 .as_ref()
7706 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7707 .unwrap_or(false);
7708 if let Some(ref modifier) = ct.table_modifier {
7709 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7711 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7712 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7714 || modifier.eq_ignore_ascii_case("SET")
7715 || modifier.eq_ignore_ascii_case("MULTISET")
7716 || modifier.to_ascii_uppercase().contains("VOLATILE")
7717 || modifier.to_ascii_uppercase().starts_with("SET ")
7718 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
7719 let skip_teradata =
7720 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7721 if !skip_transient && !skip_teradata {
7722 self.write_space();
7723 self.write_keyword(modifier);
7724 }
7725 }
7726
7727 if !is_dictionary {
7728 self.write_space();
7729 self.write_keyword("TABLE");
7730 }
7731
7732 if ct.if_not_exists {
7733 self.write_space();
7734 self.write_keyword("IF NOT EXISTS");
7735 }
7736
7737 self.write_space();
7738 self.generate_table(&ct.name)?;
7739
7740 if let Some(ref uuid) = ct.uuid {
7742 self.write_space();
7743 self.write_keyword("UUID");
7744 self.write(" '");
7745 self.write(uuid);
7746 self.write("'");
7747 }
7748
7749 if let Some(ref on_cluster) = ct.on_cluster {
7751 self.write_space();
7752 self.generate_on_cluster(on_cluster)?;
7753 }
7754
7755 if matches!(
7757 self.config.dialect,
7758 Some(crate::dialects::DialectType::Teradata)
7759 ) && !ct.teradata_post_name_options.is_empty()
7760 {
7761 for opt in &ct.teradata_post_name_options {
7762 self.write(", ");
7763 self.write(opt);
7764 }
7765 }
7766
7767 if ct.copy_grants {
7769 self.write_space();
7770 self.write_keyword("COPY GRANTS");
7771 }
7772
7773 if let Some(ref using_template) = ct.using_template {
7775 self.write_space();
7776 self.write_keyword("USING TEMPLATE");
7777 self.write_space();
7778 self.generate_expression(using_template)?;
7779 return Ok(());
7780 }
7781
7782 if is_clickhouse {
7784 if let Some(ref clone_source) = ct.clone_source {
7785 self.write_space();
7786 self.write_keyword("AS");
7787 self.write_space();
7788 self.generate_table(clone_source)?;
7789 }
7790 }
7791
7792 if !is_clickhouse {
7794 if let Some(ref clone_source) = ct.clone_source {
7795 self.write_space();
7796 if ct.is_copy && self.config.supports_table_copy {
7797 self.write_keyword("COPY");
7799 } else if ct.shallow_clone {
7800 self.write_keyword("SHALLOW CLONE");
7801 } else if ct.deep_clone {
7802 self.write_keyword("DEEP CLONE");
7803 } else {
7804 self.write_keyword("CLONE");
7805 }
7806 self.write_space();
7807 self.generate_table(clone_source)?;
7808 if let Some(ref at_clause) = ct.clone_at_clause {
7810 self.write_space();
7811 self.generate_expression(at_clause)?;
7812 }
7813 return Ok(());
7814 }
7815 }
7816
7817 if let Some(ref partition_of) = ct.partition_of {
7821 self.write_space();
7822
7823 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7825 self.write_keyword("PARTITION OF");
7827 self.write_space();
7828 self.generate_expression(&pop.this)?;
7829
7830 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7832 self.write(" (");
7833 let mut first = true;
7834 for col in &ct.columns {
7835 if !first {
7836 self.write(", ");
7837 }
7838 first = false;
7839 self.generate_column_def(col)?;
7840 }
7841 for constraint in &ct.constraints {
7842 if !first {
7843 self.write(", ");
7844 }
7845 first = false;
7846 self.generate_table_constraint(constraint)?;
7847 }
7848 self.write(")");
7849 }
7850
7851 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7853 self.write_space();
7854 self.write_keyword("FOR VALUES");
7855 self.write_space();
7856 self.generate_expression(&pop.expression)?;
7857 } else {
7858 self.write_space();
7859 self.write_keyword("DEFAULT");
7860 }
7861 } else {
7862 self.generate_expression(partition_of)?;
7864
7865 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7867 self.write(" (");
7868 let mut first = true;
7869 for col in &ct.columns {
7870 if !first {
7871 self.write(", ");
7872 }
7873 first = false;
7874 self.generate_column_def(col)?;
7875 }
7876 for constraint in &ct.constraints {
7877 if !first {
7878 self.write(", ");
7879 }
7880 first = false;
7881 self.generate_table_constraint(constraint)?;
7882 }
7883 self.write(")");
7884 }
7885 }
7886
7887 for prop in &ct.properties {
7889 self.write_space();
7890 self.generate_expression(prop)?;
7891 }
7892
7893 return Ok(());
7894 }
7895
7896 self.sqlite_inline_pk_columns.clear();
7899 if matches!(
7900 self.config.dialect,
7901 Some(crate::dialects::DialectType::SQLite)
7902 ) {
7903 for constraint in &ct.constraints {
7904 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7905 if columns.len() == 1 && name.is_none() {
7907 let pk_col_name = columns[0].name.to_ascii_lowercase();
7908 if ct
7910 .columns
7911 .iter()
7912 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
7913 {
7914 self.sqlite_inline_pk_columns.insert(pk_col_name);
7915 }
7916 }
7917 }
7918 }
7919 }
7920
7921 if !ct.columns.is_empty() {
7923 if self.config.pretty {
7924 self.write(" (");
7926 self.write_newline();
7927 self.indent_level += 1;
7928 for (i, col) in ct.columns.iter().enumerate() {
7929 if i > 0 {
7930 self.write(",");
7931 self.write_newline();
7932 }
7933 self.write_indent();
7934 self.generate_column_def(col)?;
7935 }
7936 for constraint in &ct.constraints {
7938 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7940 if columns.len() == 1
7941 && name.is_none()
7942 && self
7943 .sqlite_inline_pk_columns
7944 .contains(&columns[0].name.to_ascii_lowercase())
7945 {
7946 continue;
7947 }
7948 }
7949 self.write(",");
7950 self.write_newline();
7951 self.write_indent();
7952 self.generate_table_constraint(constraint)?;
7953 }
7954 self.indent_level -= 1;
7955 self.write_newline();
7956 self.write(")");
7957 } else {
7958 self.write(" (");
7959 for (i, col) in ct.columns.iter().enumerate() {
7960 if i > 0 {
7961 self.write(", ");
7962 }
7963 self.generate_column_def(col)?;
7964 }
7965 let mut first_constraint = true;
7967 for constraint in &ct.constraints {
7968 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7970 if columns.len() == 1
7971 && name.is_none()
7972 && self
7973 .sqlite_inline_pk_columns
7974 .contains(&columns[0].name.to_ascii_lowercase())
7975 {
7976 continue;
7977 }
7978 }
7979 if first_constraint {
7980 self.write(", ");
7981 first_constraint = false;
7982 } else {
7983 self.write(", ");
7984 }
7985 self.generate_table_constraint(constraint)?;
7986 }
7987 self.write(")");
7988 }
7989 } else if !ct.constraints.is_empty() {
7990 let has_like_only = ct
7992 .constraints
7993 .iter()
7994 .all(|c| matches!(c, TableConstraint::Like { .. }));
7995 let has_tags_only = ct
7996 .constraints
7997 .iter()
7998 .all(|c| matches!(c, TableConstraint::Tags(_)));
7999 let is_pg_like = matches!(
8003 self.config.dialect,
8004 Some(crate::dialects::DialectType::PostgreSQL)
8005 | Some(crate::dialects::DialectType::CockroachDB)
8006 | Some(crate::dialects::DialectType::Materialize)
8007 | Some(crate::dialects::DialectType::RisingWave)
8008 | Some(crate::dialects::DialectType::Redshift)
8009 | Some(crate::dialects::DialectType::Presto)
8010 | Some(crate::dialects::DialectType::Trino)
8011 | Some(crate::dialects::DialectType::Athena)
8012 );
8013 let use_parens = if has_like_only {
8014 is_pg_like
8015 } else {
8016 !has_tags_only
8017 };
8018 if self.config.pretty && use_parens {
8019 self.write(" (");
8020 self.write_newline();
8021 self.indent_level += 1;
8022 for (i, constraint) in ct.constraints.iter().enumerate() {
8023 if i > 0 {
8024 self.write(",");
8025 self.write_newline();
8026 }
8027 self.write_indent();
8028 self.generate_table_constraint(constraint)?;
8029 }
8030 self.indent_level -= 1;
8031 self.write_newline();
8032 self.write(")");
8033 } else {
8034 if use_parens {
8035 self.write(" (");
8036 } else {
8037 self.write_space();
8038 }
8039 for (i, constraint) in ct.constraints.iter().enumerate() {
8040 if i > 0 {
8041 self.write(", ");
8042 }
8043 self.generate_table_constraint(constraint)?;
8044 }
8045 if use_parens {
8046 self.write(")");
8047 }
8048 }
8049 }
8050
8051 if let Some(ref on_prop) = ct.on_property {
8053 self.write(" ");
8054 self.write_keyword("ON");
8055 self.write(" ");
8056 self.generate_expression(&on_prop.this)?;
8057 }
8058
8059 if !ct.with_partition_columns.is_empty() {
8061 if self.config.pretty {
8062 self.write_newline();
8063 } else {
8064 self.write_space();
8065 }
8066 self.write_keyword("WITH PARTITION COLUMNS");
8067 self.write(" (");
8068 if self.config.pretty {
8069 self.write_newline();
8070 self.indent_level += 1;
8071 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8072 if i > 0 {
8073 self.write(",");
8074 self.write_newline();
8075 }
8076 self.write_indent();
8077 self.generate_column_def(col)?;
8078 }
8079 self.indent_level -= 1;
8080 self.write_newline();
8081 } else {
8082 for (i, col) in ct.with_partition_columns.iter().enumerate() {
8083 if i > 0 {
8084 self.write(", ");
8085 }
8086 self.generate_column_def(col)?;
8087 }
8088 }
8089 self.write(")");
8090 }
8091
8092 if let Some(ref conn) = ct.with_connection {
8094 if self.config.pretty {
8095 self.write_newline();
8096 } else {
8097 self.write_space();
8098 }
8099 self.write_keyword("WITH CONNECTION");
8100 self.write_space();
8101 self.generate_table(conn)?;
8102 }
8103
8104 if !is_clickhouse {
8107 for prop in &ct.properties {
8108 if let Expression::SchemaCommentProperty(_) = prop {
8109 if self.config.pretty {
8110 self.write_newline();
8111 } else {
8112 self.write_space();
8113 }
8114 self.generate_expression(prop)?;
8115 }
8116 }
8117 }
8118
8119 if !ct.with_properties.is_empty() {
8121 let is_snowflake_special_table = matches!(
8123 self.config.dialect,
8124 Some(crate::dialects::DialectType::Snowflake)
8125 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
8126 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
8127 if is_snowflake_special_table {
8128 for (key, value) in &ct.with_properties {
8129 self.write_space();
8130 self.write(key);
8131 self.write("=");
8132 self.write(value);
8133 }
8134 } else if self.config.pretty {
8135 self.write_newline();
8136 self.write_keyword("WITH");
8137 self.write(" (");
8138 self.write_newline();
8139 self.indent_level += 1;
8140 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8141 if i > 0 {
8142 self.write(",");
8143 self.write_newline();
8144 }
8145 self.write_indent();
8146 self.write(key);
8147 self.write("=");
8148 self.write(value);
8149 }
8150 self.indent_level -= 1;
8151 self.write_newline();
8152 self.write(")");
8153 } else {
8154 self.write_space();
8155 self.write_keyword("WITH");
8156 self.write(" (");
8157 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
8158 if i > 0 {
8159 self.write(", ");
8160 }
8161 self.write(key);
8162 self.write("=");
8163 self.write(value);
8164 }
8165 self.write(")");
8166 }
8167 }
8168
8169 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
8170 if is_clickhouse && ct.as_select.is_some() {
8171 let mut pre = Vec::new();
8172 let mut post = Vec::new();
8173 for prop in &ct.properties {
8174 if matches!(prop, Expression::SchemaCommentProperty(_)) {
8175 post.push(prop);
8176 } else {
8177 pre.push(prop);
8178 }
8179 }
8180 (pre, post)
8181 } else {
8182 (ct.properties.iter().collect(), Vec::new())
8183 };
8184
8185 for prop in pre_as_properties {
8187 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8189 continue;
8190 }
8191 if self.config.pretty {
8192 self.write_newline();
8193 } else {
8194 self.write_space();
8195 }
8196 if let Expression::Properties(props) = prop {
8200 let is_hive_dialect = matches!(
8201 self.config.dialect,
8202 Some(crate::dialects::DialectType::Hive)
8203 | Some(crate::dialects::DialectType::Spark)
8204 | Some(crate::dialects::DialectType::Databricks)
8205 | Some(crate::dialects::DialectType::Athena)
8206 );
8207 let is_doris_starrocks = matches!(
8208 self.config.dialect,
8209 Some(crate::dialects::DialectType::Doris)
8210 | Some(crate::dialects::DialectType::StarRocks)
8211 );
8212 if is_hive_dialect {
8213 self.generate_tblproperties_clause(&props.expressions)?;
8214 } else if is_doris_starrocks {
8215 self.generate_properties_clause(&props.expressions)?;
8216 } else {
8217 self.generate_options_clause(&props.expressions)?;
8218 }
8219 } else {
8220 self.generate_expression(prop)?;
8221 }
8222 }
8223
8224 for prop in &ct.post_table_properties {
8226 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
8227 self.write(" WITH(");
8228 self.generate_system_versioning_content(svp)?;
8229 self.write(")");
8230 } else if let Expression::Properties(props) = prop {
8231 let is_doris_starrocks = matches!(
8233 self.config.dialect,
8234 Some(crate::dialects::DialectType::Doris)
8235 | Some(crate::dialects::DialectType::StarRocks)
8236 );
8237 self.write_space();
8238 if is_doris_starrocks {
8239 self.generate_properties_clause(&props.expressions)?;
8240 } else {
8241 self.generate_options_clause(&props.expressions)?;
8242 }
8243 } else {
8244 self.write_space();
8245 self.generate_expression(prop)?;
8246 }
8247 }
8248
8249 if let Some(ref rollup) = ct.rollup {
8252 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
8253 self.write_space();
8254 self.generate_rollup_property(rollup)?;
8255 }
8256 }
8257
8258 let is_mysql_compatible = matches!(
8262 self.config.dialect,
8263 Some(DialectType::MySQL)
8264 | Some(DialectType::SingleStore)
8265 | Some(DialectType::Doris)
8266 | Some(DialectType::StarRocks)
8267 | None
8268 );
8269 let is_hive_compatible = matches!(
8270 self.config.dialect,
8271 Some(DialectType::Hive)
8272 | Some(DialectType::Spark)
8273 | Some(DialectType::Databricks)
8274 | Some(DialectType::Athena)
8275 );
8276 let mysql_pretty_options =
8277 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
8278 for (key, value) in &ct.mysql_table_options {
8279 let should_output = if is_mysql_compatible {
8281 true
8282 } else if is_hive_compatible && key == "COMMENT" {
8283 true } else {
8285 false
8286 };
8287 if should_output {
8288 if mysql_pretty_options {
8289 self.write_newline();
8290 self.write_indent();
8291 } else {
8292 self.write_space();
8293 }
8294 self.write_keyword(key);
8295 if key == "COMMENT" && !self.config.schema_comment_with_eq {
8297 self.write_space();
8298 } else {
8299 self.write("=");
8300 }
8301 self.write(value);
8302 }
8303 }
8304
8305 if ct.temporary
8307 && matches!(
8308 self.config.dialect,
8309 Some(DialectType::Spark) | Some(DialectType::Databricks)
8310 )
8311 && ct.as_select.is_none()
8312 {
8313 self.write_space();
8314 self.write_keyword("USING PARQUET");
8315 }
8316
8317 if !ct.inherits.is_empty() {
8319 self.write_space();
8320 self.write_keyword("INHERITS");
8321 self.write(" (");
8322 for (i, parent) in ct.inherits.iter().enumerate() {
8323 if i > 0 {
8324 self.write(", ");
8325 }
8326 self.generate_table(parent)?;
8327 }
8328 self.write(")");
8329 }
8330
8331 if let Some(ref query) = ct.as_select {
8333 self.write_space();
8334 self.write_keyword("AS");
8335 self.write_space();
8336 let source_is_clickhouse =
8337 matches!(self.config.source_dialect, Some(DialectType::ClickHouse));
8338 let wrap_as_select =
8339 ct.as_select_parenthesized && !(is_clickhouse && source_is_clickhouse);
8340 if wrap_as_select {
8341 self.write("(");
8342 }
8343 self.generate_expression(query)?;
8344 if wrap_as_select {
8345 self.write(")");
8346 }
8347
8348 if let Some(with_data) = ct.with_data {
8350 self.write_space();
8351 self.write_keyword("WITH");
8352 if !with_data {
8353 self.write_space();
8354 self.write_keyword("NO");
8355 }
8356 self.write_space();
8357 self.write_keyword("DATA");
8358 }
8359
8360 if let Some(with_statistics) = ct.with_statistics {
8362 self.write_space();
8363 self.write_keyword("AND");
8364 if !with_statistics {
8365 self.write_space();
8366 self.write_keyword("NO");
8367 }
8368 self.write_space();
8369 self.write_keyword("STATISTICS");
8370 }
8371
8372 for index in &ct.teradata_indexes {
8374 self.write_space();
8375 match index.kind {
8376 TeradataIndexKind::NoPrimary => {
8377 self.write_keyword("NO PRIMARY INDEX");
8378 }
8379 TeradataIndexKind::Primary => {
8380 self.write_keyword("PRIMARY INDEX");
8381 }
8382 TeradataIndexKind::PrimaryAmp => {
8383 self.write_keyword("PRIMARY AMP INDEX");
8384 }
8385 TeradataIndexKind::Unique => {
8386 self.write_keyword("UNIQUE INDEX");
8387 }
8388 TeradataIndexKind::UniquePrimary => {
8389 self.write_keyword("UNIQUE PRIMARY INDEX");
8390 }
8391 TeradataIndexKind::Secondary => {
8392 self.write_keyword("INDEX");
8393 }
8394 }
8395 if let Some(ref name) = index.name {
8397 self.write_space();
8398 self.write(name);
8399 }
8400 if !index.columns.is_empty() {
8402 self.write(" (");
8403 for (i, col) in index.columns.iter().enumerate() {
8404 if i > 0 {
8405 self.write(", ");
8406 }
8407 self.write(col);
8408 }
8409 self.write(")");
8410 }
8411 }
8412
8413 if let Some(ref on_commit) = ct.on_commit {
8415 self.write_space();
8416 self.write_keyword("ON COMMIT");
8417 self.write_space();
8418 match on_commit {
8419 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8420 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8421 }
8422 }
8423
8424 if !post_as_properties.is_empty() {
8425 for prop in post_as_properties {
8426 self.write_space();
8427 self.generate_expression(prop)?;
8428 }
8429 }
8430
8431 self.athena_hive_context = saved_athena_hive_context;
8433 return Ok(());
8434 }
8435
8436 if let Some(ref on_commit) = ct.on_commit {
8438 self.write_space();
8439 self.write_keyword("ON COMMIT");
8440 self.write_space();
8441 match on_commit {
8442 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8443 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8444 }
8445 }
8446
8447 self.athena_hive_context = saved_athena_hive_context;
8449
8450 Ok(())
8451 }
8452
8453 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8456 self.generate_identifier(&col.name)?;
8458 if !matches!(col.data_type, DataType::Unknown) {
8460 self.write_space();
8461 self.generate_data_type(&col.data_type)?;
8462 }
8463 for constraint in &col.constraints {
8465 if let ColumnConstraint::Path(path_expr) = constraint {
8466 self.write_space();
8467 self.write_keyword("PATH");
8468 self.write_space();
8469 self.generate_expression(path_expr)?;
8470 }
8471 }
8472 Ok(())
8473 }
8474
8475 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8476 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8478 && col
8479 .constraints
8480 .iter()
8481 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8482 let omit_computed_type = !self.config.computed_column_with_type
8484 && col
8485 .constraints
8486 .iter()
8487 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8488
8489 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8492
8493 let has_no_type = col.no_type
8496 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8497 && col.constraints.is_empty());
8498
8499 self.generate_identifier(&col.name)?;
8500
8501 let serial_expansion = if matches!(
8503 self.config.dialect,
8504 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
8505 ) {
8506 if let DataType::Custom { ref name } = col.data_type {
8507 if name.eq_ignore_ascii_case("SERIAL") {
8508 Some("INT")
8509 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
8510 Some("BIGINT")
8511 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
8512 Some("SMALLINT")
8513 } else {
8514 None
8515 }
8516 } else {
8517 None
8518 }
8519 } else {
8520 None
8521 };
8522
8523 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
8524 {
8525 self.write_space();
8526 let saved_nullable_depth = self.clickhouse_nullable_depth;
8529 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
8530 self.clickhouse_nullable_depth = -1;
8531 }
8532 if let Some(int_type) = serial_expansion {
8533 self.write_keyword(int_type);
8535 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8536 let unsigned_type = match &col.data_type {
8538 DataType::Int { .. } => Some("UINTEGER"),
8539 DataType::BigInt { .. } => Some("UBIGINT"),
8540 DataType::SmallInt { .. } => Some("USMALLINT"),
8541 DataType::TinyInt { .. } => Some("UTINYINT"),
8542 _ => None,
8543 };
8544 if let Some(utype) = unsigned_type {
8545 self.write_keyword(utype);
8546 } else {
8547 self.generate_data_type(&col.data_type)?;
8548 }
8549 } else {
8550 self.generate_data_type(&col.data_type)?;
8551 }
8552 self.clickhouse_nullable_depth = saved_nullable_depth;
8553 }
8554
8555 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8558 self.write_space();
8559 self.write_keyword("UNSIGNED");
8560 }
8561 if col.zerofill {
8562 self.write_space();
8563 self.write_keyword("ZEROFILL");
8564 }
8565
8566 if let Some(ref charset) = col.character_set {
8570 self.write_space();
8571 self.write_keyword("CHARACTER SET");
8572 self.write_space();
8573 self.write(charset);
8574 }
8575
8576 if col.uppercase {
8577 self.write_space();
8578 self.write_keyword("UPPERCASE");
8579 }
8580
8581 if let Some(casespecific) = col.casespecific {
8582 self.write_space();
8583 if casespecific {
8584 self.write_keyword("CASESPECIFIC");
8585 } else {
8586 self.write_keyword("NOT CASESPECIFIC");
8587 }
8588 }
8589
8590 if let Some(ref format) = col.format {
8591 self.write_space();
8592 self.write_keyword("FORMAT");
8593 self.write(" '");
8594 self.write(format);
8595 self.write("'");
8596 }
8597
8598 if let Some(ref title) = col.title {
8599 self.write_space();
8600 self.write_keyword("TITLE");
8601 self.write(" '");
8602 self.write(title);
8603 self.write("'");
8604 }
8605
8606 if let Some(length) = col.inline_length {
8607 self.write_space();
8608 self.write_keyword("INLINE LENGTH");
8609 self.write(" ");
8610 self.write(&length.to_string());
8611 }
8612
8613 if let Some(ref compress) = col.compress {
8614 self.write_space();
8615 self.write_keyword("COMPRESS");
8616 if !compress.is_empty() {
8617 if compress.len() == 1 {
8619 if let Expression::Literal(lit) = &compress[0] {
8620 if let Literal::String(_) = lit.as_ref() {
8621 self.write_space();
8622 self.generate_expression(&compress[0])?;
8623 }
8624 } else {
8625 self.write(" (");
8626 self.generate_expression(&compress[0])?;
8627 self.write(")");
8628 }
8629 } else {
8630 self.write(" (");
8631 for (i, val) in compress.iter().enumerate() {
8632 if i > 0 {
8633 self.write(", ");
8634 }
8635 self.generate_expression(val)?;
8636 }
8637 self.write(")");
8638 }
8639 }
8640 }
8641
8642 if !col.constraint_order.is_empty() {
8645 let mut references_idx = 0;
8648 let mut check_idx = 0;
8649 let mut generated_idx = 0;
8650 let mut collate_idx = 0;
8651 let mut comment_idx = 0;
8652 let defer_not_null_after_identity = false;
8655 let mut pending_not_null_after_identity = false;
8656
8657 for constraint_type in &col.constraint_order {
8658 match constraint_type {
8659 ConstraintType::PrimaryKey => {
8660 if col.primary_key
8662 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8663 {
8664 if let Some(ref cname) = col.primary_key_constraint_name {
8665 self.write_space();
8666 self.write_keyword("CONSTRAINT");
8667 self.write_space();
8668 self.write(cname);
8669 }
8670 self.write_space();
8671 self.write_keyword("PRIMARY KEY");
8672 if let Some(ref order) = col.primary_key_order {
8673 self.write_space();
8674 match order {
8675 SortOrder::Asc => self.write_keyword("ASC"),
8676 SortOrder::Desc => self.write_keyword("DESC"),
8677 }
8678 }
8679 }
8680 }
8681 ConstraintType::Unique => {
8682 if col.unique {
8683 if let Some(ref cname) = col.unique_constraint_name {
8684 self.write_space();
8685 self.write_keyword("CONSTRAINT");
8686 self.write_space();
8687 self.write(cname);
8688 }
8689 self.write_space();
8690 self.write_keyword("UNIQUE");
8691 if col.unique_nulls_not_distinct {
8693 self.write(" NULLS NOT DISTINCT");
8694 }
8695 }
8696 }
8697 ConstraintType::NotNull => {
8698 if col.nullable == Some(false) {
8699 if defer_not_null_after_identity {
8700 pending_not_null_after_identity = true;
8701 continue;
8702 }
8703 if let Some(ref cname) = col.not_null_constraint_name {
8704 self.write_space();
8705 self.write_keyword("CONSTRAINT");
8706 self.write_space();
8707 self.write(cname);
8708 }
8709 self.write_space();
8710 self.write_keyword("NOT NULL");
8711 }
8712 }
8713 ConstraintType::Null => {
8714 if col.nullable == Some(true) {
8715 self.write_space();
8716 self.write_keyword("NULL");
8717 }
8718 }
8719 ConstraintType::Default => {
8720 if let Some(ref default) = col.default {
8721 self.write_space();
8722 self.write_keyword("DEFAULT");
8723 self.write_space();
8724 self.generate_expression(default)?;
8725 }
8726 }
8727 ConstraintType::AutoIncrement => {
8728 if col.auto_increment {
8729 if matches!(
8731 self.config.dialect,
8732 Some(crate::dialects::DialectType::DuckDB)
8733 ) {
8734 } else if matches!(
8736 self.config.dialect,
8737 Some(crate::dialects::DialectType::Materialize)
8738 ) {
8739 if !matches!(col.nullable, Some(false)) {
8741 self.write_space();
8742 self.write_keyword("NOT NULL");
8743 }
8744 } else if matches!(
8745 self.config.dialect,
8746 Some(crate::dialects::DialectType::PostgreSQL)
8747 ) {
8748 self.write_space();
8750 self.generate_auto_increment_keyword(col)?;
8751 } else {
8752 self.write_space();
8753 self.generate_auto_increment_keyword(col)?;
8754 if pending_not_null_after_identity {
8755 self.write_space();
8756 self.write_keyword("NOT NULL");
8757 pending_not_null_after_identity = false;
8758 }
8759 }
8760 } }
8762 ConstraintType::References => {
8763 while references_idx < col.constraints.len() {
8765 if let ColumnConstraint::References(fk_ref) =
8766 &col.constraints[references_idx]
8767 {
8768 if let Some(ref name) = fk_ref.constraint_name {
8770 self.write_space();
8771 self.write_keyword("CONSTRAINT");
8772 self.write_space();
8773 self.write(name);
8774 }
8775 self.write_space();
8776 if fk_ref.has_foreign_key_keywords {
8777 self.write_keyword("FOREIGN KEY");
8778 self.write_space();
8779 }
8780 self.write_keyword("REFERENCES");
8781 self.write_space();
8782 self.generate_table(&fk_ref.table)?;
8783 if !fk_ref.columns.is_empty() {
8784 self.write(" (");
8785 for (i, c) in fk_ref.columns.iter().enumerate() {
8786 if i > 0 {
8787 self.write(", ");
8788 }
8789 self.generate_identifier(c)?;
8790 }
8791 self.write(")");
8792 }
8793 self.generate_referential_actions(fk_ref)?;
8794 references_idx += 1;
8795 break;
8796 }
8797 references_idx += 1;
8798 }
8799 }
8800 ConstraintType::Check => {
8801 while check_idx < col.constraints.len() {
8803 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8804 if check_idx == 0 {
8806 if let Some(ref cname) = col.check_constraint_name {
8807 self.write_space();
8808 self.write_keyword("CONSTRAINT");
8809 self.write_space();
8810 self.write(cname);
8811 }
8812 }
8813 self.write_space();
8814 self.write_keyword("CHECK");
8815 self.write(" (");
8816 self.generate_expression(expr)?;
8817 self.write(")");
8818 check_idx += 1;
8819 break;
8820 }
8821 check_idx += 1;
8822 }
8823 }
8824 ConstraintType::GeneratedAsIdentity => {
8825 while generated_idx < col.constraints.len() {
8827 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8828 &col.constraints[generated_idx]
8829 {
8830 self.write_space();
8831 if matches!(
8833 self.config.dialect,
8834 Some(crate::dialects::DialectType::Redshift)
8835 ) {
8836 self.write_keyword("IDENTITY");
8837 self.write("(");
8838 if let Some(ref start) = gen.start {
8839 self.generate_expression(start)?;
8840 } else {
8841 self.write("0");
8842 }
8843 self.write(", ");
8844 if let Some(ref incr) = gen.increment {
8845 self.generate_expression(incr)?;
8846 } else {
8847 self.write("1");
8848 }
8849 self.write(")");
8850 } else {
8851 self.write_keyword("GENERATED");
8852 if gen.always {
8853 self.write_space();
8854 self.write_keyword("ALWAYS");
8855 } else {
8856 self.write_space();
8857 self.write_keyword("BY DEFAULT");
8858 if gen.on_null {
8859 self.write_space();
8860 self.write_keyword("ON NULL");
8861 }
8862 }
8863 self.write_space();
8864 self.write_keyword("AS IDENTITY");
8865
8866 let has_options = gen.start.is_some()
8867 || gen.increment.is_some()
8868 || gen.minvalue.is_some()
8869 || gen.maxvalue.is_some()
8870 || gen.cycle.is_some();
8871 if has_options {
8872 self.write(" (");
8873 let mut first = true;
8874 if let Some(ref start) = gen.start {
8875 if !first {
8876 self.write(" ");
8877 }
8878 first = false;
8879 self.write_keyword("START WITH");
8880 self.write_space();
8881 self.generate_expression(start)?;
8882 }
8883 if let Some(ref incr) = gen.increment {
8884 if !first {
8885 self.write(" ");
8886 }
8887 first = false;
8888 self.write_keyword("INCREMENT BY");
8889 self.write_space();
8890 self.generate_expression(incr)?;
8891 }
8892 if let Some(ref minv) = gen.minvalue {
8893 if !first {
8894 self.write(" ");
8895 }
8896 first = false;
8897 self.write_keyword("MINVALUE");
8898 self.write_space();
8899 self.generate_expression(minv)?;
8900 }
8901 if let Some(ref maxv) = gen.maxvalue {
8902 if !first {
8903 self.write(" ");
8904 }
8905 first = false;
8906 self.write_keyword("MAXVALUE");
8907 self.write_space();
8908 self.generate_expression(maxv)?;
8909 }
8910 if let Some(cycle) = gen.cycle {
8911 if !first {
8912 self.write(" ");
8913 }
8914 if cycle {
8915 self.write_keyword("CYCLE");
8916 } else {
8917 self.write_keyword("NO CYCLE");
8918 }
8919 }
8920 self.write(")");
8921 }
8922 }
8923 generated_idx += 1;
8924 break;
8925 }
8926 generated_idx += 1;
8927 }
8928 }
8929 ConstraintType::Collate => {
8930 while collate_idx < col.constraints.len() {
8932 if let ColumnConstraint::Collate(collation) =
8933 &col.constraints[collate_idx]
8934 {
8935 self.write_space();
8936 self.write_keyword("COLLATE");
8937 self.write_space();
8938 self.generate_identifier(collation)?;
8939 collate_idx += 1;
8940 break;
8941 }
8942 collate_idx += 1;
8943 }
8944 }
8945 ConstraintType::Comment => {
8946 while comment_idx < col.constraints.len() {
8948 if let ColumnConstraint::Comment(comment) =
8949 &col.constraints[comment_idx]
8950 {
8951 self.write_space();
8952 self.write_keyword("COMMENT");
8953 self.write_space();
8954 self.generate_string_literal(comment)?;
8955 comment_idx += 1;
8956 break;
8957 }
8958 comment_idx += 1;
8959 }
8960 }
8961 ConstraintType::Tags => {
8962 for constraint in &col.constraints {
8964 if let ColumnConstraint::Tags(tags) = constraint {
8965 self.write_space();
8966 self.write_keyword("TAG");
8967 self.write(" (");
8968 for (i, expr) in tags.expressions.iter().enumerate() {
8969 if i > 0 {
8970 self.write(", ");
8971 }
8972 self.generate_expression(expr)?;
8973 }
8974 self.write(")");
8975 break;
8976 }
8977 }
8978 }
8979 ConstraintType::ComputedColumn => {
8980 for constraint in &col.constraints {
8982 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8983 self.write_space();
8984 self.generate_computed_column_inline(cc)?;
8985 break;
8986 }
8987 }
8988 }
8989 ConstraintType::GeneratedAsRow => {
8990 for constraint in &col.constraints {
8992 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8993 self.write_space();
8994 self.generate_generated_as_row_inline(gar)?;
8995 break;
8996 }
8997 }
8998 }
8999 ConstraintType::OnUpdate => {
9000 if let Some(ref expr) = col.on_update {
9001 self.write_space();
9002 self.write_keyword("ON UPDATE");
9003 self.write_space();
9004 self.generate_expression(expr)?;
9005 }
9006 }
9007 ConstraintType::Encode => {
9008 if let Some(ref encoding) = col.encoding {
9009 self.write_space();
9010 self.write_keyword("ENCODE");
9011 self.write_space();
9012 self.write(encoding);
9013 }
9014 }
9015 ConstraintType::Path => {
9016 for constraint in &col.constraints {
9018 if let ColumnConstraint::Path(path_expr) = constraint {
9019 self.write_space();
9020 self.write_keyword("PATH");
9021 self.write_space();
9022 self.generate_expression(path_expr)?;
9023 break;
9024 }
9025 }
9026 }
9027 }
9028 }
9029 if pending_not_null_after_identity {
9030 self.write_space();
9031 self.write_keyword("NOT NULL");
9032 }
9033 } else {
9034 if col.primary_key {
9036 self.write_space();
9037 self.write_keyword("PRIMARY KEY");
9038 if let Some(ref order) = col.primary_key_order {
9039 self.write_space();
9040 match order {
9041 SortOrder::Asc => self.write_keyword("ASC"),
9042 SortOrder::Desc => self.write_keyword("DESC"),
9043 }
9044 }
9045 }
9046
9047 if col.unique {
9048 self.write_space();
9049 self.write_keyword("UNIQUE");
9050 if col.unique_nulls_not_distinct {
9052 self.write(" NULLS NOT DISTINCT");
9053 }
9054 }
9055
9056 match col.nullable {
9057 Some(false) => {
9058 self.write_space();
9059 self.write_keyword("NOT NULL");
9060 }
9061 Some(true) => {
9062 self.write_space();
9063 self.write_keyword("NULL");
9064 }
9065 None => {}
9066 }
9067
9068 if let Some(ref default) = col.default {
9069 self.write_space();
9070 self.write_keyword("DEFAULT");
9071 self.write_space();
9072 self.generate_expression(default)?;
9073 }
9074
9075 if col.auto_increment {
9076 self.write_space();
9077 self.generate_auto_increment_keyword(col)?;
9078 }
9079
9080 for constraint in &col.constraints {
9082 match constraint {
9083 ColumnConstraint::References(fk_ref) => {
9084 self.write_space();
9085 if fk_ref.has_foreign_key_keywords {
9086 self.write_keyword("FOREIGN KEY");
9087 self.write_space();
9088 }
9089 self.write_keyword("REFERENCES");
9090 self.write_space();
9091 self.generate_table(&fk_ref.table)?;
9092 if !fk_ref.columns.is_empty() {
9093 self.write(" (");
9094 for (i, c) in fk_ref.columns.iter().enumerate() {
9095 if i > 0 {
9096 self.write(", ");
9097 }
9098 self.generate_identifier(c)?;
9099 }
9100 self.write(")");
9101 }
9102 self.generate_referential_actions(fk_ref)?;
9103 }
9104 ColumnConstraint::Check(expr) => {
9105 self.write_space();
9106 self.write_keyword("CHECK");
9107 self.write(" (");
9108 self.generate_expression(expr)?;
9109 self.write(")");
9110 }
9111 ColumnConstraint::GeneratedAsIdentity(gen) => {
9112 self.write_space();
9113 if matches!(
9115 self.config.dialect,
9116 Some(crate::dialects::DialectType::Redshift)
9117 ) {
9118 self.write_keyword("IDENTITY");
9119 self.write("(");
9120 if let Some(ref start) = gen.start {
9121 self.generate_expression(start)?;
9122 } else {
9123 self.write("0");
9124 }
9125 self.write(", ");
9126 if let Some(ref incr) = gen.increment {
9127 self.generate_expression(incr)?;
9128 } else {
9129 self.write("1");
9130 }
9131 self.write(")");
9132 } else {
9133 self.write_keyword("GENERATED");
9134 if gen.always {
9135 self.write_space();
9136 self.write_keyword("ALWAYS");
9137 } else {
9138 self.write_space();
9139 self.write_keyword("BY DEFAULT");
9140 if gen.on_null {
9141 self.write_space();
9142 self.write_keyword("ON NULL");
9143 }
9144 }
9145 self.write_space();
9146 self.write_keyword("AS IDENTITY");
9147
9148 let has_options = gen.start.is_some()
9149 || gen.increment.is_some()
9150 || gen.minvalue.is_some()
9151 || gen.maxvalue.is_some()
9152 || gen.cycle.is_some();
9153 if has_options {
9154 self.write(" (");
9155 let mut first = true;
9156 if let Some(ref start) = gen.start {
9157 if !first {
9158 self.write(" ");
9159 }
9160 first = false;
9161 self.write_keyword("START WITH");
9162 self.write_space();
9163 self.generate_expression(start)?;
9164 }
9165 if let Some(ref incr) = gen.increment {
9166 if !first {
9167 self.write(" ");
9168 }
9169 first = false;
9170 self.write_keyword("INCREMENT BY");
9171 self.write_space();
9172 self.generate_expression(incr)?;
9173 }
9174 if let Some(ref minv) = gen.minvalue {
9175 if !first {
9176 self.write(" ");
9177 }
9178 first = false;
9179 self.write_keyword("MINVALUE");
9180 self.write_space();
9181 self.generate_expression(minv)?;
9182 }
9183 if let Some(ref maxv) = gen.maxvalue {
9184 if !first {
9185 self.write(" ");
9186 }
9187 first = false;
9188 self.write_keyword("MAXVALUE");
9189 self.write_space();
9190 self.generate_expression(maxv)?;
9191 }
9192 if let Some(cycle) = gen.cycle {
9193 if !first {
9194 self.write(" ");
9195 }
9196 if cycle {
9197 self.write_keyword("CYCLE");
9198 } else {
9199 self.write_keyword("NO CYCLE");
9200 }
9201 }
9202 self.write(")");
9203 }
9204 }
9205 }
9206 ColumnConstraint::Collate(collation) => {
9207 self.write_space();
9208 self.write_keyword("COLLATE");
9209 self.write_space();
9210 self.generate_identifier(collation)?;
9211 }
9212 ColumnConstraint::Comment(comment) => {
9213 self.write_space();
9214 self.write_keyword("COMMENT");
9215 self.write_space();
9216 self.generate_string_literal(comment)?;
9217 }
9218 ColumnConstraint::Path(path_expr) => {
9219 self.write_space();
9220 self.write_keyword("PATH");
9221 self.write_space();
9222 self.generate_expression(path_expr)?;
9223 }
9224 _ => {} }
9226 }
9227
9228 if let Some(ref encoding) = col.encoding {
9230 self.write_space();
9231 self.write_keyword("ENCODE");
9232 self.write_space();
9233 self.write(encoding);
9234 }
9235 }
9236
9237 if let Some(ref codec) = col.codec {
9239 self.write_space();
9240 self.write_keyword("CODEC");
9241 self.write("(");
9242 self.write(codec);
9243 self.write(")");
9244 }
9245
9246 if let Some(visible) = col.visible {
9247 self.write_space();
9248 if visible {
9249 self.write_keyword("VISIBLE");
9250 } else {
9251 self.write_keyword("INVISIBLE");
9252 }
9253 }
9254
9255 if let Some(ref ephemeral) = col.ephemeral {
9257 self.write_space();
9258 self.write_keyword("EPHEMERAL");
9259 if let Some(ref expr) = ephemeral {
9260 self.write_space();
9261 self.generate_expression(expr)?;
9262 }
9263 }
9264
9265 if let Some(ref mat_expr) = col.materialized_expr {
9267 self.write_space();
9268 self.write_keyword("MATERIALIZED");
9269 self.write_space();
9270 self.generate_expression(mat_expr)?;
9271 }
9272
9273 if let Some(ref alias_expr) = col.alias_expr {
9275 self.write_space();
9276 self.write_keyword("ALIAS");
9277 self.write_space();
9278 self.generate_expression(alias_expr)?;
9279 }
9280
9281 if let Some(ref ttl_expr) = col.ttl_expr {
9283 self.write_space();
9284 self.write_keyword("TTL");
9285 self.write_space();
9286 self.generate_expression(ttl_expr)?;
9287 }
9288
9289 if col.not_for_replication
9291 && matches!(
9292 self.config.dialect,
9293 Some(crate::dialects::DialectType::TSQL)
9294 | Some(crate::dialects::DialectType::Fabric)
9295 )
9296 {
9297 self.write_space();
9298 self.write_keyword("NOT FOR REPLICATION");
9299 }
9300
9301 if !col.options.is_empty() {
9303 self.write_space();
9304 self.generate_options_clause(&col.options)?;
9305 }
9306
9307 if !col.primary_key
9310 && self
9311 .sqlite_inline_pk_columns
9312 .contains(&col.name.name.to_ascii_lowercase())
9313 {
9314 self.write_space();
9315 self.write_keyword("PRIMARY KEY");
9316 }
9317
9318 if serial_expansion.is_some() {
9321 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
9322 self.write_space();
9323 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
9324 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
9325 self.write_space();
9326 self.write_keyword("NOT NULL");
9327 }
9328 }
9329
9330 Ok(())
9331 }
9332
9333 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
9334 match constraint {
9335 TableConstraint::PrimaryKey {
9336 name,
9337 columns,
9338 include_columns,
9339 modifiers,
9340 has_constraint_keyword,
9341 } => {
9342 if let Some(ref n) = name {
9343 if *has_constraint_keyword {
9344 self.write_keyword("CONSTRAINT");
9345 self.write_space();
9346 self.generate_identifier(n)?;
9347 self.write_space();
9348 }
9349 }
9350 self.write_keyword("PRIMARY KEY");
9351 if let Some(ref clustered) = modifiers.clustered {
9353 self.write_space();
9354 self.write_keyword(clustered);
9355 }
9356 if let Some(ref n) = name {
9358 if !*has_constraint_keyword {
9359 self.write_space();
9360 self.generate_identifier(n)?;
9361 }
9362 }
9363 self.write(" (");
9364 for (i, col) in columns.iter().enumerate() {
9365 if i > 0 {
9366 self.write(", ");
9367 }
9368 self.generate_identifier(col)?;
9369 }
9370 self.write(")");
9371 if !include_columns.is_empty() {
9372 self.write_space();
9373 self.write_keyword("INCLUDE");
9374 self.write(" (");
9375 for (i, col) in include_columns.iter().enumerate() {
9376 if i > 0 {
9377 self.write(", ");
9378 }
9379 self.generate_identifier(col)?;
9380 }
9381 self.write(")");
9382 }
9383 self.generate_constraint_modifiers(modifiers);
9384 }
9385 TableConstraint::Unique {
9386 name,
9387 columns,
9388 columns_parenthesized,
9389 modifiers,
9390 has_constraint_keyword,
9391 nulls_not_distinct,
9392 } => {
9393 if let Some(ref n) = name {
9394 if *has_constraint_keyword {
9395 self.write_keyword("CONSTRAINT");
9396 self.write_space();
9397 self.generate_identifier(n)?;
9398 self.write_space();
9399 }
9400 }
9401 self.write_keyword("UNIQUE");
9402 if let Some(ref clustered) = modifiers.clustered {
9404 self.write_space();
9405 self.write_keyword(clustered);
9406 }
9407 if *nulls_not_distinct {
9409 self.write(" NULLS NOT DISTINCT");
9410 }
9411 if let Some(ref n) = name {
9413 if !*has_constraint_keyword {
9414 self.write_space();
9415 self.generate_identifier(n)?;
9416 }
9417 }
9418 if *columns_parenthesized {
9419 self.write(" (");
9420 for (i, col) in columns.iter().enumerate() {
9421 if i > 0 {
9422 self.write(", ");
9423 }
9424 self.generate_identifier(col)?;
9425 }
9426 self.write(")");
9427 } else {
9428 for col in columns.iter() {
9430 self.write_space();
9431 self.generate_identifier(col)?;
9432 }
9433 }
9434 self.generate_constraint_modifiers(modifiers);
9435 }
9436 TableConstraint::ForeignKey {
9437 name,
9438 columns,
9439 references,
9440 on_delete,
9441 on_update,
9442 modifiers,
9443 } => {
9444 if let Some(ref n) = name {
9445 self.write_keyword("CONSTRAINT");
9446 self.write_space();
9447 self.generate_identifier(n)?;
9448 self.write_space();
9449 }
9450 self.write_keyword("FOREIGN KEY");
9451 self.write(" (");
9452 for (i, col) in columns.iter().enumerate() {
9453 if i > 0 {
9454 self.write(", ");
9455 }
9456 self.generate_identifier(col)?;
9457 }
9458 self.write(")");
9459 if let Some(ref refs) = references {
9460 self.write(" ");
9461 self.write_keyword("REFERENCES");
9462 self.write_space();
9463 self.generate_table(&refs.table)?;
9464 if !refs.columns.is_empty() {
9465 if self.config.pretty {
9466 self.write(" (");
9467 self.write_newline();
9468 self.indent_level += 1;
9469 for (i, col) in refs.columns.iter().enumerate() {
9470 if i > 0 {
9471 self.write(",");
9472 self.write_newline();
9473 }
9474 self.write_indent();
9475 self.generate_identifier(col)?;
9476 }
9477 self.indent_level -= 1;
9478 self.write_newline();
9479 self.write_indent();
9480 self.write(")");
9481 } else {
9482 self.write(" (");
9483 for (i, col) in refs.columns.iter().enumerate() {
9484 if i > 0 {
9485 self.write(", ");
9486 }
9487 self.generate_identifier(col)?;
9488 }
9489 self.write(")");
9490 }
9491 }
9492 self.generate_referential_actions(refs)?;
9493 } else {
9494 if let Some(ref action) = on_delete {
9496 self.write_space();
9497 self.write_keyword("ON DELETE");
9498 self.write_space();
9499 self.generate_referential_action(action);
9500 }
9501 if let Some(ref action) = on_update {
9502 self.write_space();
9503 self.write_keyword("ON UPDATE");
9504 self.write_space();
9505 self.generate_referential_action(action);
9506 }
9507 }
9508 self.generate_constraint_modifiers(modifiers);
9509 }
9510 TableConstraint::Check {
9511 name,
9512 expression,
9513 modifiers,
9514 } => {
9515 if let Some(ref n) = name {
9516 self.write_keyword("CONSTRAINT");
9517 self.write_space();
9518 self.generate_identifier(n)?;
9519 self.write_space();
9520 }
9521 self.write_keyword("CHECK");
9522 self.write(" (");
9523 self.generate_expression(expression)?;
9524 self.write(")");
9525 self.generate_constraint_modifiers(modifiers);
9526 }
9527 TableConstraint::Assume { name, expression } => {
9528 if let Some(ref n) = name {
9529 self.write_keyword("CONSTRAINT");
9530 self.write_space();
9531 self.generate_identifier(n)?;
9532 self.write_space();
9533 }
9534 self.write_keyword("ASSUME");
9535 self.write(" (");
9536 self.generate_expression(expression)?;
9537 self.write(")");
9538 }
9539 TableConstraint::Default {
9540 name,
9541 expression,
9542 column,
9543 } => {
9544 if let Some(ref n) = name {
9545 self.write_keyword("CONSTRAINT");
9546 self.write_space();
9547 self.generate_identifier(n)?;
9548 self.write_space();
9549 }
9550 self.write_keyword("DEFAULT");
9551 self.write_space();
9552 self.generate_expression(expression)?;
9553 self.write_space();
9554 self.write_keyword("FOR");
9555 self.write_space();
9556 self.generate_identifier(column)?;
9557 }
9558 TableConstraint::Index {
9559 name,
9560 columns,
9561 kind,
9562 modifiers,
9563 use_key_keyword,
9564 expression,
9565 index_type,
9566 granularity,
9567 } => {
9568 if expression.is_some() {
9570 self.write_keyword("INDEX");
9571 if let Some(ref n) = name {
9572 self.write_space();
9573 self.generate_identifier(n)?;
9574 }
9575 if let Some(ref expr) = expression {
9576 self.write_space();
9577 self.generate_expression(expr)?;
9578 }
9579 if let Some(ref idx_type) = index_type {
9580 self.write_space();
9581 self.write_keyword("TYPE");
9582 self.write_space();
9583 self.generate_expression(idx_type)?;
9584 }
9585 if let Some(ref gran) = granularity {
9586 self.write_space();
9587 self.write_keyword("GRANULARITY");
9588 self.write_space();
9589 self.generate_expression(gran)?;
9590 }
9591 } else {
9592 use crate::dialects::DialectType;
9596 let index_keyword = if *use_key_keyword
9597 && !matches!(self.config.dialect, Some(DialectType::MySQL))
9598 {
9599 "KEY"
9600 } else {
9601 "INDEX"
9602 };
9603
9604 if let Some(ref k) = kind {
9606 self.write_keyword(k);
9607 if k != "UNIQUE" {
9609 self.write_space();
9610 self.write_keyword(index_keyword);
9611 }
9612 } else {
9613 self.write_keyword(index_keyword);
9614 }
9615
9616 if modifiers.using_before_columns && name.is_none() {
9618 if let Some(ref using) = modifiers.using {
9619 self.write_space();
9620 self.write_keyword("USING");
9621 self.write_space();
9622 self.write_keyword(using);
9623 }
9624 }
9625
9626 if let Some(ref n) = name {
9628 self.write_space();
9629 self.generate_identifier(n)?;
9630 }
9631
9632 if modifiers.using_before_columns && name.is_some() {
9634 if let Some(ref using) = modifiers.using {
9635 self.write_space();
9636 self.write_keyword("USING");
9637 self.write_space();
9638 self.write_keyword(using);
9639 }
9640 }
9641
9642 self.write(" (");
9644 for (i, col) in columns.iter().enumerate() {
9645 if i > 0 {
9646 self.write(", ");
9647 }
9648 self.generate_identifier(col)?;
9649 }
9650 self.write(")");
9651
9652 if !modifiers.using_before_columns {
9654 if let Some(ref using) = modifiers.using {
9655 self.write_space();
9656 self.write_keyword("USING");
9657 self.write_space();
9658 self.write_keyword(using);
9659 }
9660 }
9661
9662 self.generate_constraint_modifiers_without_using(modifiers);
9664 }
9665 }
9666 TableConstraint::Projection { name, expression } => {
9667 self.write_keyword("PROJECTION");
9669 self.write_space();
9670 self.generate_identifier(name)?;
9671 self.write(" (");
9672 self.generate_expression(expression)?;
9673 self.write(")");
9674 }
9675 TableConstraint::Like { source, options } => {
9676 self.write_keyword("LIKE");
9677 self.write_space();
9678 self.generate_table(source)?;
9679 for (action, prop) in options {
9680 self.write_space();
9681 match action {
9682 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9683 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9684 }
9685 self.write_space();
9686 self.write_keyword(prop);
9687 }
9688 }
9689 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9690 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9691 self.write(" (");
9692 self.generate_identifier(start_col)?;
9693 self.write(", ");
9694 self.generate_identifier(end_col)?;
9695 self.write(")");
9696 }
9697 TableConstraint::Exclude {
9698 name,
9699 using,
9700 elements,
9701 include_columns,
9702 where_clause,
9703 with_params,
9704 using_index_tablespace,
9705 modifiers: _,
9706 } => {
9707 if let Some(ref n) = name {
9708 self.write_keyword("CONSTRAINT");
9709 self.write_space();
9710 self.generate_identifier(n)?;
9711 self.write_space();
9712 }
9713 self.write_keyword("EXCLUDE");
9714 if let Some(ref method) = using {
9715 self.write_space();
9716 self.write_keyword("USING");
9717 self.write_space();
9718 self.write(method);
9719 self.write("(");
9720 } else {
9721 self.write(" (");
9722 }
9723 for (i, elem) in elements.iter().enumerate() {
9724 if i > 0 {
9725 self.write(", ");
9726 }
9727 self.write(&elem.expression);
9728 self.write_space();
9729 self.write_keyword("WITH");
9730 self.write_space();
9731 self.write(&elem.operator);
9732 }
9733 self.write(")");
9734 if !include_columns.is_empty() {
9735 self.write_space();
9736 self.write_keyword("INCLUDE");
9737 self.write(" (");
9738 for (i, col) in include_columns.iter().enumerate() {
9739 if i > 0 {
9740 self.write(", ");
9741 }
9742 self.generate_identifier(col)?;
9743 }
9744 self.write(")");
9745 }
9746 if !with_params.is_empty() {
9747 self.write_space();
9748 self.write_keyword("WITH");
9749 self.write(" (");
9750 for (i, (key, val)) in with_params.iter().enumerate() {
9751 if i > 0 {
9752 self.write(", ");
9753 }
9754 self.write(key);
9755 self.write("=");
9756 self.write(val);
9757 }
9758 self.write(")");
9759 }
9760 if let Some(ref tablespace) = using_index_tablespace {
9761 self.write_space();
9762 self.write_keyword("USING INDEX TABLESPACE");
9763 self.write_space();
9764 self.write(tablespace);
9765 }
9766 if let Some(ref where_expr) = where_clause {
9767 self.write_space();
9768 self.write_keyword("WHERE");
9769 self.write(" (");
9770 self.generate_expression(where_expr)?;
9771 self.write(")");
9772 }
9773 }
9774 TableConstraint::Tags(tags) => {
9775 self.write_keyword("TAG");
9776 self.write(" (");
9777 for (i, expr) in tags.expressions.iter().enumerate() {
9778 if i > 0 {
9779 self.write(", ");
9780 }
9781 self.generate_expression(expr)?;
9782 }
9783 self.write(")");
9784 }
9785 TableConstraint::InitiallyDeferred { deferred } => {
9786 self.write_keyword("INITIALLY");
9787 self.write_space();
9788 if *deferred {
9789 self.write_keyword("DEFERRED");
9790 } else {
9791 self.write_keyword("IMMEDIATE");
9792 }
9793 }
9794 }
9795 Ok(())
9796 }
9797
9798 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9799 if let Some(using) = &modifiers.using {
9801 self.write_space();
9802 self.write_keyword("USING");
9803 self.write_space();
9804 self.write_keyword(using);
9805 }
9806 if let Some(enforced) = modifiers.enforced {
9808 self.write_space();
9809 if enforced {
9810 self.write_keyword("ENFORCED");
9811 } else {
9812 self.write_keyword("NOT ENFORCED");
9813 }
9814 }
9815 if let Some(deferrable) = modifiers.deferrable {
9817 self.write_space();
9818 if deferrable {
9819 self.write_keyword("DEFERRABLE");
9820 } else {
9821 self.write_keyword("NOT DEFERRABLE");
9822 }
9823 }
9824 if let Some(initially_deferred) = modifiers.initially_deferred {
9826 self.write_space();
9827 if initially_deferred {
9828 self.write_keyword("INITIALLY DEFERRED");
9829 } else {
9830 self.write_keyword("INITIALLY IMMEDIATE");
9831 }
9832 }
9833 if modifiers.norely {
9835 self.write_space();
9836 self.write_keyword("NORELY");
9837 }
9838 if modifiers.rely {
9840 self.write_space();
9841 self.write_keyword("RELY");
9842 }
9843 if modifiers.not_valid {
9845 self.write_space();
9846 self.write_keyword("NOT VALID");
9847 }
9848 if let Some(on_conflict) = &modifiers.on_conflict {
9850 self.write_space();
9851 self.write_keyword("ON CONFLICT");
9852 self.write_space();
9853 self.write_keyword(on_conflict);
9854 }
9855 if !modifiers.with_options.is_empty() {
9857 self.write_space();
9858 self.write_keyword("WITH");
9859 self.write(" (");
9860 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9861 if i > 0 {
9862 self.write(", ");
9863 }
9864 self.write(key);
9865 self.write("=");
9866 self.write(value);
9867 }
9868 self.write(")");
9869 }
9870 if let Some(ref fg) = modifiers.on_filegroup {
9872 self.write_space();
9873 self.write_keyword("ON");
9874 self.write_space();
9875 let _ = self.generate_identifier(fg);
9876 }
9877 }
9878
9879 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9881 if let Some(enforced) = modifiers.enforced {
9883 self.write_space();
9884 if enforced {
9885 self.write_keyword("ENFORCED");
9886 } else {
9887 self.write_keyword("NOT ENFORCED");
9888 }
9889 }
9890 if let Some(deferrable) = modifiers.deferrable {
9892 self.write_space();
9893 if deferrable {
9894 self.write_keyword("DEFERRABLE");
9895 } else {
9896 self.write_keyword("NOT DEFERRABLE");
9897 }
9898 }
9899 if let Some(initially_deferred) = modifiers.initially_deferred {
9901 self.write_space();
9902 if initially_deferred {
9903 self.write_keyword("INITIALLY DEFERRED");
9904 } else {
9905 self.write_keyword("INITIALLY IMMEDIATE");
9906 }
9907 }
9908 if modifiers.norely {
9910 self.write_space();
9911 self.write_keyword("NORELY");
9912 }
9913 if modifiers.rely {
9915 self.write_space();
9916 self.write_keyword("RELY");
9917 }
9918 if modifiers.not_valid {
9920 self.write_space();
9921 self.write_keyword("NOT VALID");
9922 }
9923 if let Some(on_conflict) = &modifiers.on_conflict {
9925 self.write_space();
9926 self.write_keyword("ON CONFLICT");
9927 self.write_space();
9928 self.write_keyword(on_conflict);
9929 }
9930 self.generate_index_specific_modifiers(modifiers);
9932 }
9933
9934 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9936 if let Some(ref comment) = modifiers.comment {
9937 self.write_space();
9938 self.write_keyword("COMMENT");
9939 self.write(" '");
9940 self.write(comment);
9941 self.write("'");
9942 }
9943 if let Some(visible) = modifiers.visible {
9944 self.write_space();
9945 if visible {
9946 self.write_keyword("VISIBLE");
9947 } else {
9948 self.write_keyword("INVISIBLE");
9949 }
9950 }
9951 if let Some(ref attr) = modifiers.engine_attribute {
9952 self.write_space();
9953 self.write_keyword("ENGINE_ATTRIBUTE");
9954 self.write(" = '");
9955 self.write(attr);
9956 self.write("'");
9957 }
9958 if let Some(ref parser) = modifiers.with_parser {
9959 self.write_space();
9960 self.write_keyword("WITH PARSER");
9961 self.write_space();
9962 self.write(parser);
9963 }
9964 }
9965
9966 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9967 if !fk_ref.match_after_actions {
9969 if let Some(ref match_type) = fk_ref.match_type {
9970 self.write_space();
9971 self.write_keyword("MATCH");
9972 self.write_space();
9973 match match_type {
9974 MatchType::Full => self.write_keyword("FULL"),
9975 MatchType::Partial => self.write_keyword("PARTIAL"),
9976 MatchType::Simple => self.write_keyword("SIMPLE"),
9977 }
9978 }
9979 }
9980
9981 if fk_ref.on_update_first {
9983 if let Some(ref action) = fk_ref.on_update {
9984 self.write_space();
9985 self.write_keyword("ON UPDATE");
9986 self.write_space();
9987 self.generate_referential_action(action);
9988 }
9989 if let Some(ref action) = fk_ref.on_delete {
9990 self.write_space();
9991 self.write_keyword("ON DELETE");
9992 self.write_space();
9993 self.generate_referential_action(action);
9994 }
9995 } else {
9996 if let Some(ref action) = fk_ref.on_delete {
9997 self.write_space();
9998 self.write_keyword("ON DELETE");
9999 self.write_space();
10000 self.generate_referential_action(action);
10001 }
10002 if let Some(ref action) = fk_ref.on_update {
10003 self.write_space();
10004 self.write_keyword("ON UPDATE");
10005 self.write_space();
10006 self.generate_referential_action(action);
10007 }
10008 }
10009
10010 if fk_ref.match_after_actions {
10012 if let Some(ref match_type) = fk_ref.match_type {
10013 self.write_space();
10014 self.write_keyword("MATCH");
10015 self.write_space();
10016 match match_type {
10017 MatchType::Full => self.write_keyword("FULL"),
10018 MatchType::Partial => self.write_keyword("PARTIAL"),
10019 MatchType::Simple => self.write_keyword("SIMPLE"),
10020 }
10021 }
10022 }
10023
10024 if let Some(deferrable) = fk_ref.deferrable {
10026 self.write_space();
10027 if deferrable {
10028 self.write_keyword("DEFERRABLE");
10029 } else {
10030 self.write_keyword("NOT DEFERRABLE");
10031 }
10032 }
10033
10034 Ok(())
10035 }
10036
10037 fn generate_referential_action(&mut self, action: &ReferentialAction) {
10038 match action {
10039 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
10040 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
10041 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
10042 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
10043 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
10044 }
10045 }
10046
10047 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
10048 if let Some(ref object_id_args) = dt.object_id_args {
10050 if matches!(
10051 self.config.dialect,
10052 Some(crate::dialects::DialectType::TSQL)
10053 | Some(crate::dialects::DialectType::Fabric)
10054 ) {
10055 self.write_keyword("IF NOT OBJECT_ID");
10056 self.write("(");
10057 self.write(object_id_args);
10058 self.write(")");
10059 self.write_space();
10060 self.write_keyword("IS NULL BEGIN DROP TABLE");
10061 self.write_space();
10062 for (i, table) in dt.names.iter().enumerate() {
10063 if i > 0 {
10064 self.write(", ");
10065 }
10066 self.generate_table(table)?;
10067 }
10068 self.write("; ");
10069 self.write_keyword("END");
10070 return Ok(());
10071 }
10072 }
10073
10074 let saved_athena_hive_context = self.athena_hive_context;
10076 if matches!(
10077 self.config.dialect,
10078 Some(crate::dialects::DialectType::Athena)
10079 ) {
10080 self.athena_hive_context = true;
10081 }
10082
10083 for comment in &dt.leading_comments {
10085 self.write_formatted_comment(comment);
10086 self.write_space();
10087 }
10088 if dt.iceberg {
10089 self.write_keyword("DROP ICEBERG TABLE");
10090 } else {
10091 self.write_keyword("DROP TABLE");
10092 }
10093
10094 if dt.if_exists {
10095 self.write_space();
10096 self.write_keyword("IF EXISTS");
10097 }
10098
10099 self.write_space();
10100 for (i, table) in dt.names.iter().enumerate() {
10101 if i > 0 {
10102 self.write(", ");
10103 }
10104 self.generate_table(table)?;
10105 }
10106
10107 if dt.cascade_constraints {
10108 self.write_space();
10109 self.write_keyword("CASCADE CONSTRAINTS");
10110 } else if dt.cascade {
10111 self.write_space();
10112 self.write_keyword("CASCADE");
10113 }
10114
10115 if dt.restrict {
10116 self.write_space();
10117 self.write_keyword("RESTRICT");
10118 }
10119
10120 if dt.purge {
10121 self.write_space();
10122 self.write_keyword("PURGE");
10123 }
10124
10125 if dt.sync {
10126 self.write_space();
10127 self.write_keyword("SYNC");
10128 }
10129
10130 self.athena_hive_context = saved_athena_hive_context;
10132
10133 Ok(())
10134 }
10135
10136 fn generate_undrop(&mut self, u: &Undrop) -> Result<()> {
10137 self.write_keyword("UNDROP");
10138 self.write_space();
10139 self.write_keyword(&u.kind);
10140 if u.if_exists {
10141 self.write_space();
10142 self.write_keyword("IF EXISTS");
10143 }
10144 self.write_space();
10145 self.generate_table(&u.name)?;
10146 Ok(())
10147 }
10148
10149 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
10150 let saved_athena_hive_context = self.athena_hive_context;
10152 if matches!(
10153 self.config.dialect,
10154 Some(crate::dialects::DialectType::Athena)
10155 ) {
10156 self.athena_hive_context = true;
10157 }
10158
10159 self.write_keyword("ALTER");
10160 if let Some(ref modifier) = at.table_modifier {
10162 if !matches!(
10163 self.config.dialect,
10164 Some(crate::dialects::DialectType::DuckDB)
10165 ) {
10166 self.write_space();
10167 self.write_keyword(modifier);
10168 }
10169 }
10170 self.write(" ");
10171 self.write_keyword("TABLE");
10172 if at.if_exists {
10173 self.write_space();
10174 self.write_keyword("IF EXISTS");
10175 }
10176 self.write_space();
10177 self.generate_table(&at.name)?;
10178
10179 if let Some(ref on_cluster) = at.on_cluster {
10181 self.write_space();
10182 self.generate_on_cluster(on_cluster)?;
10183 }
10184
10185 if let Some(ref partition) = at.partition {
10187 self.write_space();
10188 self.write_keyword("PARTITION");
10189 self.write("(");
10190 for (i, (key, value)) in partition.iter().enumerate() {
10191 if i > 0 {
10192 self.write(", ");
10193 }
10194 self.generate_identifier(key)?;
10195 self.write(" = ");
10196 self.generate_expression(value)?;
10197 }
10198 self.write(")");
10199 }
10200
10201 if let Some(ref with_check) = at.with_check {
10203 self.write_space();
10204 self.write_keyword(with_check);
10205 }
10206
10207 if self.config.pretty {
10208 self.write_newline();
10210 self.indent_level += 1;
10211 for (i, action) in at.actions.iter().enumerate() {
10212 let is_continuation = i > 0
10214 && matches!(
10215 (&at.actions[i - 1], action),
10216 (
10217 AlterTableAction::AddColumn { .. },
10218 AlterTableAction::AddColumn { .. }
10219 ) | (
10220 AlterTableAction::AddConstraint(_),
10221 AlterTableAction::AddConstraint(_)
10222 )
10223 );
10224 if i > 0 {
10225 self.write(",");
10226 self.write_newline();
10227 }
10228 self.write_indent();
10229 self.generate_alter_action_with_continuation(action, is_continuation)?;
10230 }
10231 self.indent_level -= 1;
10232 } else {
10233 for (i, action) in at.actions.iter().enumerate() {
10234 let is_continuation = i > 0
10236 && matches!(
10237 (&at.actions[i - 1], action),
10238 (
10239 AlterTableAction::AddColumn { .. },
10240 AlterTableAction::AddColumn { .. }
10241 ) | (
10242 AlterTableAction::AddConstraint(_),
10243 AlterTableAction::AddConstraint(_)
10244 )
10245 );
10246 if i > 0 {
10247 self.write(",");
10248 }
10249 self.write_space();
10250 self.generate_alter_action_with_continuation(action, is_continuation)?;
10251 }
10252 }
10253
10254 if let Some(ref algorithm) = at.algorithm {
10256 self.write(", ");
10257 self.write_keyword("ALGORITHM");
10258 self.write("=");
10259 self.write_keyword(algorithm);
10260 }
10261 if let Some(ref lock) = at.lock {
10262 self.write(", ");
10263 self.write_keyword("LOCK");
10264 self.write("=");
10265 self.write_keyword(lock);
10266 }
10267
10268 self.athena_hive_context = saved_athena_hive_context;
10270
10271 Ok(())
10272 }
10273
10274 fn generate_alter_action_with_continuation(
10275 &mut self,
10276 action: &AlterTableAction,
10277 is_continuation: bool,
10278 ) -> Result<()> {
10279 match action {
10280 AlterTableAction::AddColumn {
10281 column,
10282 if_not_exists,
10283 position,
10284 } => {
10285 use crate::dialects::DialectType;
10286 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
10290 let is_tsql_like = matches!(
10291 self.config.dialect,
10292 Some(DialectType::TSQL) | Some(DialectType::Fabric)
10293 );
10294 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
10296
10297 if is_continuation && (is_snowflake || is_tsql_like) {
10298 } else if is_snowflake {
10300 self.write_keyword("ADD");
10301 self.write_space();
10302 } else if is_athena {
10303 self.write_keyword("ADD COLUMNS");
10305 self.write(" (");
10306 } else if self.config.alter_table_include_column_keyword {
10307 self.write_keyword("ADD COLUMN");
10308 self.write_space();
10309 } else {
10310 self.write_keyword("ADD");
10312 self.write_space();
10313 }
10314
10315 if *if_not_exists {
10316 self.write_keyword("IF NOT EXISTS");
10317 self.write_space();
10318 }
10319 self.generate_column_def(column)?;
10320
10321 if is_athena {
10323 self.write(")");
10324 }
10325
10326 if let Some(pos) = position {
10328 self.write_space();
10329 match pos {
10330 ColumnPosition::First => self.write_keyword("FIRST"),
10331 ColumnPosition::After(col_name) => {
10332 self.write_keyword("AFTER");
10333 self.write_space();
10334 self.generate_identifier(col_name)?;
10335 }
10336 }
10337 }
10338 }
10339 AlterTableAction::DropColumn {
10340 name,
10341 if_exists,
10342 cascade,
10343 } => {
10344 self.write_keyword("DROP COLUMN");
10345 if *if_exists {
10346 self.write_space();
10347 self.write_keyword("IF EXISTS");
10348 }
10349 self.write_space();
10350 self.generate_identifier(name)?;
10351 if *cascade {
10352 self.write_space();
10353 self.write_keyword("CASCADE");
10354 }
10355 }
10356 AlterTableAction::DropColumns { names } => {
10357 self.write_keyword("DROP COLUMNS");
10358 self.write(" (");
10359 for (i, name) in names.iter().enumerate() {
10360 if i > 0 {
10361 self.write(", ");
10362 }
10363 self.generate_identifier(name)?;
10364 }
10365 self.write(")");
10366 }
10367 AlterTableAction::RenameColumn {
10368 old_name,
10369 new_name,
10370 if_exists,
10371 } => {
10372 self.write_keyword("RENAME COLUMN");
10373 if *if_exists {
10374 self.write_space();
10375 self.write_keyword("IF EXISTS");
10376 }
10377 self.write_space();
10378 self.generate_identifier(old_name)?;
10379 self.write_space();
10380 self.write_keyword("TO");
10381 self.write_space();
10382 self.generate_identifier(new_name)?;
10383 }
10384 AlterTableAction::AlterColumn {
10385 name,
10386 action,
10387 use_modify_keyword,
10388 } => {
10389 use crate::dialects::DialectType;
10390 let use_modify = *use_modify_keyword
10393 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10394 && matches!(action, AlterColumnAction::SetDataType { .. }));
10395 if use_modify {
10396 self.write_keyword("MODIFY COLUMN");
10397 self.write_space();
10398 self.generate_identifier(name)?;
10399 if let AlterColumnAction::SetDataType {
10401 data_type,
10402 using: _,
10403 collate,
10404 } = action
10405 {
10406 self.write_space();
10407 self.generate_data_type(data_type)?;
10408 if let Some(collate_name) = collate {
10410 self.write_space();
10411 self.write_keyword("COLLATE");
10412 self.write_space();
10413 self.write(&format!("'{}'", collate_name));
10415 }
10416 } else {
10417 self.write_space();
10418 self.generate_alter_column_action(action)?;
10419 }
10420 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10421 && matches!(action, AlterColumnAction::SetDataType { .. })
10422 {
10423 self.write_keyword("CHANGE COLUMN");
10425 self.write_space();
10426 self.generate_identifier(name)?;
10427 self.write_space();
10428 self.generate_identifier(name)?;
10429 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10430 self.write_space();
10431 self.generate_data_type(data_type)?;
10432 }
10433 } else {
10434 self.write_keyword("ALTER COLUMN");
10435 self.write_space();
10436 self.generate_identifier(name)?;
10437 self.write_space();
10438 self.generate_alter_column_action(action)?;
10439 }
10440 }
10441 AlterTableAction::RenameTable(new_name) => {
10442 let mysql_like = matches!(
10444 self.config.dialect,
10445 Some(DialectType::MySQL)
10446 | Some(DialectType::Doris)
10447 | Some(DialectType::StarRocks)
10448 | Some(DialectType::SingleStore)
10449 );
10450 if mysql_like {
10451 self.write_keyword("RENAME");
10452 } else {
10453 self.write_keyword("RENAME TO");
10454 }
10455 self.write_space();
10456 let rename_table_with_db = !matches!(
10458 self.config.dialect,
10459 Some(DialectType::Doris)
10460 | Some(DialectType::DuckDB)
10461 | Some(DialectType::BigQuery)
10462 | Some(DialectType::PostgreSQL)
10463 );
10464 if !rename_table_with_db {
10465 let mut stripped = new_name.clone();
10466 stripped.schema = None;
10467 stripped.catalog = None;
10468 self.generate_table(&stripped)?;
10469 } else {
10470 self.generate_table(new_name)?;
10471 }
10472 }
10473 AlterTableAction::AddConstraint(constraint) => {
10474 if !is_continuation {
10477 self.write_keyword("ADD");
10478 self.write_space();
10479 }
10480 self.generate_table_constraint(constraint)?;
10481 }
10482 AlterTableAction::DropConstraint { name, if_exists } => {
10483 self.write_keyword("DROP CONSTRAINT");
10484 if *if_exists {
10485 self.write_space();
10486 self.write_keyword("IF EXISTS");
10487 }
10488 self.write_space();
10489 self.generate_identifier(name)?;
10490 }
10491 AlterTableAction::DropForeignKey { name } => {
10492 self.write_keyword("DROP FOREIGN KEY");
10493 self.write_space();
10494 self.generate_identifier(name)?;
10495 }
10496 AlterTableAction::DropPartition {
10497 partitions,
10498 if_exists,
10499 } => {
10500 self.write_keyword("DROP");
10501 if *if_exists {
10502 self.write_space();
10503 self.write_keyword("IF EXISTS");
10504 }
10505 for (i, partition) in partitions.iter().enumerate() {
10506 if i > 0 {
10507 self.write(",");
10508 }
10509 self.write_space();
10510 self.write_keyword("PARTITION");
10511 if partition.len() == 1 && partition[0].0.name == "__expr__" {
10513 self.write_space();
10515 self.generate_expression(&partition[0].1)?;
10516 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
10517 self.write_space();
10519 self.write_keyword("ALL");
10520 } else if partition.len() == 1 && partition[0].0.name == "ID" {
10521 self.write_space();
10523 self.write_keyword("ID");
10524 self.write_space();
10525 self.generate_expression(&partition[0].1)?;
10526 } else {
10527 self.write("(");
10529 for (j, (key, value)) in partition.iter().enumerate() {
10530 if j > 0 {
10531 self.write(", ");
10532 }
10533 self.generate_identifier(key)?;
10534 self.write(" = ");
10535 self.generate_expression(value)?;
10536 }
10537 self.write(")");
10538 }
10539 }
10540 }
10541 AlterTableAction::Delete { where_clause } => {
10542 self.write_keyword("DELETE");
10543 self.write_space();
10544 self.write_keyword("WHERE");
10545 self.write_space();
10546 self.generate_expression(where_clause)?;
10547 }
10548 AlterTableAction::SwapWith(target) => {
10549 self.write_keyword("SWAP WITH");
10550 self.write_space();
10551 self.generate_table(target)?;
10552 }
10553 AlterTableAction::SetProperty { properties } => {
10554 use crate::dialects::DialectType;
10555 self.write_keyword("SET");
10556 let is_trino_presto = matches!(
10558 self.config.dialect,
10559 Some(DialectType::Trino) | Some(DialectType::Presto)
10560 );
10561 if is_trino_presto {
10562 self.write_space();
10563 self.write_keyword("PROPERTIES");
10564 }
10565 let eq = if is_trino_presto { " = " } else { "=" };
10566 for (i, (key, value)) in properties.iter().enumerate() {
10567 if i > 0 {
10568 self.write(",");
10569 }
10570 self.write_space();
10571 if key.contains(' ') {
10573 self.generate_string_literal(key)?;
10574 } else {
10575 self.write(key);
10576 }
10577 self.write(eq);
10578 self.generate_expression(value)?;
10579 }
10580 }
10581 AlterTableAction::UnsetProperty { properties } => {
10582 self.write_keyword("UNSET");
10583 for (i, name) in properties.iter().enumerate() {
10584 if i > 0 {
10585 self.write(",");
10586 }
10587 self.write_space();
10588 self.write(name);
10589 }
10590 }
10591 AlterTableAction::ClusterBy { expressions } => {
10592 self.write_keyword("CLUSTER BY");
10593 self.write(" (");
10594 for (i, expr) in expressions.iter().enumerate() {
10595 if i > 0 {
10596 self.write(", ");
10597 }
10598 self.generate_expression(expr)?;
10599 }
10600 self.write(")");
10601 }
10602 AlterTableAction::SetTag { expressions } => {
10603 self.write_keyword("SET TAG");
10604 for (i, (key, value)) in expressions.iter().enumerate() {
10605 if i > 0 {
10606 self.write(",");
10607 }
10608 self.write_space();
10609 self.write(key);
10610 self.write(" = ");
10611 self.generate_expression(value)?;
10612 }
10613 }
10614 AlterTableAction::UnsetTag { names } => {
10615 self.write_keyword("UNSET TAG");
10616 for (i, name) in names.iter().enumerate() {
10617 if i > 0 {
10618 self.write(",");
10619 }
10620 self.write_space();
10621 self.write(name);
10622 }
10623 }
10624 AlterTableAction::SetOptions { expressions } => {
10625 self.write_keyword("SET");
10626 self.write(" (");
10627 for (i, expr) in expressions.iter().enumerate() {
10628 if i > 0 {
10629 self.write(", ");
10630 }
10631 self.generate_expression(expr)?;
10632 }
10633 self.write(")");
10634 }
10635 AlterTableAction::AlterIndex { name, visible } => {
10636 self.write_keyword("ALTER INDEX");
10637 self.write_space();
10638 self.generate_identifier(name)?;
10639 self.write_space();
10640 if *visible {
10641 self.write_keyword("VISIBLE");
10642 } else {
10643 self.write_keyword("INVISIBLE");
10644 }
10645 }
10646 AlterTableAction::SetAttribute { attribute } => {
10647 self.write_keyword("SET");
10648 self.write_space();
10649 self.write_keyword(attribute);
10650 }
10651 AlterTableAction::SetStageFileFormat { options } => {
10652 self.write_keyword("SET");
10653 self.write_space();
10654 self.write_keyword("STAGE_FILE_FORMAT");
10655 self.write(" = (");
10656 if let Some(opts) = options {
10657 self.generate_space_separated_properties(opts)?;
10658 }
10659 self.write(")");
10660 }
10661 AlterTableAction::SetStageCopyOptions { options } => {
10662 self.write_keyword("SET");
10663 self.write_space();
10664 self.write_keyword("STAGE_COPY_OPTIONS");
10665 self.write(" = (");
10666 if let Some(opts) = options {
10667 self.generate_space_separated_properties(opts)?;
10668 }
10669 self.write(")");
10670 }
10671 AlterTableAction::AddColumns { columns, cascade } => {
10672 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
10675 if is_oracle {
10676 self.write_keyword("ADD");
10677 } else {
10678 self.write_keyword("ADD COLUMNS");
10679 }
10680 self.write(" (");
10681 for (i, col) in columns.iter().enumerate() {
10682 if i > 0 {
10683 self.write(", ");
10684 }
10685 self.generate_column_def(col)?;
10686 }
10687 self.write(")");
10688 if *cascade {
10689 self.write_space();
10690 self.write_keyword("CASCADE");
10691 }
10692 }
10693 AlterTableAction::ChangeColumn {
10694 old_name,
10695 new_name,
10696 data_type,
10697 comment,
10698 cascade,
10699 } => {
10700 use crate::dialects::DialectType;
10701 let is_spark = matches!(
10702 self.config.dialect,
10703 Some(DialectType::Spark) | Some(DialectType::Databricks)
10704 );
10705 let is_rename = old_name.name != new_name.name;
10706
10707 if is_spark {
10708 if is_rename {
10709 self.write_keyword("RENAME COLUMN");
10711 self.write_space();
10712 self.generate_identifier(old_name)?;
10713 self.write_space();
10714 self.write_keyword("TO");
10715 self.write_space();
10716 self.generate_identifier(new_name)?;
10717 } else if comment.is_some() {
10718 self.write_keyword("ALTER COLUMN");
10720 self.write_space();
10721 self.generate_identifier(old_name)?;
10722 self.write_space();
10723 self.write_keyword("COMMENT");
10724 self.write_space();
10725 self.write("'");
10726 self.write(comment.as_ref().unwrap());
10727 self.write("'");
10728 } else if data_type.is_some() {
10729 self.write_keyword("ALTER COLUMN");
10731 self.write_space();
10732 self.generate_identifier(old_name)?;
10733 self.write_space();
10734 self.write_keyword("TYPE");
10735 self.write_space();
10736 self.generate_data_type(data_type.as_ref().unwrap())?;
10737 } else {
10738 self.write_keyword("CHANGE COLUMN");
10740 self.write_space();
10741 self.generate_identifier(old_name)?;
10742 self.write_space();
10743 self.generate_identifier(new_name)?;
10744 }
10745 } else {
10746 if data_type.is_some() {
10748 self.write_keyword("CHANGE COLUMN");
10749 } else {
10750 self.write_keyword("CHANGE");
10751 }
10752 self.write_space();
10753 self.generate_identifier(old_name)?;
10754 self.write_space();
10755 self.generate_identifier(new_name)?;
10756 if let Some(ref dt) = data_type {
10757 self.write_space();
10758 self.generate_data_type(dt)?;
10759 }
10760 if let Some(ref c) = comment {
10761 self.write_space();
10762 self.write_keyword("COMMENT");
10763 self.write_space();
10764 self.write("'");
10765 self.write(c);
10766 self.write("'");
10767 }
10768 if *cascade {
10769 self.write_space();
10770 self.write_keyword("CASCADE");
10771 }
10772 }
10773 }
10774 AlterTableAction::AddPartition {
10775 partition,
10776 if_not_exists,
10777 location,
10778 } => {
10779 self.write_keyword("ADD");
10780 self.write_space();
10781 if *if_not_exists {
10782 self.write_keyword("IF NOT EXISTS");
10783 self.write_space();
10784 }
10785 self.generate_expression(partition)?;
10786 if let Some(ref loc) = location {
10787 self.write_space();
10788 self.write_keyword("LOCATION");
10789 self.write_space();
10790 self.generate_expression(loc)?;
10791 }
10792 }
10793 AlterTableAction::AlterSortKey {
10794 this,
10795 expressions,
10796 compound,
10797 } => {
10798 self.write_keyword("ALTER");
10800 if *compound {
10801 self.write_space();
10802 self.write_keyword("COMPOUND");
10803 }
10804 self.write_space();
10805 self.write_keyword("SORTKEY");
10806 self.write_space();
10807 if let Some(style) = this {
10808 self.write_keyword(style);
10809 } else if !expressions.is_empty() {
10810 self.write("(");
10811 for (i, expr) in expressions.iter().enumerate() {
10812 if i > 0 {
10813 self.write(", ");
10814 }
10815 self.generate_expression(expr)?;
10816 }
10817 self.write(")");
10818 }
10819 }
10820 AlterTableAction::AlterDistStyle { style, distkey } => {
10821 self.write_keyword("ALTER");
10823 self.write_space();
10824 self.write_keyword("DISTSTYLE");
10825 self.write_space();
10826 self.write_keyword(style);
10827 if let Some(col) = distkey {
10828 self.write_space();
10829 self.write_keyword("DISTKEY");
10830 self.write_space();
10831 self.generate_identifier(col)?;
10832 }
10833 }
10834 AlterTableAction::SetTableProperties { properties } => {
10835 self.write_keyword("SET TABLE PROPERTIES");
10837 self.write(" (");
10838 for (i, (key, value)) in properties.iter().enumerate() {
10839 if i > 0 {
10840 self.write(", ");
10841 }
10842 self.generate_expression(key)?;
10843 self.write(" = ");
10844 self.generate_expression(value)?;
10845 }
10846 self.write(")");
10847 }
10848 AlterTableAction::SetLocation { location } => {
10849 self.write_keyword("SET LOCATION");
10851 self.write_space();
10852 self.write("'");
10853 self.write(location);
10854 self.write("'");
10855 }
10856 AlterTableAction::SetFileFormat { format } => {
10857 self.write_keyword("SET FILE FORMAT");
10859 self.write_space();
10860 self.write_keyword(format);
10861 }
10862 AlterTableAction::ReplacePartition { partition, source } => {
10863 self.write_keyword("REPLACE PARTITION");
10865 self.write_space();
10866 self.generate_expression(partition)?;
10867 if let Some(src) = source {
10868 self.write_space();
10869 self.write_keyword("FROM");
10870 self.write_space();
10871 self.generate_expression(src)?;
10872 }
10873 }
10874 AlterTableAction::Raw { sql } => {
10875 self.write(sql);
10876 }
10877 }
10878 Ok(())
10879 }
10880
10881 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10882 match action {
10883 AlterColumnAction::SetDataType {
10884 data_type,
10885 using,
10886 collate,
10887 } => {
10888 use crate::dialects::DialectType;
10889 let is_no_prefix = matches!(
10894 self.config.dialect,
10895 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10896 );
10897 let is_type_only = matches!(
10898 self.config.dialect,
10899 Some(DialectType::Redshift)
10900 | Some(DialectType::Spark)
10901 | Some(DialectType::Databricks)
10902 );
10903 if is_type_only {
10904 self.write_keyword("TYPE");
10905 self.write_space();
10906 } else if !is_no_prefix {
10907 self.write_keyword("SET DATA TYPE");
10908 self.write_space();
10909 }
10910 self.generate_data_type(data_type)?;
10911 if let Some(ref collation) = collate {
10912 self.write_space();
10913 self.write_keyword("COLLATE");
10914 self.write_space();
10915 self.write(collation);
10916 }
10917 if let Some(ref using_expr) = using {
10918 self.write_space();
10919 self.write_keyword("USING");
10920 self.write_space();
10921 self.generate_expression(using_expr)?;
10922 }
10923 }
10924 AlterColumnAction::SetDefault(expr) => {
10925 self.write_keyword("SET DEFAULT");
10926 self.write_space();
10927 self.generate_expression(expr)?;
10928 }
10929 AlterColumnAction::DropDefault => {
10930 self.write_keyword("DROP DEFAULT");
10931 }
10932 AlterColumnAction::SetNotNull => {
10933 self.write_keyword("SET NOT NULL");
10934 }
10935 AlterColumnAction::DropNotNull => {
10936 self.write_keyword("DROP NOT NULL");
10937 }
10938 AlterColumnAction::Comment(comment) => {
10939 self.write_keyword("COMMENT");
10940 self.write_space();
10941 self.generate_string_literal(comment)?;
10942 }
10943 AlterColumnAction::SetVisible => {
10944 self.write_keyword("SET VISIBLE");
10945 }
10946 AlterColumnAction::SetInvisible => {
10947 self.write_keyword("SET INVISIBLE");
10948 }
10949 }
10950 Ok(())
10951 }
10952
10953 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10954 self.write_keyword("CREATE");
10955
10956 if ci.unique {
10957 self.write_space();
10958 self.write_keyword("UNIQUE");
10959 }
10960
10961 if let Some(ref clustered) = ci.clustered {
10963 self.write_space();
10964 self.write_keyword(clustered);
10965 }
10966
10967 self.write_space();
10968 self.write_keyword("INDEX");
10969
10970 if ci.concurrently {
10972 self.write_space();
10973 self.write_keyword("CONCURRENTLY");
10974 }
10975
10976 if ci.if_not_exists {
10977 self.write_space();
10978 self.write_keyword("IF NOT EXISTS");
10979 }
10980
10981 if !ci.name.name.is_empty() {
10983 self.write_space();
10984 self.generate_identifier(&ci.name)?;
10985 }
10986 self.write_space();
10987 self.write_keyword("ON");
10988 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10990 self.write_space();
10991 self.write_keyword("TABLE");
10992 }
10993 self.write_space();
10994 self.generate_table(&ci.table)?;
10995
10996 if !ci.columns.is_empty() || ci.using.is_some() {
10999 let space_before_paren = false;
11000
11001 if let Some(ref using) = ci.using {
11002 self.write_space();
11003 self.write_keyword("USING");
11004 self.write_space();
11005 self.write(using);
11006 if space_before_paren {
11007 self.write(" (");
11008 } else {
11009 self.write("(");
11010 }
11011 } else {
11012 if space_before_paren {
11013 self.write(" (");
11014 } else {
11015 self.write("(");
11016 }
11017 }
11018 for (i, col) in ci.columns.iter().enumerate() {
11019 if i > 0 {
11020 self.write(", ");
11021 }
11022 self.generate_identifier(&col.column)?;
11023 if let Some(ref opclass) = col.opclass {
11024 self.write_space();
11025 self.write(opclass);
11026 }
11027 if col.desc {
11028 self.write_space();
11029 self.write_keyword("DESC");
11030 } else if col.asc {
11031 self.write_space();
11032 self.write_keyword("ASC");
11033 }
11034 if let Some(nulls_first) = col.nulls_first {
11035 self.write_space();
11036 self.write_keyword("NULLS");
11037 self.write_space();
11038 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
11039 }
11040 }
11041 self.write(")");
11042 }
11043
11044 if !ci.include_columns.is_empty() {
11046 self.write_space();
11047 self.write_keyword("INCLUDE");
11048 self.write(" (");
11049 for (i, col) in ci.include_columns.iter().enumerate() {
11050 if i > 0 {
11051 self.write(", ");
11052 }
11053 self.generate_identifier(col)?;
11054 }
11055 self.write(")");
11056 }
11057
11058 if !ci.with_options.is_empty() {
11060 self.write_space();
11061 self.write_keyword("WITH");
11062 self.write(" (");
11063 for (i, (key, value)) in ci.with_options.iter().enumerate() {
11064 if i > 0 {
11065 self.write(", ");
11066 }
11067 self.write(key);
11068 self.write("=");
11069 self.write(value);
11070 }
11071 self.write(")");
11072 }
11073
11074 if let Some(ref where_clause) = ci.where_clause {
11076 self.write_space();
11077 self.write_keyword("WHERE");
11078 self.write_space();
11079 self.generate_expression(where_clause)?;
11080 }
11081
11082 if let Some(ref on_fg) = ci.on_filegroup {
11084 self.write_space();
11085 self.write_keyword("ON");
11086 self.write_space();
11087 self.write(on_fg);
11088 }
11089
11090 Ok(())
11091 }
11092
11093 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
11094 self.write_keyword("DROP INDEX");
11095
11096 if di.concurrently {
11097 self.write_space();
11098 self.write_keyword("CONCURRENTLY");
11099 }
11100
11101 if di.if_exists {
11102 self.write_space();
11103 self.write_keyword("IF EXISTS");
11104 }
11105
11106 self.write_space();
11107 self.generate_identifier(&di.name)?;
11108
11109 if let Some(ref table) = di.table {
11110 self.write_space();
11111 self.write_keyword("ON");
11112 self.write_space();
11113 self.generate_table(table)?;
11114 }
11115
11116 Ok(())
11117 }
11118
11119 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
11120 self.write_keyword("CREATE");
11121
11122 if let Some(ref algorithm) = cv.algorithm {
11124 self.write_space();
11125 self.write_keyword("ALGORITHM");
11126 self.write("=");
11127 self.write_keyword(algorithm);
11128 }
11129
11130 if let Some(ref definer) = cv.definer {
11132 self.write_space();
11133 self.write_keyword("DEFINER");
11134 self.write("=");
11135 self.write(definer);
11136 }
11137
11138 if cv.security_sql_style && !cv.security_after_name {
11140 if let Some(ref security) = cv.security {
11141 self.write_space();
11142 self.write_keyword("SQL SECURITY");
11143 self.write_space();
11144 match security {
11145 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11146 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11147 FunctionSecurity::None => self.write_keyword("NONE"),
11148 }
11149 }
11150 }
11151
11152 if cv.or_alter {
11153 self.write_space();
11154 self.write_keyword("OR ALTER");
11155 } else if cv.or_replace {
11156 self.write_space();
11157 self.write_keyword("OR REPLACE");
11158 }
11159
11160 if cv.temporary {
11161 self.write_space();
11162 self.write_keyword("TEMPORARY");
11163 }
11164
11165 if cv.materialized {
11166 self.write_space();
11167 self.write_keyword("MATERIALIZED");
11168 }
11169
11170 if cv.secure {
11172 self.write_space();
11173 self.write_keyword("SECURE");
11174 }
11175
11176 self.write_space();
11177 self.write_keyword("VIEW");
11178
11179 if cv.if_not_exists {
11180 self.write_space();
11181 self.write_keyword("IF NOT EXISTS");
11182 }
11183
11184 self.write_space();
11185 self.generate_table(&cv.name)?;
11186
11187 if let Some(ref on_cluster) = cv.on_cluster {
11189 self.write_space();
11190 self.generate_on_cluster(on_cluster)?;
11191 }
11192
11193 if let Some(ref to_table) = cv.to_table {
11195 self.write_space();
11196 self.write_keyword("TO");
11197 self.write_space();
11198 self.generate_table(to_table)?;
11199 }
11200
11201 if !cv.materialized {
11204 if !cv.columns.is_empty() {
11206 self.write(" (");
11207 for (i, col) in cv.columns.iter().enumerate() {
11208 if i > 0 {
11209 self.write(", ");
11210 }
11211 self.generate_identifier(&col.name)?;
11212 if !col.options.is_empty() {
11214 self.write_space();
11215 self.generate_options_clause(&col.options)?;
11216 }
11217 if let Some(ref comment) = col.comment {
11218 self.write_space();
11219 self.write_keyword("COMMENT");
11220 self.write_space();
11221 self.generate_string_literal(comment)?;
11222 }
11223 }
11224 self.write(")");
11225 }
11226
11227 if !cv.security_sql_style || cv.security_after_name {
11230 if let Some(ref security) = cv.security {
11231 self.write_space();
11232 if cv.security_sql_style {
11233 self.write_keyword("SQL SECURITY");
11234 } else {
11235 self.write_keyword("SECURITY");
11236 }
11237 self.write_space();
11238 match security {
11239 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11240 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11241 FunctionSecurity::None => self.write_keyword("NONE"),
11242 }
11243 }
11244 }
11245
11246 if cv.copy_grants {
11248 self.write_space();
11249 self.write_keyword("COPY GRANTS");
11250 }
11251 } else {
11252 if cv.copy_grants {
11254 self.write_space();
11255 self.write_keyword("COPY GRANTS");
11256 }
11257
11258 if let Some(ref schema) = cv.schema {
11260 self.write(" (");
11261 for (i, expr) in schema.expressions.iter().enumerate() {
11262 if i > 0 {
11263 self.write(", ");
11264 }
11265 self.generate_expression(expr)?;
11266 }
11267 self.write(")");
11268 } else if !cv.columns.is_empty() {
11269 self.write(" (");
11271 for (i, col) in cv.columns.iter().enumerate() {
11272 if i > 0 {
11273 self.write(", ");
11274 }
11275 self.generate_identifier(&col.name)?;
11276 if !col.options.is_empty() {
11278 self.write_space();
11279 self.generate_options_clause(&col.options)?;
11280 }
11281 if let Some(ref comment) = col.comment {
11282 self.write_space();
11283 self.write_keyword("COMMENT");
11284 self.write_space();
11285 self.generate_string_literal(comment)?;
11286 }
11287 }
11288 self.write(")");
11289 }
11290
11291 if let Some(ref unique_key) = cv.unique_key {
11293 self.write_space();
11294 self.write_keyword("KEY");
11295 self.write(" (");
11296 for (i, expr) in unique_key.expressions.iter().enumerate() {
11297 if i > 0 {
11298 self.write(", ");
11299 }
11300 self.generate_expression(expr)?;
11301 }
11302 self.write(")");
11303 }
11304 }
11305
11306 if let Some(ref row_access_policy) = cv.row_access_policy {
11307 self.write_space();
11308 self.write_keyword("WITH");
11309 self.write_space();
11310 self.write(row_access_policy);
11311 }
11312
11313 if let Some(ref comment) = cv.comment {
11315 self.write_space();
11316 self.write_keyword("COMMENT");
11317 self.write("=");
11318 self.generate_string_literal(comment)?;
11319 }
11320
11321 if !cv.tags.is_empty() {
11323 self.write_space();
11324 self.write_keyword("TAG");
11325 self.write(" (");
11326 for (i, (name, value)) in cv.tags.iter().enumerate() {
11327 if i > 0 {
11328 self.write(", ");
11329 }
11330 self.write(name);
11331 self.write("='");
11332 self.write(value);
11333 self.write("'");
11334 }
11335 self.write(")");
11336 }
11337
11338 if !cv.options.is_empty() {
11340 self.write_space();
11341 self.generate_options_clause(&cv.options)?;
11342 }
11343
11344 if let Some(ref build) = cv.build {
11346 self.write_space();
11347 self.write_keyword("BUILD");
11348 self.write_space();
11349 self.write_keyword(build);
11350 }
11351
11352 if let Some(ref refresh) = cv.refresh {
11354 self.write_space();
11355 self.generate_refresh_trigger_property(refresh)?;
11356 }
11357
11358 if let Some(auto_refresh) = cv.auto_refresh {
11360 self.write_space();
11361 self.write_keyword("AUTO REFRESH");
11362 self.write_space();
11363 if auto_refresh {
11364 self.write_keyword("YES");
11365 } else {
11366 self.write_keyword("NO");
11367 }
11368 }
11369
11370 for prop in &cv.table_properties {
11372 self.write_space();
11373 self.generate_expression(prop)?;
11374 }
11375
11376 if let Some(ref population) = cv.clickhouse_population {
11378 self.write_space();
11379 self.write_keyword(population);
11380 }
11381
11382 if !matches!(&cv.query, Expression::Null(_)) {
11384 self.write_space();
11385 self.write_keyword("AS");
11386 self.write_space();
11387
11388 if let Some(ref mode) = cv.locking_mode {
11390 self.write_keyword("LOCKING");
11391 self.write_space();
11392 self.write_keyword(mode);
11393 if let Some(ref access) = cv.locking_access {
11394 self.write_space();
11395 self.write_keyword("FOR");
11396 self.write_space();
11397 self.write_keyword(access);
11398 }
11399 self.write_space();
11400 }
11401
11402 if cv.query_parenthesized {
11403 self.write("(");
11404 }
11405 self.generate_expression(&cv.query)?;
11406 if cv.query_parenthesized {
11407 self.write(")");
11408 }
11409 }
11410
11411 if cv.no_schema_binding {
11413 self.write_space();
11414 self.write_keyword("WITH NO SCHEMA BINDING");
11415 }
11416
11417 Ok(())
11418 }
11419
11420 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11421 self.write_keyword("DROP");
11422
11423 if dv.materialized {
11424 self.write_space();
11425 self.write_keyword("MATERIALIZED");
11426 }
11427
11428 self.write_space();
11429 self.write_keyword("VIEW");
11430
11431 if dv.if_exists {
11432 self.write_space();
11433 self.write_keyword("IF EXISTS");
11434 }
11435
11436 self.write_space();
11437 self.generate_table(&dv.name)?;
11438
11439 Ok(())
11440 }
11441
11442 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11443 match tr.target {
11444 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11445 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11446 }
11447 if tr.if_exists {
11448 self.write_space();
11449 self.write_keyword("IF EXISTS");
11450 }
11451 self.write_space();
11452 self.generate_table(&tr.table)?;
11453
11454 if let Some(ref on_cluster) = tr.on_cluster {
11456 self.write_space();
11457 self.generate_on_cluster(on_cluster)?;
11458 }
11459
11460 if !tr.extra_tables.is_empty() {
11462 let skip_first = if let Some(first) = tr.extra_tables.first() {
11464 first.table.name == tr.table.name && first.star
11465 } else {
11466 false
11467 };
11468
11469 let strip_star = matches!(
11471 self.config.dialect,
11472 Some(crate::dialects::DialectType::PostgreSQL)
11473 | Some(crate::dialects::DialectType::Redshift)
11474 );
11475 if skip_first && !strip_star {
11476 self.write("*");
11477 }
11478
11479 for (i, entry) in tr.extra_tables.iter().enumerate() {
11481 if i == 0 && skip_first {
11482 continue; }
11484 self.write(", ");
11485 self.generate_table(&entry.table)?;
11486 if entry.star && !strip_star {
11487 self.write("*");
11488 }
11489 }
11490 }
11491
11492 if let Some(identity) = &tr.identity {
11494 self.write_space();
11495 match identity {
11496 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
11497 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
11498 }
11499 }
11500
11501 if tr.cascade {
11502 self.write_space();
11503 self.write_keyword("CASCADE");
11504 }
11505
11506 if tr.restrict {
11507 self.write_space();
11508 self.write_keyword("RESTRICT");
11509 }
11510
11511 if let Some(ref partition) = tr.partition {
11513 self.write_space();
11514 self.generate_expression(partition)?;
11515 }
11516
11517 Ok(())
11518 }
11519
11520 fn generate_use(&mut self, u: &Use) -> Result<()> {
11521 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
11523 self.write_keyword("DATABASE");
11524 self.write_space();
11525 self.generate_identifier(&u.this)?;
11526 return Ok(());
11527 }
11528
11529 self.write_keyword("USE");
11530
11531 if let Some(kind) = &u.kind {
11532 self.write_space();
11533 match kind {
11534 UseKind::Database => self.write_keyword("DATABASE"),
11535 UseKind::Schema => self.write_keyword("SCHEMA"),
11536 UseKind::Role => self.write_keyword("ROLE"),
11537 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
11538 UseKind::Catalog => self.write_keyword("CATALOG"),
11539 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
11540 }
11541 }
11542
11543 self.write_space();
11544 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
11547 self.write(&u.this.name);
11548 } else {
11549 self.generate_identifier(&u.this)?;
11550 }
11551 Ok(())
11552 }
11553
11554 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
11555 self.write_keyword("CACHE");
11556 if c.lazy {
11557 self.write_space();
11558 self.write_keyword("LAZY");
11559 }
11560 self.write_space();
11561 self.write_keyword("TABLE");
11562 self.write_space();
11563 self.generate_identifier(&c.table)?;
11564
11565 if !c.options.is_empty() {
11567 self.write_space();
11568 self.write_keyword("OPTIONS");
11569 self.write("(");
11570 for (i, (key, value)) in c.options.iter().enumerate() {
11571 if i > 0 {
11572 self.write(", ");
11573 }
11574 self.generate_expression(key)?;
11575 self.write(" = ");
11576 self.generate_expression(value)?;
11577 }
11578 self.write(")");
11579 }
11580
11581 if let Some(query) = &c.query {
11583 self.write_space();
11584 self.write_keyword("AS");
11585 self.write_space();
11586 self.generate_expression(query)?;
11587 }
11588
11589 Ok(())
11590 }
11591
11592 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
11593 self.write_keyword("UNCACHE TABLE");
11594 if u.if_exists {
11595 self.write_space();
11596 self.write_keyword("IF EXISTS");
11597 }
11598 self.write_space();
11599 self.generate_identifier(&u.table)?;
11600 Ok(())
11601 }
11602
11603 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
11604 self.write_keyword("LOAD DATA");
11605 if l.local {
11606 self.write_space();
11607 self.write_keyword("LOCAL");
11608 }
11609 self.write_space();
11610 self.write_keyword("INPATH");
11611 self.write_space();
11612 self.write("'");
11613 self.write(&l.inpath);
11614 self.write("'");
11615
11616 if l.overwrite {
11617 self.write_space();
11618 self.write_keyword("OVERWRITE");
11619 }
11620
11621 self.write_space();
11622 self.write_keyword("INTO TABLE");
11623 self.write_space();
11624 self.generate_expression(&l.table)?;
11625
11626 if !l.partition.is_empty() {
11628 self.write_space();
11629 self.write_keyword("PARTITION");
11630 self.write("(");
11631 for (i, (col, val)) in l.partition.iter().enumerate() {
11632 if i > 0 {
11633 self.write(", ");
11634 }
11635 self.generate_identifier(col)?;
11636 self.write(" = ");
11637 self.generate_expression(val)?;
11638 }
11639 self.write(")");
11640 }
11641
11642 if let Some(fmt) = &l.input_format {
11644 self.write_space();
11645 self.write_keyword("INPUTFORMAT");
11646 self.write_space();
11647 self.write("'");
11648 self.write(fmt);
11649 self.write("'");
11650 }
11651
11652 if let Some(serde) = &l.serde {
11654 self.write_space();
11655 self.write_keyword("SERDE");
11656 self.write_space();
11657 self.write("'");
11658 self.write(serde);
11659 self.write("'");
11660 }
11661
11662 Ok(())
11663 }
11664
11665 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
11666 self.write_keyword("PRAGMA");
11667 self.write_space();
11668
11669 if let Some(schema) = &p.schema {
11671 self.generate_identifier(schema)?;
11672 self.write(".");
11673 }
11674
11675 self.generate_identifier(&p.name)?;
11677
11678 if p.use_assignment_syntax {
11680 self.write(" = ");
11681 if let Some(value) = &p.value {
11682 self.generate_expression(value)?;
11683 } else if let Some(arg) = p.args.first() {
11684 self.generate_expression(arg)?;
11685 }
11686 } else if !p.args.is_empty() {
11687 self.write("(");
11688 for (i, arg) in p.args.iter().enumerate() {
11689 if i > 0 {
11690 self.write(", ");
11691 }
11692 self.generate_expression(arg)?;
11693 }
11694 self.write(")");
11695 }
11696
11697 Ok(())
11698 }
11699
11700 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
11701 self.write_keyword("GRANT");
11702 self.write_space();
11703
11704 for (i, privilege) in g.privileges.iter().enumerate() {
11706 if i > 0 {
11707 self.write(", ");
11708 }
11709 self.write_keyword(&privilege.name);
11710 if !privilege.columns.is_empty() {
11712 self.write("(");
11713 for (j, col) in privilege.columns.iter().enumerate() {
11714 if j > 0 {
11715 self.write(", ");
11716 }
11717 self.write(col);
11718 }
11719 self.write(")");
11720 }
11721 }
11722
11723 self.write_space();
11724 self.write_keyword("ON");
11725 self.write_space();
11726
11727 if let Some(kind) = &g.kind {
11729 self.write_keyword(kind);
11730 self.write_space();
11731 }
11732
11733 {
11735 use crate::dialects::DialectType;
11736 let should_upper = matches!(
11737 self.config.dialect,
11738 Some(DialectType::PostgreSQL)
11739 | Some(DialectType::CockroachDB)
11740 | Some(DialectType::Materialize)
11741 | Some(DialectType::RisingWave)
11742 ) && (g.kind.as_deref() == Some("FUNCTION")
11743 || g.kind.as_deref() == Some("PROCEDURE"));
11744 if should_upper {
11745 use crate::expressions::Identifier;
11746 let upper_id = Identifier {
11747 name: g.securable.name.to_ascii_uppercase(),
11748 quoted: g.securable.quoted,
11749 ..g.securable.clone()
11750 };
11751 self.generate_identifier(&upper_id)?;
11752 } else {
11753 self.generate_identifier(&g.securable)?;
11754 }
11755 }
11756
11757 if !g.function_params.is_empty() {
11759 self.write("(");
11760 for (i, param) in g.function_params.iter().enumerate() {
11761 if i > 0 {
11762 self.write(", ");
11763 }
11764 self.write(param);
11765 }
11766 self.write(")");
11767 }
11768
11769 self.write_space();
11770 self.write_keyword("TO");
11771 self.write_space();
11772
11773 for (i, principal) in g.principals.iter().enumerate() {
11775 if i > 0 {
11776 self.write(", ");
11777 }
11778 if principal.is_role {
11779 self.write_keyword("ROLE");
11780 self.write_space();
11781 } else if principal.is_group {
11782 self.write_keyword("GROUP");
11783 self.write_space();
11784 } else if principal.is_share {
11785 self.write_keyword("SHARE");
11786 self.write_space();
11787 }
11788 self.generate_identifier(&principal.name)?;
11789 }
11790
11791 if g.grant_option {
11793 self.write_space();
11794 self.write_keyword("WITH GRANT OPTION");
11795 }
11796
11797 if let Some(ref principal) = g.as_principal {
11799 self.write_space();
11800 self.write_keyword("AS");
11801 self.write_space();
11802 self.generate_identifier(principal)?;
11803 }
11804
11805 Ok(())
11806 }
11807
11808 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
11809 self.write_keyword("REVOKE");
11810 self.write_space();
11811
11812 if r.grant_option {
11814 self.write_keyword("GRANT OPTION FOR");
11815 self.write_space();
11816 }
11817
11818 for (i, privilege) in r.privileges.iter().enumerate() {
11820 if i > 0 {
11821 self.write(", ");
11822 }
11823 self.write_keyword(&privilege.name);
11824 if !privilege.columns.is_empty() {
11826 self.write("(");
11827 for (j, col) in privilege.columns.iter().enumerate() {
11828 if j > 0 {
11829 self.write(", ");
11830 }
11831 self.write(col);
11832 }
11833 self.write(")");
11834 }
11835 }
11836
11837 self.write_space();
11838 self.write_keyword("ON");
11839 self.write_space();
11840
11841 if let Some(kind) = &r.kind {
11843 self.write_keyword(kind);
11844 self.write_space();
11845 }
11846
11847 {
11849 use crate::dialects::DialectType;
11850 let should_upper = matches!(
11851 self.config.dialect,
11852 Some(DialectType::PostgreSQL)
11853 | Some(DialectType::CockroachDB)
11854 | Some(DialectType::Materialize)
11855 | Some(DialectType::RisingWave)
11856 ) && (r.kind.as_deref() == Some("FUNCTION")
11857 || r.kind.as_deref() == Some("PROCEDURE"));
11858 if should_upper {
11859 use crate::expressions::Identifier;
11860 let upper_id = Identifier {
11861 name: r.securable.name.to_ascii_uppercase(),
11862 quoted: r.securable.quoted,
11863 ..r.securable.clone()
11864 };
11865 self.generate_identifier(&upper_id)?;
11866 } else {
11867 self.generate_identifier(&r.securable)?;
11868 }
11869 }
11870
11871 if !r.function_params.is_empty() {
11873 self.write("(");
11874 for (i, param) in r.function_params.iter().enumerate() {
11875 if i > 0 {
11876 self.write(", ");
11877 }
11878 self.write(param);
11879 }
11880 self.write(")");
11881 }
11882
11883 self.write_space();
11884 self.write_keyword("FROM");
11885 self.write_space();
11886
11887 for (i, principal) in r.principals.iter().enumerate() {
11889 if i > 0 {
11890 self.write(", ");
11891 }
11892 if principal.is_role {
11893 self.write_keyword("ROLE");
11894 self.write_space();
11895 } else if principal.is_group {
11896 self.write_keyword("GROUP");
11897 self.write_space();
11898 } else if principal.is_share {
11899 self.write_keyword("SHARE");
11900 self.write_space();
11901 }
11902 self.generate_identifier(&principal.name)?;
11903 }
11904
11905 if r.cascade {
11907 self.write_space();
11908 self.write_keyword("CASCADE");
11909 } else if r.restrict {
11910 self.write_space();
11911 self.write_keyword("RESTRICT");
11912 }
11913
11914 Ok(())
11915 }
11916
11917 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11918 self.write_keyword("COMMENT");
11919
11920 if c.exists {
11922 self.write_space();
11923 self.write_keyword("IF EXISTS");
11924 }
11925
11926 self.write_space();
11927 self.write_keyword("ON");
11928
11929 if c.materialized {
11931 self.write_space();
11932 self.write_keyword("MATERIALIZED");
11933 }
11934
11935 self.write_space();
11936 self.write_keyword(&c.kind);
11937 self.write_space();
11938
11939 self.generate_expression(&c.this)?;
11941
11942 self.write_space();
11943 self.write_keyword("IS");
11944 self.write_space();
11945
11946 self.generate_expression(&c.expression)?;
11948
11949 Ok(())
11950 }
11951
11952 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11953 self.write_keyword("SET");
11954
11955 for (i, item) in s.items.iter().enumerate() {
11956 if i > 0 {
11957 self.write(",");
11958 }
11959 self.write_space();
11960
11961 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11963 if let Some(ref kind) = item.kind {
11964 if has_variable_kind {
11968 if matches!(
11969 self.config.dialect,
11970 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
11971 ) {
11972 self.write_keyword("VARIABLE");
11973 self.write_space();
11974 }
11975 } else {
11976 self.write_keyword(kind);
11977 self.write_space();
11978 }
11979 }
11980
11981 let name_str = match &item.name {
11983 Expression::Identifier(id) => Some(id.name.as_str()),
11984 _ => None,
11985 };
11986
11987 let is_transaction = name_str == Some("TRANSACTION");
11988 let is_character_set = name_str == Some("CHARACTER SET");
11989 let is_names = name_str == Some("NAMES");
11990 let is_collate = name_str == Some("COLLATE");
11991 let is_value_only =
11992 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11993
11994 if is_transaction {
11995 self.write_keyword("TRANSACTION");
11997 if let Expression::Identifier(id) = &item.value {
11998 if !id.name.is_empty() {
11999 self.write_space();
12000 self.write(&id.name);
12001 }
12002 }
12003 } else if is_character_set {
12004 self.write_keyword("CHARACTER SET");
12006 self.write_space();
12007 self.generate_set_value(&item.value)?;
12008 } else if is_names {
12009 self.write_keyword("NAMES");
12011 self.write_space();
12012 self.generate_set_value(&item.value)?;
12013 } else if is_collate {
12014 self.write_keyword("COLLATE");
12016 self.write_space();
12017 self.generate_set_value(&item.value)?;
12018 } else if has_variable_kind {
12019 if let Some(ns) = name_str {
12022 self.write(ns);
12023 } else {
12024 self.generate_expression(&item.name)?;
12025 }
12026 self.write(" = ");
12027 self.generate_set_value(&item.value)?;
12028 } else if is_value_only {
12029 self.generate_expression(&item.name)?;
12031 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
12032 self.generate_expression(&item.name)?;
12034 self.write_space();
12035 self.generate_set_value(&item.value)?;
12036 } else {
12037 match &item.name {
12040 Expression::Identifier(id) => {
12041 self.write(&id.name);
12042 }
12043 _ => {
12044 self.generate_expression(&item.name)?;
12045 }
12046 }
12047 self.write(" = ");
12048 self.generate_set_value(&item.value)?;
12049 }
12050 }
12051
12052 Ok(())
12053 }
12054
12055 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
12058 if let Expression::Identifier(id) = value {
12059 match id.name.as_str() {
12060 "DEFAULT" | "ON" | "OFF" => {
12061 self.write_keyword(&id.name);
12062 return Ok(());
12063 }
12064 _ => {}
12065 }
12066 }
12067 self.generate_expression(value)
12068 }
12069
12070 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
12073 self.write_keyword("ALTER");
12074 if let Some(ref algorithm) = av.algorithm {
12076 self.write_space();
12077 self.write_keyword("ALGORITHM");
12078 self.write(" = ");
12079 self.write_keyword(algorithm);
12080 }
12081 if let Some(ref definer) = av.definer {
12082 self.write_space();
12083 self.write_keyword("DEFINER");
12084 self.write(" = ");
12085 self.write(definer);
12086 }
12087 if let Some(ref sql_security) = av.sql_security {
12088 self.write_space();
12089 self.write_keyword("SQL SECURITY");
12090 self.write(" = ");
12091 self.write_keyword(sql_security);
12092 }
12093 self.write_space();
12094 self.write_keyword("VIEW");
12095 self.write_space();
12096 self.generate_table(&av.name)?;
12097
12098 if !av.columns.is_empty() {
12100 self.write(" (");
12101 for (i, col) in av.columns.iter().enumerate() {
12102 if i > 0 {
12103 self.write(", ");
12104 }
12105 self.generate_identifier(&col.name)?;
12106 if let Some(ref comment) = col.comment {
12107 self.write_space();
12108 self.write_keyword("COMMENT");
12109 self.write(" ");
12110 self.generate_string_literal(comment)?;
12111 }
12112 }
12113 self.write(")");
12114 }
12115
12116 if let Some(ref opt) = av.with_option {
12118 self.write_space();
12119 self.write_keyword("WITH");
12120 self.write_space();
12121 self.write_keyword(opt);
12122 }
12123
12124 for action in &av.actions {
12125 self.write_space();
12126 match action {
12127 AlterViewAction::Rename(new_name) => {
12128 self.write_keyword("RENAME TO");
12129 self.write_space();
12130 self.generate_table(new_name)?;
12131 }
12132 AlterViewAction::OwnerTo(owner) => {
12133 self.write_keyword("OWNER TO");
12134 self.write_space();
12135 self.generate_identifier(owner)?;
12136 }
12137 AlterViewAction::SetSchema(schema) => {
12138 self.write_keyword("SET SCHEMA");
12139 self.write_space();
12140 self.generate_identifier(schema)?;
12141 }
12142 AlterViewAction::SetAuthorization(auth) => {
12143 self.write_keyword("SET AUTHORIZATION");
12144 self.write_space();
12145 self.write(auth);
12146 }
12147 AlterViewAction::AlterColumn { name, action } => {
12148 self.write_keyword("ALTER COLUMN");
12149 self.write_space();
12150 self.generate_identifier(name)?;
12151 self.write_space();
12152 self.generate_alter_column_action(action)?;
12153 }
12154 AlterViewAction::AsSelect(query) => {
12155 self.write_keyword("AS");
12156 self.write_space();
12157 self.generate_expression(query)?;
12158 }
12159 AlterViewAction::SetTblproperties(props) => {
12160 self.write_keyword("SET TBLPROPERTIES");
12161 self.write(" (");
12162 for (i, (key, value)) in props.iter().enumerate() {
12163 if i > 0 {
12164 self.write(", ");
12165 }
12166 self.generate_string_literal(key)?;
12167 self.write("=");
12168 self.generate_string_literal(value)?;
12169 }
12170 self.write(")");
12171 }
12172 AlterViewAction::UnsetTblproperties(keys) => {
12173 self.write_keyword("UNSET TBLPROPERTIES");
12174 self.write(" (");
12175 for (i, key) in keys.iter().enumerate() {
12176 if i > 0 {
12177 self.write(", ");
12178 }
12179 self.generate_string_literal(key)?;
12180 }
12181 self.write(")");
12182 }
12183 }
12184 }
12185
12186 Ok(())
12187 }
12188
12189 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
12190 self.write_keyword("ALTER INDEX");
12191 self.write_space();
12192 self.generate_identifier(&ai.name)?;
12193
12194 if let Some(table) = &ai.table {
12195 self.write_space();
12196 self.write_keyword("ON");
12197 self.write_space();
12198 self.generate_table(table)?;
12199 }
12200
12201 for action in &ai.actions {
12202 self.write_space();
12203 match action {
12204 AlterIndexAction::Rename(new_name) => {
12205 self.write_keyword("RENAME TO");
12206 self.write_space();
12207 self.generate_identifier(new_name)?;
12208 }
12209 AlterIndexAction::SetTablespace(tablespace) => {
12210 self.write_keyword("SET TABLESPACE");
12211 self.write_space();
12212 self.generate_identifier(tablespace)?;
12213 }
12214 AlterIndexAction::Visible(visible) => {
12215 if *visible {
12216 self.write_keyword("VISIBLE");
12217 } else {
12218 self.write_keyword("INVISIBLE");
12219 }
12220 }
12221 }
12222 }
12223
12224 Ok(())
12225 }
12226
12227 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
12228 for comment in &cs.leading_comments {
12230 self.write_formatted_comment(comment);
12231 self.write_space();
12232 }
12233
12234 let saved_athena_hive_context = self.athena_hive_context;
12236 if matches!(
12237 self.config.dialect,
12238 Some(crate::dialects::DialectType::Athena)
12239 ) {
12240 self.athena_hive_context = true;
12241 }
12242
12243 self.write_keyword("CREATE SCHEMA");
12244
12245 if cs.if_not_exists {
12246 self.write_space();
12247 self.write_keyword("IF NOT EXISTS");
12248 }
12249
12250 self.write_space();
12251 for (i, part) in cs.name.iter().enumerate() {
12252 if i > 0 {
12253 self.write(".");
12254 }
12255 self.generate_identifier(part)?;
12256 }
12257
12258 if let Some(ref clone_parts) = cs.clone_from {
12259 self.write_keyword(" CLONE ");
12260 for (i, part) in clone_parts.iter().enumerate() {
12261 if i > 0 {
12262 self.write(".");
12263 }
12264 self.generate_identifier(part)?;
12265 }
12266 }
12267
12268 if let Some(ref at_clause) = cs.at_clause {
12269 self.write_space();
12270 self.generate_expression(at_clause)?;
12271 }
12272
12273 if let Some(auth) = &cs.authorization {
12274 self.write_space();
12275 self.write_keyword("AUTHORIZATION");
12276 self.write_space();
12277 self.generate_identifier(auth)?;
12278 }
12279
12280 let with_properties: Vec<_> = cs
12283 .properties
12284 .iter()
12285 .filter(|p| matches!(p, Expression::Property(_)))
12286 .collect();
12287 let other_properties: Vec<_> = cs
12288 .properties
12289 .iter()
12290 .filter(|p| !matches!(p, Expression::Property(_)))
12291 .collect();
12292
12293 if !with_properties.is_empty() {
12295 self.write_space();
12296 self.write_keyword("WITH");
12297 self.write(" (");
12298 for (i, prop) in with_properties.iter().enumerate() {
12299 if i > 0 {
12300 self.write(", ");
12301 }
12302 self.generate_expression(prop)?;
12303 }
12304 self.write(")");
12305 }
12306
12307 for prop in other_properties {
12309 self.write_space();
12310 self.generate_expression(prop)?;
12311 }
12312
12313 self.athena_hive_context = saved_athena_hive_context;
12315
12316 Ok(())
12317 }
12318
12319 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
12320 self.write_keyword("DROP SCHEMA");
12321
12322 if ds.if_exists {
12323 self.write_space();
12324 self.write_keyword("IF EXISTS");
12325 }
12326
12327 self.write_space();
12328 self.generate_identifier(&ds.name)?;
12329
12330 if ds.cascade {
12331 self.write_space();
12332 self.write_keyword("CASCADE");
12333 }
12334
12335 Ok(())
12336 }
12337
12338 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
12339 self.write_keyword("DROP NAMESPACE");
12340
12341 if dn.if_exists {
12342 self.write_space();
12343 self.write_keyword("IF EXISTS");
12344 }
12345
12346 self.write_space();
12347 self.generate_identifier(&dn.name)?;
12348
12349 if dn.cascade {
12350 self.write_space();
12351 self.write_keyword("CASCADE");
12352 }
12353
12354 Ok(())
12355 }
12356
12357 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
12358 self.write_keyword("CREATE DATABASE");
12359
12360 if cd.if_not_exists {
12361 self.write_space();
12362 self.write_keyword("IF NOT EXISTS");
12363 }
12364
12365 self.write_space();
12366 self.generate_identifier(&cd.name)?;
12367
12368 if let Some(ref clone_src) = cd.clone_from {
12369 self.write_keyword(" CLONE ");
12370 self.generate_identifier(clone_src)?;
12371 }
12372
12373 if let Some(ref at_clause) = cd.at_clause {
12375 self.write_space();
12376 self.generate_expression(at_clause)?;
12377 }
12378
12379 for option in &cd.options {
12380 self.write_space();
12381 match option {
12382 DatabaseOption::CharacterSet(charset) => {
12383 self.write_keyword("CHARACTER SET");
12384 self.write(" = ");
12385 self.write(&format!("'{}'", charset));
12386 }
12387 DatabaseOption::Collate(collate) => {
12388 self.write_keyword("COLLATE");
12389 self.write(" = ");
12390 self.write(&format!("'{}'", collate));
12391 }
12392 DatabaseOption::Owner(owner) => {
12393 self.write_keyword("OWNER");
12394 self.write(" = ");
12395 self.generate_identifier(owner)?;
12396 }
12397 DatabaseOption::Template(template) => {
12398 self.write_keyword("TEMPLATE");
12399 self.write(" = ");
12400 self.generate_identifier(template)?;
12401 }
12402 DatabaseOption::Encoding(encoding) => {
12403 self.write_keyword("ENCODING");
12404 self.write(" = ");
12405 self.write(&format!("'{}'", encoding));
12406 }
12407 DatabaseOption::Location(location) => {
12408 self.write_keyword("LOCATION");
12409 self.write(" = ");
12410 self.write(&format!("'{}'", location));
12411 }
12412 }
12413 }
12414
12415 Ok(())
12416 }
12417
12418 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
12419 self.write_keyword("DROP DATABASE");
12420
12421 if dd.if_exists {
12422 self.write_space();
12423 self.write_keyword("IF EXISTS");
12424 }
12425
12426 self.write_space();
12427 self.generate_identifier(&dd.name)?;
12428
12429 if dd.sync {
12430 self.write_space();
12431 self.write_keyword("SYNC");
12432 }
12433
12434 Ok(())
12435 }
12436
12437 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
12438 self.write_keyword("CREATE");
12439
12440 if cf.or_alter {
12441 self.write_space();
12442 self.write_keyword("OR ALTER");
12443 } else if cf.or_replace {
12444 self.write_space();
12445 self.write_keyword("OR REPLACE");
12446 }
12447
12448 if cf.temporary {
12449 self.write_space();
12450 self.write_keyword("TEMPORARY");
12451 }
12452
12453 self.write_space();
12454 if cf.is_table_function {
12455 self.write_keyword("TABLE FUNCTION");
12456 } else {
12457 self.write_keyword("FUNCTION");
12458 }
12459
12460 if cf.if_not_exists {
12461 self.write_space();
12462 self.write_keyword("IF NOT EXISTS");
12463 }
12464
12465 self.write_space();
12466 self.generate_table(&cf.name)?;
12467 if cf.has_parens {
12468 let func_multiline = self.config.pretty
12469 && matches!(
12470 self.config.dialect,
12471 Some(crate::dialects::DialectType::TSQL)
12472 | Some(crate::dialects::DialectType::Fabric)
12473 )
12474 && !cf.parameters.is_empty();
12475 if func_multiline {
12476 self.write("(\n");
12477 self.indent_level += 2;
12478 self.write_indent();
12479 self.generate_function_parameters(&cf.parameters)?;
12480 self.write("\n");
12481 self.indent_level -= 2;
12482 self.write(")");
12483 } else {
12484 self.write("(");
12485 self.generate_function_parameters(&cf.parameters)?;
12486 self.write(")");
12487 }
12488 }
12489
12490 let use_multiline = self.config.pretty
12493 && matches!(
12494 self.config.dialect,
12495 Some(crate::dialects::DialectType::BigQuery)
12496 | Some(crate::dialects::DialectType::TSQL)
12497 | Some(crate::dialects::DialectType::Fabric)
12498 );
12499
12500 if cf.language_first {
12501 if let Some(lang) = &cf.language {
12503 if use_multiline {
12504 self.write_newline();
12505 } else {
12506 self.write_space();
12507 }
12508 self.write_keyword("LANGUAGE");
12509 self.write_space();
12510 self.write(lang);
12511 }
12512
12513 if let Some(sql_data) = &cf.sql_data_access {
12515 self.write_space();
12516 match sql_data {
12517 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12518 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12519 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12520 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12521 }
12522 }
12523
12524 if let Some(ref rtb) = cf.returns_table_body {
12525 if use_multiline {
12526 self.write_newline();
12527 } else {
12528 self.write_space();
12529 }
12530 self.write_keyword("RETURNS");
12531 self.write_space();
12532 self.write(rtb);
12533 } else if let Some(return_type) = &cf.return_type {
12534 if use_multiline {
12535 self.write_newline();
12536 } else {
12537 self.write_space();
12538 }
12539 self.write_keyword("RETURNS");
12540 self.write_space();
12541 self.generate_data_type(return_type)?;
12542 }
12543 } else {
12544 let is_duckdb = matches!(
12547 self.config.dialect,
12548 Some(crate::dialects::DialectType::DuckDB)
12549 );
12550 if let Some(ref rtb) = cf.returns_table_body {
12551 if !(is_duckdb && rtb.is_empty()) {
12552 if use_multiline {
12553 self.write_newline();
12554 } else {
12555 self.write_space();
12556 }
12557 self.write_keyword("RETURNS");
12558 self.write_space();
12559 self.write(rtb);
12560 }
12561 } else if let Some(return_type) = &cf.return_type {
12562 if !is_duckdb {
12564 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
12565 if use_multiline {
12566 self.write_newline();
12567 } else {
12568 self.write_space();
12569 }
12570 self.write_keyword("RETURNS");
12571 self.write_space();
12572 if is_table_return {
12573 self.write_keyword("TABLE");
12574 } else {
12575 self.generate_data_type(return_type)?;
12576 }
12577 }
12578 }
12579 }
12580
12581 if !cf.property_order.is_empty() {
12583 let is_bigquery = matches!(
12585 self.config.dialect,
12586 Some(crate::dialects::DialectType::BigQuery)
12587 );
12588 let property_order = if is_bigquery {
12589 let mut reordered = Vec::new();
12591 let mut has_as = false;
12592 let mut has_options = false;
12593 for prop in &cf.property_order {
12594 match prop {
12595 FunctionPropertyKind::As => has_as = true,
12596 FunctionPropertyKind::Options => has_options = true,
12597 _ => {}
12598 }
12599 }
12600 if has_as && has_options {
12601 for prop in &cf.property_order {
12603 if *prop != FunctionPropertyKind::As
12604 && *prop != FunctionPropertyKind::Options
12605 {
12606 reordered.push(*prop);
12607 }
12608 }
12609 reordered.push(FunctionPropertyKind::Options);
12610 reordered.push(FunctionPropertyKind::As);
12611 reordered
12612 } else {
12613 cf.property_order.clone()
12614 }
12615 } else {
12616 cf.property_order.clone()
12617 };
12618
12619 for prop in &property_order {
12620 match prop {
12621 FunctionPropertyKind::Set => {
12622 self.generate_function_set_options(cf)?;
12623 }
12624 FunctionPropertyKind::As => {
12625 self.generate_function_body(cf)?;
12626 }
12627 FunctionPropertyKind::Using => {
12628 self.generate_function_using_resources(cf)?;
12629 }
12630 FunctionPropertyKind::Language => {
12631 if !cf.language_first {
12632 if let Some(lang) = &cf.language {
12634 let use_multiline = self.config.pretty
12636 && matches!(
12637 self.config.dialect,
12638 Some(crate::dialects::DialectType::BigQuery)
12639 );
12640 if use_multiline {
12641 self.write_newline();
12642 } else {
12643 self.write_space();
12644 }
12645 self.write_keyword("LANGUAGE");
12646 self.write_space();
12647 self.write(lang);
12648 }
12649 }
12650 }
12651 FunctionPropertyKind::Determinism => {
12652 self.generate_function_determinism(cf)?;
12653 }
12654 FunctionPropertyKind::NullInput => {
12655 self.generate_function_null_input(cf)?;
12656 }
12657 FunctionPropertyKind::Security => {
12658 self.generate_function_security(cf)?;
12659 }
12660 FunctionPropertyKind::SqlDataAccess => {
12661 if !cf.language_first {
12662 self.generate_function_sql_data_access(cf)?;
12664 }
12665 }
12666 FunctionPropertyKind::Options => {
12667 if !cf.options.is_empty() {
12668 self.write_space();
12669 self.generate_options_clause(&cf.options)?;
12670 }
12671 }
12672 FunctionPropertyKind::Environment => {
12673 if !cf.environment.is_empty() {
12674 self.write_space();
12675 self.generate_environment_clause(&cf.environment)?;
12676 }
12677 }
12678 FunctionPropertyKind::Handler => {
12679 if let Some(ref h) = cf.handler {
12680 self.write_space();
12681 self.write_keyword("HANDLER");
12682 if cf.handler_uses_eq {
12683 self.write(" = ");
12684 } else {
12685 self.write_space();
12686 }
12687 self.write("'");
12688 self.write(h);
12689 self.write("'");
12690 }
12691 }
12692 FunctionPropertyKind::RuntimeVersion => {
12693 if let Some(ref runtime_version) = cf.runtime_version {
12694 self.write_space();
12695 self.write_keyword("RUNTIME_VERSION");
12696 self.write("='");
12697 self.write(runtime_version);
12698 self.write("'");
12699 }
12700 }
12701 FunctionPropertyKind::Packages => {
12702 if let Some(ref packages) = cf.packages {
12703 self.write_space();
12704 self.write_keyword("PACKAGES");
12705 self.write("=(");
12706 for (i, package) in packages.iter().enumerate() {
12707 if i > 0 {
12708 self.write(", ");
12709 }
12710 self.write("'");
12711 self.write(package);
12712 self.write("'");
12713 }
12714 self.write(")");
12715 }
12716 }
12717 FunctionPropertyKind::ParameterStyle => {
12718 if let Some(ref ps) = cf.parameter_style {
12719 self.write_space();
12720 self.write_keyword("PARAMETER STYLE");
12721 self.write_space();
12722 self.write_keyword(ps);
12723 }
12724 }
12725 }
12726 }
12727
12728 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
12730 {
12731 self.write_space();
12732 self.generate_options_clause(&cf.options)?;
12733 }
12734
12735 if !cf.environment.is_empty()
12737 && !cf
12738 .property_order
12739 .contains(&FunctionPropertyKind::Environment)
12740 {
12741 self.write_space();
12742 self.generate_environment_clause(&cf.environment)?;
12743 }
12744 } else {
12745 if matches!(
12748 self.config.dialect,
12749 Some(crate::dialects::DialectType::BigQuery)
12750 ) {
12751 self.generate_function_determinism(cf)?;
12752 }
12753
12754 let use_multiline = self.config.pretty
12756 && matches!(
12757 self.config.dialect,
12758 Some(crate::dialects::DialectType::BigQuery)
12759 );
12760
12761 if !cf.language_first {
12762 if let Some(lang) = &cf.language {
12763 if use_multiline {
12764 self.write_newline();
12765 } else {
12766 self.write_space();
12767 }
12768 self.write_keyword("LANGUAGE");
12769 self.write_space();
12770 self.write(lang);
12771 }
12772
12773 self.generate_function_sql_data_access(cf)?;
12775 }
12776
12777 if !matches!(
12779 self.config.dialect,
12780 Some(crate::dialects::DialectType::BigQuery)
12781 ) {
12782 self.generate_function_determinism(cf)?;
12783 }
12784
12785 self.generate_function_null_input(cf)?;
12786 self.generate_function_security(cf)?;
12787 self.generate_function_set_options(cf)?;
12788
12789 if !cf.options.is_empty() {
12791 self.write_space();
12792 self.generate_options_clause(&cf.options)?;
12793 }
12794
12795 if !cf.environment.is_empty() {
12797 self.write_space();
12798 self.generate_environment_clause(&cf.environment)?;
12799 }
12800
12801 if let Some(ref h) = cf.handler {
12802 self.write_space();
12803 self.write_keyword("HANDLER");
12804 if cf.handler_uses_eq {
12805 self.write(" = ");
12806 } else {
12807 self.write_space();
12808 }
12809 self.write("'");
12810 self.write(h);
12811 self.write("'");
12812 }
12813
12814 if let Some(ref runtime_version) = cf.runtime_version {
12815 self.write_space();
12816 self.write_keyword("RUNTIME_VERSION");
12817 self.write("='");
12818 self.write(runtime_version);
12819 self.write("'");
12820 }
12821
12822 if let Some(ref packages) = cf.packages {
12823 self.write_space();
12824 self.write_keyword("PACKAGES");
12825 self.write("=(");
12826 for (i, package) in packages.iter().enumerate() {
12827 if i > 0 {
12828 self.write(", ");
12829 }
12830 self.write("'");
12831 self.write(package);
12832 self.write("'");
12833 }
12834 self.write(")");
12835 }
12836
12837 self.generate_function_body(cf)?;
12838 self.generate_function_using_resources(cf)?;
12839 }
12840
12841 Ok(())
12842 }
12843
12844 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
12846 for opt in &cf.set_options {
12847 self.write_space();
12848 self.write_keyword("SET");
12849 self.write_space();
12850 self.write(&opt.name);
12851 match &opt.value {
12852 FunctionSetValue::Value { value, use_to } => {
12853 if *use_to {
12854 self.write(" TO ");
12855 } else {
12856 self.write(" = ");
12857 }
12858 self.write(value);
12859 }
12860 FunctionSetValue::FromCurrent => {
12861 self.write_space();
12862 self.write_keyword("FROM CURRENT");
12863 }
12864 }
12865 }
12866 Ok(())
12867 }
12868
12869 fn generate_function_using_resources(&mut self, cf: &CreateFunction) -> Result<()> {
12870 if cf.using_resources.is_empty() {
12871 return Ok(());
12872 }
12873
12874 self.write_space();
12875 self.write_keyword("USING");
12876 for resource in &cf.using_resources {
12877 self.write_space();
12878 self.write_keyword(&resource.kind);
12879 self.write_space();
12880 self.generate_string_literal(&resource.uri)?;
12881 }
12882 Ok(())
12883 }
12884
12885 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
12887 if let Some(body) = &cf.body {
12888 self.write_space();
12890 let use_multiline = self.config.pretty
12892 && matches!(
12893 self.config.dialect,
12894 Some(crate::dialects::DialectType::BigQuery)
12895 );
12896 match body {
12897 FunctionBody::Block(block) => {
12898 self.write_keyword("AS");
12899 if matches!(
12900 self.config.dialect,
12901 Some(crate::dialects::DialectType::TSQL)
12902 ) {
12903 self.write(" BEGIN ");
12904 self.write(block);
12905 self.write(" END");
12906 } else if matches!(
12907 self.config.dialect,
12908 Some(crate::dialects::DialectType::PostgreSQL)
12909 ) {
12910 self.write(" $$");
12911 self.write(block);
12912 self.write("$$");
12913 } else {
12914 let escaped = self.escape_block_for_single_quote(block);
12916 if use_multiline {
12918 self.write_newline();
12919 } else {
12920 self.write(" ");
12921 }
12922 self.write("'");
12923 self.write(&escaped);
12924 self.write("'");
12925 }
12926 }
12927 FunctionBody::StringLiteral(s) => {
12928 self.write_keyword("AS");
12929 if use_multiline {
12931 self.write_newline();
12932 } else {
12933 self.write(" ");
12934 }
12935 self.write("'");
12936 self.write(s);
12937 self.write("'");
12938 }
12939 FunctionBody::Expression(expr) => {
12940 self.write_keyword("AS");
12941 self.write_space();
12942 self.generate_expression(expr)?;
12943 }
12944 FunctionBody::External(name) => {
12945 self.write_keyword("EXTERNAL NAME");
12946 self.write(" '");
12947 self.write(name);
12948 self.write("'");
12949 }
12950 FunctionBody::Return(expr) => {
12951 if matches!(
12952 self.config.dialect,
12953 Some(crate::dialects::DialectType::DuckDB)
12954 ) {
12955 self.write_keyword("AS");
12957 self.write_space();
12958 let is_table_return = cf.returns_table_body.is_some()
12960 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
12961 if is_table_return {
12962 self.write_keyword("TABLE");
12963 self.write_space();
12964 }
12965 self.generate_expression(expr)?;
12966 } else {
12967 if self.config.create_function_return_as {
12968 self.write_keyword("AS");
12969 if self.config.pretty
12971 && matches!(
12972 self.config.dialect,
12973 Some(crate::dialects::DialectType::TSQL)
12974 | Some(crate::dialects::DialectType::Fabric)
12975 )
12976 {
12977 self.write_newline();
12978 } else {
12979 self.write_space();
12980 }
12981 }
12982 self.write_keyword("RETURN");
12983 self.write_space();
12984 self.generate_expression(expr)?;
12985 }
12986 }
12987 FunctionBody::Statements(stmts) => {
12988 self.write_keyword("AS");
12989 self.write(" BEGIN ");
12990 for (i, stmt) in stmts.iter().enumerate() {
12991 if i > 0 {
12992 self.write(" ");
12993 }
12994 self.generate_expression(stmt)?;
12995 self.write(";");
12996 }
12997 self.write(" END");
12998 }
12999 FunctionBody::RawBlock(text) => {
13000 self.write_newline();
13001 self.write(text);
13002 }
13003 FunctionBody::DollarQuoted { content, tag } => {
13004 self.write_keyword("AS");
13005 self.write(" ");
13006 let supports_dollar_quoting = matches!(
13008 self.config.dialect,
13009 Some(crate::dialects::DialectType::PostgreSQL)
13010 | Some(crate::dialects::DialectType::Databricks)
13011 | Some(crate::dialects::DialectType::Redshift)
13012 | Some(crate::dialects::DialectType::DuckDB)
13013 );
13014 if supports_dollar_quoting {
13015 self.write("$");
13017 if let Some(t) = tag {
13018 self.write(t);
13019 }
13020 self.write("$");
13021 self.write(content);
13022 self.write("$");
13023 if let Some(t) = tag {
13024 self.write(t);
13025 }
13026 self.write("$");
13027 } else {
13028 let escaped = self.escape_block_for_single_quote(content);
13030 self.write("'");
13031 self.write(&escaped);
13032 self.write("'");
13033 }
13034 }
13035 }
13036 }
13037 Ok(())
13038 }
13039
13040 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
13042 if let Some(det) = cf.deterministic {
13043 self.write_space();
13044 if matches!(
13045 self.config.dialect,
13046 Some(crate::dialects::DialectType::BigQuery)
13047 ) {
13048 if det {
13050 self.write_keyword("DETERMINISTIC");
13051 } else {
13052 self.write_keyword("NOT DETERMINISTIC");
13053 }
13054 } else {
13055 if det {
13057 self.write_keyword("IMMUTABLE");
13058 } else {
13059 self.write_keyword("VOLATILE");
13060 }
13061 }
13062 }
13063 Ok(())
13064 }
13065
13066 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
13068 if let Some(returns_null) = cf.returns_null_on_null_input {
13069 self.write_space();
13070 if returns_null {
13071 if cf.strict {
13072 self.write_keyword("STRICT");
13073 } else {
13074 self.write_keyword("RETURNS NULL ON NULL INPUT");
13075 }
13076 } else {
13077 self.write_keyword("CALLED ON NULL INPUT");
13078 }
13079 }
13080 Ok(())
13081 }
13082
13083 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
13085 if let Some(security) = &cf.security {
13086 self.write_space();
13087 if matches!(
13089 self.config.dialect,
13090 Some(crate::dialects::DialectType::MySQL)
13091 ) {
13092 self.write_keyword("SQL SECURITY");
13093 } else {
13094 self.write_keyword("SECURITY");
13095 }
13096 self.write_space();
13097 match security {
13098 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13099 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13100 FunctionSecurity::None => self.write_keyword("NONE"),
13101 }
13102 }
13103 Ok(())
13104 }
13105
13106 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
13108 if let Some(sql_data) = &cf.sql_data_access {
13109 self.write_space();
13110 match sql_data {
13111 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
13112 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
13113 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
13114 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
13115 }
13116 }
13117 Ok(())
13118 }
13119
13120 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
13121 for (i, param) in params.iter().enumerate() {
13122 if i > 0 {
13123 self.write(", ");
13124 }
13125
13126 if let Some(mode) = ¶m.mode {
13127 if let Some(text) = ¶m.mode_text {
13128 self.write(text);
13129 } else {
13130 match mode {
13131 ParameterMode::In => self.write_keyword("IN"),
13132 ParameterMode::Out => self.write_keyword("OUT"),
13133 ParameterMode::InOut => self.write_keyword("INOUT"),
13134 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
13135 }
13136 }
13137 self.write_space();
13138 }
13139
13140 if let Some(name) = ¶m.name {
13141 self.generate_identifier(name)?;
13142 let skip_type =
13144 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
13145 if !skip_type {
13146 self.write_space();
13147 self.generate_data_type(¶m.data_type)?;
13148 }
13149 } else {
13150 self.generate_data_type(¶m.data_type)?;
13151 }
13152
13153 if let Some(default) = ¶m.default {
13154 if self.config.parameter_default_equals {
13155 self.write(" = ");
13156 } else {
13157 self.write(" DEFAULT ");
13158 }
13159 self.generate_expression(default)?;
13160 }
13161 }
13162
13163 Ok(())
13164 }
13165
13166 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
13167 self.write_keyword("DROP FUNCTION");
13168
13169 if df.if_exists {
13170 self.write_space();
13171 self.write_keyword("IF EXISTS");
13172 }
13173
13174 self.write_space();
13175 self.generate_table(&df.name)?;
13176
13177 if let Some(params) = &df.parameters {
13178 self.write(" (");
13179 for (i, dt) in params.iter().enumerate() {
13180 if i > 0 {
13181 self.write(", ");
13182 }
13183 self.generate_data_type(dt)?;
13184 }
13185 self.write(")");
13186 }
13187
13188 if df.cascade {
13189 self.write_space();
13190 self.write_keyword("CASCADE");
13191 }
13192
13193 Ok(())
13194 }
13195
13196 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
13197 self.write_keyword("CREATE");
13198
13199 if cp.or_alter {
13200 self.write_space();
13201 self.write_keyword("OR ALTER");
13202 } else if cp.or_replace {
13203 self.write_space();
13204 self.write_keyword("OR REPLACE");
13205 }
13206
13207 self.write_space();
13208 if cp.use_proc_keyword {
13209 self.write_keyword("PROC");
13210 } else {
13211 self.write_keyword("PROCEDURE");
13212 }
13213
13214 if cp.if_not_exists {
13215 self.write_space();
13216 self.write_keyword("IF NOT EXISTS");
13217 }
13218
13219 self.write_space();
13220 self.generate_table(&cp.name)?;
13221 if cp.has_parens {
13222 self.write("(");
13223 self.generate_function_parameters(&cp.parameters)?;
13224 self.write(")");
13225 } else if !cp.parameters.is_empty() {
13226 self.write_space();
13228 self.generate_function_parameters(&cp.parameters)?;
13229 }
13230
13231 if let Some(return_type) = &cp.return_type {
13233 self.write_space();
13234 self.write_keyword("RETURNS");
13235 self.write_space();
13236 self.generate_data_type(return_type)?;
13237 }
13238
13239 if let Some(execute_as) = &cp.execute_as {
13241 self.write_space();
13242 self.write_keyword("EXECUTE AS");
13243 self.write_space();
13244 self.write_keyword(execute_as);
13245 }
13246
13247 if let Some(lang) = &cp.language {
13248 self.write_space();
13249 self.write_keyword("LANGUAGE");
13250 self.write_space();
13251 self.write(lang);
13252 }
13253
13254 if let Some(security) = &cp.security {
13255 self.write_space();
13256 self.write_keyword("SECURITY");
13257 self.write_space();
13258 match security {
13259 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
13260 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
13261 FunctionSecurity::None => self.write_keyword("NONE"),
13262 }
13263 }
13264
13265 if !cp.with_options.is_empty() {
13267 self.write_space();
13268 self.write_keyword("WITH");
13269 self.write_space();
13270 for (i, opt) in cp.with_options.iter().enumerate() {
13271 if i > 0 {
13272 self.write(", ");
13273 }
13274 self.write(opt);
13275 }
13276 }
13277
13278 if let Some(body) = &cp.body {
13279 self.write_space();
13280 match body {
13281 FunctionBody::Block(block) => {
13282 self.write_keyword("AS");
13283 if matches!(
13284 self.config.dialect,
13285 Some(crate::dialects::DialectType::TSQL)
13286 ) {
13287 self.write(" BEGIN ");
13288 self.write(block);
13289 self.write(" END");
13290 } else if matches!(
13291 self.config.dialect,
13292 Some(crate::dialects::DialectType::PostgreSQL)
13293 ) {
13294 self.write(" $$");
13295 self.write(block);
13296 self.write("$$");
13297 } else {
13298 let escaped = self.escape_block_for_single_quote(block);
13300 self.write(" '");
13301 self.write(&escaped);
13302 self.write("'");
13303 }
13304 }
13305 FunctionBody::StringLiteral(s) => {
13306 self.write_keyword("AS");
13307 self.write(" '");
13308 self.write(s);
13309 self.write("'");
13310 }
13311 FunctionBody::Expression(expr) => {
13312 self.write_keyword("AS");
13313 self.write_space();
13314 self.generate_expression(expr)?;
13315 }
13316 FunctionBody::External(name) => {
13317 self.write_keyword("EXTERNAL NAME");
13318 self.write(" '");
13319 self.write(name);
13320 self.write("'");
13321 }
13322 FunctionBody::Return(expr) => {
13323 self.write_keyword("RETURN");
13324 self.write_space();
13325 self.generate_expression(expr)?;
13326 }
13327 FunctionBody::Statements(stmts) => {
13328 self.write_keyword("AS");
13329 self.write(" BEGIN ");
13330 for (i, stmt) in stmts.iter().enumerate() {
13331 if i > 0 {
13332 self.write(" ");
13333 }
13334 self.generate_expression(stmt)?;
13335 self.write(";");
13336 }
13337 self.write(" END");
13338 }
13339 FunctionBody::RawBlock(text) => {
13340 self.write_newline();
13341 self.write(text);
13342 }
13343 FunctionBody::DollarQuoted { content, tag } => {
13344 self.write_keyword("AS");
13345 self.write(" ");
13346 let supports_dollar_quoting = matches!(
13348 self.config.dialect,
13349 Some(crate::dialects::DialectType::PostgreSQL)
13350 | Some(crate::dialects::DialectType::Databricks)
13351 | Some(crate::dialects::DialectType::Redshift)
13352 | Some(crate::dialects::DialectType::DuckDB)
13353 );
13354 if supports_dollar_quoting {
13355 self.write("$");
13357 if let Some(t) = tag {
13358 self.write(t);
13359 }
13360 self.write("$");
13361 self.write(content);
13362 self.write("$");
13363 if let Some(t) = tag {
13364 self.write(t);
13365 }
13366 self.write("$");
13367 } else {
13368 let escaped = self.escape_block_for_single_quote(content);
13370 self.write("'");
13371 self.write(&escaped);
13372 self.write("'");
13373 }
13374 }
13375 }
13376 }
13377
13378 Ok(())
13379 }
13380
13381 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
13382 self.write_keyword("DROP PROCEDURE");
13383
13384 if dp.if_exists {
13385 self.write_space();
13386 self.write_keyword("IF EXISTS");
13387 }
13388
13389 self.write_space();
13390 self.generate_table(&dp.name)?;
13391
13392 if let Some(params) = &dp.parameters {
13393 self.write(" (");
13394 for (i, dt) in params.iter().enumerate() {
13395 if i > 0 {
13396 self.write(", ");
13397 }
13398 self.generate_data_type(dt)?;
13399 }
13400 self.write(")");
13401 }
13402
13403 if dp.cascade {
13404 self.write_space();
13405 self.write_keyword("CASCADE");
13406 }
13407
13408 Ok(())
13409 }
13410
13411 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
13412 self.write_keyword("CREATE");
13413
13414 if cs.or_replace {
13415 self.write_space();
13416 self.write_keyword("OR REPLACE");
13417 }
13418
13419 if cs.temporary {
13420 self.write_space();
13421 self.write_keyword("TEMPORARY");
13422 }
13423
13424 self.write_space();
13425 self.write_keyword("SEQUENCE");
13426
13427 if cs.if_not_exists {
13428 self.write_space();
13429 self.write_keyword("IF NOT EXISTS");
13430 }
13431
13432 self.write_space();
13433 self.generate_table(&cs.name)?;
13434
13435 if let Some(as_type) = &cs.as_type {
13437 self.write_space();
13438 self.write_keyword("AS");
13439 self.write_space();
13440 self.generate_data_type(as_type)?;
13441 }
13442
13443 if let Some(comment) = &cs.comment {
13445 self.write_space();
13446 self.write_keyword("COMMENT");
13447 self.write("=");
13448 self.generate_string_literal(comment)?;
13449 }
13450
13451 if !cs.property_order.is_empty() {
13453 for prop in &cs.property_order {
13454 match prop {
13455 SeqPropKind::Start => {
13456 if let Some(start) = cs.start {
13457 self.write_space();
13458 self.write_keyword("START WITH");
13459 self.write(&format!(" {}", start));
13460 }
13461 }
13462 SeqPropKind::Increment => {
13463 if let Some(inc) = cs.increment {
13464 self.write_space();
13465 self.write_keyword("INCREMENT BY");
13466 self.write(&format!(" {}", inc));
13467 }
13468 }
13469 SeqPropKind::Minvalue => {
13470 if let Some(min) = &cs.minvalue {
13471 self.write_space();
13472 match min {
13473 SequenceBound::Value(v) => {
13474 self.write_keyword("MINVALUE");
13475 self.write(&format!(" {}", v));
13476 }
13477 SequenceBound::None => {
13478 self.write_keyword("NO MINVALUE");
13479 }
13480 }
13481 }
13482 }
13483 SeqPropKind::Maxvalue => {
13484 if let Some(max) = &cs.maxvalue {
13485 self.write_space();
13486 match max {
13487 SequenceBound::Value(v) => {
13488 self.write_keyword("MAXVALUE");
13489 self.write(&format!(" {}", v));
13490 }
13491 SequenceBound::None => {
13492 self.write_keyword("NO MAXVALUE");
13493 }
13494 }
13495 }
13496 }
13497 SeqPropKind::Cache => {
13498 if let Some(cache) = cs.cache {
13499 self.write_space();
13500 self.write_keyword("CACHE");
13501 self.write(&format!(" {}", cache));
13502 }
13503 }
13504 SeqPropKind::NoCache => {
13505 self.write_space();
13506 self.write_keyword("NO CACHE");
13507 }
13508 SeqPropKind::NoCacheWord => {
13509 self.write_space();
13510 self.write_keyword("NOCACHE");
13511 }
13512 SeqPropKind::Cycle => {
13513 self.write_space();
13514 self.write_keyword("CYCLE");
13515 }
13516 SeqPropKind::NoCycle => {
13517 self.write_space();
13518 self.write_keyword("NO CYCLE");
13519 }
13520 SeqPropKind::NoCycleWord => {
13521 self.write_space();
13522 self.write_keyword("NOCYCLE");
13523 }
13524 SeqPropKind::OwnedBy => {
13525 if !cs.owned_by_none {
13527 if let Some(owned) = &cs.owned_by {
13528 self.write_space();
13529 self.write_keyword("OWNED BY");
13530 self.write_space();
13531 self.generate_table(owned)?;
13532 }
13533 }
13534 }
13535 SeqPropKind::Order => {
13536 self.write_space();
13537 self.write_keyword("ORDER");
13538 }
13539 SeqPropKind::NoOrder => {
13540 self.write_space();
13541 self.write_keyword("NOORDER");
13542 }
13543 SeqPropKind::Comment => {
13544 }
13546 SeqPropKind::Sharing => {
13547 if let Some(val) = &cs.sharing {
13548 self.write_space();
13549 self.write(&format!("SHARING={}", val));
13550 }
13551 }
13552 SeqPropKind::Keep => {
13553 self.write_space();
13554 self.write_keyword("KEEP");
13555 }
13556 SeqPropKind::NoKeep => {
13557 self.write_space();
13558 self.write_keyword("NOKEEP");
13559 }
13560 SeqPropKind::Scale => {
13561 self.write_space();
13562 self.write_keyword("SCALE");
13563 if let Some(modifier) = &cs.scale_modifier {
13564 if !modifier.is_empty() {
13565 self.write_space();
13566 self.write_keyword(modifier);
13567 }
13568 }
13569 }
13570 SeqPropKind::NoScale => {
13571 self.write_space();
13572 self.write_keyword("NOSCALE");
13573 }
13574 SeqPropKind::Shard => {
13575 self.write_space();
13576 self.write_keyword("SHARD");
13577 if let Some(modifier) = &cs.shard_modifier {
13578 if !modifier.is_empty() {
13579 self.write_space();
13580 self.write_keyword(modifier);
13581 }
13582 }
13583 }
13584 SeqPropKind::NoShard => {
13585 self.write_space();
13586 self.write_keyword("NOSHARD");
13587 }
13588 SeqPropKind::Session => {
13589 self.write_space();
13590 self.write_keyword("SESSION");
13591 }
13592 SeqPropKind::Global => {
13593 self.write_space();
13594 self.write_keyword("GLOBAL");
13595 }
13596 SeqPropKind::NoMinvalueWord => {
13597 self.write_space();
13598 self.write_keyword("NOMINVALUE");
13599 }
13600 SeqPropKind::NoMaxvalueWord => {
13601 self.write_space();
13602 self.write_keyword("NOMAXVALUE");
13603 }
13604 }
13605 }
13606 } else {
13607 if let Some(inc) = cs.increment {
13609 self.write_space();
13610 self.write_keyword("INCREMENT BY");
13611 self.write(&format!(" {}", inc));
13612 }
13613
13614 if let Some(min) = &cs.minvalue {
13615 self.write_space();
13616 match min {
13617 SequenceBound::Value(v) => {
13618 self.write_keyword("MINVALUE");
13619 self.write(&format!(" {}", v));
13620 }
13621 SequenceBound::None => {
13622 self.write_keyword("NO MINVALUE");
13623 }
13624 }
13625 }
13626
13627 if let Some(max) = &cs.maxvalue {
13628 self.write_space();
13629 match max {
13630 SequenceBound::Value(v) => {
13631 self.write_keyword("MAXVALUE");
13632 self.write(&format!(" {}", v));
13633 }
13634 SequenceBound::None => {
13635 self.write_keyword("NO MAXVALUE");
13636 }
13637 }
13638 }
13639
13640 if let Some(start) = cs.start {
13641 self.write_space();
13642 self.write_keyword("START WITH");
13643 self.write(&format!(" {}", start));
13644 }
13645
13646 if let Some(cache) = cs.cache {
13647 self.write_space();
13648 self.write_keyword("CACHE");
13649 self.write(&format!(" {}", cache));
13650 }
13651
13652 if cs.cycle {
13653 self.write_space();
13654 self.write_keyword("CYCLE");
13655 }
13656
13657 if let Some(owned) = &cs.owned_by {
13658 self.write_space();
13659 self.write_keyword("OWNED BY");
13660 self.write_space();
13661 self.generate_table(owned)?;
13662 }
13663 }
13664
13665 Ok(())
13666 }
13667
13668 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
13669 self.write_keyword("DROP SEQUENCE");
13670
13671 if ds.if_exists {
13672 self.write_space();
13673 self.write_keyword("IF EXISTS");
13674 }
13675
13676 self.write_space();
13677 self.generate_table(&ds.name)?;
13678
13679 if ds.cascade {
13680 self.write_space();
13681 self.write_keyword("CASCADE");
13682 }
13683
13684 Ok(())
13685 }
13686
13687 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
13688 self.write_keyword("ALTER SEQUENCE");
13689
13690 if als.if_exists {
13691 self.write_space();
13692 self.write_keyword("IF EXISTS");
13693 }
13694
13695 self.write_space();
13696 self.generate_table(&als.name)?;
13697
13698 if let Some(inc) = als.increment {
13699 self.write_space();
13700 self.write_keyword("INCREMENT BY");
13701 self.write(&format!(" {}", inc));
13702 }
13703
13704 if let Some(min) = &als.minvalue {
13705 self.write_space();
13706 match min {
13707 SequenceBound::Value(v) => {
13708 self.write_keyword("MINVALUE");
13709 self.write(&format!(" {}", v));
13710 }
13711 SequenceBound::None => {
13712 self.write_keyword("NO MINVALUE");
13713 }
13714 }
13715 }
13716
13717 if let Some(max) = &als.maxvalue {
13718 self.write_space();
13719 match max {
13720 SequenceBound::Value(v) => {
13721 self.write_keyword("MAXVALUE");
13722 self.write(&format!(" {}", v));
13723 }
13724 SequenceBound::None => {
13725 self.write_keyword("NO MAXVALUE");
13726 }
13727 }
13728 }
13729
13730 if let Some(start) = als.start {
13731 self.write_space();
13732 self.write_keyword("START WITH");
13733 self.write(&format!(" {}", start));
13734 }
13735
13736 if let Some(restart) = &als.restart {
13737 self.write_space();
13738 self.write_keyword("RESTART");
13739 if let Some(val) = restart {
13740 self.write_keyword(" WITH");
13741 self.write(&format!(" {}", val));
13742 }
13743 }
13744
13745 if let Some(cache) = als.cache {
13746 self.write_space();
13747 self.write_keyword("CACHE");
13748 self.write(&format!(" {}", cache));
13749 }
13750
13751 if let Some(cycle) = als.cycle {
13752 self.write_space();
13753 if cycle {
13754 self.write_keyword("CYCLE");
13755 } else {
13756 self.write_keyword("NO CYCLE");
13757 }
13758 }
13759
13760 if let Some(owned) = &als.owned_by {
13761 self.write_space();
13762 self.write_keyword("OWNED BY");
13763 self.write_space();
13764 if let Some(table) = owned {
13765 self.generate_table(table)?;
13766 } else {
13767 self.write_keyword("NONE");
13768 }
13769 }
13770
13771 Ok(())
13772 }
13773
13774 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
13775 self.write_keyword("CREATE");
13776
13777 if ct.or_alter {
13778 self.write_space();
13779 self.write_keyword("OR ALTER");
13780 } else if ct.or_replace {
13781 self.write_space();
13782 self.write_keyword("OR REPLACE");
13783 }
13784
13785 if ct.constraint {
13786 self.write_space();
13787 self.write_keyword("CONSTRAINT");
13788 }
13789
13790 self.write_space();
13791 self.write_keyword("TRIGGER");
13792 self.write_space();
13793 self.generate_identifier(&ct.name)?;
13794
13795 self.write_space();
13796 match ct.timing {
13797 TriggerTiming::Before => self.write_keyword("BEFORE"),
13798 TriggerTiming::After => self.write_keyword("AFTER"),
13799 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
13800 }
13801
13802 for (i, event) in ct.events.iter().enumerate() {
13804 if i > 0 {
13805 self.write_keyword(" OR");
13806 }
13807 self.write_space();
13808 match event {
13809 TriggerEvent::Insert => self.write_keyword("INSERT"),
13810 TriggerEvent::Update(cols) => {
13811 self.write_keyword("UPDATE");
13812 if let Some(cols) = cols {
13813 self.write_space();
13814 self.write_keyword("OF");
13815 for (j, col) in cols.iter().enumerate() {
13816 if j > 0 {
13817 self.write(",");
13818 }
13819 self.write_space();
13820 self.generate_identifier(col)?;
13821 }
13822 }
13823 }
13824 TriggerEvent::Delete => self.write_keyword("DELETE"),
13825 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
13826 }
13827 }
13828
13829 self.write_space();
13830 self.write_keyword("ON");
13831 self.write_space();
13832 self.generate_table(&ct.table)?;
13833
13834 if let Some(ref_clause) = &ct.referencing {
13836 self.write_space();
13837 self.write_keyword("REFERENCING");
13838 if let Some(old_table) = &ref_clause.old_table {
13839 self.write_space();
13840 self.write_keyword("OLD TABLE AS");
13841 self.write_space();
13842 self.generate_identifier(old_table)?;
13843 }
13844 if let Some(new_table) = &ref_clause.new_table {
13845 self.write_space();
13846 self.write_keyword("NEW TABLE AS");
13847 self.write_space();
13848 self.generate_identifier(new_table)?;
13849 }
13850 if let Some(old_row) = &ref_clause.old_row {
13851 self.write_space();
13852 self.write_keyword("OLD ROW AS");
13853 self.write_space();
13854 self.generate_identifier(old_row)?;
13855 }
13856 if let Some(new_row) = &ref_clause.new_row {
13857 self.write_space();
13858 self.write_keyword("NEW ROW AS");
13859 self.write_space();
13860 self.generate_identifier(new_row)?;
13861 }
13862 }
13863
13864 if let Some(deferrable) = ct.deferrable {
13866 self.write_space();
13867 if deferrable {
13868 self.write_keyword("DEFERRABLE");
13869 } else {
13870 self.write_keyword("NOT DEFERRABLE");
13871 }
13872 }
13873
13874 if let Some(initially) = ct.initially_deferred {
13875 self.write_space();
13876 self.write_keyword("INITIALLY");
13877 self.write_space();
13878 if initially {
13879 self.write_keyword("DEFERRED");
13880 } else {
13881 self.write_keyword("IMMEDIATE");
13882 }
13883 }
13884
13885 if let Some(for_each) = ct.for_each {
13886 self.write_space();
13887 self.write_keyword("FOR EACH");
13888 self.write_space();
13889 match for_each {
13890 TriggerForEach::Row => self.write_keyword("ROW"),
13891 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
13892 }
13893 }
13894
13895 if let Some(when) = &ct.when {
13897 self.write_space();
13898 self.write_keyword("WHEN");
13899 if ct.when_paren {
13900 self.write(" (");
13901 self.generate_expression(when)?;
13902 self.write(")");
13903 } else {
13904 self.write_space();
13905 self.generate_expression(when)?;
13906 }
13907 }
13908
13909 self.write_space();
13911 match &ct.body {
13912 TriggerBody::Execute { function, args } => {
13913 self.write_keyword("EXECUTE FUNCTION");
13914 self.write_space();
13915 self.generate_table(function)?;
13916 self.write("(");
13917 for (i, arg) in args.iter().enumerate() {
13918 if i > 0 {
13919 self.write(", ");
13920 }
13921 self.generate_expression(arg)?;
13922 }
13923 self.write(")");
13924 }
13925 TriggerBody::Block(block) => {
13926 self.write_keyword("BEGIN");
13927 self.write_space();
13928 self.write(block);
13929 self.write_space();
13930 self.write_keyword("END");
13931 }
13932 }
13933
13934 Ok(())
13935 }
13936
13937 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
13938 self.write_keyword("DROP TRIGGER");
13939
13940 if dt.if_exists {
13941 self.write_space();
13942 self.write_keyword("IF EXISTS");
13943 }
13944
13945 self.write_space();
13946 self.generate_identifier(&dt.name)?;
13947
13948 if let Some(table) = &dt.table {
13949 self.write_space();
13950 self.write_keyword("ON");
13951 self.write_space();
13952 self.generate_table(table)?;
13953 }
13954
13955 if dt.cascade {
13956 self.write_space();
13957 self.write_keyword("CASCADE");
13958 }
13959
13960 Ok(())
13961 }
13962
13963 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
13964 self.write_keyword("CREATE TYPE");
13965
13966 if ct.if_not_exists {
13967 self.write_space();
13968 self.write_keyword("IF NOT EXISTS");
13969 }
13970
13971 self.write_space();
13972 self.generate_table(&ct.name)?;
13973
13974 self.write_space();
13975 self.write_keyword("AS");
13976 self.write_space();
13977
13978 match &ct.definition {
13979 TypeDefinition::Enum(values) => {
13980 self.write_keyword("ENUM");
13981 self.write(" (");
13982 for (i, val) in values.iter().enumerate() {
13983 if i > 0 {
13984 self.write(", ");
13985 }
13986 self.write(&format!("'{}'", val));
13987 }
13988 self.write(")");
13989 }
13990 TypeDefinition::Composite(attrs) => {
13991 self.write("(");
13992 for (i, attr) in attrs.iter().enumerate() {
13993 if i > 0 {
13994 self.write(", ");
13995 }
13996 self.generate_identifier(&attr.name)?;
13997 self.write_space();
13998 self.generate_data_type(&attr.data_type)?;
13999 if let Some(collate) = &attr.collate {
14000 self.write_space();
14001 self.write_keyword("COLLATE");
14002 self.write_space();
14003 self.generate_identifier(collate)?;
14004 }
14005 }
14006 self.write(")");
14007 }
14008 TypeDefinition::Range {
14009 subtype,
14010 subtype_diff,
14011 canonical,
14012 } => {
14013 self.write_keyword("RANGE");
14014 self.write(" (");
14015 self.write_keyword("SUBTYPE");
14016 self.write(" = ");
14017 self.generate_data_type(subtype)?;
14018 if let Some(diff) = subtype_diff {
14019 self.write(", ");
14020 self.write_keyword("SUBTYPE_DIFF");
14021 self.write(" = ");
14022 self.write(diff);
14023 }
14024 if let Some(canon) = canonical {
14025 self.write(", ");
14026 self.write_keyword("CANONICAL");
14027 self.write(" = ");
14028 self.write(canon);
14029 }
14030 self.write(")");
14031 }
14032 TypeDefinition::Base {
14033 input,
14034 output,
14035 internallength,
14036 } => {
14037 self.write("(");
14038 self.write_keyword("INPUT");
14039 self.write(" = ");
14040 self.write(input);
14041 self.write(", ");
14042 self.write_keyword("OUTPUT");
14043 self.write(" = ");
14044 self.write(output);
14045 if let Some(len) = internallength {
14046 self.write(", ");
14047 self.write_keyword("INTERNALLENGTH");
14048 self.write(" = ");
14049 self.write(&len.to_string());
14050 }
14051 self.write(")");
14052 }
14053 TypeDefinition::Domain {
14054 base_type,
14055 default,
14056 constraints,
14057 } => {
14058 self.generate_data_type(base_type)?;
14059 if let Some(def) = default {
14060 self.write_space();
14061 self.write_keyword("DEFAULT");
14062 self.write_space();
14063 self.generate_expression(def)?;
14064 }
14065 for constr in constraints {
14066 self.write_space();
14067 if let Some(name) = &constr.name {
14068 self.write_keyword("CONSTRAINT");
14069 self.write_space();
14070 self.generate_identifier(name)?;
14071 self.write_space();
14072 }
14073 self.write_keyword("CHECK");
14074 self.write(" (");
14075 self.generate_expression(&constr.check)?;
14076 self.write(")");
14077 }
14078 }
14079 }
14080
14081 Ok(())
14082 }
14083
14084 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
14085 self.write_keyword("CREATE");
14086 if task.or_replace {
14087 self.write_space();
14088 self.write_keyword("OR REPLACE");
14089 }
14090 self.write_space();
14091 self.write_keyword("TASK");
14092 if task.if_not_exists {
14093 self.write_space();
14094 self.write_keyword("IF NOT EXISTS");
14095 }
14096 self.write_space();
14097 self.write(&task.name);
14098 if !task.properties.is_empty() {
14099 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
14101 self.write_space();
14102 }
14103 self.write(&task.properties);
14104 }
14105 self.write_space();
14106 self.write_keyword("AS");
14107 self.write_space();
14108 self.generate_expression(&task.body)?;
14109 Ok(())
14110 }
14111
14112 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
14113 self.write_keyword("DROP TYPE");
14114
14115 if dt.if_exists {
14116 self.write_space();
14117 self.write_keyword("IF EXISTS");
14118 }
14119
14120 self.write_space();
14121 self.generate_table(&dt.name)?;
14122
14123 if dt.cascade {
14124 self.write_space();
14125 self.write_keyword("CASCADE");
14126 }
14127
14128 Ok(())
14129 }
14130
14131 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
14132 let saved_athena_hive_context = self.athena_hive_context;
14134 if matches!(
14135 self.config.dialect,
14136 Some(crate::dialects::DialectType::Athena)
14137 ) {
14138 self.athena_hive_context = true;
14139 }
14140
14141 for comment in &d.leading_comments {
14143 self.write_formatted_comment(comment);
14144 self.write(" ");
14145 }
14146
14147 self.write_keyword("DESCRIBE");
14148
14149 if d.extended {
14150 self.write_space();
14151 self.write_keyword("EXTENDED");
14152 } else if d.formatted {
14153 self.write_space();
14154 self.write_keyword("FORMATTED");
14155 }
14156
14157 if let Some(ref style) = d.style {
14159 self.write_space();
14160 self.write_keyword(style);
14161 }
14162
14163 let should_output_kind = match self.config.dialect {
14165 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
14167 false
14168 }
14169 Some(DialectType::Snowflake) => true,
14171 _ => d.kind.is_some(),
14172 };
14173 if should_output_kind {
14174 if let Some(ref kind) = d.kind {
14175 self.write_space();
14176 self.write_keyword(kind);
14177 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
14178 self.write_space();
14179 self.write_keyword("TABLE");
14180 }
14181 }
14182
14183 self.write_space();
14184 self.generate_expression(&d.target)?;
14185
14186 if !d.params.is_empty() {
14188 self.write("(");
14189 for (i, param) in d.params.iter().enumerate() {
14190 if i > 0 {
14191 self.write(", ");
14192 }
14193 self.write(param);
14194 }
14195 self.write(")");
14196 }
14197
14198 if let Some(ref partition) = d.partition {
14200 self.write_space();
14201 self.generate_expression(partition)?;
14202 }
14203
14204 if d.as_json {
14206 self.write_space();
14207 self.write_keyword("AS JSON");
14208 }
14209
14210 for (name, value) in &d.properties {
14212 self.write_space();
14213 self.write(name);
14214 self.write("=");
14215 self.write(value);
14216 }
14217
14218 self.athena_hive_context = saved_athena_hive_context;
14220
14221 Ok(())
14222 }
14223
14224 fn generate_show(&mut self, s: &Show) -> Result<()> {
14227 self.write_keyword("SHOW");
14228 self.write_space();
14229
14230 let show_terse = s.terse
14233 && !matches!(
14234 s.this.as_str(),
14235 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
14236 );
14237 if show_terse {
14238 self.write_keyword("TERSE");
14239 self.write_space();
14240 }
14241
14242 self.write_keyword(&s.this);
14244
14245 if let Some(ref target_expr) = s.target {
14247 self.write_space();
14248 self.generate_expression(target_expr)?;
14249 }
14250
14251 if s.history {
14253 self.write_space();
14254 self.write_keyword("HISTORY");
14255 }
14256
14257 if let Some(ref for_target) = s.for_target {
14259 self.write_space();
14260 self.write_keyword("FOR");
14261 self.write_space();
14262 self.generate_expression(for_target)?;
14263 }
14264
14265 use crate::dialects::DialectType;
14269 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
14270 let is_mysql = matches!(self.config.dialect, Some(DialectType::MySQL));
14271 let mysql_tables_scope_as_from = is_mysql
14272 && matches!(s.this.as_str(), "TABLES" | "FULL TABLES")
14273 && s.scope_kind.as_deref() == Some("SCHEMA")
14274 && s.scope.is_some()
14275 && s.from.is_none();
14276
14277 if !is_snowflake && s.from.is_some() {
14278 if let Some(ref scope_kind) = s.scope_kind {
14282 self.write_space();
14283 self.write_keyword("IN");
14284 self.write_space();
14285 self.write_keyword(scope_kind);
14286 if let Some(ref scope) = s.scope {
14287 self.write_space();
14288 self.generate_expression(scope)?;
14289 }
14290 } else if let Some(ref scope) = s.scope {
14291 self.write_space();
14292 self.write_keyword("IN");
14293 self.write_space();
14294 self.generate_expression(scope)?;
14295 }
14296
14297 if let Some(ref from) = s.from {
14299 self.write_space();
14300 self.write_keyword("FROM");
14301 self.write_space();
14302 self.generate_expression(from)?;
14303 }
14304
14305 if let Some(ref db) = s.db {
14307 self.write_space();
14308 self.write_keyword("FROM");
14309 self.write_space();
14310 self.generate_expression(db)?;
14311 }
14312
14313 if let Some(ref like) = s.like {
14315 self.write_space();
14316 self.write_keyword("LIKE");
14317 self.write_space();
14318 self.generate_expression(like)?;
14319 }
14320 } else {
14321 if let Some(ref like) = s.like {
14325 self.write_space();
14326 self.write_keyword("LIKE");
14327 self.write_space();
14328 self.generate_expression(like)?;
14329 }
14330
14331 if mysql_tables_scope_as_from {
14333 self.write_space();
14334 self.write_keyword("FROM");
14335 self.write_space();
14336 self.generate_expression(s.scope.as_ref().unwrap())?;
14337 } else if let Some(ref scope_kind) = s.scope_kind {
14338 self.write_space();
14339 self.write_keyword("IN");
14340 self.write_space();
14341 self.write_keyword(scope_kind);
14342 if let Some(ref scope) = s.scope {
14343 self.write_space();
14344 self.generate_expression(scope)?;
14345 }
14346 } else if let Some(ref scope) = s.scope {
14347 self.write_space();
14348 self.write_keyword("IN");
14349 self.write_space();
14350 self.generate_expression(scope)?;
14351 }
14352 }
14353
14354 if let Some(ref starts_with) = s.starts_with {
14356 self.write_space();
14357 self.write_keyword("STARTS WITH");
14358 self.write_space();
14359 self.generate_expression(starts_with)?;
14360 }
14361
14362 if let Some(ref limit) = s.limit {
14364 self.write_space();
14365 self.generate_limit(limit)?;
14366 }
14367
14368 if is_snowflake {
14370 if let Some(ref from) = s.from {
14371 self.write_space();
14372 self.write_keyword("FROM");
14373 self.write_space();
14374 self.generate_expression(from)?;
14375 }
14376 }
14377
14378 if let Some(ref where_clause) = s.where_clause {
14380 self.write_space();
14381 self.write_keyword("WHERE");
14382 self.write_space();
14383 self.generate_expression(where_clause)?;
14384 }
14385
14386 if let Some(is_mutex) = s.mutex {
14388 self.write_space();
14389 if is_mutex {
14390 self.write_keyword("MUTEX");
14391 } else {
14392 self.write_keyword("STATUS");
14393 }
14394 }
14395
14396 if !s.privileges.is_empty() {
14398 self.write_space();
14399 self.write_keyword("WITH PRIVILEGES");
14400 self.write_space();
14401 for (i, priv_name) in s.privileges.iter().enumerate() {
14402 if i > 0 {
14403 self.write(", ");
14404 }
14405 self.write_keyword(priv_name);
14406 }
14407 }
14408
14409 Ok(())
14410 }
14411
14412 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
14415 use crate::dialects::DialectType;
14416 match lit {
14417 Literal::String(s) => {
14418 self.generate_string_literal(s)?;
14419 }
14420 Literal::Number(n) => {
14421 if matches!(self.config.dialect, Some(DialectType::MySQL))
14422 && n.len() > 2
14423 && (n.starts_with("0x") || n.starts_with("0X"))
14424 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
14425 {
14426 return self.generate_identifier(&Identifier {
14427 name: n.clone(),
14428 quoted: true,
14429 trailing_comments: Vec::new(),
14430 span: None,
14431 });
14432 }
14433 let n = if n.contains('_')
14437 && !matches!(
14438 self.config.dialect,
14439 Some(DialectType::ClickHouse)
14440 | Some(DialectType::DuckDB)
14441 | Some(DialectType::PostgreSQL)
14442 | Some(DialectType::Hive)
14443 | Some(DialectType::Spark)
14444 | Some(DialectType::Databricks)
14445 ) {
14446 std::borrow::Cow::Owned(n.replace('_', ""))
14447 } else {
14448 std::borrow::Cow::Borrowed(n.as_str())
14449 };
14450 if n.starts_with('.') {
14453 self.write("0");
14454 self.write(&n);
14455 } else if n.starts_with("-.") {
14456 self.write("-0");
14458 self.write(&n[1..]);
14459 } else {
14460 self.write(&n);
14461 }
14462 }
14463 Literal::HexString(h) => {
14464 match self.config.dialect {
14466 Some(DialectType::Spark)
14467 | Some(DialectType::Databricks)
14468 | Some(DialectType::Teradata) => self.write("X'"),
14469 _ => self.write("x'"),
14470 }
14471 self.write(h);
14472 self.write("'");
14473 }
14474 Literal::HexNumber(h) => {
14475 match self.config.dialect {
14479 Some(DialectType::BigQuery)
14480 | Some(DialectType::ClickHouse)
14481 | Some(DialectType::TSQL)
14482 | Some(DialectType::Fabric) => {
14483 self.write("0x");
14484 self.write(h);
14485 }
14486 _ => {
14487 if let Ok(val) = u64::from_str_radix(h, 16) {
14489 self.write(&val.to_string());
14490 } else {
14491 self.write("0x");
14493 self.write(h);
14494 }
14495 }
14496 }
14497 }
14498 Literal::BitString(b) => {
14499 self.write("B'");
14501 self.write(b);
14502 self.write("'");
14503 }
14504 Literal::ByteString(b) => {
14505 self.write("b'");
14507 self.write_escaped_byte_string(b);
14509 self.write("'");
14510 }
14511 Literal::NationalString(s) => {
14512 let keep_n_prefix = matches!(
14515 self.config.dialect,
14516 Some(DialectType::TSQL)
14517 | Some(DialectType::Oracle)
14518 | Some(DialectType::MySQL)
14519 | None
14520 );
14521 if keep_n_prefix {
14522 self.write("N'");
14523 } else {
14524 self.write("'");
14525 }
14526 self.write(s);
14527 self.write("'");
14528 }
14529 Literal::Date(d) => {
14530 self.generate_date_literal(d)?;
14531 }
14532 Literal::Time(t) => {
14533 self.generate_time_literal(t)?;
14534 }
14535 Literal::Timestamp(ts) => {
14536 self.generate_timestamp_literal(ts)?;
14537 }
14538 Literal::Datetime(dt) => {
14539 self.generate_datetime_literal(dt)?;
14540 }
14541 Literal::TripleQuotedString(s, _quote_char) => {
14542 if matches!(
14544 self.config.dialect,
14545 Some(crate::dialects::DialectType::BigQuery)
14546 | Some(crate::dialects::DialectType::DuckDB)
14547 | Some(crate::dialects::DialectType::Snowflake)
14548 | Some(crate::dialects::DialectType::Spark)
14549 | Some(crate::dialects::DialectType::Hive)
14550 | Some(crate::dialects::DialectType::Presto)
14551 | Some(crate::dialects::DialectType::Trino)
14552 | Some(crate::dialects::DialectType::PostgreSQL)
14553 | Some(crate::dialects::DialectType::MySQL)
14554 | Some(crate::dialects::DialectType::Redshift)
14555 | Some(crate::dialects::DialectType::TSQL)
14556 | Some(crate::dialects::DialectType::Oracle)
14557 | Some(crate::dialects::DialectType::ClickHouse)
14558 | Some(crate::dialects::DialectType::Databricks)
14559 | Some(crate::dialects::DialectType::SQLite)
14560 ) {
14561 self.generate_string_literal(s)?;
14562 } else {
14563 let quotes = format!("{0}{0}{0}", _quote_char);
14565 self.write("es);
14566 self.write(s);
14567 self.write("es);
14568 }
14569 }
14570 Literal::EscapeString(s) => {
14571 use crate::dialects::DialectType;
14575 let content = if let Some(c) = s.strip_prefix("e:") {
14576 c
14577 } else if let Some(c) = s.strip_prefix("E:") {
14578 c
14579 } else {
14580 s.as_str()
14581 };
14582
14583 if matches!(
14585 self.config.dialect,
14586 Some(DialectType::MySQL) | Some(DialectType::TiDB)
14587 ) {
14588 self.write(content);
14589 } else {
14590 let prefix = if matches!(
14592 self.config.dialect,
14593 Some(DialectType::SingleStore)
14594 | Some(DialectType::DuckDB)
14595 | Some(DialectType::PostgreSQL)
14596 | Some(DialectType::CockroachDB)
14597 | Some(DialectType::Materialize)
14598 | Some(DialectType::RisingWave)
14599 ) {
14600 "e'"
14601 } else {
14602 "E'"
14603 };
14604
14605 let normalized = content.replace("\\'", "''");
14607 self.write(prefix);
14608 self.write(&normalized);
14609 self.write("'");
14610 }
14611 }
14612 Literal::DollarString(s) => {
14613 use crate::dialects::DialectType;
14616 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
14618 let escape_backslash = matches!(
14620 self.config.dialect,
14621 Some(DialectType::ClickHouse) | Some(DialectType::Snowflake)
14622 );
14623 let use_backslash_quote =
14627 matches!(self.config.dialect, Some(DialectType::Snowflake));
14628
14629 let mut escaped = String::with_capacity(content.len() + 4);
14630 for ch in content.chars() {
14631 if escape_backslash && ch == '\\' {
14632 escaped.push('\\');
14634 escaped.push('\\');
14635 } else if ch == '\'' {
14636 if use_backslash_quote {
14637 escaped.push('\\');
14638 escaped.push('\'');
14639 } else {
14640 escaped.push('\'');
14641 escaped.push('\'');
14642 }
14643 } else {
14644 escaped.push(ch);
14645 }
14646 }
14647 self.write("'");
14648 self.write(&escaped);
14649 self.write("'");
14650 }
14651 Literal::RawString(s) => {
14652 use crate::dialects::DialectType;
14658
14659 let escape_backslash = matches!(
14661 self.config.dialect,
14662 Some(DialectType::BigQuery)
14663 | Some(DialectType::MySQL)
14664 | Some(DialectType::SingleStore)
14665 | Some(DialectType::TiDB)
14666 | Some(DialectType::Hive)
14667 | Some(DialectType::Spark)
14668 | Some(DialectType::Databricks)
14669 | Some(DialectType::Drill)
14670 | Some(DialectType::Snowflake)
14671 | Some(DialectType::Redshift)
14672 | Some(DialectType::ClickHouse)
14673 );
14674
14675 let backslash_escapes_quote = matches!(
14678 self.config.dialect,
14679 Some(DialectType::BigQuery)
14680 | Some(DialectType::Hive)
14681 | Some(DialectType::Spark)
14682 | Some(DialectType::Databricks)
14683 | Some(DialectType::Drill)
14684 | Some(DialectType::Snowflake)
14685 | Some(DialectType::Redshift)
14686 );
14687
14688 let supports_escape_sequences = escape_backslash;
14691
14692 let mut escaped = String::with_capacity(s.len() + 4);
14693 for ch in s.chars() {
14694 if escape_backslash && ch == '\\' {
14695 escaped.push('\\');
14697 escaped.push('\\');
14698 } else if ch == '\'' {
14699 if backslash_escapes_quote {
14700 escaped.push('\\');
14702 escaped.push('\'');
14703 } else {
14704 escaped.push('\'');
14706 escaped.push('\'');
14707 }
14708 } else if supports_escape_sequences {
14709 match ch {
14712 '\n' => {
14713 escaped.push('\\');
14714 escaped.push('n');
14715 }
14716 '\r' => {
14717 escaped.push('\\');
14718 escaped.push('r');
14719 }
14720 '\t' => {
14721 escaped.push('\\');
14722 escaped.push('t');
14723 }
14724 '\x07' => {
14725 escaped.push('\\');
14726 escaped.push('a');
14727 }
14728 '\x08' => {
14729 escaped.push('\\');
14730 escaped.push('b');
14731 }
14732 '\x0C' => {
14733 escaped.push('\\');
14734 escaped.push('f');
14735 }
14736 '\x0B' => {
14737 escaped.push('\\');
14738 escaped.push('v');
14739 }
14740 _ => escaped.push(ch),
14741 }
14742 } else {
14743 escaped.push(ch);
14744 }
14745 }
14746 self.write("'");
14747 self.write(&escaped);
14748 self.write("'");
14749 }
14750 }
14751 Ok(())
14752 }
14753
14754 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
14756 use crate::dialects::DialectType;
14757
14758 match self.config.dialect {
14759 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
14761 self.write("CAST('");
14762 self.write(d);
14763 self.write("' AS DATE)");
14764 }
14765 Some(DialectType::BigQuery) => {
14768 self.write("CAST('");
14769 self.write(d);
14770 self.write("' AS DATE)");
14771 }
14772 Some(DialectType::Exasol) => {
14775 self.write("CAST('");
14776 self.write(d);
14777 self.write("' AS DATE)");
14778 }
14779 Some(DialectType::Snowflake) => {
14782 self.write("CAST('");
14783 self.write(d);
14784 self.write("' AS DATE)");
14785 }
14786 Some(DialectType::PostgreSQL)
14788 | Some(DialectType::MySQL)
14789 | Some(DialectType::SingleStore)
14790 | Some(DialectType::TiDB)
14791 | Some(DialectType::Redshift) => {
14792 self.write("CAST('");
14793 self.write(d);
14794 self.write("' AS DATE)");
14795 }
14796 Some(DialectType::DuckDB)
14798 | Some(DialectType::Presto)
14799 | Some(DialectType::Trino)
14800 | Some(DialectType::Athena)
14801 | Some(DialectType::Spark)
14802 | Some(DialectType::Databricks)
14803 | Some(DialectType::Hive) => {
14804 self.write("CAST('");
14805 self.write(d);
14806 self.write("' AS DATE)");
14807 }
14808 Some(DialectType::Oracle) => {
14810 self.write("TO_DATE('");
14811 self.write(d);
14812 self.write("', 'YYYY-MM-DD')");
14813 }
14814 _ => {
14816 self.write_keyword("DATE");
14817 self.write(" '");
14818 self.write(d);
14819 self.write("'");
14820 }
14821 }
14822 Ok(())
14823 }
14824
14825 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
14827 use crate::dialects::DialectType;
14828
14829 match self.config.dialect {
14830 Some(DialectType::TSQL) => {
14832 self.write("CAST('");
14833 self.write(t);
14834 self.write("' AS TIME)");
14835 }
14836 _ => {
14838 self.write_keyword("TIME");
14839 self.write(" '");
14840 self.write(t);
14841 self.write("'");
14842 }
14843 }
14844 Ok(())
14845 }
14846
14847 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
14849 use crate::expressions::Literal;
14850
14851 match expr {
14852 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
14853 let Literal::Date(d) = lit.as_ref() else {
14854 unreachable!()
14855 };
14856 self.write("CAST('");
14858 self.write(d);
14859 self.write("' AS DATE)");
14860 }
14861 _ => {
14862 self.generate_expression(expr)?;
14864 }
14865 }
14866 Ok(())
14867 }
14868
14869 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
14871 use crate::dialects::DialectType;
14872
14873 match self.config.dialect {
14874 Some(DialectType::TSQL) => {
14876 self.write("CAST('");
14877 self.write(ts);
14878 self.write("' AS DATETIME2)");
14879 }
14880 Some(DialectType::BigQuery) => {
14883 self.write("CAST('");
14884 self.write(ts);
14885 self.write("' AS TIMESTAMP)");
14886 }
14887 Some(DialectType::Snowflake) => {
14890 self.write("CAST('");
14891 self.write(ts);
14892 self.write("' AS TIMESTAMP)");
14893 }
14894 Some(DialectType::Dremio) => {
14897 self.write("CAST('");
14898 self.write(ts);
14899 self.write("' AS TIMESTAMP)");
14900 }
14901 Some(DialectType::Exasol) => {
14904 self.write("CAST('");
14905 self.write(ts);
14906 self.write("' AS TIMESTAMP)");
14907 }
14908 Some(DialectType::Oracle) => {
14911 self.write("TO_TIMESTAMP('");
14912 self.write(ts);
14913 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
14914 }
14915 Some(DialectType::Presto) | Some(DialectType::Trino) => {
14917 if Self::timestamp_has_timezone(ts) {
14918 self.write("CAST('");
14919 self.write(ts);
14920 self.write("' AS TIMESTAMP WITH TIME ZONE)");
14921 } else {
14922 self.write("CAST('");
14923 self.write(ts);
14924 self.write("' AS TIMESTAMP)");
14925 }
14926 }
14927 Some(DialectType::ClickHouse) => {
14929 self.write("CAST('");
14930 self.write(ts);
14931 self.write("' AS Nullable(DateTime))");
14932 }
14933 Some(DialectType::Spark) => {
14935 self.write("CAST('");
14936 self.write(ts);
14937 self.write("' AS TIMESTAMP)");
14938 }
14939 Some(DialectType::Redshift) => {
14942 if ts == "epoch" {
14943 self.write_keyword("TIMESTAMP");
14944 self.write(" '");
14945 self.write(ts);
14946 self.write("'");
14947 } else {
14948 self.write("CAST('");
14949 self.write(ts);
14950 self.write("' AS TIMESTAMP)");
14951 }
14952 }
14953 Some(DialectType::PostgreSQL)
14955 | Some(DialectType::Hive)
14956 | Some(DialectType::SQLite)
14957 | Some(DialectType::DuckDB)
14958 | Some(DialectType::Athena)
14959 | Some(DialectType::Drill)
14960 | Some(DialectType::Teradata) => {
14961 self.write("CAST('");
14962 self.write(ts);
14963 self.write("' AS TIMESTAMP)");
14964 }
14965 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
14967 self.write("CAST('");
14968 self.write(ts);
14969 self.write("' AS DATETIME)");
14970 }
14971 Some(DialectType::Databricks) => {
14973 self.write("CAST('");
14974 self.write(ts);
14975 self.write("' AS TIMESTAMP_NTZ)");
14976 }
14977 _ => {
14979 self.write_keyword("TIMESTAMP");
14980 self.write(" '");
14981 self.write(ts);
14982 self.write("'");
14983 }
14984 }
14985 Ok(())
14986 }
14987
14988 fn timestamp_has_timezone(ts: &str) -> bool {
14991 let ts_lower = ts.to_ascii_lowercase();
14995
14996 let continent_prefixes = [
14998 "africa/",
14999 "america/",
15000 "antarctica/",
15001 "arctic/",
15002 "asia/",
15003 "atlantic/",
15004 "australia/",
15005 "europe/",
15006 "indian/",
15007 "pacific/",
15008 "etc/",
15009 "brazil/",
15010 "canada/",
15011 "chile/",
15012 "mexico/",
15013 "us/",
15014 ];
15015
15016 for prefix in &continent_prefixes {
15017 if ts_lower.contains(prefix) {
15018 return true;
15019 }
15020 }
15021
15022 let tz_abbrevs = [
15025 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
15026 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
15027 " sgt", " aest", " aedt", " acst", " acdt", " awst",
15028 ];
15029
15030 for abbrev in &tz_abbrevs {
15031 if ts_lower.ends_with(abbrev) {
15032 return true;
15033 }
15034 }
15035
15036 let trimmed = ts.trim();
15040 if let Some(last_space) = trimmed.rfind(' ') {
15041 let suffix = &trimmed[last_space + 1..];
15042 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
15043 let rest = &suffix[1..];
15045 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
15046 return true;
15047 }
15048 }
15049 }
15050
15051 false
15052 }
15053
15054 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
15056 use crate::dialects::DialectType;
15057
15058 match self.config.dialect {
15059 Some(DialectType::BigQuery) => {
15062 self.write("CAST('");
15063 self.write(dt);
15064 self.write("' AS DATETIME)");
15065 }
15066 Some(DialectType::DuckDB) => {
15068 self.write("CAST('");
15069 self.write(dt);
15070 self.write("' AS TIMESTAMP)");
15071 }
15072 _ => {
15075 self.write_keyword("DATETIME");
15076 self.write(" '");
15077 self.write(dt);
15078 self.write("'");
15079 }
15080 }
15081 Ok(())
15082 }
15083
15084 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
15086 use crate::dialects::DialectType;
15087
15088 match self.config.dialect {
15089 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
15093 self.write("'");
15095 for c in s.chars() {
15096 match c {
15097 '\'' => self.write("\\'"),
15098 '\\' => self.write("\\\\"),
15099 '\n' => self.write("\\n"),
15100 '\r' => self.write("\\r"),
15101 '\t' => self.write("\\t"),
15102 '\0' => self.write("\\0"),
15103 _ => self.output.push(c),
15104 }
15105 }
15106 self.write("'");
15107 }
15108 Some(DialectType::Drill) => {
15109 self.write("'");
15112 for c in s.chars() {
15113 match c {
15114 '\'' => self.write("''"),
15115 '\\' => self.write("\\\\"),
15116 '\n' => self.write("\\n"),
15117 '\r' => self.write("\\r"),
15118 '\t' => self.write("\\t"),
15119 '\0' => self.write("\\0"),
15120 _ => self.output.push(c),
15121 }
15122 }
15123 self.write("'");
15124 }
15125 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
15126 self.write("'");
15127 for c in s.chars() {
15128 match c {
15129 '\'' => self.write("''"),
15131 '\\' => self.write("\\\\"),
15132 '\n' => self.write("\\n"),
15133 '\r' => self.write("\\r"),
15134 '\t' => self.write("\\t"),
15135 '\0' => self.output.push('\0'),
15137 _ => self.output.push(c),
15138 }
15139 }
15140 self.write("'");
15141 }
15142 Some(DialectType::BigQuery) => {
15144 self.write("'");
15145 for c in s.chars() {
15146 match c {
15147 '\'' => self.write("\\'"),
15148 '\\' => self.write("\\\\"),
15149 '\n' => self.write("\\n"),
15150 '\r' => self.write("\\r"),
15151 '\t' => self.write("\\t"),
15152 '\0' => self.write("\\0"),
15153 '\x07' => self.write("\\a"),
15154 '\x08' => self.write("\\b"),
15155 '\x0C' => self.write("\\f"),
15156 '\x0B' => self.write("\\v"),
15157 _ => self.output.push(c),
15158 }
15159 }
15160 self.write("'");
15161 }
15162 Some(DialectType::Athena) => {
15166 if self.athena_hive_context {
15167 self.write("'");
15169 for c in s.chars() {
15170 match c {
15171 '\'' => self.write("\\'"),
15172 '\\' => self.write("\\\\"),
15173 '\n' => self.write("\\n"),
15174 '\r' => self.write("\\r"),
15175 '\t' => self.write("\\t"),
15176 '\0' => self.write("\\0"),
15177 _ => self.output.push(c),
15178 }
15179 }
15180 self.write("'");
15181 } else {
15182 self.write("'");
15184 for c in s.chars() {
15185 match c {
15186 '\'' => self.write("''"),
15187 _ => self.output.push(c),
15189 }
15190 }
15191 self.write("'");
15192 }
15193 }
15194 Some(DialectType::Snowflake) => {
15199 self.write("'");
15200 for c in s.chars() {
15201 match c {
15202 '\'' => self.write("\\'"),
15203 '\n' => self.write("\\n"),
15206 '\r' => self.write("\\r"),
15207 '\t' => self.write("\\t"),
15208 _ => self.output.push(c),
15209 }
15210 }
15211 self.write("'");
15212 }
15213 Some(DialectType::PostgreSQL) => {
15215 self.write("'");
15216 for c in s.chars() {
15217 match c {
15218 '\'' => self.write("''"),
15219 _ => self.output.push(c),
15220 }
15221 }
15222 self.write("'");
15223 }
15224 Some(DialectType::Redshift) => {
15226 self.write("'");
15227 for c in s.chars() {
15228 match c {
15229 '\'' => self.write("\\'"),
15230 _ => self.output.push(c),
15231 }
15232 }
15233 self.write("'");
15234 }
15235 Some(DialectType::Oracle) => {
15237 self.write("'");
15238 for ch in s.chars() {
15239 if ch == '\'' {
15240 self.output.push_str("''");
15241 } else {
15242 self.output.push(ch);
15243 }
15244 }
15245 self.write("'");
15246 }
15247 Some(DialectType::ClickHouse) => {
15250 self.write("'");
15251 for c in s.chars() {
15252 match c {
15253 '\'' => self.write("''"),
15254 '\\' => self.write("\\\\"),
15255 '\n' => self.write("\\n"),
15256 '\r' => self.write("\\r"),
15257 '\t' => self.write("\\t"),
15258 '\0' => self.write("\\0"),
15259 '\x07' => self.write("\\a"),
15260 '\x08' => self.write("\\b"),
15261 '\x0C' => self.write("\\f"),
15262 '\x0B' => self.write("\\v"),
15263 c if c.is_control() || (c as u32) < 0x20 => {
15265 let byte = c as u32;
15266 if byte < 256 {
15267 self.write(&format!("\\x{:02X}", byte));
15268 } else {
15269 self.output.push(c);
15270 }
15271 }
15272 _ => self.output.push(c),
15273 }
15274 }
15275 self.write("'");
15276 }
15277 _ => {
15280 self.write("'");
15281 for ch in s.chars() {
15282 if ch == '\'' {
15283 self.output.push_str("''");
15284 } else {
15285 self.output.push(ch);
15286 }
15287 }
15288 self.write("'");
15289 }
15290 }
15291 Ok(())
15292 }
15293
15294 fn write_escaped_byte_string(&mut self, s: &str) {
15297 for c in s.chars() {
15298 match c {
15299 '\'' => self.write("\\'"),
15301 '\\' => self.write("\\\\"),
15303 _ if !c.is_control() => self.output.push(c),
15305 _ => {
15307 let byte = c as u32;
15308 if byte < 256 {
15309 self.write(&format!("\\x{:02x}", byte));
15310 } else {
15311 for b in c.to_string().as_bytes() {
15313 self.write(&format!("\\x{:02x}", b));
15314 }
15315 }
15316 }
15317 }
15318 }
15319 }
15320
15321 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
15322 use crate::dialects::DialectType;
15323
15324 match self.config.dialect {
15326 Some(DialectType::TSQL) => {
15329 self.write(if b.value { "1" } else { "0" });
15330 }
15331 Some(DialectType::Oracle) => {
15333 self.write(if b.value { "1" } else { "0" });
15334 }
15335 Some(DialectType::MySQL) => {
15337 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15338 }
15339 _ => {
15341 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
15342 }
15343 }
15344 Ok(())
15345 }
15346
15347 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
15350 let name = &id.name;
15351 let quote_style = &self.config.identifier_quote_style;
15352
15353 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
15357
15358 let output_name = if self.config.normalize_identifiers && !id.quoted {
15360 name.to_ascii_lowercase()
15361 } else {
15362 name.to_string()
15363 };
15364
15365 if needs_quoting {
15366 let quote_style = if matches!(self.config.dialect, Some(DialectType::ClickHouse))
15367 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
15368 && quote_style.start == '"'
15369 && output_name.contains('"')
15370 {
15371 &IdentifierQuoteStyle::BACKTICK
15372 } else {
15373 quote_style
15374 };
15375 let escaped_name = if quote_style.start == quote_style.end {
15377 output_name.replace(
15378 quote_style.end,
15379 &format!("{}{}", quote_style.end, quote_style.end),
15380 )
15381 } else {
15382 output_name.replace(
15383 quote_style.end,
15384 &format!("{}{}", quote_style.end, quote_style.end),
15385 )
15386 };
15387 self.write(&format!(
15388 "{}{}{}",
15389 quote_style.start, escaped_name, quote_style.end
15390 ));
15391 } else {
15392 self.write(&output_name);
15393 }
15394
15395 for comment in &id.trailing_comments {
15397 self.write(" ");
15398 self.write_formatted_comment(comment);
15399 }
15400 Ok(())
15401 }
15402
15403 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
15404 use crate::dialects::DialectType;
15405
15406 let name = &id.name;
15407
15408 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
15410 && self.athena_hive_context
15411 {
15412 &IdentifierQuoteStyle::BACKTICK
15413 } else {
15414 &self.config.identifier_quote_style
15415 };
15416
15417 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
15424 let needs_digit_quoting = starts_with_digit
15425 && !self.config.identifiers_can_start_with_digit
15426 && self.config.dialect.is_some();
15427 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
15428 && name.len() > 2
15429 && (name.starts_with("0x") || name.starts_with("0X"))
15430 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
15431 let clickhouse_unsafe_identifier =
15432 matches!(self.config.dialect, Some(DialectType::ClickHouse))
15433 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
15434 && !name.starts_with('{')
15435 && !name.contains('(')
15436 && !name.contains(')')
15437 && name != "?"
15438 && name
15439 .chars()
15440 .any(|c| !(c.is_ascii_alphanumeric() || c == '_'));
15441 let needs_quoting = id.quoted
15442 || self.is_reserved_keyword(name)
15443 || self.config.always_quote_identifiers
15444 || needs_digit_quoting
15445 || mysql_invalid_hex_identifier
15446 || clickhouse_unsafe_identifier;
15447
15448 let (base_name, suffix) = if needs_quoting {
15451 if let Some(paren_pos) = name.find('(') {
15453 let base = &name[..paren_pos];
15454 let rest = &name[paren_pos..];
15455 if rest.starts_with('(')
15457 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
15458 {
15459 let close_paren = rest.find(')').unwrap_or(rest.len());
15461 let inside = &rest[1..close_paren];
15462 if inside.chars().all(|c| c.is_ascii_digit()) {
15463 (base.to_string(), rest.to_string())
15464 } else {
15465 (name.to_string(), String::new())
15466 }
15467 } else {
15468 (name.to_string(), String::new())
15469 }
15470 } else if name.ends_with(" ASC") {
15471 let base = &name[..name.len() - 4];
15472 (base.to_string(), " ASC".to_string())
15473 } else if name.ends_with(" DESC") {
15474 let base = &name[..name.len() - 5];
15475 (base.to_string(), " DESC".to_string())
15476 } else {
15477 (name.to_string(), String::new())
15478 }
15479 } else {
15480 (name.to_string(), String::new())
15481 };
15482
15483 let output_name = if self.config.normalize_identifiers && !id.quoted {
15487 base_name.to_ascii_lowercase()
15488 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
15489 && !id.quoted
15490 && self.is_reserved_keyword(name)
15491 {
15492 base_name.to_ascii_uppercase()
15495 } else {
15496 base_name
15497 };
15498
15499 if needs_quoting {
15500 let escaped_name = if quote_style.start == quote_style.end {
15502 output_name.replace(
15504 quote_style.end,
15505 &format!("{}{}", quote_style.end, quote_style.end),
15506 )
15507 } else {
15508 output_name.replace(
15510 quote_style.end,
15511 &format!("{}{}", quote_style.end, quote_style.end),
15512 )
15513 };
15514 self.write(&format!(
15515 "{}{}{}{}",
15516 quote_style.start, escaped_name, quote_style.end, suffix
15517 ));
15518 } else {
15519 self.write(&output_name);
15520 }
15521
15522 for comment in &id.trailing_comments {
15524 self.write(" ");
15525 self.write_formatted_comment(comment);
15526 }
15527 Ok(())
15528 }
15529
15530 fn generate_column(&mut self, col: &Column) -> Result<()> {
15531 use crate::dialects::DialectType;
15532
15533 if let Some(table) = &col.table {
15534 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
15538 && !table.quoted
15539 && table.name.eq_ignore_ascii_case("LOCAL");
15540
15541 if is_exasol_local_prefix {
15542 self.write("LOCAL");
15544 } else {
15545 self.generate_identifier(table)?;
15546 }
15547 self.write(".");
15548 }
15549 self.generate_identifier(&col.name)?;
15550 if col.join_mark && self.config.supports_column_join_marks {
15553 self.write(" (+)");
15554 }
15555 for comment in &col.trailing_comments {
15557 self.write_space();
15558 self.write_formatted_comment(comment);
15559 }
15560 Ok(())
15561 }
15562
15563 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
15566 use crate::dialects::DialectType;
15567 use crate::expressions::PseudocolumnType;
15568
15569 if pc.kind == PseudocolumnType::Sysdate
15571 && !matches!(
15572 self.config.dialect,
15573 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
15574 )
15575 {
15576 self.write_keyword("CURRENT_TIMESTAMP");
15577 if matches!(
15579 self.config.dialect,
15580 Some(DialectType::MySQL)
15581 | Some(DialectType::ClickHouse)
15582 | Some(DialectType::Spark)
15583 | Some(DialectType::Databricks)
15584 | Some(DialectType::Hive)
15585 ) {
15586 self.write("()");
15587 }
15588 } else {
15589 self.write(pc.kind.as_str());
15590 }
15591 Ok(())
15592 }
15593
15594 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
15596 use crate::dialects::DialectType;
15597
15598 let supports_connect_by = matches!(
15601 self.config.dialect,
15602 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
15603 );
15604
15605 if !supports_connect_by && self.config.dialect.is_some() {
15606 if self.config.pretty {
15608 self.write_newline();
15609 } else {
15610 self.write_space();
15611 }
15612 self.write_unsupported_comment(
15613 "CONNECT BY requires manual conversion to recursive CTE",
15614 )?;
15615 }
15616
15617 if let Some(start) = &connect.start {
15619 if self.config.pretty {
15620 self.write_newline();
15621 } else {
15622 self.write_space();
15623 }
15624 self.write_keyword("START WITH");
15625 self.write_space();
15626 self.generate_expression(start)?;
15627 }
15628
15629 if self.config.pretty {
15631 self.write_newline();
15632 } else {
15633 self.write_space();
15634 }
15635 self.write_keyword("CONNECT BY");
15636 if connect.nocycle {
15637 self.write_space();
15638 self.write_keyword("NOCYCLE");
15639 }
15640 self.write_space();
15641 self.generate_expression(&connect.connect)?;
15642
15643 Ok(())
15644 }
15645
15646 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
15648 self.generate_connect(connect)
15649 }
15650
15651 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
15653 self.write_keyword("PRIOR");
15654 self.write_space();
15655 self.generate_expression(&prior.this)?;
15656 Ok(())
15657 }
15658
15659 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
15662 self.write_keyword("CONNECT_BY_ROOT");
15663 self.write_space();
15664 self.generate_expression(&cbr.this)?;
15665 Ok(())
15666 }
15667
15668 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
15670 use crate::dialects::DialectType;
15671
15672 let supports_match_recognize = matches!(
15674 self.config.dialect,
15675 Some(DialectType::Oracle)
15676 | Some(DialectType::Snowflake)
15677 | Some(DialectType::Presto)
15678 | Some(DialectType::Trino)
15679 );
15680
15681 if let Some(source) = &mr.this {
15683 self.generate_expression(source)?;
15684 }
15685
15686 if !supports_match_recognize {
15687 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
15688 return Ok(());
15689 }
15690
15691 if self.config.pretty {
15693 self.write_newline();
15694 } else {
15695 self.write_space();
15696 }
15697
15698 self.write_keyword("MATCH_RECOGNIZE");
15699 self.write(" (");
15700
15701 if self.config.pretty {
15702 self.indent_level += 1;
15703 }
15704
15705 let mut needs_separator = false;
15706
15707 if let Some(partition_by) = &mr.partition_by {
15709 if !partition_by.is_empty() {
15710 if self.config.pretty {
15711 self.write_newline();
15712 self.write_indent();
15713 }
15714 self.write_keyword("PARTITION BY");
15715 self.write_space();
15716 for (i, expr) in partition_by.iter().enumerate() {
15717 if i > 0 {
15718 self.write(", ");
15719 }
15720 self.generate_expression(expr)?;
15721 }
15722 needs_separator = true;
15723 }
15724 }
15725
15726 if let Some(order_by) = &mr.order_by {
15728 if !order_by.is_empty() {
15729 if needs_separator {
15730 if self.config.pretty {
15731 self.write_newline();
15732 self.write_indent();
15733 } else {
15734 self.write_space();
15735 }
15736 } else if self.config.pretty {
15737 self.write_newline();
15738 self.write_indent();
15739 }
15740 self.write_keyword("ORDER BY");
15741 if self.config.pretty {
15743 self.indent_level += 1;
15744 for (i, ordered) in order_by.iter().enumerate() {
15745 if i > 0 {
15746 self.write(",");
15747 }
15748 self.write_newline();
15749 self.write_indent();
15750 self.generate_ordered(ordered)?;
15751 }
15752 self.indent_level -= 1;
15753 } else {
15754 self.write_space();
15755 for (i, ordered) in order_by.iter().enumerate() {
15756 if i > 0 {
15757 self.write(", ");
15758 }
15759 self.generate_ordered(ordered)?;
15760 }
15761 }
15762 needs_separator = true;
15763 }
15764 }
15765
15766 if let Some(measures) = &mr.measures {
15768 if !measures.is_empty() {
15769 if needs_separator {
15770 if self.config.pretty {
15771 self.write_newline();
15772 self.write_indent();
15773 } else {
15774 self.write_space();
15775 }
15776 } else if self.config.pretty {
15777 self.write_newline();
15778 self.write_indent();
15779 }
15780 self.write_keyword("MEASURES");
15781 if self.config.pretty {
15783 self.indent_level += 1;
15784 for (i, measure) in measures.iter().enumerate() {
15785 if i > 0 {
15786 self.write(",");
15787 }
15788 self.write_newline();
15789 self.write_indent();
15790 if let Some(semantics) = &measure.window_frame {
15792 match semantics {
15793 MatchRecognizeSemantics::Running => {
15794 self.write_keyword("RUNNING");
15795 self.write_space();
15796 }
15797 MatchRecognizeSemantics::Final => {
15798 self.write_keyword("FINAL");
15799 self.write_space();
15800 }
15801 }
15802 }
15803 self.generate_expression(&measure.this)?;
15804 }
15805 self.indent_level -= 1;
15806 } else {
15807 self.write_space();
15808 for (i, measure) in measures.iter().enumerate() {
15809 if i > 0 {
15810 self.write(", ");
15811 }
15812 if let Some(semantics) = &measure.window_frame {
15814 match semantics {
15815 MatchRecognizeSemantics::Running => {
15816 self.write_keyword("RUNNING");
15817 self.write_space();
15818 }
15819 MatchRecognizeSemantics::Final => {
15820 self.write_keyword("FINAL");
15821 self.write_space();
15822 }
15823 }
15824 }
15825 self.generate_expression(&measure.this)?;
15826 }
15827 }
15828 needs_separator = true;
15829 }
15830 }
15831
15832 if let Some(rows) = &mr.rows {
15834 if needs_separator {
15835 if self.config.pretty {
15836 self.write_newline();
15837 self.write_indent();
15838 } else {
15839 self.write_space();
15840 }
15841 } else if self.config.pretty {
15842 self.write_newline();
15843 self.write_indent();
15844 }
15845 match rows {
15846 MatchRecognizeRows::OneRowPerMatch => {
15847 self.write_keyword("ONE ROW PER MATCH");
15848 }
15849 MatchRecognizeRows::AllRowsPerMatch => {
15850 self.write_keyword("ALL ROWS PER MATCH");
15851 }
15852 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
15853 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
15854 }
15855 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
15856 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
15857 }
15858 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
15859 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
15860 }
15861 }
15862 needs_separator = true;
15863 }
15864
15865 if let Some(after) = &mr.after {
15867 if needs_separator {
15868 if self.config.pretty {
15869 self.write_newline();
15870 self.write_indent();
15871 } else {
15872 self.write_space();
15873 }
15874 } else if self.config.pretty {
15875 self.write_newline();
15876 self.write_indent();
15877 }
15878 match after {
15879 MatchRecognizeAfter::PastLastRow => {
15880 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
15881 }
15882 MatchRecognizeAfter::ToNextRow => {
15883 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
15884 }
15885 MatchRecognizeAfter::ToFirst(ident) => {
15886 self.write_keyword("AFTER MATCH SKIP TO FIRST");
15887 self.write_space();
15888 self.generate_identifier(ident)?;
15889 }
15890 MatchRecognizeAfter::ToLast(ident) => {
15891 self.write_keyword("AFTER MATCH SKIP TO LAST");
15892 self.write_space();
15893 self.generate_identifier(ident)?;
15894 }
15895 }
15896 needs_separator = true;
15897 }
15898
15899 if let Some(pattern) = &mr.pattern {
15901 if needs_separator {
15902 if self.config.pretty {
15903 self.write_newline();
15904 self.write_indent();
15905 } else {
15906 self.write_space();
15907 }
15908 } else if self.config.pretty {
15909 self.write_newline();
15910 self.write_indent();
15911 }
15912 self.write_keyword("PATTERN");
15913 self.write_space();
15914 self.write("(");
15915 self.write(pattern);
15916 self.write(")");
15917 needs_separator = true;
15918 }
15919
15920 if let Some(define) = &mr.define {
15922 if !define.is_empty() {
15923 if needs_separator {
15924 if self.config.pretty {
15925 self.write_newline();
15926 self.write_indent();
15927 } else {
15928 self.write_space();
15929 }
15930 } else if self.config.pretty {
15931 self.write_newline();
15932 self.write_indent();
15933 }
15934 self.write_keyword("DEFINE");
15935 if self.config.pretty {
15937 self.indent_level += 1;
15938 for (i, (name, expr)) in define.iter().enumerate() {
15939 if i > 0 {
15940 self.write(",");
15941 }
15942 self.write_newline();
15943 self.write_indent();
15944 self.generate_identifier(name)?;
15945 self.write(" AS ");
15946 self.generate_expression(expr)?;
15947 }
15948 self.indent_level -= 1;
15949 } else {
15950 self.write_space();
15951 for (i, (name, expr)) in define.iter().enumerate() {
15952 if i > 0 {
15953 self.write(", ");
15954 }
15955 self.generate_identifier(name)?;
15956 self.write(" AS ");
15957 self.generate_expression(expr)?;
15958 }
15959 }
15960 }
15961 }
15962
15963 if self.config.pretty {
15964 self.indent_level -= 1;
15965 self.write_newline();
15966 }
15967 self.write(")");
15968
15969 if let Some(alias) = &mr.alias {
15971 self.write(" ");
15972 if mr.alias_explicit_as {
15973 self.write_keyword("AS");
15974 self.write(" ");
15975 }
15976 self.generate_identifier(alias)?;
15977 }
15978
15979 Ok(())
15980 }
15981
15982 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
15984 use crate::dialects::DialectType;
15985
15986 let supports_hints = matches!(
15988 self.config.dialect,
15989 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
15991 Some(DialectType::Spark) | Some(DialectType::Hive) |
15992 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
15993 );
15994
15995 if !supports_hints || hint.expressions.is_empty() {
15996 return Ok(());
15997 }
15998
15999 let mut hint_strings: Vec<String> = Vec::new();
16002 for expr in &hint.expressions {
16003 match expr {
16004 HintExpression::Raw(text) => {
16005 let parsed = self.parse_raw_hint_text(text);
16007 hint_strings.extend(parsed);
16008 }
16009 _ => {
16010 hint_strings.push(self.hint_expression_to_string(expr)?);
16011 }
16012 }
16013 }
16014
16015 let use_multiline = self.config.pretty && hint_strings.len() > 1;
16019
16020 if use_multiline {
16021 self.write(" /*+ ");
16023 for (i, hint_str) in hint_strings.iter().enumerate() {
16024 if i > 0 {
16025 self.write_newline();
16026 self.write(" "); }
16028 self.write(hint_str);
16029 }
16030 self.write(" */");
16031 } else {
16032 self.write(" /*+ ");
16034 let sep = match self.config.dialect {
16035 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
16036 _ => " ",
16037 };
16038 for (i, hint_str) in hint_strings.iter().enumerate() {
16039 if i > 0 {
16040 self.write(sep);
16041 }
16042 self.write(hint_str);
16043 }
16044 self.write(" */");
16045 }
16046
16047 Ok(())
16048 }
16049
16050 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
16054 let mut results = Vec::new();
16055 let mut chars = text.chars().peekable();
16056 let mut current = String::new();
16057 let mut paren_depth = 0;
16058 let mut has_unparseable_content = false;
16059 let mut position_after_last_function = 0;
16060 let mut char_position = 0;
16061
16062 while let Some(c) = chars.next() {
16063 char_position += c.len_utf8();
16064 match c {
16065 '(' => {
16066 paren_depth += 1;
16067 current.push(c);
16068 }
16069 ')' => {
16070 paren_depth -= 1;
16071 current.push(c);
16072 if paren_depth == 0 {
16074 let trimmed = current.trim().to_string();
16075 if !trimmed.is_empty() {
16076 let formatted = self.format_hint_function(&trimmed);
16078 results.push(formatted);
16079 }
16080 current.clear();
16081 position_after_last_function = char_position;
16082 }
16083 }
16084 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
16085 }
16087 _ if paren_depth == 0 => {
16088 current.push(c);
16090 }
16091 _ => {
16092 current.push(c);
16093 }
16094 }
16095 }
16096
16097 let remaining_text = text[position_after_last_function..].trim();
16099 if !remaining_text.is_empty() {
16100 let words: Vec<&str> = remaining_text.split_whitespace().collect();
16104 let looks_like_hint_functions = words.iter().all(|word| {
16105 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
16107 });
16108
16109 if !looks_like_hint_functions && words.len() > 1 {
16110 has_unparseable_content = true;
16111 }
16112 }
16113
16114 if has_unparseable_content {
16116 return vec![text.trim().to_string()];
16117 }
16118
16119 if results.is_empty() {
16121 results.push(text.trim().to_string());
16122 }
16123
16124 results
16125 }
16126
16127 fn format_hint_function(&self, hint: &str) -> String {
16130 if !self.config.pretty {
16131 return hint.to_string();
16132 }
16133
16134 if let Some(paren_pos) = hint.find('(') {
16136 if hint.ends_with(')') {
16137 let name = &hint[..paren_pos];
16138 let args_str = &hint[paren_pos + 1..hint.len() - 1];
16139
16140 let args: Vec<&str> = args_str.split_whitespace().collect();
16142
16143 let total_args_width: usize =
16145 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() {
16149 let mut result = format!("{}(\n", name);
16150 for arg in &args {
16151 result.push_str(" "); result.push_str(arg);
16153 result.push('\n');
16154 }
16155 result.push_str(" )"); return result;
16157 }
16158 }
16159 }
16160
16161 hint.to_string()
16162 }
16163
16164 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
16166 match expr {
16167 HintExpression::Function { name, args } => {
16168 let arg_strings: Vec<String> = args
16170 .iter()
16171 .map(|arg| {
16172 let mut gen = Generator::with_arc_config(self.config.clone());
16173 gen.generate_expression(arg)?;
16174 Ok(gen.output)
16175 })
16176 .collect::<Result<Vec<_>>>()?;
16177
16178 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
16180 + arg_strings.len().saturating_sub(1); let args_multiline =
16185 self.config.pretty && total_args_width > self.config.max_text_width;
16186
16187 if args_multiline && !arg_strings.is_empty() {
16188 let mut result = format!("{}(\n", name);
16190 for arg_str in &arg_strings {
16191 result.push_str(" "); result.push_str(arg_str);
16193 result.push('\n');
16194 }
16195 result.push_str(" )"); Ok(result)
16197 } else {
16198 let args_str = arg_strings.join(" ");
16200 Ok(format!("{}({})", name, args_str))
16201 }
16202 }
16203 HintExpression::Identifier(name) => Ok(name.clone()),
16204 HintExpression::Raw(text) => {
16205 if self.config.pretty {
16207 Ok(self.format_hint_function(text))
16208 } else {
16209 Ok(text.clone())
16210 }
16211 }
16212 }
16213 }
16214
16215 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
16216 if table.only {
16218 self.write_keyword("ONLY");
16219 self.write_space();
16220 }
16221
16222 if let Some(ref identifier_func) = table.identifier_func {
16224 self.generate_expression(identifier_func)?;
16225 if !table.name.name.is_empty() {
16227 if let Some(catalog) = &table.catalog {
16228 self.write(".");
16229 self.generate_identifier(catalog)?;
16230 }
16231 if let Some(schema) = &table.schema {
16232 self.write(".");
16233 self.generate_identifier(schema)?;
16234 }
16235 self.write(".");
16236 self.generate_identifier(&table.name)?;
16237 }
16238 } else {
16239 if let Some(catalog) = &table.catalog {
16240 self.generate_identifier(catalog)?;
16241 self.write(".");
16242 }
16243 if let Some(schema) = &table.schema {
16244 self.generate_identifier(schema)?;
16245 self.write(".");
16246 }
16247 self.generate_identifier(&table.name)?;
16248 }
16249
16250 if let Some(changes) = &table.changes {
16252 self.write(" ");
16253 self.generate_changes(changes)?;
16254 }
16255
16256 if !table.partitions.is_empty() {
16258 self.write_space();
16259 self.write_keyword("PARTITION");
16260 self.write("(");
16261 for (i, partition) in table.partitions.iter().enumerate() {
16262 if i > 0 {
16263 self.write(", ");
16264 }
16265 self.generate_identifier(partition)?;
16266 }
16267 self.write(")");
16268 }
16269
16270 if table.changes.is_none() {
16273 if let Some(when) = &table.when {
16274 self.write_space();
16275 self.generate_historical_data(when)?;
16276 }
16277 }
16278
16279 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
16281 if !system_time_post_alias {
16282 if let Some(ref system_time) = table.system_time {
16283 self.write_space();
16284 self.write(system_time);
16285 }
16286 }
16287
16288 if let Some(ref version) = table.version {
16290 self.write_space();
16291 self.generate_version(version)?;
16292 }
16293
16294 let alias_post_tablesample = self.config.alias_post_tablesample;
16298
16299 if alias_post_tablesample {
16300 self.generate_table_sample_clause(table)?;
16302 }
16303
16304 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
16307 && table.hints.iter().any(|h| {
16308 if let Expression::Identifier(id) = h {
16309 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
16310 } else {
16311 false
16312 }
16313 });
16314 if !table.hints.is_empty() && !is_sqlite_hint {
16315 for hint in &table.hints {
16316 self.write_space();
16317 self.generate_expression(hint)?;
16318 }
16319 }
16320
16321 if let Some(alias) = &table.alias {
16322 self.write_space();
16323 let always_use_as = self.config.dialect.is_none()
16326 || matches!(
16327 self.config.dialect,
16328 Some(DialectType::Generic)
16329 | Some(DialectType::PostgreSQL)
16330 | Some(DialectType::Redshift)
16331 | Some(DialectType::Snowflake)
16332 | Some(DialectType::BigQuery)
16333 | Some(DialectType::DuckDB)
16334 | Some(DialectType::Presto)
16335 | Some(DialectType::Trino)
16336 | Some(DialectType::TSQL)
16337 | Some(DialectType::Fabric)
16338 | Some(DialectType::MySQL)
16339 | Some(DialectType::Spark)
16340 | Some(DialectType::Hive)
16341 | Some(DialectType::SQLite)
16342 | Some(DialectType::Drill)
16343 );
16344 let is_stage_ref = table.name.name.starts_with('@');
16345 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16347 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
16348 self.write_keyword("AS");
16349 self.write_space();
16350 }
16351 self.generate_identifier(alias)?;
16352
16353 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
16356 self.write("(");
16357 for (i, col_alias) in table.column_aliases.iter().enumerate() {
16358 if i > 0 {
16359 self.write(", ");
16360 }
16361 self.generate_identifier(col_alias)?;
16362 }
16363 self.write(")");
16364 }
16365 }
16366
16367 if system_time_post_alias {
16369 if let Some(ref system_time) = table.system_time {
16370 self.write_space();
16371 self.write(system_time);
16372 }
16373 }
16374
16375 if !alias_post_tablesample {
16377 self.generate_table_sample_clause(table)?;
16378 }
16379
16380 if is_sqlite_hint {
16382 for hint in &table.hints {
16383 self.write_space();
16384 self.generate_expression(hint)?;
16385 }
16386 }
16387
16388 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16390 self.write_space();
16391 self.write_keyword("FINAL");
16392 }
16393
16394 for comment in &table.trailing_comments {
16396 self.write_space();
16397 self.write_formatted_comment(comment);
16398 }
16399 Ok(())
16403 }
16404
16405 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
16407 if let Some(ref ts) = table.table_sample {
16408 self.write_space();
16409 if ts.is_using_sample {
16410 self.write_keyword("USING SAMPLE");
16411 } else {
16412 self.write_keyword(self.config.tablesample_keywords);
16414 }
16415 self.generate_sample_body(ts)?;
16416 if let Some(ref seed) = ts.seed {
16418 self.write_space();
16419 self.write_keyword(self.config.tablesample_seed_keyword);
16420 self.write(" (");
16421 self.generate_expression(seed)?;
16422 self.write(")");
16423 }
16424 }
16425 Ok(())
16426 }
16427
16428 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
16429 if sr.quoted {
16433 self.write("'");
16434 }
16435
16436 self.write(&sr.name);
16437 if let Some(path) = &sr.path {
16438 self.write(path);
16439 }
16440
16441 if sr.quoted {
16442 self.write("'");
16443 }
16444
16445 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
16447 if has_options {
16448 self.write(" (");
16449 let mut first = true;
16450
16451 if let Some(file_format) = &sr.file_format {
16452 if !first {
16453 self.write(", ");
16454 }
16455 self.write_keyword("FILE_FORMAT");
16456 self.write(" => ");
16457 self.generate_expression(file_format)?;
16458 first = false;
16459 }
16460
16461 if let Some(pattern) = &sr.pattern {
16462 if !first {
16463 self.write(", ");
16464 }
16465 self.write_keyword("PATTERN");
16466 self.write(" => '");
16467 self.write(pattern);
16468 self.write("'");
16469 }
16470
16471 self.write(")");
16472 }
16473 Ok(())
16474 }
16475
16476 fn generate_star(&mut self, star: &Star) -> Result<()> {
16477 use crate::dialects::DialectType;
16478
16479 if let Some(table) = &star.table {
16480 self.generate_identifier(table)?;
16481 self.write(".");
16482 }
16483 self.write("*");
16484
16485 if let Some(except) = &star.except {
16487 if !except.is_empty() {
16488 self.write_space();
16489 match self.config.dialect {
16491 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
16492 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
16493 self.write_keyword("EXCLUDE")
16494 }
16495 _ => self.write_keyword("EXCEPT"), }
16497 self.write(" (");
16498 for (i, col) in except.iter().enumerate() {
16499 if i > 0 {
16500 self.write(", ");
16501 }
16502 self.generate_identifier(col)?;
16503 }
16504 self.write(")");
16505 }
16506 }
16507
16508 if let Some(replace) = &star.replace {
16510 if !replace.is_empty() {
16511 self.write_space();
16512 self.write_keyword("REPLACE");
16513 self.write(" (");
16514 for (i, alias) in replace.iter().enumerate() {
16515 if i > 0 {
16516 self.write(", ");
16517 }
16518 self.generate_expression(&alias.this)?;
16519 self.write_space();
16520 self.write_keyword("AS");
16521 self.write_space();
16522 self.generate_identifier(&alias.alias)?;
16523 }
16524 self.write(")");
16525 }
16526 }
16527
16528 if let Some(rename) = &star.rename {
16530 if !rename.is_empty() {
16531 self.write_space();
16532 self.write_keyword("RENAME");
16533 self.write(" (");
16534 for (i, (old_name, new_name)) in rename.iter().enumerate() {
16535 if i > 0 {
16536 self.write(", ");
16537 }
16538 self.generate_identifier(old_name)?;
16539 self.write_space();
16540 self.write_keyword("AS");
16541 self.write_space();
16542 self.generate_identifier(new_name)?;
16543 }
16544 self.write(")");
16545 }
16546 }
16547
16548 for comment in &star.trailing_comments {
16550 self.write_space();
16551 self.write_formatted_comment(comment);
16552 }
16553
16554 Ok(())
16555 }
16556
16557 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
16559 self.write("{");
16560 match expr {
16561 Expression::Star(star) => {
16562 self.generate_star(star)?;
16564 }
16565 Expression::ILike(ilike) => {
16566 self.generate_expression(&ilike.left)?;
16568 self.write_space();
16569 self.write_keyword("ILIKE");
16570 self.write_space();
16571 self.generate_expression(&ilike.right)?;
16572 }
16573 _ => {
16574 self.generate_expression(expr)?;
16575 }
16576 }
16577 self.write("}");
16578 Ok(())
16579 }
16580
16581 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
16582 match &alias.this {
16586 Expression::Column(col) => {
16587 if let Some(table) = &col.table {
16589 self.generate_identifier(table)?;
16590 self.write(".");
16591 }
16592 self.generate_identifier(&col.name)?;
16593 }
16594 _ => {
16595 self.generate_expression(&alias.this)?;
16596 }
16597 }
16598
16599 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
16603 for comment in &alias.pre_alias_comments {
16604 self.write_space();
16605 self.write_formatted_comment(comment);
16606 }
16607 }
16608
16609 use crate::dialects::DialectType;
16610
16611 let is_table_source = matches!(
16617 &alias.this,
16618 Expression::JSONTable(_)
16619 | Expression::XMLTable(_)
16620 | Expression::TableFromRows(_)
16621 | Expression::Unnest(_)
16622 | Expression::MatchRecognize(_)
16623 | Expression::Select(_)
16624 | Expression::Subquery(_)
16625 | Expression::Paren(_)
16626 );
16627 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16628 let skip_as = is_table_source && dialect_skips_table_alias_as;
16629
16630 self.write_space();
16631 if !skip_as {
16632 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16633 if let Some(ref alias_keyword) = alias.alias_keyword {
16634 self.write(alias_keyword);
16635 } else {
16636 self.write_keyword("AS");
16637 }
16638 } else {
16639 self.write_keyword("AS");
16640 }
16641 self.write_space();
16642 }
16643
16644 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
16646
16647 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
16649 self.write("(");
16651 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16652 if i > 0 {
16653 self.write(", ");
16654 }
16655 self.generate_alias_identifier(col_alias)?;
16656 }
16657 self.write(")");
16658 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
16659 self.generate_alias_identifier(&alias.alias)?;
16661 self.write("(");
16662 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16663 if i > 0 {
16664 self.write(", ");
16665 }
16666 self.generate_alias_identifier(col_alias)?;
16667 }
16668 self.write(")");
16669 } else {
16670 self.generate_alias_identifier(&alias.alias)?;
16672 }
16673
16674 for comment in &alias.trailing_comments {
16676 self.write_space();
16677 self.write_formatted_comment(comment);
16678 }
16679
16680 if alias.trailing_comments.is_empty() {
16685 for comment in &alias.pre_alias_comments {
16686 self.write_space();
16687 self.write_formatted_comment(comment);
16688 }
16689 }
16690
16691 Ok(())
16692 }
16693
16694 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
16695 use crate::dialects::DialectType;
16696
16697 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
16699 self.generate_expression(&cast.this)?;
16700 self.write(" :> ");
16701 self.generate_data_type(&cast.to)?;
16702 return Ok(());
16703 }
16704
16705 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
16707 let is_unknown_type = matches!(cast.to, DataType::Unknown)
16708 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
16709 if is_unknown_type {
16710 if let Some(format) = &cast.format {
16711 self.write_keyword("CAST");
16712 self.write("(");
16713 self.generate_expression(&cast.this)?;
16714 self.write_space();
16715 self.write_keyword("AS");
16716 self.write_space();
16717 self.write_keyword("FORMAT");
16718 self.write_space();
16719 self.generate_expression(format)?;
16720 self.write(")");
16721 return Ok(());
16722 }
16723 }
16724 }
16725
16726 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
16729 if let Some(format) = &cast.format {
16730 let is_date = matches!(cast.to, DataType::Date);
16732 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
16733
16734 if is_date || is_timestamp {
16735 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
16736 self.write_keyword(func_name);
16737 self.write("(");
16738 self.generate_expression(&cast.this)?;
16739 self.write(", ");
16740
16741 if let Expression::Literal(lit) = format.as_ref() {
16744 if let Literal::String(fmt_str) = lit.as_ref() {
16745 let normalized = self.normalize_oracle_format(fmt_str);
16746 self.write("'");
16747 self.write(&normalized);
16748 self.write("'");
16749 }
16750 } else {
16751 self.generate_expression(format)?;
16752 }
16753
16754 self.write(")");
16755 return Ok(());
16756 }
16757 }
16758 }
16759
16760 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
16763 if let Expression::Array(arr) = &cast.this {
16764 self.generate_data_type(&cast.to)?;
16765 self.write("[");
16767 for (i, expr) in arr.expressions.iter().enumerate() {
16768 if i > 0 {
16769 self.write(", ");
16770 }
16771 self.generate_expression(expr)?;
16772 }
16773 self.write("]");
16774 return Ok(());
16775 }
16776 if matches!(&cast.this, Expression::ArrayFunc(_)) {
16777 self.generate_data_type(&cast.to)?;
16778 self.generate_expression(&cast.this)?;
16779 return Ok(());
16780 }
16781 }
16782
16783 if matches!(
16786 self.config.dialect,
16787 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
16788 ) {
16789 if let Expression::Struct(ref s) = cast.this {
16790 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
16791 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
16792 self.write_keyword("CAST");
16793 self.write("(");
16794 self.generate_struct_as_row(s)?;
16795 self.write_space();
16796 self.write_keyword("AS");
16797 self.write_space();
16798 self.generate_data_type(&cast.to)?;
16799 self.write(")");
16800 return Ok(());
16801 }
16802 }
16803 }
16804
16805 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
16808
16809 if use_double_colon {
16810 self.generate_expression(&cast.this)?;
16812 self.write("::");
16813 self.generate_data_type(&cast.to)?;
16814 } else {
16815 self.write_keyword("CAST");
16817 self.write("(");
16818 self.generate_expression(&cast.this)?;
16819 self.write_space();
16820 self.write_keyword("AS");
16821 self.write_space();
16822 if matches!(
16825 self.config.dialect,
16826 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
16827 ) {
16828 match &cast.to {
16829 DataType::Custom { ref name } => {
16830 if name.eq_ignore_ascii_case("LONGTEXT")
16831 || name.eq_ignore_ascii_case("MEDIUMTEXT")
16832 || name.eq_ignore_ascii_case("TINYTEXT")
16833 || name.eq_ignore_ascii_case("LONGBLOB")
16834 || name.eq_ignore_ascii_case("MEDIUMBLOB")
16835 || name.eq_ignore_ascii_case("TINYBLOB")
16836 {
16837 self.write_keyword("CHAR");
16838 } else {
16839 self.generate_data_type(&cast.to)?;
16840 }
16841 }
16842 DataType::VarChar { length, .. } => {
16843 self.write_keyword("CHAR");
16845 if let Some(n) = length {
16846 self.write(&format!("({})", n));
16847 }
16848 }
16849 DataType::Text => {
16850 self.write_keyword("CHAR");
16852 }
16853 DataType::Timestamp {
16854 precision,
16855 timezone: false,
16856 } => {
16857 self.write_keyword("DATETIME");
16859 if let Some(p) = precision {
16860 self.write(&format!("({})", p));
16861 }
16862 }
16863 _ => {
16864 self.generate_data_type(&cast.to)?;
16865 }
16866 }
16867 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
16868 match &cast.to {
16870 DataType::String { length } => {
16871 self.write_keyword("VARCHAR");
16872 if let Some(n) = length {
16873 self.write(&format!("({})", n));
16874 }
16875 }
16876 _ => {
16877 self.generate_data_type(&cast.to)?;
16878 }
16879 }
16880 } else {
16881 self.generate_data_type(&cast.to)?;
16882 }
16883
16884 if let Some(default) = &cast.default {
16886 self.write_space();
16887 self.write_keyword("DEFAULT");
16888 self.write_space();
16889 self.generate_expression(default)?;
16890 self.write_space();
16891 self.write_keyword("ON");
16892 self.write_space();
16893 self.write_keyword("CONVERSION");
16894 self.write_space();
16895 self.write_keyword("ERROR");
16896 }
16897
16898 if let Some(format) = &cast.format {
16901 if matches!(
16903 self.config.dialect,
16904 Some(crate::dialects::DialectType::Oracle)
16905 ) {
16906 self.write(", ");
16907 } else {
16908 self.write_space();
16909 self.write_keyword("FORMAT");
16910 self.write_space();
16911 }
16912 self.generate_expression(format)?;
16913 }
16914
16915 self.write(")");
16916 for comment in &cast.trailing_comments {
16918 self.write_space();
16919 self.write_formatted_comment(comment);
16920 }
16921 }
16922 Ok(())
16923 }
16924
16925 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
16928 self.write_keyword("ROW");
16929 self.write("(");
16930 for (i, (_, expr)) in s.fields.iter().enumerate() {
16931 if i > 0 {
16932 self.write(", ");
16933 }
16934 if let Expression::Struct(ref inner_s) = expr {
16936 self.generate_struct_as_row(inner_s)?;
16937 } else {
16938 self.generate_expression(expr)?;
16939 }
16940 }
16941 self.write(")");
16942 Ok(())
16943 }
16944
16945 fn normalize_oracle_format(&self, format: &str) -> String {
16948 let mut result = String::new();
16951 let chars: Vec<char> = format.chars().collect();
16952 let mut i = 0;
16953
16954 while i < chars.len() {
16955 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
16956 if i + 2 < chars.len() {
16958 let next = chars[i + 2];
16959 if next == '1' || next == '2' {
16960 result.push('H');
16962 result.push('H');
16963 i += 2;
16964 continue;
16965 }
16966 }
16967 result.push_str("HH12");
16969 i += 2;
16970 } else {
16971 result.push(chars[i]);
16972 i += 1;
16973 }
16974 }
16975
16976 result
16977 }
16978
16979 fn dialect_prefers_double_colon(&self) -> bool {
16982 matches!(self.config.dialect, Some(DialectType::ClickHouse))
16983 }
16984
16985 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16987 use crate::dialects::DialectType;
16988
16989 let use_percent_operator = matches!(
16991 self.config.dialect,
16992 Some(DialectType::Snowflake)
16993 | Some(DialectType::MySQL)
16994 | Some(DialectType::Presto)
16995 | Some(DialectType::Trino)
16996 | Some(DialectType::PostgreSQL)
16997 | Some(DialectType::DuckDB)
16998 | Some(DialectType::Hive)
16999 | Some(DialectType::Spark)
17000 | Some(DialectType::Databricks)
17001 | Some(DialectType::Athena)
17002 );
17003
17004 if use_percent_operator {
17005 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
17008 if needs_paren(&f.this) {
17009 self.write("(");
17010 self.generate_expression(&f.this)?;
17011 self.write(")");
17012 } else {
17013 self.generate_expression(&f.this)?;
17014 }
17015 self.write(" % ");
17016 if needs_paren(&f.expression) {
17017 self.write("(");
17018 self.generate_expression(&f.expression)?;
17019 self.write(")");
17020 } else {
17021 self.generate_expression(&f.expression)?;
17022 }
17023 Ok(())
17024 } else {
17025 self.generate_binary_func("MOD", &f.this, &f.expression)
17026 }
17027 }
17028
17029 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17031 use crate::dialects::DialectType;
17032
17033 let func_name = match self.config.dialect {
17035 Some(DialectType::Snowflake) => "COALESCE",
17036 _ => "IFNULL",
17037 };
17038
17039 self.generate_binary_func(func_name, &f.this, &f.expression)
17040 }
17041
17042 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
17044 if let Some(ref original_name) = f.original_name {
17046 return self.generate_binary_func(original_name, &f.this, &f.expression);
17047 }
17048
17049 use crate::dialects::DialectType;
17051 let func_name = match self.config.dialect {
17052 Some(DialectType::Snowflake)
17053 | Some(DialectType::ClickHouse)
17054 | Some(DialectType::PostgreSQL)
17055 | Some(DialectType::Presto)
17056 | Some(DialectType::Trino)
17057 | Some(DialectType::Athena)
17058 | Some(DialectType::DuckDB)
17059 | Some(DialectType::BigQuery)
17060 | Some(DialectType::Spark)
17061 | Some(DialectType::Databricks)
17062 | Some(DialectType::Hive) => "COALESCE",
17063 Some(DialectType::MySQL)
17064 | Some(DialectType::Doris)
17065 | Some(DialectType::StarRocks)
17066 | Some(DialectType::SingleStore)
17067 | Some(DialectType::TiDB) => "IFNULL",
17068 _ => "NVL",
17069 };
17070
17071 self.generate_binary_func(func_name, &f.this, &f.expression)
17072 }
17073
17074 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
17076 use crate::dialects::DialectType;
17077
17078 let func_name = match self.config.dialect {
17080 Some(DialectType::Snowflake) => "STDDEV",
17081 _ => "STDDEV_SAMP",
17082 };
17083
17084 self.generate_agg_func(func_name, f)
17085 }
17086
17087 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
17088 self.generate_expression(&coll.this)?;
17089 self.write_space();
17090 self.write_keyword("COLLATE");
17091 self.write_space();
17092 if coll.quoted {
17093 self.write("'");
17095 self.write(&coll.collation);
17096 self.write("'");
17097 } else if coll.double_quoted {
17098 self.write("\"");
17100 self.write(&coll.collation);
17101 self.write("\"");
17102 } else {
17103 self.write(&coll.collation);
17105 }
17106 Ok(())
17107 }
17108
17109 fn generate_case(&mut self, case: &Case) -> Result<()> {
17110 let multiline_case = if self.config.pretty {
17112 let mut statements: Vec<String> = Vec::new();
17114 let operand_str = if let Some(operand) = &case.operand {
17115 let s = self.generate_to_string(operand)?;
17116 statements.push(format!("CASE {}", s));
17117 s
17118 } else {
17119 statements.push("CASE".to_string());
17120 String::new()
17121 };
17122 let _ = operand_str;
17123 for (condition, result) in &case.whens {
17124 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
17125 statements.push(format!("THEN {}", self.generate_to_string(result)?));
17126 }
17127 if let Some(else_) = &case.else_ {
17128 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
17129 }
17130 statements.push("END".to_string());
17131 self.too_wide(&statements)
17132 } else {
17133 false
17134 };
17135
17136 self.write_keyword("CASE");
17137 if let Some(operand) = &case.operand {
17138 self.write_space();
17139 self.generate_expression(operand)?;
17140 }
17141 if multiline_case {
17142 self.indent_level += 1;
17143 }
17144 for (condition, result) in &case.whens {
17145 if multiline_case {
17146 self.write_newline();
17147 self.write_indent();
17148 } else {
17149 self.write_space();
17150 }
17151 self.write_keyword("WHEN");
17152 self.write_space();
17153 self.generate_expression(condition)?;
17154 if multiline_case {
17155 self.write_newline();
17156 self.write_indent();
17157 } else {
17158 self.write_space();
17159 }
17160 self.write_keyword("THEN");
17161 self.write_space();
17162 self.generate_expression(result)?;
17163 }
17164 if let Some(else_) = &case.else_ {
17165 if multiline_case {
17166 self.write_newline();
17167 self.write_indent();
17168 } else {
17169 self.write_space();
17170 }
17171 self.write_keyword("ELSE");
17172 self.write_space();
17173 self.generate_expression(else_)?;
17174 }
17175 if multiline_case {
17176 self.indent_level -= 1;
17177 self.write_newline();
17178 self.write_indent();
17179 } else {
17180 self.write_space();
17181 }
17182 self.write_keyword("END");
17183 for comment in &case.comments {
17185 self.write(" ");
17186 self.write_formatted_comment(comment);
17187 }
17188 Ok(())
17189 }
17190
17191 fn generate_function(&mut self, func: &Function) -> Result<()> {
17192 let normalized_name = self.normalize_func_name(&func.name);
17194
17195 if matches!(self.config.dialect, Some(DialectType::DuckDB))
17197 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
17198 {
17199 self.write("LIST_FILTER(");
17200 self.write("[");
17201 for (i, arg) in func.args.iter().enumerate() {
17202 if i > 0 {
17203 self.write(", ");
17204 }
17205 self.generate_expression(arg)?;
17206 }
17207 self.write("], _u -> NOT _u IS NULL)");
17208 return Ok(());
17209 }
17210
17211 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17214 && func.name.eq_ignore_ascii_case("TO_VARIANT")
17215 && func.args.len() == 1
17216 {
17217 let array_expressions = match &func.args[0] {
17218 Expression::ArrayFunc(arr) => Some(&arr.expressions),
17219 Expression::Array(arr) => Some(&arr.expressions),
17220 _ => None,
17221 };
17222 if let Some(expressions) = array_expressions {
17223 self.write_keyword("TO_VARIANT");
17224 self.write("(");
17225 self.write_keyword("ARRAY_CONSTRUCT");
17226 self.write("(");
17227 for (i, arg) in expressions.iter().enumerate() {
17228 if i > 0 {
17229 self.write(", ");
17230 }
17231 self.generate_expression(arg)?;
17232 }
17233 self.write(")");
17234 self.write(")");
17235 return Ok(());
17236 }
17237 }
17238
17239 if func.name.eq_ignore_ascii_case("STRUCT")
17241 && !matches!(
17242 self.config.dialect,
17243 Some(DialectType::BigQuery)
17244 | Some(DialectType::Spark)
17245 | Some(DialectType::Databricks)
17246 | Some(DialectType::Hive)
17247 | None
17248 )
17249 {
17250 return self.generate_struct_function_cross_dialect(func);
17251 }
17252
17253 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
17256 self.generate_expression(&func.args[0])?;
17257 self.write("::?");
17258 if let Expression::Literal(lit) = &func.args[1] {
17260 if let crate::expressions::Literal::String(key) = lit.as_ref() {
17261 self.write(key);
17262 }
17263 } else {
17264 self.generate_expression(&func.args[1])?;
17265 }
17266 return Ok(());
17267 }
17268
17269 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
17271 self.generate_expression(&func.args[0])?;
17272 self.write(" # ");
17273 self.generate_expression(&func.args[1])?;
17274 return Ok(());
17275 }
17276
17277 if matches!(
17279 self.config.dialect,
17280 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
17281 ) && func.name.eq_ignore_ascii_case("TRY")
17282 && func.args.len() == 1
17283 {
17284 self.generate_expression(&func.args[0])?;
17285 return Ok(());
17286 }
17287
17288 if self.config.dialect == Some(DialectType::ClickHouse)
17290 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
17291 && func.args.len() == 1
17292 {
17293 self.write("dateTrunc('DAY', ");
17294 self.generate_expression(&func.args[0])?;
17295 self.write(")");
17296 return Ok(());
17297 }
17298
17299 if self.config.dialect == Some(DialectType::ClickHouse)
17301 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17302 && func.args.len() == 2
17303 {
17304 self.write("dateTrunc(");
17305 self.generate_expression(&func.args[0])?;
17306 self.write(", ");
17307 self.generate_expression(&func.args[1])?;
17308 self.write(")");
17309 return Ok(());
17310 }
17311
17312 if matches!(
17314 self.config.dialect,
17315 Some(DialectType::Presto | DialectType::Trino | DialectType::Athena)
17316 ) && func.name.eq_ignore_ascii_case("SUBSTRING")
17317 {
17318 self.write_keyword("SUBSTR");
17319 self.write("(");
17320 for (i, arg) in func.args.iter().enumerate() {
17321 if i > 0 {
17322 self.write(", ");
17323 }
17324 self.generate_expression(arg)?;
17325 }
17326 self.write(")");
17327 return Ok(());
17328 }
17329
17330 if self.config.dialect == Some(DialectType::Snowflake)
17331 && func.name.eq_ignore_ascii_case("LIST_DISTINCT")
17332 && func.args.len() == 1
17333 {
17334 self.write_keyword("ARRAY_DISTINCT");
17335 self.write("(");
17336 self.write_keyword("ARRAY_COMPACT");
17337 self.write("(");
17338 self.generate_expression(&func.args[0])?;
17339 self.write("))");
17340 return Ok(());
17341 }
17342
17343 if self.config.dialect == Some(DialectType::Snowflake)
17344 && func.name.eq_ignore_ascii_case("LIST")
17345 && func.args.len() == 1
17346 && !matches!(func.args.first(), Some(Expression::Select(_)))
17347 {
17348 self.write_keyword("ARRAY_AGG");
17349 self.write("(");
17350 self.generate_expression(&func.args[0])?;
17351 self.write(")");
17352 return Ok(());
17353 }
17354
17355 if self.config.dialect == Some(DialectType::Redshift)
17357 && func.name.eq_ignore_ascii_case("CONCAT")
17358 && func.args.len() >= 2
17359 {
17360 for (i, arg) in func.args.iter().enumerate() {
17361 if i > 0 {
17362 self.write(" || ");
17363 }
17364 self.generate_expression(arg)?;
17365 }
17366 return Ok(());
17367 }
17368
17369 if self.config.dialect == Some(DialectType::Redshift)
17371 && func.name.eq_ignore_ascii_case("CONCAT_WS")
17372 && func.args.len() >= 2
17373 {
17374 let sep = &func.args[0];
17375 for (i, arg) in func.args.iter().skip(1).enumerate() {
17376 if i > 0 {
17377 self.write(" || ");
17378 self.generate_expression(sep)?;
17379 self.write(" || ");
17380 }
17381 self.generate_expression(arg)?;
17382 }
17383 return Ok(());
17384 }
17385
17386 if self.config.dialect == Some(DialectType::Redshift)
17389 && (func.name.eq_ignore_ascii_case("DATEDIFF")
17390 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
17391 && func.args.len() == 3
17392 {
17393 self.write_keyword("DATEDIFF");
17394 self.write("(");
17395 self.write_redshift_date_part(&func.args[0]);
17397 self.write(", ");
17398 self.generate_expression(&func.args[1])?;
17399 self.write(", ");
17400 self.generate_expression(&func.args[2])?;
17401 self.write(")");
17402 return Ok(());
17403 }
17404
17405 if self.config.dialect == Some(DialectType::Redshift)
17408 && (func.name.eq_ignore_ascii_case("DATEADD")
17409 || func.name.eq_ignore_ascii_case("DATE_ADD"))
17410 && func.args.len() == 3
17411 {
17412 self.write_keyword("DATEADD");
17413 self.write("(");
17414 self.write_redshift_date_part(&func.args[0]);
17416 self.write(", ");
17417 self.generate_expression(&func.args[1])?;
17418 self.write(", ");
17419 self.generate_expression(&func.args[2])?;
17420 self.write(")");
17421 return Ok(());
17422 }
17423
17424 if func.name.eq_ignore_ascii_case("UUID_STRING")
17426 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
17427 {
17428 if matches!(
17429 self.config.dialect,
17430 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
17431 ) {
17432 self.write_keyword("CAST");
17433 self.write("(");
17434 self.write_keyword("UUID");
17435 self.write("() ");
17436 self.write_keyword("AS");
17437 self.write(" ");
17438 self.write_keyword("STRING");
17439 self.write(")");
17440 return Ok(());
17441 }
17442
17443 if matches!(
17444 self.config.dialect,
17445 Some(DialectType::Presto | DialectType::Trino)
17446 ) {
17447 self.write_keyword("CAST");
17448 self.write("(");
17449 self.write_keyword("UUID");
17450 self.write("() ");
17451 self.write_keyword("AS");
17452 self.write(" ");
17453 self.write_keyword("VARCHAR");
17454 self.write(")");
17455 return Ok(());
17456 }
17457
17458 if self.config.dialect == Some(DialectType::DuckDB) && func.args.len() == 2 {
17459 self.write("(SELECT LOWER(SUBSTRING(h, 1, 8) || '-' || SUBSTRING(h, 9, 4) || '-' || '5' || SUBSTRING(h, 14, 3) || '-' || FORMAT('{:02x}', CAST('0x' || SUBSTRING(h, 17, 2) AS INT) & 63 | 128) || SUBSTRING(h, 19, 2) || '-' || SUBSTRING(h, 21, 12)) FROM (SELECT SUBSTRING(SHA1(UNHEX(REPLACE(");
17460 self.generate_expression(&func.args[0])?;
17461 self.write(", '-', '')) || ENCODE(");
17462 self.generate_expression(&func.args[1])?;
17463 self.write(")), 1, 32) AS h))");
17464 return Ok(());
17465 }
17466
17467 let func_name = match self.config.dialect {
17468 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
17469 Some(DialectType::BigQuery) => "GENERATE_UUID",
17470 _ => "UUID",
17471 };
17472 self.write_keyword(func_name);
17473 self.write("()");
17474 return Ok(());
17475 }
17476
17477 if matches!(self.config.dialect, Some(DialectType::Snowflake))
17481 && func.name.eq_ignore_ascii_case("GENERATOR")
17482 {
17483 let has_positional_args =
17484 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
17485 if has_positional_args {
17486 let param_names = ["ROWCOUNT", "TIMELIMIT"];
17487 self.write_keyword("GENERATOR");
17488 self.write("(");
17489 for (i, arg) in func.args.iter().enumerate() {
17490 if i > 0 {
17491 self.write(", ");
17492 }
17493 if i < param_names.len() {
17494 self.write_keyword(param_names[i]);
17495 self.write(" => ");
17496 self.generate_expression(arg)?;
17497 } else {
17498 self.generate_expression(arg)?;
17499 }
17500 }
17501 self.write(")");
17502 return Ok(());
17503 }
17504 }
17505
17506 if self.config.dialect == Some(DialectType::Redshift)
17509 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
17510 && func.args.len() == 2
17511 {
17512 self.write_keyword("DATE_TRUNC");
17513 self.write("(");
17514 self.write_redshift_date_part_quoted(&func.args[0]);
17516 self.write(", ");
17517 self.generate_expression(&func.args[1])?;
17518 self.write(")");
17519 return Ok(());
17520 }
17521
17522 if matches!(
17524 self.config.dialect,
17525 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17526 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17527 || func.name.eq_ignore_ascii_case("DATEPART"))
17528 && func.args.len() == 2
17529 {
17530 self.write_keyword("DATEPART");
17531 self.write("(");
17532 self.generate_expression(&func.args[0])?;
17533 self.write(", ");
17534 self.generate_expression(&func.args[1])?;
17535 self.write(")");
17536 return Ok(());
17537 }
17538
17539 if matches!(
17541 self.config.dialect,
17542 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
17543 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17544 || func.name.eq_ignore_ascii_case("DATEPART"))
17545 && func.args.len() == 2
17546 {
17547 self.write_keyword("EXTRACT");
17548 self.write("(");
17549 match &func.args[0] {
17551 Expression::Literal(lit)
17552 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
17553 {
17554 let crate::expressions::Literal::String(s) = lit.as_ref() else {
17555 unreachable!()
17556 };
17557 self.write(&s.to_ascii_lowercase());
17558 }
17559 _ => self.generate_expression(&func.args[0])?,
17560 }
17561 self.write_space();
17562 self.write_keyword("FROM");
17563 self.write_space();
17564 self.generate_expression(&func.args[1])?;
17565 self.write(")");
17566 return Ok(());
17567 }
17568
17569 if self.config.dialect == Some(DialectType::PostgreSQL)
17571 && matches!(
17572 func.name.to_ascii_uppercase().as_str(),
17573 "DATE_ADD" | "DATE_SUB"
17574 )
17575 && func.args.len() == 2
17576 && matches!(func.args[1], Expression::Interval(_))
17577 {
17578 self.generate_expression(&func.args[0])?;
17579 self.write_space();
17580 if func.name.eq_ignore_ascii_case("DATE_SUB") {
17581 self.write("-");
17582 } else {
17583 self.write("+");
17584 }
17585 self.write_space();
17586 self.generate_expression(&func.args[1])?;
17587 return Ok(());
17588 }
17589
17590 if self.config.dialect == Some(DialectType::Dremio)
17593 && (func.name.eq_ignore_ascii_case("DATE_PART")
17594 || func.name.eq_ignore_ascii_case("DATEPART"))
17595 && func.args.len() == 2
17596 {
17597 self.write_keyword("EXTRACT");
17598 self.write("(");
17599 self.generate_expression(&func.args[0])?;
17600 self.write_space();
17601 self.write_keyword("FROM");
17602 self.write_space();
17603 self.generate_dremio_date_expression(&func.args[1])?;
17605 self.write(")");
17606 return Ok(());
17607 }
17608
17609 if self.config.dialect == Some(DialectType::Dremio)
17611 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
17612 && func.args.is_empty()
17613 {
17614 self.write_keyword("CURRENT_DATE_UTC");
17615 return Ok(());
17616 }
17617
17618 if self.config.dialect == Some(DialectType::Dremio)
17622 && func.name.eq_ignore_ascii_case("DATETYPE")
17623 && func.args.len() == 3
17624 {
17625 fn get_int_literal(expr: &Expression) -> Option<i64> {
17627 if let Expression::Literal(lit) = expr {
17628 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
17629 s.parse::<i64>().ok()
17630 } else {
17631 None
17632 }
17633 } else {
17634 None
17635 }
17636 }
17637
17638 if let (Some(year), Some(month), Some(day)) = (
17640 get_int_literal(&func.args[0]),
17641 get_int_literal(&func.args[1]),
17642 get_int_literal(&func.args[2]),
17643 ) {
17644 self.write_keyword("DATE");
17646 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
17647 return Ok(());
17648 }
17649
17650 self.write_keyword("CAST");
17652 self.write("(");
17653 self.write_keyword("CONCAT");
17654 self.write("(");
17655 self.generate_expression(&func.args[0])?;
17656 self.write(", '-', ");
17657 self.generate_expression(&func.args[1])?;
17658 self.write(", '-', ");
17659 self.generate_expression(&func.args[2])?;
17660 self.write(")");
17661 self.write_space();
17662 self.write_keyword("AS");
17663 self.write_space();
17664 self.write_keyword("DATE");
17665 self.write(")");
17666 return Ok(());
17667 }
17668
17669 let is_presto_like = matches!(
17672 self.config.dialect,
17673 Some(DialectType::Presto) | Some(DialectType::Trino)
17674 );
17675 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
17676 self.write_keyword("DATE_ADD");
17677 self.write("(");
17678 self.generate_expression(&func.args[0])?;
17680 self.write(", ");
17681 let interval = &func.args[1];
17683 let needs_cast = !self.returns_integer_type(interval);
17684 if needs_cast {
17685 self.write_keyword("CAST");
17686 self.write("(");
17687 }
17688 self.generate_expression(interval)?;
17689 if needs_cast {
17690 self.write_space();
17691 self.write_keyword("AS");
17692 self.write_space();
17693 self.write_keyword("BIGINT");
17694 self.write(")");
17695 }
17696 self.write(", ");
17697 self.generate_expression(&func.args[2])?;
17699 self.write(")");
17700 return Ok(());
17701 }
17702
17703 let use_brackets = func.use_bracket_syntax;
17705
17706 let has_ordinality = func.name.len() >= 16
17711 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
17712 let output_name = if has_ordinality {
17713 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
17714 self.normalize_func_name(base_name)
17715 } else {
17716 normalized_name.clone()
17717 };
17718
17719 let quote_source_clickhouse_function =
17722 matches!(self.config.dialect, Some(DialectType::ClickHouse))
17723 && matches!(self.config.source_dialect, Some(DialectType::ClickHouse))
17724 && func.quoted;
17725
17726 if quote_source_clickhouse_function {
17727 self.generate_identifier(&Identifier {
17728 name: func.name.clone(),
17729 quoted: true,
17730 trailing_comments: Vec::new(),
17731 span: None,
17732 })?;
17733 } else if func.name.contains('.') && !has_ordinality {
17734 if func.quoted {
17737 self.write("`");
17738 self.write(&func.name);
17739 self.write("`");
17740 } else {
17741 self.write(&func.name);
17742 }
17743 } else {
17744 self.write(&output_name);
17745 }
17746
17747 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
17750 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
17751 || func.name.eq_ignore_ascii_case("SESSION_USER")
17752 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
17753 {
17754 matches!(
17755 self.config.dialect,
17756 Some(DialectType::Snowflake)
17757 | Some(DialectType::Spark)
17758 | Some(DialectType::Databricks)
17759 | Some(DialectType::Hive)
17760 )
17761 } else {
17762 false
17763 };
17764 !needs_parens
17765 };
17766 if force_parens {
17767 for comment in &func.trailing_comments {
17769 self.write_space();
17770 self.write_formatted_comment(comment);
17771 }
17772 return Ok(());
17773 }
17774
17775 if func.name.eq_ignore_ascii_case("CUBE")
17777 || func.name.eq_ignore_ascii_case("ROLLUP")
17778 || func.name.eq_ignore_ascii_case("GROUPING SETS")
17779 {
17780 self.write(" (");
17781 } else if use_brackets {
17782 self.write("[");
17783 } else {
17784 self.write("(");
17785 }
17786 if func.distinct {
17787 self.write_keyword("DISTINCT");
17788 self.write_space();
17789 }
17790
17791 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
17793 && (func.name.eq_ignore_ascii_case("TABLE")
17794 || func.name.eq_ignore_ascii_case("FLATTEN"));
17795 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
17797 || func.name.eq_ignore_ascii_case("CUBE")
17798 || func.name.eq_ignore_ascii_case("ROLLUP");
17799 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
17800 if is_grouping_func {
17801 true
17802 } else {
17803 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
17805 for arg in &func.args {
17806 let mut temp_gen = Generator::with_arc_config(self.config.clone());
17807 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
17809 expr_strings.push(temp_gen.output);
17810 }
17811 self.too_wide(&expr_strings)
17812 }
17813 } else {
17814 false
17815 };
17816
17817 if should_split {
17818 self.write_newline();
17820 self.indent_level += 1;
17821 for (i, arg) in func.args.iter().enumerate() {
17822 self.write_indent();
17823 self.generate_expression(arg)?;
17824 if i + 1 < func.args.len() {
17825 self.write(",");
17826 }
17827 self.write_newline();
17828 }
17829 self.indent_level -= 1;
17830 self.write_indent();
17831 } else {
17832 for (i, arg) in func.args.iter().enumerate() {
17834 if i > 0 {
17835 self.write(", ");
17836 }
17837 self.generate_expression(arg)?;
17838 }
17839 }
17840
17841 if use_brackets {
17842 self.write("]");
17843 } else {
17844 self.write(")");
17845 }
17846 if has_ordinality {
17848 self.write_space();
17849 self.write_keyword("WITH ORDINALITY");
17850 }
17851 for comment in &func.trailing_comments {
17853 self.write_space();
17854 self.write_formatted_comment(comment);
17855 }
17856 Ok(())
17857 }
17858
17859 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
17860 self.generate_expression(&fe.this)?;
17861 self.write_keyword(" EMITS ");
17862 self.generate_expression(&fe.emits)?;
17863 Ok(())
17864 }
17865
17866 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
17867 let mut normalized_name = self.normalize_func_name(&func.name);
17869
17870 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
17872 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
17873 match self.config.dialect {
17874 Some(DialectType::ClickHouse) => {
17875 normalized_name = if is_max {
17876 Cow::Borrowed("argMax")
17877 } else {
17878 Cow::Borrowed("argMin")
17879 };
17880 }
17881 Some(DialectType::DuckDB) => {
17882 normalized_name = if is_max {
17883 Cow::Borrowed("ARG_MAX")
17884 } else {
17885 Cow::Borrowed("ARG_MIN")
17886 };
17887 }
17888 _ => {}
17889 }
17890 }
17891 self.write(normalized_name.as_ref());
17892 self.write("(");
17893 if func.distinct {
17894 self.write_keyword("DISTINCT");
17895 self.write_space();
17896 }
17897
17898 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
17902 let needs_multi_arg_transform =
17903 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
17904
17905 if needs_multi_arg_transform {
17906 self.write_keyword("CASE");
17908 for arg in &func.args {
17909 self.write_space();
17910 self.write_keyword("WHEN");
17911 self.write_space();
17912 self.generate_expression(arg)?;
17913 self.write_space();
17914 self.write_keyword("IS NULL THEN NULL");
17915 }
17916 self.write_space();
17917 self.write_keyword("ELSE");
17918 self.write(" (");
17919 for (i, arg) in func.args.iter().enumerate() {
17920 if i > 0 {
17921 self.write(", ");
17922 }
17923 self.generate_expression(arg)?;
17924 }
17925 self.write(")");
17926 self.write_space();
17927 self.write_keyword("END");
17928 } else {
17929 for (i, arg) in func.args.iter().enumerate() {
17930 if i > 0 {
17931 self.write(", ");
17932 }
17933 self.generate_expression(arg)?;
17934 }
17935 }
17936
17937 let clickhouse_ignore_nulls_outside =
17939 matches!(self.config.dialect, Some(DialectType::ClickHouse));
17940 if self.config.ignore_nulls_in_func
17941 && !matches!(
17942 self.config.dialect,
17943 Some(DialectType::DuckDB) | Some(DialectType::ClickHouse)
17944 )
17945 {
17946 if let Some(ignore) = func.ignore_nulls {
17947 self.write_space();
17948 if ignore {
17949 self.write_keyword("IGNORE NULLS");
17950 } else {
17951 self.write_keyword("RESPECT NULLS");
17952 }
17953 }
17954 }
17955
17956 if !func.order_by.is_empty() {
17958 self.write_space();
17959 self.write_keyword("ORDER BY");
17960 self.write_space();
17961 for (i, ord) in func.order_by.iter().enumerate() {
17962 if i > 0 {
17963 self.write(", ");
17964 }
17965 self.generate_ordered(ord)?;
17966 }
17967 }
17968
17969 if let Some(limit) = &func.limit {
17971 self.write_space();
17972 self.write_keyword("LIMIT");
17973 self.write_space();
17974 if let Expression::Tuple(t) = limit.as_ref() {
17976 if t.expressions.len() == 2 {
17977 self.generate_expression(&t.expressions[0])?;
17978 self.write(", ");
17979 self.generate_expression(&t.expressions[1])?;
17980 } else {
17981 self.generate_expression(limit)?;
17982 }
17983 } else {
17984 self.generate_expression(limit)?;
17985 }
17986 }
17987
17988 self.write(")");
17989
17990 if (!self.config.ignore_nulls_in_func || clickhouse_ignore_nulls_outside)
17992 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17993 {
17994 if let Some(ignore) = func.ignore_nulls {
17995 self.write_space();
17996 if ignore {
17997 self.write_keyword("IGNORE NULLS");
17998 } else {
17999 self.write_keyword("RESPECT NULLS");
18000 }
18001 }
18002 }
18003
18004 if let Some(filter) = &func.filter {
18005 self.write_space();
18006 self.write_keyword("FILTER");
18007 self.write("(");
18008 self.write_keyword("WHERE");
18009 self.write_space();
18010 self.generate_expression(filter)?;
18011 self.write(")");
18012 }
18013
18014 Ok(())
18015 }
18016
18017 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
18018 self.generate_expression(&wf.this)?;
18019
18020 if let Some(keep) = &wf.keep {
18022 self.write_space();
18023 self.write_keyword("KEEP");
18024 self.write(" (");
18025 self.write_keyword("DENSE_RANK");
18026 self.write_space();
18027 if keep.first {
18028 self.write_keyword("FIRST");
18029 } else {
18030 self.write_keyword("LAST");
18031 }
18032 self.write_space();
18033 self.write_keyword("ORDER BY");
18034 self.write_space();
18035 for (i, ord) in keep.order_by.iter().enumerate() {
18036 if i > 0 {
18037 self.write(", ");
18038 }
18039 self.generate_ordered(ord)?;
18040 }
18041 self.write(")");
18042 }
18043
18044 let has_over = !wf.over.partition_by.is_empty()
18046 || !wf.over.order_by.is_empty()
18047 || wf.over.frame.is_some()
18048 || wf.over.window_name.is_some();
18049
18050 if has_over {
18052 self.write_space();
18053 self.write_keyword("OVER");
18054
18055 let has_specs = !wf.over.partition_by.is_empty()
18057 || !wf.over.order_by.is_empty()
18058 || wf.over.frame.is_some();
18059
18060 if wf.over.window_name.is_some() && !has_specs {
18061 self.write_space();
18063 self.write(&wf.over.window_name.as_ref().unwrap().name);
18064 } else {
18065 self.write(" (");
18067 self.generate_over(&wf.over)?;
18068 self.write(")");
18069 }
18070 } else if wf.keep.is_none() {
18071 self.write_space();
18073 self.write_keyword("OVER");
18074 self.write(" ()");
18075 }
18076
18077 Ok(())
18078 }
18079
18080 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
18082 self.generate_expression(&wg.this)?;
18083 self.write_space();
18084 self.write_keyword("WITHIN GROUP");
18085 self.write(" (");
18086 self.write_keyword("ORDER BY");
18087 self.write_space();
18088 for (i, ord) in wg.order_by.iter().enumerate() {
18089 if i > 0 {
18090 self.write(", ");
18091 }
18092 self.generate_ordered(ord)?;
18093 }
18094 self.write(")");
18095 Ok(())
18096 }
18097
18098 fn generate_over(&mut self, over: &Over) -> Result<()> {
18100 let mut has_content = false;
18101
18102 if let Some(name) = &over.window_name {
18104 self.write(&name.name);
18105 has_content = true;
18106 }
18107
18108 if !over.partition_by.is_empty() {
18110 if has_content {
18111 self.write_space();
18112 }
18113 self.write_keyword("PARTITION BY");
18114 self.write_space();
18115 for (i, expr) in over.partition_by.iter().enumerate() {
18116 if i > 0 {
18117 self.write(", ");
18118 }
18119 self.generate_expression(expr)?;
18120 }
18121 has_content = true;
18122 }
18123
18124 if !over.order_by.is_empty() {
18126 if has_content {
18127 self.write_space();
18128 }
18129 self.write_keyword("ORDER BY");
18130 self.write_space();
18131 for (i, ordered) in over.order_by.iter().enumerate() {
18132 if i > 0 {
18133 self.write(", ");
18134 }
18135 self.generate_ordered(ordered)?;
18136 }
18137 has_content = true;
18138 }
18139
18140 if let Some(frame) = &over.frame {
18142 if has_content {
18143 self.write_space();
18144 }
18145 self.generate_window_frame(frame)?;
18146 }
18147
18148 Ok(())
18149 }
18150
18151 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
18152 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18154
18155 if !lowercase_frame {
18157 if let Some(kind_text) = &frame.kind_text {
18158 self.write(kind_text);
18159 } else {
18160 match frame.kind {
18161 WindowFrameKind::Rows => self.write_keyword("ROWS"),
18162 WindowFrameKind::Range => self.write_keyword("RANGE"),
18163 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
18164 }
18165 }
18166 } else {
18167 match frame.kind {
18168 WindowFrameKind::Rows => self.write("rows"),
18169 WindowFrameKind::Range => self.write("range"),
18170 WindowFrameKind::Groups => self.write("groups"),
18171 }
18172 }
18173
18174 self.write_space();
18177 let should_normalize = self.config.normalize_window_frame_between
18178 && frame.end.is_none()
18179 && matches!(
18180 frame.start,
18181 WindowFrameBound::Preceding(_)
18182 | WindowFrameBound::Following(_)
18183 | WindowFrameBound::UnboundedPreceding
18184 | WindowFrameBound::UnboundedFollowing
18185 );
18186
18187 if let Some(end) = &frame.end {
18188 self.write_keyword("BETWEEN");
18190 self.write_space();
18191 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18192 self.write_space();
18193 self.write_keyword("AND");
18194 self.write_space();
18195 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
18196 } else if should_normalize {
18197 self.write_keyword("BETWEEN");
18199 self.write_space();
18200 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18201 self.write_space();
18202 self.write_keyword("AND");
18203 self.write_space();
18204 self.write_keyword("CURRENT ROW");
18205 } else {
18206 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
18208 }
18209
18210 if let Some(exclude) = &frame.exclude {
18212 self.write_space();
18213 self.write_keyword("EXCLUDE");
18214 self.write_space();
18215 match exclude {
18216 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
18217 WindowFrameExclude::Group => self.write_keyword("GROUP"),
18218 WindowFrameExclude::Ties => self.write_keyword("TIES"),
18219 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
18220 }
18221 }
18222
18223 Ok(())
18224 }
18225
18226 fn generate_window_frame_bound(
18227 &mut self,
18228 bound: &WindowFrameBound,
18229 side_text: Option<&str>,
18230 ) -> Result<()> {
18231 let lowercase_frame = self.config.lowercase_window_frame_keywords;
18233
18234 match bound {
18235 WindowFrameBound::CurrentRow => {
18236 self.write_keyword("CURRENT ROW");
18237 }
18238 WindowFrameBound::UnboundedPreceding => {
18239 self.write_keyword("UNBOUNDED");
18240 self.write_space();
18241 if lowercase_frame {
18242 self.write("preceding");
18243 } else if let Some(text) = side_text {
18244 self.write(text);
18245 } else {
18246 self.write_keyword("PRECEDING");
18247 }
18248 }
18249 WindowFrameBound::UnboundedFollowing => {
18250 self.write_keyword("UNBOUNDED");
18251 self.write_space();
18252 if lowercase_frame {
18253 self.write("following");
18254 } else if let Some(text) = side_text {
18255 self.write(text);
18256 } else {
18257 self.write_keyword("FOLLOWING");
18258 }
18259 }
18260 WindowFrameBound::Preceding(expr) => {
18261 self.generate_expression(expr)?;
18262 self.write_space();
18263 if lowercase_frame {
18264 self.write("preceding");
18265 } else if let Some(text) = side_text {
18266 self.write(text);
18267 } else {
18268 self.write_keyword("PRECEDING");
18269 }
18270 }
18271 WindowFrameBound::Following(expr) => {
18272 self.generate_expression(expr)?;
18273 self.write_space();
18274 if lowercase_frame {
18275 self.write("following");
18276 } else if let Some(text) = side_text {
18277 self.write(text);
18278 } else {
18279 self.write_keyword("FOLLOWING");
18280 }
18281 }
18282 WindowFrameBound::BarePreceding => {
18283 if lowercase_frame {
18284 self.write("preceding");
18285 } else if let Some(text) = side_text {
18286 self.write(text);
18287 } else {
18288 self.write_keyword("PRECEDING");
18289 }
18290 }
18291 WindowFrameBound::BareFollowing => {
18292 if lowercase_frame {
18293 self.write("following");
18294 } else if let Some(text) = side_text {
18295 self.write(text);
18296 } else {
18297 self.write_keyword("FOLLOWING");
18298 }
18299 }
18300 WindowFrameBound::Value(expr) => {
18301 self.generate_expression(expr)?;
18303 }
18304 }
18305 Ok(())
18306 }
18307
18308 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
18309 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
18312 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
18313 && !matches!(&interval.this, Some(Expression::Literal(_)));
18314
18315 if self.config.single_string_interval {
18318 if let (
18319 Some(Expression::Literal(lit)),
18320 Some(IntervalUnitSpec::Simple {
18321 ref unit,
18322 ref use_plural,
18323 }),
18324 ) = (&interval.this, &interval.unit)
18325 {
18326 if let Literal::String(ref val) = lit.as_ref() {
18327 self.write_keyword("INTERVAL");
18328 self.write_space();
18329 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18330 let unit_str = self.interval_unit_str(unit, effective_plural);
18331 self.write("'");
18332 self.write(val);
18333 self.write(" ");
18334 self.write(&unit_str);
18335 self.write("'");
18336 return Ok(());
18337 }
18338 }
18339 }
18340
18341 if !skip_interval_keyword {
18342 self.write_keyword("INTERVAL");
18343 }
18344
18345 if let Some(ref value) = interval.this {
18347 if !skip_interval_keyword {
18348 self.write_space();
18349 }
18350 let needs_parens = interval.unit.is_some()
18354 && matches!(
18355 value,
18356 Expression::Add(_)
18357 | Expression::Sub(_)
18358 | Expression::Mul(_)
18359 | Expression::Div(_)
18360 | Expression::Mod(_)
18361 | Expression::BitwiseAnd(_)
18362 | Expression::BitwiseOr(_)
18363 | Expression::BitwiseXor(_)
18364 );
18365 if needs_parens {
18366 self.write("(");
18367 }
18368 self.generate_expression(value)?;
18369 if needs_parens {
18370 self.write(")");
18371 }
18372 }
18373
18374 if let Some(ref unit_spec) = interval.unit {
18376 self.write_space();
18377 self.write_interval_unit_spec(unit_spec)?;
18378 }
18379
18380 Ok(())
18381 }
18382
18383 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
18385 match (unit, use_plural) {
18386 (IntervalUnit::Year, false) => "YEAR",
18387 (IntervalUnit::Year, true) => "YEARS",
18388 (IntervalUnit::Quarter, false) => "QUARTER",
18389 (IntervalUnit::Quarter, true) => "QUARTERS",
18390 (IntervalUnit::Month, false) => "MONTH",
18391 (IntervalUnit::Month, true) => "MONTHS",
18392 (IntervalUnit::Week, false) => "WEEK",
18393 (IntervalUnit::Week, true) => "WEEKS",
18394 (IntervalUnit::Day, false) => "DAY",
18395 (IntervalUnit::Day, true) => "DAYS",
18396 (IntervalUnit::Hour, false) => "HOUR",
18397 (IntervalUnit::Hour, true) => "HOURS",
18398 (IntervalUnit::Minute, false) => "MINUTE",
18399 (IntervalUnit::Minute, true) => "MINUTES",
18400 (IntervalUnit::Second, false) => "SECOND",
18401 (IntervalUnit::Second, true) => "SECONDS",
18402 (IntervalUnit::Millisecond, false) => "MILLISECOND",
18403 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
18404 (IntervalUnit::Microsecond, false) => "MICROSECOND",
18405 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
18406 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
18407 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
18408 }
18409 }
18410
18411 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
18412 match unit_spec {
18413 IntervalUnitSpec::Simple { unit, use_plural } => {
18414 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
18416 self.write_simple_interval_unit(unit, effective_plural);
18417 }
18418 IntervalUnitSpec::Span(span) => {
18419 self.write_simple_interval_unit(&span.this, false);
18420 self.write_space();
18421 self.write_keyword("TO");
18422 self.write_space();
18423 self.write_simple_interval_unit(&span.expression, false);
18424 }
18425 IntervalUnitSpec::ExprSpan(span) => {
18426 self.generate_expression(&span.this)?;
18428 self.write_space();
18429 self.write_keyword("TO");
18430 self.write_space();
18431 self.generate_expression(&span.expression)?;
18432 }
18433 IntervalUnitSpec::Expr(expr) => {
18434 self.generate_expression(expr)?;
18435 }
18436 }
18437 Ok(())
18438 }
18439
18440 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
18441 match (unit, use_plural) {
18443 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
18444 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
18445 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
18446 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
18447 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
18448 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
18449 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
18450 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
18451 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
18452 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
18453 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
18454 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
18455 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
18456 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
18457 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
18458 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
18459 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
18460 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
18461 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
18462 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
18463 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
18464 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
18465 }
18466 }
18467
18468 fn write_redshift_date_part(&mut self, expr: &Expression) {
18471 let part_str = self.extract_date_part_string(expr);
18472 if let Some(part) = part_str {
18473 let normalized = self.normalize_date_part(&part);
18474 self.write_keyword(&normalized);
18475 } else {
18476 let _ = self.generate_expression(expr);
18478 }
18479 }
18480
18481 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
18484 let part_str = self.extract_date_part_string(expr);
18485 if let Some(part) = part_str {
18486 let normalized = self.normalize_date_part(&part);
18487 self.write("'");
18488 self.write(&normalized);
18489 self.write("'");
18490 } else {
18491 let _ = self.generate_expression(expr);
18493 }
18494 }
18495
18496 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
18498 match expr {
18499 Expression::Literal(lit)
18500 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
18501 {
18502 let crate::expressions::Literal::String(s) = lit.as_ref() else {
18503 unreachable!()
18504 };
18505 Some(s.clone())
18506 }
18507 Expression::Identifier(id) => Some(id.name.clone()),
18508 Expression::Var(v) => Some(v.this.clone()),
18509 Expression::Column(col) if col.table.is_none() => {
18510 Some(col.name.name.clone())
18512 }
18513 _ => None,
18514 }
18515 }
18516
18517 fn normalize_date_part(&self, part: &str) -> String {
18520 let mut buf = [0u8; 64];
18521 let lower: &str = if part.len() <= 64 {
18522 for (i, b) in part.bytes().enumerate() {
18523 buf[i] = b.to_ascii_lowercase();
18524 }
18525 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
18526 } else {
18527 return part.to_ascii_uppercase();
18528 };
18529 match lower {
18530 "day" | "days" | "d" => "DAY".to_string(),
18531 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
18532 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
18533 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
18534 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
18535 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
18536 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
18537 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
18538 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
18539 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
18540 _ => part.to_ascii_uppercase(),
18541 }
18542 }
18543
18544 fn write_datetime_field(&mut self, field: &DateTimeField) {
18545 match field {
18546 DateTimeField::Year => self.write_keyword("YEAR"),
18547 DateTimeField::Month => self.write_keyword("MONTH"),
18548 DateTimeField::Day => self.write_keyword("DAY"),
18549 DateTimeField::Hour => self.write_keyword("HOUR"),
18550 DateTimeField::Minute => self.write_keyword("MINUTE"),
18551 DateTimeField::Second => self.write_keyword("SECOND"),
18552 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
18553 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
18554 DateTimeField::DayOfWeek => {
18555 let name = match self.config.dialect {
18556 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
18557 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
18558 _ => "DOW",
18559 };
18560 self.write_keyword(name);
18561 }
18562 DateTimeField::DayOfYear => {
18563 let name = match self.config.dialect {
18564 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
18565 _ => "DOY",
18566 };
18567 self.write_keyword(name);
18568 }
18569 DateTimeField::Week => self.write_keyword("WEEK"),
18570 DateTimeField::WeekWithModifier(modifier) => {
18571 self.write_keyword("WEEK");
18572 self.write("(");
18573 self.write(modifier);
18574 self.write(")");
18575 }
18576 DateTimeField::Quarter => self.write_keyword("QUARTER"),
18577 DateTimeField::Epoch => self.write_keyword("EPOCH"),
18578 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
18579 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
18580 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
18581 DateTimeField::Date => self.write_keyword("DATE"),
18582 DateTimeField::Time => self.write_keyword("TIME"),
18583 DateTimeField::Custom(name) => self.write(name),
18584 }
18585 }
18586
18587 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
18589 match field {
18590 DateTimeField::Year => self.write("year"),
18591 DateTimeField::Month => self.write("month"),
18592 DateTimeField::Day => self.write("day"),
18593 DateTimeField::Hour => self.write("hour"),
18594 DateTimeField::Minute => self.write("minute"),
18595 DateTimeField::Second => self.write("second"),
18596 DateTimeField::Millisecond => self.write("millisecond"),
18597 DateTimeField::Microsecond => self.write("microsecond"),
18598 DateTimeField::DayOfWeek => self.write("dow"),
18599 DateTimeField::DayOfYear => self.write("doy"),
18600 DateTimeField::Week => self.write("week"),
18601 DateTimeField::WeekWithModifier(modifier) => {
18602 self.write("week(");
18603 self.write(modifier);
18604 self.write(")");
18605 }
18606 DateTimeField::Quarter => self.write("quarter"),
18607 DateTimeField::Epoch => self.write("epoch"),
18608 DateTimeField::Timezone => self.write("timezone"),
18609 DateTimeField::TimezoneHour => self.write("timezone_hour"),
18610 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
18611 DateTimeField::Date => self.write("date"),
18612 DateTimeField::Time => self.write("time"),
18613 DateTimeField::Custom(name) => self.write(name),
18614 }
18615 }
18616
18617 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
18620 self.write_keyword(name);
18621 self.write("(");
18622 self.generate_expression(arg)?;
18623 self.write(")");
18624 Ok(())
18625 }
18626
18627 fn generate_unary_func(
18629 &mut self,
18630 default_name: &str,
18631 f: &crate::expressions::UnaryFunc,
18632 ) -> Result<()> {
18633 let name = f.original_name.as_deref().unwrap_or(default_name);
18634 self.write_keyword(name);
18635 self.write("(");
18636 self.generate_expression(&f.this)?;
18637 self.write(")");
18638 Ok(())
18639 }
18640
18641 fn generate_sqrt_cbrt(
18643 &mut self,
18644 f: &crate::expressions::UnaryFunc,
18645 func_name: &str,
18646 _op: &str,
18647 ) -> Result<()> {
18648 self.write_keyword(func_name);
18651 self.write("(");
18652 self.generate_expression(&f.this)?;
18653 self.write(")");
18654 Ok(())
18655 }
18656
18657 fn generate_binary_func(
18658 &mut self,
18659 name: &str,
18660 arg1: &Expression,
18661 arg2: &Expression,
18662 ) -> Result<()> {
18663 self.write_keyword(name);
18664 self.write("(");
18665 self.generate_expression(arg1)?;
18666 self.write(", ");
18667 self.generate_expression(arg2)?;
18668 self.write(")");
18669 Ok(())
18670 }
18671
18672 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
18676 let func_name = f.name.as_deref().unwrap_or("CHAR");
18678 self.write_keyword(func_name);
18679 self.write("(");
18680 for (i, arg) in f.args.iter().enumerate() {
18681 if i > 0 {
18682 self.write(", ");
18683 }
18684 self.generate_expression(arg)?;
18685 }
18686 if let Some(ref charset) = f.charset {
18687 self.write(" ");
18688 self.write_keyword("USING");
18689 self.write(" ");
18690 self.write(charset);
18691 }
18692 self.write(")");
18693 Ok(())
18694 }
18695
18696 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
18697 use crate::dialects::DialectType;
18698
18699 match self.config.dialect {
18700 Some(DialectType::Teradata) => {
18701 self.generate_expression(&f.this)?;
18703 self.write(" ** ");
18704 self.generate_expression(&f.expression)?;
18705 Ok(())
18706 }
18707 _ => {
18708 self.generate_binary_func("POWER", &f.this, &f.expression)
18710 }
18711 }
18712 }
18713
18714 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
18715 self.write_func_name(name);
18716 self.write("(");
18717 for (i, arg) in args.iter().enumerate() {
18718 if i > 0 {
18719 self.write(", ");
18720 }
18721 self.generate_expression(arg)?;
18722 }
18723 self.write(")");
18724 Ok(())
18725 }
18726
18727 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
18730 self.write_keyword("CONCAT_WS");
18731 self.write("(");
18732 self.generate_expression(&f.separator)?;
18733 for expr in &f.expressions {
18734 self.write(", ");
18735 self.generate_expression(expr)?;
18736 }
18737 self.write(")");
18738 Ok(())
18739 }
18740
18741 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18742 if let Expression::Concat(op) = expr {
18743 Self::collect_concat_operands(&op.left, out);
18744 Self::collect_concat_operands(&op.right, out);
18745 } else {
18746 out.push(expr);
18747 }
18748 }
18749
18750 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
18751 let mut operands = Vec::new();
18752 Self::collect_concat_operands(&op.left, &mut operands);
18753 Self::collect_concat_operands(&op.right, &mut operands);
18754
18755 self.write_keyword("CONCAT");
18756 self.write("(");
18757 for (i, operand) in operands.iter().enumerate() {
18758 if i > 0 {
18759 self.write(", ");
18760 }
18761 self.generate_expression(operand)?;
18762 }
18763 self.write(")");
18764 Ok(())
18765 }
18766
18767 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18768 if let Expression::DPipe(dpipe) = expr {
18769 Self::collect_dpipe_operands(&dpipe.this, out);
18770 Self::collect_dpipe_operands(&dpipe.expression, out);
18771 } else {
18772 out.push(expr);
18773 }
18774 }
18775
18776 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
18777 let mut operands = Vec::new();
18778 Self::collect_dpipe_operands(&e.this, &mut operands);
18779 Self::collect_dpipe_operands(&e.expression, &mut operands);
18780
18781 self.write_keyword("CONCAT");
18782 self.write("(");
18783 for (i, operand) in operands.iter().enumerate() {
18784 if i > 0 {
18785 self.write(", ");
18786 }
18787 self.generate_expression(operand)?;
18788 }
18789 self.write(")");
18790 Ok(())
18791 }
18792
18793 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
18794 let use_substr = matches!(
18796 self.config.dialect,
18797 Some(
18798 DialectType::Oracle
18799 | DialectType::Presto
18800 | DialectType::Trino
18801 | DialectType::Athena
18802 )
18803 );
18804 if use_substr {
18805 self.write_keyword("SUBSTR");
18806 } else {
18807 self.write_keyword("SUBSTRING");
18808 }
18809 self.write("(");
18810 self.generate_expression(&f.this)?;
18811 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
18813 let use_comma_syntax = matches!(
18815 self.config.dialect,
18816 Some(DialectType::Spark)
18817 | Some(DialectType::Hive)
18818 | Some(DialectType::Databricks)
18819 | Some(DialectType::TSQL)
18820 | Some(DialectType::Fabric)
18821 );
18822 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
18823 self.write_space();
18825 self.write_keyword("FROM");
18826 self.write_space();
18827 self.generate_expression(&f.start)?;
18828 if let Some(length) = &f.length {
18829 self.write_space();
18830 self.write_keyword("FOR");
18831 self.write_space();
18832 self.generate_expression(length)?;
18833 }
18834 } else {
18835 self.write(", ");
18837 self.generate_expression(&f.start)?;
18838 if let Some(length) = &f.length {
18839 self.write(", ");
18840 self.generate_expression(length)?;
18841 }
18842 }
18843 self.write(")");
18844 Ok(())
18845 }
18846
18847 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
18848 self.write_keyword("OVERLAY");
18849 self.write("(");
18850 self.generate_expression(&f.this)?;
18851 self.write_space();
18852 self.write_keyword("PLACING");
18853 self.write_space();
18854 self.generate_expression(&f.replacement)?;
18855 self.write_space();
18856 self.write_keyword("FROM");
18857 self.write_space();
18858 self.generate_expression(&f.from)?;
18859 if let Some(length) = &f.length {
18860 self.write_space();
18861 self.write_keyword("FOR");
18862 self.write_space();
18863 self.generate_expression(length)?;
18864 }
18865 self.write(")");
18866 Ok(())
18867 }
18868
18869 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
18870 if f.position_explicit && f.characters.is_none() {
18873 match f.position {
18874 TrimPosition::Leading => {
18875 self.write_keyword("LTRIM");
18876 self.write("(");
18877 self.generate_expression(&f.this)?;
18878 self.write(")");
18879 return Ok(());
18880 }
18881 TrimPosition::Trailing => {
18882 self.write_keyword("RTRIM");
18883 self.write("(");
18884 self.generate_expression(&f.this)?;
18885 self.write(")");
18886 return Ok(());
18887 }
18888 TrimPosition::Both => {
18889 }
18892 }
18893 }
18894
18895 self.write_keyword("TRIM");
18896 self.write("(");
18897 let force_standard = f.characters.is_some()
18900 && !f.sql_standard_syntax
18901 && matches!(
18902 self.config.dialect,
18903 Some(DialectType::Hive)
18904 | Some(DialectType::Spark)
18905 | Some(DialectType::Databricks)
18906 | Some(DialectType::ClickHouse)
18907 );
18908 let use_standard = (f.sql_standard_syntax || force_standard)
18909 && !(f.position_explicit
18910 && f.characters.is_none()
18911 && matches!(f.position, TrimPosition::Both));
18912 if use_standard {
18913 if f.position_explicit {
18916 match f.position {
18917 TrimPosition::Both => self.write_keyword("BOTH"),
18918 TrimPosition::Leading => self.write_keyword("LEADING"),
18919 TrimPosition::Trailing => self.write_keyword("TRAILING"),
18920 }
18921 self.write_space();
18922 }
18923 if let Some(chars) = &f.characters {
18924 self.generate_expression(chars)?;
18925 self.write_space();
18926 }
18927 self.write_keyword("FROM");
18928 self.write_space();
18929 self.generate_expression(&f.this)?;
18930 } else {
18931 self.generate_expression(&f.this)?;
18933 if let Some(chars) = &f.characters {
18934 self.write(", ");
18935 self.generate_expression(chars)?;
18936 }
18937 }
18938 self.write(")");
18939 Ok(())
18940 }
18941
18942 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
18943 self.write_keyword("REPLACE");
18944 self.write("(");
18945 self.generate_expression(&f.this)?;
18946 self.write(", ");
18947 self.generate_expression(&f.old)?;
18948 self.write(", ");
18949 self.generate_expression(&f.new)?;
18950 self.write(")");
18951 Ok(())
18952 }
18953
18954 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
18955 self.write_keyword(name);
18956 self.write("(");
18957 self.generate_expression(&f.this)?;
18958 self.write(", ");
18959 self.generate_expression(&f.length)?;
18960 self.write(")");
18961 Ok(())
18962 }
18963
18964 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
18965 self.write_keyword("REPEAT");
18966 self.write("(");
18967 self.generate_expression(&f.this)?;
18968 self.write(", ");
18969 self.generate_expression(&f.times)?;
18970 self.write(")");
18971 Ok(())
18972 }
18973
18974 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
18975 self.write_keyword(name);
18976 self.write("(");
18977 self.generate_expression(&f.this)?;
18978 self.write(", ");
18979 self.generate_expression(&f.length)?;
18980 if let Some(fill) = &f.fill {
18981 self.write(", ");
18982 self.generate_expression(fill)?;
18983 }
18984 self.write(")");
18985 Ok(())
18986 }
18987
18988 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
18989 self.write_keyword("SPLIT");
18990 self.write("(");
18991 self.generate_expression(&f.this)?;
18992 self.write(", ");
18993 self.generate_expression(&f.delimiter)?;
18994 self.write(")");
18995 Ok(())
18996 }
18997
18998 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
18999 use crate::dialects::DialectType;
19000 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
19002 self.generate_expression(&f.this)?;
19003 self.write(" ~ ");
19004 self.generate_expression(&f.pattern)?;
19005 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
19006 self.generate_expression(&f.this)?;
19008 self.write_keyword(" REGEXP_LIKE ");
19009 self.generate_expression(&f.pattern)?;
19010 } else if matches!(
19011 self.config.dialect,
19012 Some(DialectType::SingleStore)
19013 | Some(DialectType::Spark)
19014 | Some(DialectType::Hive)
19015 | Some(DialectType::Databricks)
19016 ) && f.flags.is_none()
19017 {
19018 self.generate_expression(&f.this)?;
19020 self.write_keyword(" RLIKE ");
19021 self.generate_expression(&f.pattern)?;
19022 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
19023 self.write_keyword("REGEXP");
19025 self.write("(");
19026 self.generate_expression(&f.this)?;
19027 self.write(", ");
19028 self.generate_expression(&f.pattern)?;
19029 if let Some(flags) = &f.flags {
19030 self.write(", ");
19031 self.generate_expression(flags)?;
19032 }
19033 self.write(")");
19034 } else {
19035 self.write_keyword("REGEXP_LIKE");
19036 self.write("(");
19037 self.generate_expression(&f.this)?;
19038 self.write(", ");
19039 self.generate_expression(&f.pattern)?;
19040 if let Some(flags) = &f.flags {
19041 self.write(", ");
19042 self.generate_expression(flags)?;
19043 }
19044 self.write(")");
19045 }
19046 Ok(())
19047 }
19048
19049 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
19050 self.write_keyword("REGEXP_REPLACE");
19051 self.write("(");
19052 self.generate_expression(&f.this)?;
19053 self.write(", ");
19054 self.generate_expression(&f.pattern)?;
19055 self.write(", ");
19056 self.generate_expression(&f.replacement)?;
19057 if let Some(flags) = &f.flags {
19058 self.write(", ");
19059 self.generate_expression(flags)?;
19060 }
19061 self.write(")");
19062 Ok(())
19063 }
19064
19065 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
19066 self.write_keyword("REGEXP_EXTRACT");
19067 self.write("(");
19068 self.generate_expression(&f.this)?;
19069 self.write(", ");
19070 self.generate_expression(&f.pattern)?;
19071 if let Some(group) = &f.group {
19072 self.write(", ");
19073 self.generate_expression(group)?;
19074 }
19075 self.write(")");
19076 Ok(())
19077 }
19078
19079 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
19082 self.write_keyword("ROUND");
19083 self.write("(");
19084 self.generate_expression(&f.this)?;
19085 if let Some(decimals) = &f.decimals {
19086 self.write(", ");
19087 self.generate_expression(decimals)?;
19088 }
19089 self.write(")");
19090 Ok(())
19091 }
19092
19093 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
19094 self.write_keyword("FLOOR");
19095 self.write("(");
19096 self.generate_expression(&f.this)?;
19097 if let Some(to) = &f.to {
19099 self.write(" ");
19100 self.write_keyword("TO");
19101 self.write(" ");
19102 self.generate_expression(to)?;
19103 } else if let Some(scale) = &f.scale {
19104 self.write(", ");
19105 self.generate_expression(scale)?;
19106 }
19107 self.write(")");
19108 Ok(())
19109 }
19110
19111 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
19112 self.write_keyword("CEIL");
19113 self.write("(");
19114 self.generate_expression(&f.this)?;
19115 if let Some(to) = &f.to {
19117 self.write(" ");
19118 self.write_keyword("TO");
19119 self.write(" ");
19120 self.generate_expression(to)?;
19121 } else if let Some(decimals) = &f.decimals {
19122 self.write(", ");
19123 self.generate_expression(decimals)?;
19124 }
19125 self.write(")");
19126 Ok(())
19127 }
19128
19129 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
19130 use crate::expressions::Literal;
19131
19132 if let Some(base) = &f.base {
19133 if self.is_log_base_none() {
19136 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
19137 {
19138 self.write_func_name("LOG2");
19139 self.write("(");
19140 self.generate_expression(&f.this)?;
19141 self.write(")");
19142 return Ok(());
19143 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
19144 {
19145 self.write_func_name("LOG10");
19146 self.write("(");
19147 self.generate_expression(&f.this)?;
19148 self.write(")");
19149 return Ok(());
19150 }
19151 }
19153
19154 self.write_func_name("LOG");
19155 self.write("(");
19156 if self.is_log_value_first() {
19157 self.generate_expression(&f.this)?;
19159 self.write(", ");
19160 self.generate_expression(base)?;
19161 } else {
19162 self.generate_expression(base)?;
19164 self.write(", ");
19165 self.generate_expression(&f.this)?;
19166 }
19167 self.write(")");
19168 } else {
19169 self.write_func_name("LOG");
19171 self.write("(");
19172 self.generate_expression(&f.this)?;
19173 self.write(")");
19174 }
19175 Ok(())
19176 }
19177
19178 fn is_log_value_first(&self) -> bool {
19181 use crate::dialects::DialectType;
19182 matches!(
19183 self.config.dialect,
19184 Some(DialectType::BigQuery)
19185 | Some(DialectType::TSQL)
19186 | Some(DialectType::Tableau)
19187 | Some(DialectType::Fabric)
19188 )
19189 }
19190
19191 fn is_log_base_none(&self) -> bool {
19194 use crate::dialects::DialectType;
19195 matches!(
19196 self.config.dialect,
19197 Some(DialectType::Presto)
19198 | Some(DialectType::Trino)
19199 | Some(DialectType::ClickHouse)
19200 | Some(DialectType::Athena)
19201 )
19202 }
19203
19204 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
19207 self.write_keyword("CURRENT_TIME");
19208 if let Some(precision) = f.precision {
19209 self.write(&format!("({})", precision));
19210 } else if matches!(
19211 self.config.dialect,
19212 Some(crate::dialects::DialectType::MySQL)
19213 | Some(crate::dialects::DialectType::SingleStore)
19214 | Some(crate::dialects::DialectType::TiDB)
19215 ) {
19216 self.write("()");
19217 }
19218 Ok(())
19219 }
19220
19221 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
19222 use crate::dialects::DialectType;
19223
19224 if f.sysdate {
19226 match self.config.dialect {
19227 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
19228 self.write_keyword("SYSDATE");
19229 return Ok(());
19230 }
19231 Some(DialectType::Snowflake) => {
19232 self.write_keyword("SYSDATE");
19234 self.write("()");
19235 return Ok(());
19236 }
19237 _ => {
19238 }
19240 }
19241 }
19242
19243 self.write_keyword("CURRENT_TIMESTAMP");
19244 if let Some(precision) = f.precision {
19246 self.write(&format!("({})", precision));
19247 } else if matches!(
19248 self.config.dialect,
19249 Some(crate::dialects::DialectType::MySQL)
19250 | Some(crate::dialects::DialectType::SingleStore)
19251 | Some(crate::dialects::DialectType::TiDB)
19252 | Some(crate::dialects::DialectType::Spark)
19253 | Some(crate::dialects::DialectType::Hive)
19254 | Some(crate::dialects::DialectType::Databricks)
19255 | Some(crate::dialects::DialectType::ClickHouse)
19256 | Some(crate::dialects::DialectType::BigQuery)
19257 | Some(crate::dialects::DialectType::Snowflake)
19258 | Some(crate::dialects::DialectType::Exasol)
19259 ) {
19260 self.write("()");
19261 }
19262 Ok(())
19263 }
19264
19265 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
19266 if self.config.dialect == Some(DialectType::Exasol) {
19268 self.write_keyword("CONVERT_TZ");
19269 self.write("(");
19270 self.generate_expression(&f.this)?;
19271 self.write(", 'UTC', ");
19272 self.generate_expression(&f.zone)?;
19273 self.write(")");
19274 return Ok(());
19275 }
19276
19277 self.generate_expression(&f.this)?;
19278 self.write_space();
19279 self.write_keyword("AT TIME ZONE");
19280 self.write_space();
19281 self.generate_expression(&f.zone)?;
19282 Ok(())
19283 }
19284
19285 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
19286 use crate::dialects::DialectType;
19287
19288 let is_presto_like = matches!(
19291 self.config.dialect,
19292 Some(DialectType::Presto) | Some(DialectType::Trino)
19293 );
19294
19295 if is_presto_like {
19296 self.write_keyword(name);
19297 self.write("(");
19298 self.write("'");
19300 self.write_simple_interval_unit(&f.unit, false);
19301 self.write("'");
19302 self.write(", ");
19303 let needs_cast = !self.returns_integer_type(&f.interval);
19305 if needs_cast {
19306 self.write_keyword("CAST");
19307 self.write("(");
19308 }
19309 self.generate_expression(&f.interval)?;
19310 if needs_cast {
19311 self.write_space();
19312 self.write_keyword("AS");
19313 self.write_space();
19314 self.write_keyword("BIGINT");
19315 self.write(")");
19316 }
19317 self.write(", ");
19318 self.generate_expression(&f.this)?;
19319 self.write(")");
19320 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
19321 self.generate_expression(&f.this)?;
19322 self.write_space();
19323 if name.eq_ignore_ascii_case("DATE_SUB") {
19324 self.write("-");
19325 } else {
19326 self.write("+");
19327 }
19328 self.write_space();
19329 self.write_keyword("INTERVAL");
19330 self.write_space();
19331 self.write("'");
19332 let mut interval_gen = Generator::with_arc_config(self.config.clone());
19333 let interval_sql = interval_gen.generate(&f.interval)?;
19334 self.write(&interval_sql);
19335 self.write(" ");
19336 self.write_simple_interval_unit(&f.unit, false);
19337 self.write("'");
19338 } else {
19339 self.write_keyword(name);
19340 self.write("(");
19341 self.generate_expression(&f.this)?;
19342 self.write(", ");
19343 self.write_keyword("INTERVAL");
19344 self.write_space();
19345 self.generate_expression(&f.interval)?;
19346 self.write_space();
19347 self.write_simple_interval_unit(&f.unit, false); self.write(")");
19349 }
19350 Ok(())
19351 }
19352
19353 fn returns_integer_type(&self, expr: &Expression) -> bool {
19356 use crate::expressions::{DataType, Literal};
19357 match expr {
19358 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
19360 let Literal::Number(n) = lit.as_ref() else {
19361 unreachable!()
19362 };
19363 !n.contains('.')
19364 }
19365
19366 Expression::Floor(f) => self.returns_integer_type(&f.this),
19368
19369 Expression::Round(f) => {
19371 f.decimals.is_none() && self.returns_integer_type(&f.this)
19373 }
19374
19375 Expression::Sign(f) => self.returns_integer_type(&f.this),
19377
19378 Expression::Abs(f) => self.returns_integer_type(&f.this),
19380
19381 Expression::Mul(op) => {
19383 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19384 }
19385 Expression::Add(op) => {
19386 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19387 }
19388 Expression::Sub(op) => {
19389 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
19390 }
19391 Expression::Mod(op) => self.returns_integer_type(&op.left),
19392
19393 Expression::Cast(c) => matches!(
19395 &c.to,
19396 DataType::BigInt { .. }
19397 | DataType::Int { .. }
19398 | DataType::SmallInt { .. }
19399 | DataType::TinyInt { .. }
19400 ),
19401
19402 Expression::Neg(op) => self.returns_integer_type(&op.this),
19404
19405 Expression::Paren(p) => self.returns_integer_type(&p.this),
19407
19408 _ => false,
19411 }
19412 }
19413
19414 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
19415 self.write_keyword("DATEDIFF");
19416 self.write("(");
19417 if let Some(unit) = &f.unit {
19418 self.write_simple_interval_unit(unit, false); self.write(", ");
19420 }
19421 self.generate_expression(&f.this)?;
19422 self.write(", ");
19423 self.generate_expression(&f.expression)?;
19424 self.write(")");
19425 Ok(())
19426 }
19427
19428 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
19429 if self.config.dialect == Some(DialectType::ClickHouse) {
19430 self.write("dateTrunc");
19431 } else {
19432 self.write_keyword("DATE_TRUNC");
19433 }
19434 self.write("('");
19435 self.write_datetime_field(&f.unit);
19436 self.write("', ");
19437 self.generate_expression(&f.this)?;
19438 self.write(")");
19439 Ok(())
19440 }
19441
19442 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
19443 use crate::dialects::DialectType;
19444 use crate::expressions::DateTimeField;
19445
19446 self.write_keyword("LAST_DAY");
19447 self.write("(");
19448 self.generate_expression(&f.this)?;
19449 if let Some(unit) = &f.unit {
19450 self.write(", ");
19451 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
19454 if let DateTimeField::WeekWithModifier(_) = unit {
19455 self.write_keyword("WEEK");
19456 } else {
19457 self.write_datetime_field(unit);
19458 }
19459 } else {
19460 self.write_datetime_field(unit);
19461 }
19462 }
19463 self.write(")");
19464 Ok(())
19465 }
19466
19467 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
19468 if matches!(
19470 self.config.dialect,
19471 Some(DialectType::TSQL) | Some(DialectType::Fabric)
19472 ) {
19473 self.write_keyword("DATEPART");
19474 self.write("(");
19475 self.write_datetime_field(&f.field);
19476 self.write(", ");
19477 self.generate_expression(&f.this)?;
19478 self.write(")");
19479 return Ok(());
19480 }
19481 self.write_keyword("EXTRACT");
19482 self.write("(");
19483 if matches!(
19485 self.config.dialect,
19486 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
19487 ) {
19488 self.write_datetime_field_lower(&f.field);
19489 } else {
19490 self.write_datetime_field(&f.field);
19491 }
19492 self.write_space();
19493 self.write_keyword("FROM");
19494 self.write_space();
19495 self.generate_expression(&f.this)?;
19496 self.write(")");
19497 Ok(())
19498 }
19499
19500 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
19501 self.write_keyword("TO_DATE");
19502 self.write("(");
19503 self.generate_expression(&f.this)?;
19504 if let Some(format) = &f.format {
19505 self.write(", ");
19506 self.generate_expression(format)?;
19507 }
19508 self.write(")");
19509 Ok(())
19510 }
19511
19512 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
19513 self.write_keyword("TO_TIMESTAMP");
19514 self.write("(");
19515 self.generate_expression(&f.this)?;
19516 if let Some(format) = &f.format {
19517 self.write(", ");
19518 self.generate_expression(format)?;
19519 }
19520 self.write(")");
19521 Ok(())
19522 }
19523
19524 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
19527 use crate::dialects::DialectType;
19528
19529 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
19531 self.write_keyword("CASE WHEN");
19532 self.write_space();
19533 self.generate_expression(&f.condition)?;
19534 self.write_space();
19535 self.write_keyword("THEN");
19536 self.write_space();
19537 self.generate_expression(&f.true_value)?;
19538 if let Some(false_val) = &f.false_value {
19539 self.write_space();
19540 self.write_keyword("ELSE");
19541 self.write_space();
19542 self.generate_expression(false_val)?;
19543 }
19544 self.write_space();
19545 self.write_keyword("END");
19546 return Ok(());
19547 }
19548
19549 if self.config.dialect == Some(DialectType::Exasol) {
19551 self.write_keyword("IF");
19552 self.write_space();
19553 self.generate_expression(&f.condition)?;
19554 self.write_space();
19555 self.write_keyword("THEN");
19556 self.write_space();
19557 self.generate_expression(&f.true_value)?;
19558 if let Some(false_val) = &f.false_value {
19559 self.write_space();
19560 self.write_keyword("ELSE");
19561 self.write_space();
19562 self.generate_expression(false_val)?;
19563 }
19564 self.write_space();
19565 self.write_keyword("ENDIF");
19566 return Ok(());
19567 }
19568
19569 let func_name = match self.config.dialect {
19571 Some(DialectType::ClickHouse) => f.original_name.as_deref().unwrap_or("IF"),
19572 Some(DialectType::Snowflake) => "IFF",
19573 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
19574 Some(DialectType::Drill) => "`IF`",
19575 _ => "IF",
19576 };
19577 self.write(func_name);
19578 self.write("(");
19579 self.generate_expression(&f.condition)?;
19580 self.write(", ");
19581 self.generate_expression(&f.true_value)?;
19582 if let Some(false_val) = &f.false_value {
19583 self.write(", ");
19584 self.generate_expression(false_val)?;
19585 }
19586 self.write(")");
19587 Ok(())
19588 }
19589
19590 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
19591 self.write_keyword("NVL2");
19592 self.write("(");
19593 self.generate_expression(&f.this)?;
19594 self.write(", ");
19595 self.generate_expression(&f.true_value)?;
19596 self.write(", ");
19597 self.generate_expression(&f.false_value)?;
19598 self.write(")");
19599 Ok(())
19600 }
19601
19602 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
19605 let count_name = match self.config.normalize_functions {
19607 NormalizeFunctions::Upper => "COUNT".to_string(),
19608 NormalizeFunctions::Lower => "count".to_string(),
19609 NormalizeFunctions::None => f
19610 .original_name
19611 .clone()
19612 .unwrap_or_else(|| "COUNT".to_string()),
19613 };
19614 self.write(&count_name);
19615 self.write("(");
19616 if f.distinct {
19617 self.write_keyword("DISTINCT");
19618 self.write_space();
19619 }
19620 if f.star {
19621 self.write("*");
19622 } else if let Some(ref expr) = f.this {
19623 if let Expression::Tuple(tuple) = expr {
19625 let needs_transform =
19629 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
19630
19631 if needs_transform {
19632 self.write_keyword("CASE");
19634 for e in &tuple.expressions {
19635 self.write_space();
19636 self.write_keyword("WHEN");
19637 self.write_space();
19638 self.generate_expression(e)?;
19639 self.write_space();
19640 self.write_keyword("IS NULL THEN NULL");
19641 }
19642 self.write_space();
19643 self.write_keyword("ELSE");
19644 self.write(" (");
19645 for (i, e) in tuple.expressions.iter().enumerate() {
19646 if i > 0 {
19647 self.write(", ");
19648 }
19649 self.generate_expression(e)?;
19650 }
19651 self.write(")");
19652 self.write_space();
19653 self.write_keyword("END");
19654 } else {
19655 for (i, e) in tuple.expressions.iter().enumerate() {
19656 if i > 0 {
19657 self.write(", ");
19658 }
19659 self.generate_expression(e)?;
19660 }
19661 }
19662 } else {
19663 self.generate_expression(expr)?;
19664 }
19665 }
19666 let clickhouse_ignore_nulls_outside =
19667 matches!(self.config.dialect, Some(DialectType::ClickHouse));
19668 if let Some(ignore) = f.ignore_nulls.filter(|_| !clickhouse_ignore_nulls_outside) {
19669 self.write_space();
19670 if ignore {
19671 self.write_keyword("IGNORE NULLS");
19672 } else {
19673 self.write_keyword("RESPECT NULLS");
19674 }
19675 }
19676 self.write(")");
19677 if let Some(ignore) = f.ignore_nulls.filter(|_| clickhouse_ignore_nulls_outside) {
19678 self.write_space();
19679 if ignore {
19680 self.write_keyword("IGNORE NULLS");
19681 } else {
19682 self.write_keyword("RESPECT NULLS");
19683 }
19684 }
19685 if let Some(ref filter) = f.filter {
19686 self.write_space();
19687 self.write_keyword("FILTER");
19688 self.write("(");
19689 self.write_keyword("WHERE");
19690 self.write_space();
19691 self.generate_expression(filter)?;
19692 self.write(")");
19693 }
19694 Ok(())
19695 }
19696
19697 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19698 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19700 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19701 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19702 NormalizeFunctions::None => {
19703 if let Some(ref original) = f.name {
19706 Cow::Owned(original.clone())
19707 } else {
19708 Cow::Owned(name.to_ascii_lowercase())
19709 }
19710 }
19711 };
19712 self.write(func_name.as_ref());
19713 self.write("(");
19714 if f.distinct {
19715 self.write_keyword("DISTINCT");
19716 self.write_space();
19717 }
19718 let is_zero_arg_mode =
19721 name.eq_ignore_ascii_case("MODE") && matches!(f.this, Expression::Null(_));
19722 if !is_zero_arg_mode {
19723 self.generate_expression(&f.this)?;
19724 }
19725 if self.config.ignore_nulls_in_func
19728 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19729 {
19730 match f.ignore_nulls {
19731 Some(true) => {
19732 self.write_space();
19733 self.write_keyword("IGNORE NULLS");
19734 }
19735 Some(false) => {
19736 self.write_space();
19737 self.write_keyword("RESPECT NULLS");
19738 }
19739 None => {}
19740 }
19741 }
19742 if let Some((ref expr, is_max)) = f.having_max {
19745 self.write_space();
19746 self.write_keyword("HAVING");
19747 self.write_space();
19748 if is_max {
19749 self.write_keyword("MAX");
19750 } else {
19751 self.write_keyword("MIN");
19752 }
19753 self.write_space();
19754 self.generate_expression(expr)?;
19755 }
19756 if !f.order_by.is_empty() {
19758 self.write_space();
19759 self.write_keyword("ORDER BY");
19760 self.write_space();
19761 for (i, ord) in f.order_by.iter().enumerate() {
19762 if i > 0 {
19763 self.write(", ");
19764 }
19765 self.generate_ordered(ord)?;
19766 }
19767 }
19768 if let Some(ref limit) = f.limit {
19770 self.write_space();
19771 self.write_keyword("LIMIT");
19772 self.write_space();
19773 if let Expression::Tuple(t) = limit.as_ref() {
19775 if t.expressions.len() == 2 {
19776 self.generate_expression(&t.expressions[0])?;
19777 self.write(", ");
19778 self.generate_expression(&t.expressions[1])?;
19779 } else {
19780 self.generate_expression(limit)?;
19781 }
19782 } else {
19783 self.generate_expression(limit)?;
19784 }
19785 }
19786 self.write(")");
19787 if !self.config.ignore_nulls_in_func
19790 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19791 {
19792 match f.ignore_nulls {
19793 Some(true) => {
19794 self.write_space();
19795 self.write_keyword("IGNORE NULLS");
19796 }
19797 Some(false) => {
19798 self.write_space();
19799 self.write_keyword("RESPECT NULLS");
19800 }
19801 None => {}
19802 }
19803 }
19804 if let Some(ref filter) = f.filter {
19805 self.write_space();
19806 self.write_keyword("FILTER");
19807 self.write("(");
19808 self.write_keyword("WHERE");
19809 self.write_space();
19810 self.generate_expression(filter)?;
19811 self.write(")");
19812 }
19813 Ok(())
19814 }
19815
19816 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19819 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19821 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19823 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19824 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19825 NormalizeFunctions::None => {
19826 if let Some(ref original) = f.name {
19827 Cow::Owned(original.clone())
19828 } else {
19829 Cow::Owned(name.to_ascii_lowercase())
19830 }
19831 }
19832 };
19833 self.write(func_name.as_ref());
19834 self.write("(");
19835 if f.distinct {
19836 self.write_keyword("DISTINCT");
19837 self.write_space();
19838 }
19839 if !matches!(f.this, Expression::Null(_)) {
19840 self.generate_expression(&f.this)?;
19841 }
19842 self.write(", ");
19843 self.write_keyword("TRUE");
19844 self.write(")");
19845 return Ok(());
19846 }
19847 self.generate_agg_func(name, f)
19848 }
19849
19850 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
19851 self.write_keyword("GROUP_CONCAT");
19852 self.write("(");
19853 if f.distinct {
19854 self.write_keyword("DISTINCT");
19855 self.write_space();
19856 }
19857 self.generate_expression(&f.this)?;
19858 if let Some(ref order_by) = f.order_by {
19859 self.write_space();
19860 self.write_keyword("ORDER BY");
19861 self.write_space();
19862 for (i, ord) in order_by.iter().enumerate() {
19863 if i > 0 {
19864 self.write(", ");
19865 }
19866 self.generate_ordered(ord)?;
19867 }
19868 }
19869 if let Some(ref sep) = f.separator {
19870 if matches!(
19873 self.config.dialect,
19874 Some(crate::dialects::DialectType::SQLite)
19875 ) {
19876 self.write(", ");
19877 self.generate_expression(sep)?;
19878 } else {
19879 self.write_space();
19880 self.write_keyword("SEPARATOR");
19881 self.write_space();
19882 self.generate_expression(sep)?;
19883 }
19884 }
19885 if let Some(ref limit) = f.limit {
19886 self.write_space();
19887 self.write_keyword("LIMIT");
19888 self.write_space();
19889 self.generate_expression(limit)?;
19890 }
19891 self.write(")");
19892 if let Some(ref filter) = f.filter {
19893 self.write_space();
19894 self.write_keyword("FILTER");
19895 self.write("(");
19896 self.write_keyword("WHERE");
19897 self.write_space();
19898 self.generate_expression(filter)?;
19899 self.write(")");
19900 }
19901 Ok(())
19902 }
19903
19904 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
19905 let is_tsql = matches!(
19906 self.config.dialect,
19907 Some(crate::dialects::DialectType::TSQL)
19908 );
19909 self.write_keyword("STRING_AGG");
19910 self.write("(");
19911 if f.distinct {
19912 self.write_keyword("DISTINCT");
19913 self.write_space();
19914 }
19915 self.generate_expression(&f.this)?;
19916 if let Some(ref separator) = f.separator {
19917 self.write(", ");
19918 self.generate_expression(separator)?;
19919 }
19920 if !is_tsql {
19922 if let Some(ref order_by) = f.order_by {
19923 self.write_space();
19924 self.write_keyword("ORDER BY");
19925 self.write_space();
19926 for (i, ord) in order_by.iter().enumerate() {
19927 if i > 0 {
19928 self.write(", ");
19929 }
19930 self.generate_ordered(ord)?;
19931 }
19932 }
19933 }
19934 if let Some(ref limit) = f.limit {
19935 self.write_space();
19936 self.write_keyword("LIMIT");
19937 self.write_space();
19938 self.generate_expression(limit)?;
19939 }
19940 self.write(")");
19941 if is_tsql {
19943 if let Some(ref order_by) = f.order_by {
19944 self.write_space();
19945 self.write_keyword("WITHIN GROUP");
19946 self.write(" (");
19947 self.write_keyword("ORDER BY");
19948 self.write_space();
19949 for (i, ord) in order_by.iter().enumerate() {
19950 if i > 0 {
19951 self.write(", ");
19952 }
19953 self.generate_ordered(ord)?;
19954 }
19955 self.write(")");
19956 }
19957 }
19958 if let Some(ref filter) = f.filter {
19959 self.write_space();
19960 self.write_keyword("FILTER");
19961 self.write("(");
19962 self.write_keyword("WHERE");
19963 self.write_space();
19964 self.generate_expression(filter)?;
19965 self.write(")");
19966 }
19967 Ok(())
19968 }
19969
19970 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
19971 use crate::dialects::DialectType;
19972 self.write_keyword("LISTAGG");
19973 self.write("(");
19974 if f.distinct {
19975 self.write_keyword("DISTINCT");
19976 self.write_space();
19977 }
19978 self.generate_expression(&f.this)?;
19979 if let Some(ref sep) = f.separator {
19980 self.write(", ");
19981 self.generate_expression(sep)?;
19982 } else if matches!(
19983 self.config.dialect,
19984 Some(DialectType::Trino) | Some(DialectType::Presto)
19985 ) {
19986 self.write(", ','");
19988 }
19989 if let Some(ref overflow) = f.on_overflow {
19990 self.write_space();
19991 self.write_keyword("ON OVERFLOW");
19992 self.write_space();
19993 match overflow {
19994 ListAggOverflow::Error => self.write_keyword("ERROR"),
19995 ListAggOverflow::Truncate { filler, with_count } => {
19996 self.write_keyword("TRUNCATE");
19997 if let Some(ref fill) = filler {
19998 self.write_space();
19999 self.generate_expression(fill)?;
20000 }
20001 if *with_count {
20002 self.write_space();
20003 self.write_keyword("WITH COUNT");
20004 } else {
20005 self.write_space();
20006 self.write_keyword("WITHOUT COUNT");
20007 }
20008 }
20009 }
20010 }
20011 self.write(")");
20012 if let Some(ref order_by) = f.order_by {
20013 self.write_space();
20014 self.write_keyword("WITHIN GROUP");
20015 self.write(" (");
20016 self.write_keyword("ORDER BY");
20017 self.write_space();
20018 for (i, ord) in order_by.iter().enumerate() {
20019 if i > 0 {
20020 self.write(", ");
20021 }
20022 self.generate_ordered(ord)?;
20023 }
20024 self.write(")");
20025 }
20026 if let Some(ref filter) = f.filter {
20027 self.write_space();
20028 self.write_keyword("FILTER");
20029 self.write("(");
20030 self.write_keyword("WHERE");
20031 self.write_space();
20032 self.generate_expression(filter)?;
20033 self.write(")");
20034 }
20035 Ok(())
20036 }
20037
20038 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
20039 self.write_keyword("SUM_IF");
20040 self.write("(");
20041 self.generate_expression(&f.this)?;
20042 self.write(", ");
20043 self.generate_expression(&f.condition)?;
20044 self.write(")");
20045 if let Some(ref filter) = f.filter {
20046 self.write_space();
20047 self.write_keyword("FILTER");
20048 self.write("(");
20049 self.write_keyword("WHERE");
20050 self.write_space();
20051 self.generate_expression(filter)?;
20052 self.write(")");
20053 }
20054 Ok(())
20055 }
20056
20057 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
20058 self.write_keyword("APPROX_PERCENTILE");
20059 self.write("(");
20060 self.generate_expression(&f.this)?;
20061 self.write(", ");
20062 self.generate_expression(&f.percentile)?;
20063 if let Some(ref acc) = f.accuracy {
20064 self.write(", ");
20065 self.generate_expression(acc)?;
20066 }
20067 self.write(")");
20068 if let Some(ref filter) = f.filter {
20069 self.write_space();
20070 self.write_keyword("FILTER");
20071 self.write("(");
20072 self.write_keyword("WHERE");
20073 self.write_space();
20074 self.generate_expression(filter)?;
20075 self.write(")");
20076 }
20077 Ok(())
20078 }
20079
20080 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
20081 self.write_keyword(name);
20082 self.write("(");
20083 self.generate_expression(&f.percentile)?;
20084 self.write(")");
20085 if let Some(ref order_by) = f.order_by {
20086 self.write_space();
20087 self.write_keyword("WITHIN GROUP");
20088 self.write(" (");
20089 self.write_keyword("ORDER BY");
20090 self.write_space();
20091 self.generate_expression(&f.this)?;
20092 for ord in order_by.iter() {
20093 if ord.desc {
20094 self.write_space();
20095 self.write_keyword("DESC");
20096 }
20097 }
20098 self.write(")");
20099 }
20100 if let Some(ref filter) = f.filter {
20101 self.write_space();
20102 self.write_keyword("FILTER");
20103 self.write("(");
20104 self.write_keyword("WHERE");
20105 self.write_space();
20106 self.generate_expression(filter)?;
20107 self.write(")");
20108 }
20109 Ok(())
20110 }
20111
20112 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
20115 self.write_keyword("NTILE");
20116 self.write("(");
20117 if let Some(num_buckets) = &f.num_buckets {
20118 self.generate_expression(num_buckets)?;
20119 }
20120 if let Some(order_by) = &f.order_by {
20121 self.write_keyword(" ORDER BY ");
20122 for (i, ob) in order_by.iter().enumerate() {
20123 if i > 0 {
20124 self.write(", ");
20125 }
20126 self.generate_ordered(ob)?;
20127 }
20128 }
20129 self.write(")");
20130 Ok(())
20131 }
20132
20133 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
20134 self.write_keyword(name);
20135 self.write("(");
20136 self.generate_expression(&f.this)?;
20137 if let Some(ref offset) = f.offset {
20138 self.write(", ");
20139 self.generate_expression(offset)?;
20140 if let Some(ref default) = f.default {
20141 self.write(", ");
20142 self.generate_expression(default)?;
20143 }
20144 }
20145 if self.config.ignore_nulls_in_func {
20147 match f.ignore_nulls {
20148 Some(true) => {
20149 self.write_space();
20150 self.write_keyword("IGNORE NULLS");
20151 }
20152 Some(false) => {
20153 self.write_space();
20154 self.write_keyword("RESPECT NULLS");
20155 }
20156 None => {}
20157 }
20158 }
20159 self.write(")");
20160 if !self.config.ignore_nulls_in_func {
20162 match f.ignore_nulls {
20163 Some(true) => {
20164 self.write_space();
20165 self.write_keyword("IGNORE NULLS");
20166 }
20167 Some(false) => {
20168 self.write_space();
20169 self.write_keyword("RESPECT NULLS");
20170 }
20171 None => {}
20172 }
20173 }
20174 Ok(())
20175 }
20176
20177 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
20178 self.write_keyword(name);
20179 self.write("(");
20180 self.generate_expression(&f.this)?;
20181 if !f.order_by.is_empty() {
20183 self.write_space();
20184 self.write_keyword("ORDER BY");
20185 self.write_space();
20186 for (i, ordered) in f.order_by.iter().enumerate() {
20187 if i > 0 {
20188 self.write(", ");
20189 }
20190 self.generate_ordered(ordered)?;
20191 }
20192 }
20193 if self.config.ignore_nulls_in_func {
20195 match f.ignore_nulls {
20196 Some(true) => {
20197 self.write_space();
20198 self.write_keyword("IGNORE NULLS");
20199 }
20200 Some(false) => {
20201 self.write_space();
20202 self.write_keyword("RESPECT NULLS");
20203 }
20204 None => {}
20205 }
20206 }
20207 self.write(")");
20208 if !self.config.ignore_nulls_in_func {
20210 match f.ignore_nulls {
20211 Some(true) => {
20212 self.write_space();
20213 self.write_keyword("IGNORE NULLS");
20214 }
20215 Some(false) => {
20216 self.write_space();
20217 self.write_keyword("RESPECT NULLS");
20218 }
20219 None => {}
20220 }
20221 }
20222 Ok(())
20223 }
20224
20225 fn generate_value_func_with_ignore_nulls_bool(
20228 &mut self,
20229 name: &str,
20230 f: &ValueFunc,
20231 ) -> Result<()> {
20232 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
20233 self.write_keyword(name);
20234 self.write("(");
20235 self.generate_expression(&f.this)?;
20236 self.write(", ");
20237 self.write_keyword("TRUE");
20238 self.write(")");
20239 return Ok(());
20240 }
20241 self.generate_value_func(name, f)
20242 }
20243
20244 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
20245 self.write_keyword("NTH_VALUE");
20246 self.write("(");
20247 self.generate_expression(&f.this)?;
20248 self.write(", ");
20249 self.generate_expression(&f.offset)?;
20250 if self.config.ignore_nulls_in_func {
20252 match f.ignore_nulls {
20253 Some(true) => {
20254 self.write_space();
20255 self.write_keyword("IGNORE NULLS");
20256 }
20257 Some(false) => {
20258 self.write_space();
20259 self.write_keyword("RESPECT NULLS");
20260 }
20261 None => {}
20262 }
20263 }
20264 self.write(")");
20265 if matches!(
20267 self.config.dialect,
20268 Some(crate::dialects::DialectType::Snowflake)
20269 ) {
20270 match f.from_first {
20271 Some(true) => {
20272 self.write_space();
20273 self.write_keyword("FROM FIRST");
20274 }
20275 Some(false) => {
20276 self.write_space();
20277 self.write_keyword("FROM LAST");
20278 }
20279 None => {}
20280 }
20281 }
20282 if !self.config.ignore_nulls_in_func {
20284 match f.ignore_nulls {
20285 Some(true) => {
20286 self.write_space();
20287 self.write_keyword("IGNORE NULLS");
20288 }
20289 Some(false) => {
20290 self.write_space();
20291 self.write_keyword("RESPECT NULLS");
20292 }
20293 None => {}
20294 }
20295 }
20296 Ok(())
20297 }
20298
20299 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
20302 if matches!(
20305 self.config.dialect,
20306 Some(crate::dialects::DialectType::ClickHouse)
20307 ) {
20308 self.write_keyword("POSITION");
20309 self.write("(");
20310 self.generate_expression(&f.string)?;
20311 self.write(", ");
20312 self.generate_expression(&f.substring)?;
20313 if let Some(ref start) = f.start {
20314 self.write(", ");
20315 self.generate_expression(start)?;
20316 }
20317 self.write(")");
20318 return Ok(());
20319 }
20320
20321 self.write_keyword("POSITION");
20322 self.write("(");
20323 self.generate_expression(&f.substring)?;
20324 self.write_space();
20325 self.write_keyword("IN");
20326 self.write_space();
20327 self.generate_expression(&f.string)?;
20328 if let Some(ref start) = f.start {
20329 self.write(", ");
20330 self.generate_expression(start)?;
20331 }
20332 self.write(")");
20333 Ok(())
20334 }
20335
20336 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
20339 if f.lower.is_some() || f.upper.is_some() {
20341 self.write_keyword("RANDOM");
20342 self.write("(");
20343 if let Some(ref lower) = f.lower {
20344 self.generate_expression(lower)?;
20345 }
20346 if let Some(ref upper) = f.upper {
20347 self.write(", ");
20348 self.generate_expression(upper)?;
20349 }
20350 self.write(")");
20351 return Ok(());
20352 }
20353 let func_name = match self.config.dialect {
20355 Some(crate::dialects::DialectType::Snowflake)
20356 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
20357 _ => "RAND",
20358 };
20359 self.write_keyword(func_name);
20360 self.write("(");
20361 if !matches!(
20363 self.config.dialect,
20364 Some(crate::dialects::DialectType::DuckDB)
20365 ) {
20366 if let Some(ref seed) = f.seed {
20367 self.generate_expression(seed)?;
20368 }
20369 }
20370 self.write(")");
20371 Ok(())
20372 }
20373
20374 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
20375 self.write_keyword("TRUNCATE");
20376 self.write("(");
20377 self.generate_expression(&f.this)?;
20378 if let Some(ref decimals) = f.decimals {
20379 self.write(", ");
20380 self.generate_expression(decimals)?;
20381 }
20382 self.write(")");
20383 Ok(())
20384 }
20385
20386 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
20389 self.write_keyword("DECODE");
20390 self.write("(");
20391 self.generate_expression(&f.this)?;
20392 for (search, result) in &f.search_results {
20393 self.write(", ");
20394 self.generate_expression(search)?;
20395 self.write(", ");
20396 self.generate_expression(result)?;
20397 }
20398 if let Some(ref default) = f.default {
20399 self.write(", ");
20400 self.generate_expression(default)?;
20401 }
20402 self.write(")");
20403 Ok(())
20404 }
20405
20406 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
20409 self.write_keyword(name);
20410 self.write("(");
20411 self.generate_expression(&f.this)?;
20412 self.write(", ");
20413 self.generate_expression(&f.format)?;
20414 self.write(")");
20415 Ok(())
20416 }
20417
20418 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
20419 self.write_keyword("FROM_UNIXTIME");
20420 self.write("(");
20421 self.generate_expression(&f.this)?;
20422 if let Some(ref format) = f.format {
20423 self.write(", ");
20424 self.generate_expression(format)?;
20425 }
20426 self.write(")");
20427 Ok(())
20428 }
20429
20430 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
20431 self.write_keyword("UNIX_TIMESTAMP");
20432 self.write("(");
20433 if let Some(ref expr) = f.this {
20434 self.generate_expression(expr)?;
20435 if let Some(ref format) = f.format {
20436 self.write(", ");
20437 self.generate_expression(format)?;
20438 }
20439 } else if matches!(
20440 self.config.dialect,
20441 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
20442 ) {
20443 self.write_keyword("CURRENT_TIMESTAMP");
20445 self.write("()");
20446 }
20447 self.write(")");
20448 Ok(())
20449 }
20450
20451 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
20452 self.write_keyword("MAKE_DATE");
20453 self.write("(");
20454 self.generate_expression(&f.year)?;
20455 self.write(", ");
20456 self.generate_expression(&f.month)?;
20457 self.write(", ");
20458 self.generate_expression(&f.day)?;
20459 self.write(")");
20460 Ok(())
20461 }
20462
20463 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
20464 self.write_keyword("MAKE_TIMESTAMP");
20465 self.write("(");
20466 self.generate_expression(&f.year)?;
20467 self.write(", ");
20468 self.generate_expression(&f.month)?;
20469 self.write(", ");
20470 self.generate_expression(&f.day)?;
20471 self.write(", ");
20472 self.generate_expression(&f.hour)?;
20473 self.write(", ");
20474 self.generate_expression(&f.minute)?;
20475 self.write(", ");
20476 self.generate_expression(&f.second)?;
20477 if let Some(ref tz) = f.timezone {
20478 self.write(", ");
20479 self.generate_expression(tz)?;
20480 }
20481 self.write(")");
20482 Ok(())
20483 }
20484
20485 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
20487 match expr {
20488 Expression::Struct(s) => {
20489 if s.fields.iter().all(|(name, _)| name.is_some()) {
20490 Some(
20491 s.fields
20492 .iter()
20493 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
20494 .collect(),
20495 )
20496 } else {
20497 None
20498 }
20499 }
20500 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20501 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
20503 Some(
20504 f.args
20505 .iter()
20506 .filter_map(|a| {
20507 if let Expression::Alias(alias) = a {
20508 Some(alias.alias.name.clone())
20509 } else {
20510 None
20511 }
20512 })
20513 .collect(),
20514 )
20515 } else {
20516 None
20517 }
20518 }
20519 _ => None,
20520 }
20521 }
20522
20523 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
20525 match expr {
20526 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
20527 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20528 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
20529 }
20530 _ => false,
20531 }
20532 }
20533
20534 fn struct_field_count(expr: &Expression) -> usize {
20536 match expr {
20537 Expression::Struct(s) => s.fields.len(),
20538 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
20539 _ => 0,
20540 }
20541 }
20542
20543 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
20545 match expr {
20546 Expression::Struct(s) => {
20547 let mut new_fields = Vec::with_capacity(s.fields.len());
20548 for (i, (name, value)) in s.fields.iter().enumerate() {
20549 if name.is_none() && i < field_names.len() {
20550 new_fields.push((Some(field_names[i].clone()), value.clone()));
20551 } else {
20552 new_fields.push((name.clone(), value.clone()));
20553 }
20554 }
20555 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
20556 }
20557 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
20558 let mut new_args = Vec::with_capacity(f.args.len());
20559 for (i, arg) in f.args.iter().enumerate() {
20560 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
20561 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
20563 this: arg.clone(),
20564 alias: crate::expressions::Identifier::new(field_names[i].clone()),
20565 column_aliases: Vec::new(),
20566 alias_explicit_as: false,
20567 alias_keyword: None,
20568 pre_alias_comments: Vec::new(),
20569 trailing_comments: Vec::new(),
20570 inferred_type: None,
20571 })));
20572 } else {
20573 new_args.push(arg.clone());
20574 }
20575 }
20576 Expression::Function(Box::new(crate::expressions::Function {
20577 name: f.name.clone(),
20578 args: new_args,
20579 distinct: f.distinct,
20580 trailing_comments: f.trailing_comments.clone(),
20581 use_bracket_syntax: f.use_bracket_syntax,
20582 no_parens: f.no_parens,
20583 quoted: f.quoted,
20584 span: None,
20585 inferred_type: None,
20586 }))
20587 }
20588 _ => expr.clone(),
20589 }
20590 }
20591
20592 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
20596 let first = match expressions.first() {
20597 Some(e) => e,
20598 None => return expressions.to_vec(),
20599 };
20600
20601 let field_names = match Self::extract_struct_field_names(first) {
20602 Some(names) if !names.is_empty() => names,
20603 _ => return expressions.to_vec(),
20604 };
20605
20606 let mut result = Vec::with_capacity(expressions.len());
20607 for (idx, expr) in expressions.iter().enumerate() {
20608 if idx == 0 {
20609 result.push(expr.clone());
20610 continue;
20611 }
20612 if Self::struct_field_count(expr) == field_names.len()
20614 && Self::struct_has_unnamed_fields(expr)
20615 {
20616 result.push(Self::apply_struct_field_names(expr, &field_names));
20617 } else {
20618 result.push(expr.clone());
20619 }
20620 }
20621 result
20622 }
20623
20624 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
20627 let needs_inheritance = matches!(
20630 self.config.dialect,
20631 Some(DialectType::DuckDB)
20632 | Some(DialectType::Spark)
20633 | Some(DialectType::Databricks)
20634 | Some(DialectType::Hive)
20635 | Some(DialectType::Snowflake)
20636 | Some(DialectType::Presto)
20637 | Some(DialectType::Trino)
20638 );
20639 let propagated: Vec<Expression>;
20640 let expressions = if needs_inheritance && f.expressions.len() > 1 {
20641 propagated = Self::inherit_struct_field_names(&f.expressions);
20642 &propagated
20643 } else {
20644 &f.expressions
20645 };
20646
20647 let should_split = if self.config.pretty && !expressions.is_empty() {
20649 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
20650 for expr in expressions {
20651 let mut temp_gen = Generator::with_arc_config(self.config.clone());
20652 Arc::make_mut(&mut temp_gen.config).pretty = false;
20653 temp_gen.generate_expression(expr)?;
20654 expr_strings.push(temp_gen.output);
20655 }
20656 self.too_wide(&expr_strings)
20657 } else {
20658 false
20659 };
20660
20661 if f.bracket_notation {
20662 let (open, close) = match self.config.dialect {
20666 None
20667 | Some(DialectType::Generic)
20668 | Some(DialectType::Spark)
20669 | Some(DialectType::Databricks)
20670 | Some(DialectType::Hive) => {
20671 self.write_keyword("ARRAY");
20672 ("(", ")")
20673 }
20674 Some(DialectType::Presto)
20675 | Some(DialectType::Trino)
20676 | Some(DialectType::PostgreSQL)
20677 | Some(DialectType::Redshift)
20678 | Some(DialectType::Materialize)
20679 | Some(DialectType::RisingWave)
20680 | Some(DialectType::CockroachDB) => {
20681 self.write_keyword("ARRAY");
20682 ("[", "]")
20683 }
20684 _ => ("[", "]"),
20685 };
20686 self.write(open);
20687 if should_split {
20688 self.write_newline();
20689 self.indent_level += 1;
20690 for (i, expr) in expressions.iter().enumerate() {
20691 self.write_indent();
20692 self.generate_expression(expr)?;
20693 if i + 1 < expressions.len() {
20694 self.write(",");
20695 }
20696 self.write_newline();
20697 }
20698 self.indent_level -= 1;
20699 self.write_indent();
20700 } else {
20701 for (i, expr) in expressions.iter().enumerate() {
20702 if i > 0 {
20703 self.write(", ");
20704 }
20705 self.generate_expression(expr)?;
20706 }
20707 }
20708 self.write(close);
20709 } else {
20710 if f.use_list_keyword {
20712 self.write_keyword("LIST");
20713 } else {
20714 self.write_keyword("ARRAY");
20715 }
20716 let has_subquery = expressions
20719 .iter()
20720 .any(|e| matches!(e, Expression::Select(_)));
20721 let (open, close) = if matches!(
20722 self.config.dialect,
20723 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
20724 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
20725 && has_subquery)
20726 {
20727 ("(", ")")
20728 } else {
20729 ("[", "]")
20730 };
20731 self.write(open);
20732 if should_split {
20733 self.write_newline();
20734 self.indent_level += 1;
20735 for (i, expr) in expressions.iter().enumerate() {
20736 self.write_indent();
20737 self.generate_expression(expr)?;
20738 if i + 1 < expressions.len() {
20739 self.write(",");
20740 }
20741 self.write_newline();
20742 }
20743 self.indent_level -= 1;
20744 self.write_indent();
20745 } else {
20746 for (i, expr) in expressions.iter().enumerate() {
20747 if i > 0 {
20748 self.write(", ");
20749 }
20750 self.generate_expression(expr)?;
20751 }
20752 }
20753 self.write(close);
20754 }
20755 Ok(())
20756 }
20757
20758 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
20759 self.write_keyword("ARRAY_SORT");
20760 self.write("(");
20761 self.generate_expression(&f.this)?;
20762 if let Some(ref comp) = f.comparator {
20763 self.write(", ");
20764 self.generate_expression(comp)?;
20765 }
20766 self.write(")");
20767 Ok(())
20768 }
20769
20770 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
20771 self.write_keyword(name);
20772 self.write("(");
20773 self.generate_expression(&f.this)?;
20774 self.write(", ");
20775 self.generate_expression(&f.separator)?;
20776 if let Some(ref null_rep) = f.null_replacement {
20777 self.write(", ");
20778 self.generate_expression(null_rep)?;
20779 }
20780 self.write(")");
20781 Ok(())
20782 }
20783
20784 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
20785 self.write_keyword("UNNEST");
20786 self.write("(");
20787 self.generate_expression(&f.this)?;
20788 for extra in &f.expressions {
20789 self.write(", ");
20790 self.generate_expression(extra)?;
20791 }
20792 self.write(")");
20793 if f.with_ordinality {
20794 self.write_space();
20795 if self.config.unnest_with_ordinality {
20796 self.write_keyword("WITH ORDINALITY");
20798 } else if f.offset_alias.is_some() {
20799 if let Some(ref alias) = f.alias {
20802 self.write_keyword("AS");
20803 self.write_space();
20804 self.generate_identifier(alias)?;
20805 self.write_space();
20806 }
20807 self.write_keyword("WITH OFFSET");
20808 if let Some(ref offset_alias) = f.offset_alias {
20809 self.write_space();
20810 self.write_keyword("AS");
20811 self.write_space();
20812 self.generate_identifier(offset_alias)?;
20813 }
20814 } else {
20815 self.write_keyword("WITH OFFSET");
20817 if f.alias.is_none() {
20818 self.write(" AS offset");
20819 }
20820 }
20821 }
20822 if let Some(ref alias) = f.alias {
20823 let should_add_alias = if !f.with_ordinality {
20825 true
20826 } else if self.config.unnest_with_ordinality {
20827 true
20829 } else if f.offset_alias.is_some() {
20830 false
20832 } else {
20833 true
20835 };
20836 if should_add_alias {
20837 self.write_space();
20838 self.write_keyword("AS");
20839 self.write_space();
20840 self.generate_identifier(alias)?;
20841 }
20842 }
20843 Ok(())
20844 }
20845
20846 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
20847 self.write_keyword("FILTER");
20848 self.write("(");
20849 self.generate_expression(&f.this)?;
20850 self.write(", ");
20851 self.generate_expression(&f.filter)?;
20852 self.write(")");
20853 Ok(())
20854 }
20855
20856 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
20857 self.write_keyword("TRANSFORM");
20858 self.write("(");
20859 self.generate_expression(&f.this)?;
20860 self.write(", ");
20861 self.generate_expression(&f.transform)?;
20862 self.write(")");
20863 Ok(())
20864 }
20865
20866 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
20867 self.write_keyword(name);
20868 self.write("(");
20869 self.generate_expression(&f.start)?;
20870 self.write(", ");
20871 self.generate_expression(&f.stop)?;
20872 if let Some(ref step) = f.step {
20873 self.write(", ");
20874 self.generate_expression(step)?;
20875 }
20876 self.write(")");
20877 Ok(())
20878 }
20879
20880 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
20883 self.write_keyword("STRUCT");
20884 self.write("(");
20885 for (i, (name, expr)) in f.fields.iter().enumerate() {
20886 if i > 0 {
20887 self.write(", ");
20888 }
20889 if let Some(ref id) = name {
20890 self.generate_identifier(id)?;
20891 self.write(" ");
20892 self.write_keyword("AS");
20893 self.write(" ");
20894 }
20895 self.generate_expression(expr)?;
20896 }
20897 self.write(")");
20898 Ok(())
20899 }
20900
20901 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
20903 let mut names: Vec<Option<String>> = Vec::new();
20906 let mut values: Vec<&Expression> = Vec::new();
20907 let mut all_named = true;
20908
20909 for arg in &func.args {
20910 match arg {
20911 Expression::Alias(a) => {
20912 names.push(Some(a.alias.name.clone()));
20913 values.push(&a.this);
20914 }
20915 _ => {
20916 names.push(None);
20917 values.push(arg);
20918 all_named = false;
20919 }
20920 }
20921 }
20922
20923 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20924 self.write("{");
20926 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20927 if i > 0 {
20928 self.write(", ");
20929 }
20930 if let Some(n) = name {
20931 self.write("'");
20932 self.write(n);
20933 self.write("'");
20934 } else {
20935 self.write("'_");
20936 self.write(&i.to_string());
20937 self.write("'");
20938 }
20939 self.write(": ");
20940 self.generate_expression(value)?;
20941 }
20942 self.write("}");
20943 return Ok(());
20944 }
20945
20946 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20947 self.write_keyword("OBJECT_CONSTRUCT");
20949 self.write("(");
20950 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20951 if i > 0 {
20952 self.write(", ");
20953 }
20954 if let Some(n) = name {
20955 self.write("'");
20956 self.write(n);
20957 self.write("'");
20958 } else {
20959 self.write("'_");
20960 self.write(&i.to_string());
20961 self.write("'");
20962 }
20963 self.write(", ");
20964 self.generate_expression(value)?;
20965 }
20966 self.write(")");
20967 return Ok(());
20968 }
20969
20970 if matches!(
20971 self.config.dialect,
20972 Some(DialectType::Presto) | Some(DialectType::Trino)
20973 ) {
20974 if all_named && !names.is_empty() {
20975 self.write_keyword("CAST");
20978 self.write("(");
20979 self.write_keyword("ROW");
20980 self.write("(");
20981 for (i, value) in values.iter().enumerate() {
20982 if i > 0 {
20983 self.write(", ");
20984 }
20985 self.generate_expression(value)?;
20986 }
20987 self.write(")");
20988 self.write(" ");
20989 self.write_keyword("AS");
20990 self.write(" ");
20991 self.write_keyword("ROW");
20992 self.write("(");
20993 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20994 if i > 0 {
20995 self.write(", ");
20996 }
20997 if let Some(n) = name {
20998 self.write(n);
20999 }
21000 self.write(" ");
21001 let type_str = Self::infer_sql_type_for_presto(value);
21002 self.write_keyword(&type_str);
21003 }
21004 self.write(")");
21005 self.write(")");
21006 } else {
21007 self.write_keyword("ROW");
21009 self.write("(");
21010 for (i, value) in values.iter().enumerate() {
21011 if i > 0 {
21012 self.write(", ");
21013 }
21014 self.generate_expression(value)?;
21015 }
21016 self.write(")");
21017 }
21018 return Ok(());
21019 }
21020
21021 self.write_keyword("ROW");
21023 self.write("(");
21024 for (i, value) in values.iter().enumerate() {
21025 if i > 0 {
21026 self.write(", ");
21027 }
21028 self.generate_expression(value)?;
21029 }
21030 self.write(")");
21031 Ok(())
21032 }
21033
21034 fn infer_sql_type_for_presto(expr: &Expression) -> String {
21036 match expr {
21037 Expression::Literal(lit)
21038 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
21039 {
21040 "VARCHAR".to_string()
21041 }
21042 Expression::Literal(lit)
21043 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
21044 {
21045 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
21046 unreachable!()
21047 };
21048 if n.contains('.') {
21049 "DOUBLE".to_string()
21050 } else {
21051 "INTEGER".to_string()
21052 }
21053 }
21054 Expression::Boolean(_) => "BOOLEAN".to_string(),
21055 Expression::Literal(lit)
21056 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
21057 {
21058 "DATE".to_string()
21059 }
21060 Expression::Literal(lit)
21061 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
21062 {
21063 "TIMESTAMP".to_string()
21064 }
21065 Expression::Literal(lit)
21066 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
21067 {
21068 "TIMESTAMP".to_string()
21069 }
21070 Expression::Array(_) | Expression::ArrayFunc(_) => {
21071 "ARRAY(VARCHAR)".to_string()
21073 }
21074 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
21076 Expression::Function(f) => {
21077 if f.name.eq_ignore_ascii_case("STRUCT") {
21078 "ROW".to_string()
21079 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
21080 "DATE".to_string()
21081 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
21082 || f.name.eq_ignore_ascii_case("NOW")
21083 {
21084 "TIMESTAMP".to_string()
21085 } else {
21086 "VARCHAR".to_string()
21087 }
21088 }
21089 _ => "VARCHAR".to_string(),
21090 }
21091 }
21092
21093 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
21094 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
21096 self.write_keyword("STRUCT_EXTRACT");
21097 self.write("(");
21098 self.generate_expression(&f.this)?;
21099 self.write(", ");
21100 self.write("'");
21102 self.write(&f.field.name);
21103 self.write("'");
21104 self.write(")");
21105 return Ok(());
21106 }
21107 self.generate_expression(&f.this)?;
21108 self.write(".");
21109 self.generate_identifier(&f.field)
21110 }
21111
21112 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
21113 if matches!(
21114 self.config.dialect,
21115 Some(DialectType::Spark | DialectType::Databricks)
21116 ) {
21117 self.write_keyword("STRUCT");
21118 self.write("(");
21119 for (i, (name, value)) in f.pairs.iter().enumerate() {
21120 if i > 0 {
21121 self.write(", ");
21122 }
21123 self.generate_expression(value)?;
21124 self.write(" ");
21125 self.write_keyword("AS");
21126 self.write(" ");
21127 if let Expression::Literal(lit) = name {
21128 if let Literal::String(field_name) = lit.as_ref() {
21129 self.generate_identifier(&Identifier::new(field_name))?;
21130 } else {
21131 self.generate_expression(name)?;
21132 }
21133 } else {
21134 self.generate_expression(name)?;
21135 }
21136 }
21137 self.write(")");
21138 return Ok(());
21139 }
21140
21141 self.write_keyword("NAMED_STRUCT");
21142 self.write("(");
21143 for (i, (name, value)) in f.pairs.iter().enumerate() {
21144 if i > 0 {
21145 self.write(", ");
21146 }
21147 self.generate_expression(name)?;
21148 self.write(", ");
21149 self.generate_expression(value)?;
21150 }
21151 self.write(")");
21152 Ok(())
21153 }
21154
21155 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
21158 if f.curly_brace_syntax {
21159 if f.with_map_keyword {
21161 self.write_keyword("MAP");
21162 self.write(" ");
21163 }
21164 self.write("{");
21165 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
21166 if i > 0 {
21167 self.write(", ");
21168 }
21169 self.generate_expression(key)?;
21170 self.write(": ");
21171 self.generate_expression(val)?;
21172 }
21173 self.write("}");
21174 } else {
21175 self.write_keyword("MAP");
21177 self.write("(");
21178 self.write_keyword("ARRAY");
21179 self.write("[");
21180 for (i, key) in f.keys.iter().enumerate() {
21181 if i > 0 {
21182 self.write(", ");
21183 }
21184 self.generate_expression(key)?;
21185 }
21186 self.write("], ");
21187 self.write_keyword("ARRAY");
21188 self.write("[");
21189 for (i, val) in f.values.iter().enumerate() {
21190 if i > 0 {
21191 self.write(", ");
21192 }
21193 self.generate_expression(val)?;
21194 }
21195 self.write("])");
21196 }
21197 Ok(())
21198 }
21199
21200 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
21201 self.write_keyword(name);
21202 self.write("(");
21203 self.generate_expression(&f.this)?;
21204 self.write(", ");
21205 self.generate_expression(&f.transform)?;
21206 self.write(")");
21207 Ok(())
21208 }
21209
21210 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
21213 use crate::dialects::DialectType;
21214
21215 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
21217
21218 if use_arrow {
21219 self.generate_expression(&f.this)?;
21221 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
21222 self.write(" ->> ");
21223 } else {
21224 self.write(" -> ");
21225 }
21226 self.generate_expression(&f.path)?;
21227 return Ok(());
21228 }
21229
21230 if f.hash_arrow_syntax
21232 && matches!(
21233 self.config.dialect,
21234 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21235 )
21236 {
21237 self.generate_expression(&f.this)?;
21238 self.write(" #>> ");
21239 self.generate_expression(&f.path)?;
21240 return Ok(());
21241 }
21242
21243 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21246 match name {
21247 "JSON_EXTRACT_SCALAR"
21248 | "JSON_EXTRACT_PATH_TEXT"
21249 | "JSON_EXTRACT"
21250 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
21251 _ => name,
21252 }
21253 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
21254 match name {
21255 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
21256 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
21257 _ => name,
21258 }
21259 } else {
21260 name
21261 };
21262
21263 self.write_keyword(func_name);
21264 self.write("(");
21265 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
21267 if let Expression::Cast(ref cast) = f.this {
21268 if matches!(cast.to, crate::expressions::DataType::Json) {
21269 self.generate_expression(&cast.this)?;
21270 } else {
21271 self.generate_expression(&f.this)?;
21272 }
21273 } else {
21274 self.generate_expression(&f.this)?;
21275 }
21276 } else {
21277 self.generate_expression(&f.this)?;
21278 }
21279 if matches!(
21282 self.config.dialect,
21283 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21284 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
21285 {
21286 if let Expression::Literal(ref lit) = f.path {
21287 if let Literal::String(ref s) = lit.as_ref() {
21288 let parts = Self::decompose_json_path(s);
21289 for part in &parts {
21290 self.write(", '");
21291 self.write(part);
21292 self.write("'");
21293 }
21294 }
21295 } else {
21296 self.write(", ");
21297 self.generate_expression(&f.path)?;
21298 }
21299 } else {
21300 self.write(", ");
21301 self.generate_expression(&f.path)?;
21302 }
21303
21304 if let Some(ref wrapper) = f.wrapper_option {
21307 self.write_space();
21308 self.write_keyword(wrapper);
21309 }
21310 if let Some(ref quotes) = f.quotes_option {
21311 self.write_space();
21312 self.write_keyword(quotes);
21313 if f.on_scalar_string {
21314 self.write_space();
21315 self.write_keyword("ON SCALAR STRING");
21316 }
21317 }
21318 if let Some(ref on_err) = f.on_error {
21319 self.write_space();
21320 self.write_keyword(on_err);
21321 }
21322 if let Some(ref ret_type) = f.returning {
21323 self.write_space();
21324 self.write_keyword("RETURNING");
21325 self.write_space();
21326 self.generate_data_type(ret_type)?;
21327 }
21328
21329 self.write(")");
21330 Ok(())
21331 }
21332
21333 fn dialect_supports_json_arrow(&self) -> bool {
21335 use crate::dialects::DialectType;
21336 match self.config.dialect {
21337 Some(DialectType::PostgreSQL) => true,
21339 Some(DialectType::MySQL) => true,
21340 Some(DialectType::DuckDB) => true,
21341 Some(DialectType::CockroachDB) => true,
21342 Some(DialectType::StarRocks) => true,
21343 Some(DialectType::SQLite) => true,
21344 _ => false,
21346 }
21347 }
21348
21349 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
21350 use crate::dialects::DialectType;
21351
21352 if matches!(
21354 self.config.dialect,
21355 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
21356 ) && name == "JSON_EXTRACT_PATH"
21357 {
21358 self.generate_expression(&f.this)?;
21359 self.write(" #> ");
21360 if f.paths.len() == 1 {
21361 self.generate_expression(&f.paths[0])?;
21362 } else {
21363 self.write_keyword("ARRAY");
21365 self.write("[");
21366 for (i, path) in f.paths.iter().enumerate() {
21367 if i > 0 {
21368 self.write(", ");
21369 }
21370 self.generate_expression(path)?;
21371 }
21372 self.write("]");
21373 }
21374 return Ok(());
21375 }
21376
21377 self.write_keyword(name);
21378 self.write("(");
21379 self.generate_expression(&f.this)?;
21380 for path in &f.paths {
21381 self.write(", ");
21382 self.generate_expression(path)?;
21383 }
21384 self.write(")");
21385 Ok(())
21386 }
21387
21388 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
21389 use crate::dialects::DialectType;
21390
21391 self.write_keyword("JSON_OBJECT");
21392 self.write("(");
21393 if f.star {
21394 self.write("*");
21395 } else {
21396 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
21400 || matches!(
21401 self.config.dialect,
21402 Some(DialectType::BigQuery)
21403 | Some(DialectType::MySQL)
21404 | Some(DialectType::SQLite)
21405 );
21406
21407 for (i, (key, value)) in f.pairs.iter().enumerate() {
21408 if i > 0 {
21409 self.write(", ");
21410 }
21411 self.generate_expression(key)?;
21412 if use_comma_syntax {
21413 self.write(", ");
21414 } else {
21415 self.write(": ");
21416 }
21417 self.generate_expression(value)?;
21418 }
21419 }
21420 if let Some(null_handling) = f.null_handling {
21421 self.write_space();
21422 match null_handling {
21423 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21424 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21425 }
21426 }
21427 if f.with_unique_keys {
21428 self.write_space();
21429 self.write_keyword("WITH UNIQUE KEYS");
21430 }
21431 if let Some(ref ret_type) = f.returning_type {
21432 self.write_space();
21433 self.write_keyword("RETURNING");
21434 self.write_space();
21435 self.generate_data_type(ret_type)?;
21436 if f.format_json {
21437 self.write_space();
21438 self.write_keyword("FORMAT JSON");
21439 }
21440 if let Some(ref enc) = f.encoding {
21441 self.write_space();
21442 self.write_keyword("ENCODING");
21443 self.write_space();
21444 self.write(enc);
21445 }
21446 }
21447 self.write(")");
21448 Ok(())
21449 }
21450
21451 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
21452 self.write_keyword(name);
21453 self.write("(");
21454 self.generate_expression(&f.this)?;
21455 for (path, value) in &f.path_values {
21456 self.write(", ");
21457 self.generate_expression(path)?;
21458 self.write(", ");
21459 self.generate_expression(value)?;
21460 }
21461 self.write(")");
21462 Ok(())
21463 }
21464
21465 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
21466 self.write_keyword("JSON_ARRAYAGG");
21467 self.write("(");
21468 self.generate_expression(&f.this)?;
21469 if let Some(ref order_by) = f.order_by {
21470 self.write_space();
21471 self.write_keyword("ORDER BY");
21472 self.write_space();
21473 for (i, ord) in order_by.iter().enumerate() {
21474 if i > 0 {
21475 self.write(", ");
21476 }
21477 self.generate_ordered(ord)?;
21478 }
21479 }
21480 if let Some(null_handling) = f.null_handling {
21481 self.write_space();
21482 match null_handling {
21483 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21484 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21485 }
21486 }
21487 self.write(")");
21488 if let Some(ref filter) = f.filter {
21489 self.write_space();
21490 self.write_keyword("FILTER");
21491 self.write("(");
21492 self.write_keyword("WHERE");
21493 self.write_space();
21494 self.generate_expression(filter)?;
21495 self.write(")");
21496 }
21497 Ok(())
21498 }
21499
21500 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
21501 self.write_keyword("JSON_OBJECTAGG");
21502 self.write("(");
21503 self.generate_expression(&f.key)?;
21504 self.write(": ");
21505 self.generate_expression(&f.value)?;
21506 if let Some(null_handling) = f.null_handling {
21507 self.write_space();
21508 match null_handling {
21509 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
21510 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
21511 }
21512 }
21513 self.write(")");
21514 if let Some(ref filter) = f.filter {
21515 self.write_space();
21516 self.write_keyword("FILTER");
21517 self.write("(");
21518 self.write_keyword("WHERE");
21519 self.write_space();
21520 self.generate_expression(filter)?;
21521 self.write(")");
21522 }
21523 Ok(())
21524 }
21525
21526 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
21529 use crate::dialects::DialectType;
21530
21531 if self.config.dialect == Some(DialectType::Redshift) {
21533 self.write_keyword("CAST");
21534 self.write("(");
21535 self.generate_expression(&f.this)?;
21536 self.write_space();
21537 self.write_keyword("AS");
21538 self.write_space();
21539 self.generate_data_type(&f.to)?;
21540 self.write(")");
21541 return Ok(());
21542 }
21543
21544 self.write_keyword("CONVERT");
21545 self.write("(");
21546 self.generate_data_type(&f.to)?;
21547 self.write(", ");
21548 self.generate_expression(&f.this)?;
21549 if let Some(ref style) = f.style {
21550 self.write(", ");
21551 self.generate_expression(style)?;
21552 }
21553 self.write(")");
21554 Ok(())
21555 }
21556
21557 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
21560 if f.colon {
21561 self.write_keyword("LAMBDA");
21563 self.write_space();
21564 for (i, param) in f.parameters.iter().enumerate() {
21565 if i > 0 {
21566 self.write(", ");
21567 }
21568 self.generate_identifier(param)?;
21569 }
21570 self.write(" : ");
21571 } else {
21572 if f.parameters.len() == 1 {
21574 self.generate_identifier(&f.parameters[0])?;
21575 } else {
21576 self.write("(");
21577 for (i, param) in f.parameters.iter().enumerate() {
21578 if i > 0 {
21579 self.write(", ");
21580 }
21581 self.generate_identifier(param)?;
21582 }
21583 self.write(")");
21584 }
21585 self.write(" -> ");
21586 }
21587 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
21588 if let Expression::Lambda(inner) = &f.body {
21589 self.generate_lambda_with_parenthesized_single_param(inner)?;
21590 return Ok(());
21591 }
21592 }
21593
21594 self.generate_expression(&f.body)
21595 }
21596
21597 fn generate_lambda_with_parenthesized_single_param(&mut self, f: &LambdaExpr) -> Result<()> {
21598 if f.colon {
21599 return self.generate_lambda(f);
21600 }
21601
21602 self.write("(");
21603 for (i, param) in f.parameters.iter().enumerate() {
21604 if i > 0 {
21605 self.write(", ");
21606 }
21607 self.generate_identifier(param)?;
21608 }
21609 self.write(") -> ");
21610 self.generate_expression(&f.body)
21611 }
21612
21613 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
21614 self.generate_identifier(&f.name)?;
21615 match f.separator {
21616 NamedArgSeparator::DArrow => self.write(" => "),
21617 NamedArgSeparator::ColonEq => self.write(" := "),
21618 NamedArgSeparator::Eq => self.write(" = "),
21619 }
21620 self.generate_expression(&f.value)
21621 }
21622
21623 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
21624 self.write_keyword(&f.prefix);
21625 self.write(" ");
21626 self.generate_expression(&f.this)
21627 }
21628
21629 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
21630 match f.style {
21631 ParameterStyle::Question => self.write("?"),
21632 ParameterStyle::Dollar => {
21633 self.write("$");
21634 if let Some(idx) = f.index {
21635 self.write(&idx.to_string());
21636 } else if let Some(ref name) = f.name {
21637 self.write(name);
21639 }
21640 }
21641 ParameterStyle::DollarBrace => {
21642 self.write("${");
21644 if let Some(ref name) = f.name {
21645 self.write(name);
21646 }
21647 if let Some(ref expr) = f.expression {
21648 self.write(":");
21649 self.write(expr);
21650 }
21651 self.write("}");
21652 }
21653 ParameterStyle::Colon => {
21654 self.write(":");
21655 if let Some(idx) = f.index {
21656 self.write(&idx.to_string());
21657 } else if let Some(ref name) = f.name {
21658 self.write(name);
21659 }
21660 }
21661 ParameterStyle::At => {
21662 self.write("@");
21663 if let Some(ref name) = f.name {
21664 if f.string_quoted {
21665 self.write("'");
21666 self.write(name);
21667 self.write("'");
21668 } else if f.quoted {
21669 self.write("\"");
21670 self.write(name);
21671 self.write("\"");
21672 } else {
21673 self.write(name);
21674 }
21675 }
21676 }
21677 ParameterStyle::DoubleAt => {
21678 self.write("@@");
21679 if let Some(ref name) = f.name {
21680 self.write(name);
21681 }
21682 }
21683 ParameterStyle::DoubleDollar => {
21684 self.write("$$");
21685 if let Some(ref name) = f.name {
21686 self.write(name);
21687 }
21688 }
21689 ParameterStyle::Percent => {
21690 if let Some(ref name) = f.name {
21691 self.write("%(");
21693 self.write(name);
21694 self.write(")s");
21695 } else {
21696 self.write("%s");
21698 }
21699 }
21700 ParameterStyle::Brace => {
21701 self.write("{");
21704 if let Some(ref name) = f.name {
21705 self.write(name);
21706 }
21707 if let Some(ref expr) = f.expression {
21708 self.write(": ");
21709 self.write(expr);
21710 }
21711 self.write("}");
21712 }
21713 }
21714 Ok(())
21715 }
21716
21717 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
21718 self.write("?");
21719 if let Some(idx) = f.index {
21720 self.write(&idx.to_string());
21721 }
21722 Ok(())
21723 }
21724
21725 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
21726 if f.is_block {
21727 self.write("/*");
21728 self.write(&f.text);
21729 self.write("*/");
21730 } else {
21731 self.write("--");
21732 self.write(&f.text);
21733 }
21734 Ok(())
21735 }
21736
21737 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
21740 self.generate_expression(&f.this)?;
21741 if f.not {
21742 self.write_space();
21743 self.write_keyword("NOT");
21744 }
21745 self.write_space();
21746 self.write_keyword("SIMILAR TO");
21747 self.write_space();
21748 self.generate_expression(&f.pattern)?;
21749 if let Some(ref escape) = f.escape {
21750 self.write_space();
21751 self.write_keyword("ESCAPE");
21752 self.write_space();
21753 self.generate_expression(escape)?;
21754 }
21755 Ok(())
21756 }
21757
21758 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
21759 self.generate_expression(&f.this)?;
21760 self.write_space();
21761 if let Some(op) = &f.op {
21763 match op {
21764 QuantifiedOp::Eq => self.write("="),
21765 QuantifiedOp::Neq => self.write("<>"),
21766 QuantifiedOp::Lt => self.write("<"),
21767 QuantifiedOp::Lte => self.write("<="),
21768 QuantifiedOp::Gt => self.write(">"),
21769 QuantifiedOp::Gte => self.write(">="),
21770 }
21771 self.write_space();
21772 }
21773 self.write_keyword(name);
21774
21775 if matches!(&f.subquery, Expression::Subquery(_)) {
21777 self.write_space();
21778 self.generate_expression(&f.subquery)?;
21779 } else {
21780 self.write("(");
21781
21782 let is_statement = matches!(
21783 &f.subquery,
21784 Expression::Select(_)
21785 | Expression::Union(_)
21786 | Expression::Intersect(_)
21787 | Expression::Except(_)
21788 );
21789
21790 if self.config.pretty && is_statement {
21791 self.write_newline();
21792 self.indent_level += 1;
21793 self.write_indent();
21794 }
21795 self.generate_expression(&f.subquery)?;
21796 if self.config.pretty && is_statement {
21797 self.write_newline();
21798 self.indent_level -= 1;
21799 self.write_indent();
21800 }
21801 self.write(")");
21802 }
21803 Ok(())
21804 }
21805
21806 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
21807 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
21809 self.generate_expression(this)?;
21810 self.write_space();
21811 self.write_keyword("OVERLAPS");
21812 self.write_space();
21813 self.generate_expression(expr)?;
21814 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
21815 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
21816 {
21817 self.write("(");
21819 self.generate_expression(ls)?;
21820 self.write(", ");
21821 self.generate_expression(le)?;
21822 self.write(")");
21823 self.write_space();
21824 self.write_keyword("OVERLAPS");
21825 self.write_space();
21826 self.write("(");
21827 self.generate_expression(rs)?;
21828 self.write(", ");
21829 self.generate_expression(re)?;
21830 self.write(")");
21831 }
21832 Ok(())
21833 }
21834
21835 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
21838 use crate::dialects::DialectType;
21839
21840 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
21842 self.generate_expression(&cast.this)?;
21843 self.write(" !:> ");
21844 self.generate_data_type(&cast.to)?;
21845 return Ok(());
21846 }
21847
21848 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
21850 self.write_keyword("TRYCAST");
21851 self.write("(");
21852 self.generate_expression(&cast.this)?;
21853 self.write_space();
21854 self.write_keyword("AS");
21855 self.write_space();
21856 self.generate_data_type(&cast.to)?;
21857 self.write(")");
21858 return Ok(());
21859 }
21860
21861 let keyword = if matches!(
21863 self.config.dialect,
21864 Some(DialectType::Hive)
21865 | Some(DialectType::MySQL)
21866 | Some(DialectType::SQLite)
21867 | Some(DialectType::Oracle)
21868 | Some(DialectType::ClickHouse)
21869 | Some(DialectType::Redshift)
21870 | Some(DialectType::PostgreSQL)
21871 | Some(DialectType::StarRocks)
21872 | Some(DialectType::Doris)
21873 ) {
21874 "CAST"
21875 } else {
21876 "TRY_CAST"
21877 };
21878
21879 self.write_keyword(keyword);
21880 self.write("(");
21881 self.generate_expression(&cast.this)?;
21882 self.write_space();
21883 self.write_keyword("AS");
21884 self.write_space();
21885 self.generate_data_type(&cast.to)?;
21886
21887 if let Some(format) = &cast.format {
21889 self.write_space();
21890 self.write_keyword("FORMAT");
21891 self.write_space();
21892 self.generate_expression(format)?;
21893 }
21894
21895 self.write(")");
21896 Ok(())
21897 }
21898
21899 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
21900 self.write_keyword("SAFE_CAST");
21901 self.write("(");
21902 self.generate_expression(&cast.this)?;
21903 self.write_space();
21904 self.write_keyword("AS");
21905 self.write_space();
21906 self.generate_data_type(&cast.to)?;
21907
21908 if let Some(format) = &cast.format {
21910 self.write_space();
21911 self.write_keyword("FORMAT");
21912 self.write_space();
21913 self.generate_expression(format)?;
21914 }
21915
21916 self.write(")");
21917 Ok(())
21918 }
21919
21920 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
21923 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
21927 if needs_parens {
21928 self.write("(");
21929 }
21930 self.generate_expression(&s.this)?;
21931 if needs_parens {
21932 self.write(")");
21933 }
21934 self.write("[");
21935 self.generate_expression(&s.index)?;
21936 self.write("]");
21937 Ok(())
21938 }
21939
21940 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
21941 self.generate_expression(&d.this)?;
21942 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
21945 && matches!(
21946 &d.this,
21947 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
21948 );
21949 if use_colon {
21950 self.write(":");
21951 } else {
21952 self.write(".");
21953 }
21954 self.generate_identifier(&d.field)
21955 }
21956
21957 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
21958 self.generate_expression(&m.this)?;
21959 self.write(".");
21960 if m.method.quoted {
21963 let q = self.config.identifier_quote;
21964 self.write(&format!("{}{}{}", q, m.method.name, q));
21965 } else {
21966 self.write(&m.method.name);
21967 }
21968 self.write("(");
21969 for (i, arg) in m.args.iter().enumerate() {
21970 if i > 0 {
21971 self.write(", ");
21972 }
21973 self.generate_expression(arg)?;
21974 }
21975 self.write(")");
21976 Ok(())
21977 }
21978
21979 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
21980 let needs_parens = matches!(
21983 &s.this,
21984 Expression::JsonExtract(f) if f.arrow_syntax
21985 ) || matches!(
21986 &s.this,
21987 Expression::JsonExtractScalar(f) if f.arrow_syntax
21988 );
21989
21990 if needs_parens {
21991 self.write("(");
21992 }
21993 self.generate_expression(&s.this)?;
21994 if needs_parens {
21995 self.write(")");
21996 }
21997 self.write("[");
21998 if let Some(start) = &s.start {
21999 self.generate_expression(start)?;
22000 }
22001 self.write(":");
22002 if let Some(end) = &s.end {
22003 self.generate_expression(end)?;
22004 }
22005 self.write("]");
22006 Ok(())
22007 }
22008
22009 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22010 match &op.left {
22014 Expression::Column(col) => {
22015 if let Some(table) = &col.table {
22018 self.generate_identifier(table)?;
22019 self.write(".");
22020 }
22021 self.generate_identifier(&col.name)?;
22022 if col.join_mark && self.config.supports_column_join_marks {
22024 self.write(" (+)");
22025 }
22026 if op.left_comments.is_empty() {
22028 for comment in &col.trailing_comments {
22029 self.write_space();
22030 self.write_formatted_comment(comment);
22031 }
22032 }
22033 }
22034 Expression::Add(inner_op)
22035 | Expression::Sub(inner_op)
22036 | Expression::Mul(inner_op)
22037 | Expression::Div(inner_op)
22038 | Expression::Concat(inner_op) => {
22039 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22041 Expression::Add(_) => "+",
22042 Expression::Sub(_) => "-",
22043 Expression::Mul(_) => "*",
22044 Expression::Div(_) => "/",
22045 Expression::Concat(_) => "||",
22046 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22047 })?;
22048 }
22049 _ => {
22050 self.generate_expression(&op.left)?;
22051 }
22052 }
22053 for comment in &op.left_comments {
22055 self.write_space();
22056 self.write_formatted_comment(comment);
22057 }
22058 if self.config.pretty
22059 && matches!(self.config.dialect, Some(DialectType::Snowflake))
22060 && (operator == "AND" || operator == "OR")
22061 {
22062 self.write_newline();
22063 self.write_indent();
22064 self.write_keyword(operator);
22065 } else {
22066 self.write_space();
22067 if operator.chars().all(|c| c.is_alphabetic()) {
22068 self.write_keyword(operator);
22069 } else {
22070 self.write(operator);
22071 }
22072 }
22073 for comment in &op.operator_comments {
22075 self.write_space();
22076 self.write_formatted_comment(comment);
22077 }
22078 self.write_space();
22079 self.generate_expression(&op.right)?;
22080 for comment in &op.trailing_comments {
22082 self.write_space();
22083 self.write_formatted_comment(comment);
22084 }
22085 Ok(())
22086 }
22087
22088 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
22089 let keyword = connector.keyword();
22090 let Some(terms) = self.flatten_connector_terms(op, connector) else {
22091 return self.generate_binary_op(op, keyword);
22092 };
22093
22094 let wrap_clickhouse_or_term = |generator: &mut Self, term: &Expression| -> Result<()> {
22095 let should_wrap = matches!(connector, ConnectorOperator::Or)
22096 && matches!(generator.config.dialect, Some(DialectType::ClickHouse))
22097 && matches!(
22098 generator.config.source_dialect,
22099 Some(DialectType::ClickHouse)
22100 )
22101 && matches!(term, Expression::And(_));
22102 if should_wrap {
22103 generator.write("(");
22104 generator.generate_expression(term)?;
22105 generator.write(")");
22106 } else {
22107 generator.generate_expression(term)?;
22108 }
22109 Ok(())
22110 };
22111
22112 wrap_clickhouse_or_term(self, terms[0])?;
22113 for term in terms.iter().skip(1) {
22114 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
22115 self.write_newline();
22116 self.write_indent();
22117 self.write_keyword(keyword);
22118 } else {
22119 self.write_space();
22120 self.write_keyword(keyword);
22121 }
22122 self.write_space();
22123 wrap_clickhouse_or_term(self, term)?;
22124 }
22125
22126 Ok(())
22127 }
22128
22129 fn flatten_connector_terms<'a>(
22130 &self,
22131 root: &'a BinaryOp,
22132 connector: ConnectorOperator,
22133 ) -> Option<Vec<&'a Expression>> {
22134 if !root.left_comments.is_empty()
22135 || !root.operator_comments.is_empty()
22136 || !root.trailing_comments.is_empty()
22137 {
22138 return None;
22139 }
22140
22141 let mut terms = Vec::new();
22142 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
22143
22144 while let Some(expr) = stack.pop() {
22145 match (connector, expr) {
22146 (ConnectorOperator::And, Expression::And(inner))
22147 if inner.left_comments.is_empty()
22148 && inner.operator_comments.is_empty()
22149 && inner.trailing_comments.is_empty() =>
22150 {
22151 stack.push(&inner.right);
22152 stack.push(&inner.left);
22153 }
22154 (ConnectorOperator::Or, Expression::Or(inner))
22155 if inner.left_comments.is_empty()
22156 && inner.operator_comments.is_empty()
22157 && inner.trailing_comments.is_empty() =>
22158 {
22159 stack.push(&inner.right);
22160 stack.push(&inner.left);
22161 }
22162 _ => terms.push(expr),
22163 }
22164 }
22165
22166 if terms.len() > 1 {
22167 Some(terms)
22168 } else {
22169 None
22170 }
22171 }
22172
22173 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
22175 self.generate_expression(&op.left)?;
22176 self.write_space();
22177 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
22179 self.write("`ILIKE`");
22180 } else {
22181 self.write_keyword(operator);
22182 }
22183 if let Some(quantifier) = &op.quantifier {
22184 self.write_space();
22185 self.write_keyword(quantifier);
22186 let is_any =
22191 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
22192 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
22193 self.write_space();
22194 }
22195 } else {
22196 self.write_space();
22197 }
22198 self.generate_expression(&op.right)?;
22199 if let Some(escape) = &op.escape {
22200 self.write_space();
22201 self.write_keyword("ESCAPE");
22202 self.write_space();
22203 self.generate_expression(escape)?;
22204 }
22205 Ok(())
22206 }
22207
22208 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
22211 use crate::dialects::DialectType;
22212 self.generate_expression(&op.left)?;
22213 self.write_space();
22214 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
22215 self.write("<=>");
22216 } else {
22217 self.write_keyword("IS NOT DISTINCT FROM");
22218 }
22219 self.write_space();
22220 self.generate_expression(&op.right)?;
22221 Ok(())
22222 }
22223
22224 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
22226 self.generate_expression(&op.left)?;
22227 self.write_space();
22228 self.write_keyword("IS DISTINCT FROM");
22229 self.write_space();
22230 self.generate_expression(&op.right)?;
22231 Ok(())
22232 }
22233
22234 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
22236 match &op.left {
22238 Expression::Column(col) => {
22239 if let Some(table) = &col.table {
22240 self.generate_identifier(table)?;
22241 self.write(".");
22242 }
22243 self.generate_identifier(&col.name)?;
22244 if col.join_mark && self.config.supports_column_join_marks {
22246 self.write(" (+)");
22247 }
22248 }
22249 Expression::Add(inner_op)
22250 | Expression::Sub(inner_op)
22251 | Expression::Mul(inner_op)
22252 | Expression::Div(inner_op)
22253 | Expression::Concat(inner_op) => {
22254 self.generate_binary_op_no_trailing(inner_op, match &op.left {
22255 Expression::Add(_) => "+",
22256 Expression::Sub(_) => "-",
22257 Expression::Mul(_) => "*",
22258 Expression::Div(_) => "/",
22259 Expression::Concat(_) => "||",
22260 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
22261 })?;
22262 }
22263 _ => {
22264 self.generate_expression(&op.left)?;
22265 }
22266 }
22267 for comment in &op.left_comments {
22269 self.write_space();
22270 self.write_formatted_comment(comment);
22271 }
22272 self.write_space();
22273 if operator.chars().all(|c| c.is_alphabetic()) {
22274 self.write_keyword(operator);
22275 } else {
22276 self.write(operator);
22277 }
22278 for comment in &op.operator_comments {
22280 self.write_space();
22281 self.write_formatted_comment(comment);
22282 }
22283 self.write_space();
22284 match &op.right {
22287 Expression::Column(col) => {
22288 if let Some(table) = &col.table {
22289 self.generate_identifier(table)?;
22290 self.write(".");
22291 }
22292 self.generate_identifier(&col.name)?;
22293 if col.join_mark && self.config.supports_column_join_marks {
22295 self.write(" (+)");
22296 }
22297 }
22298 _ => {
22299 self.generate_expression(&op.right)?;
22300 }
22301 }
22302 Ok(())
22304 }
22305
22306 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
22307 if operator.chars().all(|c| c.is_alphabetic()) {
22308 self.write_keyword(operator);
22309 self.write_space();
22310 } else {
22311 self.write(operator);
22312 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
22314 self.write_space();
22315 }
22316 }
22317 self.generate_expression(&op.this)
22318 }
22319
22320 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
22321 let is_generic =
22325 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22326 let use_prefix_not =
22327 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
22328 if use_prefix_not {
22329 self.write_keyword("NOT");
22330 self.write_space();
22331 }
22332 self.generate_expression(&in_expr.this)?;
22333 if in_expr.global {
22334 self.write_space();
22335 self.write_keyword("GLOBAL");
22336 }
22337 if in_expr.not && !use_prefix_not {
22338 self.write_space();
22339 self.write_keyword("NOT");
22340 }
22341 self.write_space();
22342 self.write_keyword("IN");
22343
22344 if let Some(unnest_expr) = &in_expr.unnest {
22346 self.write_space();
22347 self.write_keyword("UNNEST");
22348 self.write("(");
22349 self.generate_expression(unnest_expr)?;
22350 self.write(")");
22351 return Ok(());
22352 }
22353
22354 if let Some(query) = &in_expr.query {
22355 let is_bare = in_expr.expressions.is_empty()
22358 && !matches!(
22359 query,
22360 Expression::Select(_)
22361 | Expression::Union(_)
22362 | Expression::Intersect(_)
22363 | Expression::Except(_)
22364 | Expression::Subquery(_)
22365 );
22366 if is_bare {
22367 self.write_space();
22369 self.generate_expression(query)?;
22370 } else {
22371 self.write(" (");
22373 let is_statement = matches!(
22374 query,
22375 Expression::Select(_)
22376 | Expression::Union(_)
22377 | Expression::Intersect(_)
22378 | Expression::Except(_)
22379 | Expression::Subquery(_)
22380 );
22381 if self.config.pretty && is_statement {
22382 self.write_newline();
22383 self.indent_level += 1;
22384 self.write_indent();
22385 }
22386 self.generate_expression(query)?;
22387 if self.config.pretty && is_statement {
22388 self.write_newline();
22389 self.indent_level -= 1;
22390 self.write_indent();
22391 }
22392 self.write(")");
22393 }
22394 } else {
22395 let is_duckdb = matches!(
22399 self.config.dialect,
22400 Some(crate::dialects::DialectType::DuckDB)
22401 );
22402 let is_clickhouse = matches!(
22403 self.config.dialect,
22404 Some(crate::dialects::DialectType::ClickHouse)
22405 );
22406 let single_expr = in_expr.expressions.len() == 1;
22407 if is_clickhouse && single_expr {
22408 if let Expression::Array(arr) = &in_expr.expressions[0] {
22409 self.write(" (");
22411 for (i, expr) in arr.expressions.iter().enumerate() {
22412 if i > 0 {
22413 self.write(", ");
22414 }
22415 self.generate_expression(expr)?;
22416 }
22417 self.write(")");
22418 } else if in_expr.is_field {
22419 self.write_space();
22420 self.generate_expression(&in_expr.expressions[0])?;
22421 } else {
22422 self.write(" (");
22423 self.generate_expression(&in_expr.expressions[0])?;
22424 self.write(")");
22425 }
22426 } else {
22427 let is_bare_ref = single_expr
22428 && matches!(
22429 &in_expr.expressions[0],
22430 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
22431 );
22432 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
22433 self.write_space();
22436 self.generate_expression(&in_expr.expressions[0])?;
22437 } else {
22438 self.write(" (");
22440 for (i, expr) in in_expr.expressions.iter().enumerate() {
22441 if i > 0 {
22442 self.write(", ");
22443 }
22444 self.generate_expression(expr)?;
22445 }
22446 self.write(")");
22447 }
22448 }
22449 }
22450
22451 Ok(())
22452 }
22453
22454 fn generate_between(&mut self, between: &Between) -> Result<()> {
22455 let use_prefix_not = between.not
22457 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
22458 if use_prefix_not {
22459 self.write_keyword("NOT");
22460 self.write_space();
22461 }
22462 self.generate_expression(&between.this)?;
22463 if between.not && !use_prefix_not {
22464 self.write_space();
22465 self.write_keyword("NOT");
22466 }
22467 self.write_space();
22468 self.write_keyword("BETWEEN");
22469 if let Some(sym) = between.symmetric {
22471 if sym {
22472 self.write(" SYMMETRIC");
22473 } else {
22474 self.write(" ASYMMETRIC");
22475 }
22476 }
22477 self.write_space();
22478 self.generate_expression(&between.low)?;
22479 self.write_space();
22480 self.write_keyword("AND");
22481 self.write_space();
22482 self.generate_expression(&between.high)
22483 }
22484
22485 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
22486 let use_prefix_not = is_null.not
22488 && (self.config.dialect.is_none()
22489 || self.config.dialect == Some(DialectType::Generic)
22490 || is_null.postfix_form);
22491 if use_prefix_not {
22492 self.write_keyword("NOT");
22494 self.write_space();
22495 self.generate_expression(&is_null.this)?;
22496 self.write_space();
22497 self.write_keyword("IS");
22498 self.write_space();
22499 self.write_keyword("NULL");
22500 } else {
22501 self.generate_expression(&is_null.this)?;
22502 self.write_space();
22503 self.write_keyword("IS");
22504 if is_null.not {
22505 self.write_space();
22506 self.write_keyword("NOT");
22507 }
22508 self.write_space();
22509 self.write_keyword("NULL");
22510 }
22511 Ok(())
22512 }
22513
22514 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
22515 self.generate_expression(&is_true.this)?;
22516 self.write_space();
22517 self.write_keyword("IS");
22518 if is_true.not {
22519 self.write_space();
22520 self.write_keyword("NOT");
22521 }
22522 self.write_space();
22523 self.write_keyword("TRUE");
22524 Ok(())
22525 }
22526
22527 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
22528 self.generate_expression(&is_false.this)?;
22529 self.write_space();
22530 self.write_keyword("IS");
22531 if is_false.not {
22532 self.write_space();
22533 self.write_keyword("NOT");
22534 }
22535 self.write_space();
22536 self.write_keyword("FALSE");
22537 Ok(())
22538 }
22539
22540 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
22541 self.generate_expression(&is_json.this)?;
22542 self.write_space();
22543 self.write_keyword("IS");
22544 if is_json.negated {
22545 self.write_space();
22546 self.write_keyword("NOT");
22547 }
22548 self.write_space();
22549 self.write_keyword("JSON");
22550
22551 if let Some(ref json_type) = is_json.json_type {
22553 self.write_space();
22554 self.write_keyword(json_type);
22555 }
22556
22557 match &is_json.unique_keys {
22559 Some(JsonUniqueKeys::With) => {
22560 self.write_space();
22561 self.write_keyword("WITH UNIQUE KEYS");
22562 }
22563 Some(JsonUniqueKeys::Without) => {
22564 self.write_space();
22565 self.write_keyword("WITHOUT UNIQUE KEYS");
22566 }
22567 Some(JsonUniqueKeys::Shorthand) => {
22568 self.write_space();
22569 self.write_keyword("UNIQUE KEYS");
22570 }
22571 None => {}
22572 }
22573
22574 Ok(())
22575 }
22576
22577 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
22578 self.generate_expression(&is_expr.left)?;
22579 self.write_space();
22580 self.write_keyword("IS");
22581 self.write_space();
22582 self.generate_expression(&is_expr.right)
22583 }
22584
22585 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
22586 if exists.not {
22587 self.write_keyword("NOT");
22588 self.write_space();
22589 }
22590 self.write_keyword("EXISTS");
22591 self.write("(");
22592 let is_statement = matches!(
22593 &exists.this,
22594 Expression::Select(_)
22595 | Expression::Union(_)
22596 | Expression::Intersect(_)
22597 | Expression::Except(_)
22598 );
22599 if self.config.pretty && is_statement {
22600 self.write_newline();
22601 self.indent_level += 1;
22602 self.write_indent();
22603 self.generate_expression(&exists.this)?;
22604 self.write_newline();
22605 self.indent_level -= 1;
22606 self.write_indent();
22607 self.write(")");
22608 } else {
22609 self.generate_expression(&exists.this)?;
22610 self.write(")");
22611 }
22612 Ok(())
22613 }
22614
22615 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
22616 self.generate_expression(&op.left)?;
22617 self.write_space();
22618 self.write_keyword("MEMBER OF");
22619 self.write("(");
22620 self.generate_expression(&op.right)?;
22621 self.write(")");
22622 Ok(())
22623 }
22624
22625 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
22626 if subquery.lateral {
22627 self.write_keyword("LATERAL");
22628 self.write_space();
22629 }
22630
22631 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
22635 matches!(
22636 &p.this,
22637 Expression::Select(_)
22638 | Expression::Union(_)
22639 | Expression::Intersect(_)
22640 | Expression::Except(_)
22641 | Expression::Subquery(_)
22642 )
22643 } else {
22644 false
22645 };
22646
22647 let is_statement = matches!(
22649 &subquery.this,
22650 Expression::Select(_)
22651 | Expression::Union(_)
22652 | Expression::Intersect(_)
22653 | Expression::Except(_)
22654 | Expression::Merge(_)
22655 );
22656
22657 if !skip_outer_parens {
22658 self.write("(");
22659 if self.config.pretty && is_statement {
22660 self.write_newline();
22661 self.indent_level += 1;
22662 self.write_indent();
22663 }
22664 }
22665 self.generate_expression(&subquery.this)?;
22666
22667 if subquery.modifiers_inside {
22669 if let Some(order_by) = &subquery.order_by {
22671 self.write_space();
22672 self.write_keyword("ORDER BY");
22673 self.write_space();
22674 for (i, ord) in order_by.expressions.iter().enumerate() {
22675 if i > 0 {
22676 self.write(", ");
22677 }
22678 self.generate_ordered(ord)?;
22679 }
22680 }
22681
22682 if let Some(limit) = &subquery.limit {
22683 self.write_space();
22684 self.write_keyword("LIMIT");
22685 self.write_space();
22686 self.generate_expression(&limit.this)?;
22687 if limit.percent {
22688 self.write_space();
22689 self.write_keyword("PERCENT");
22690 }
22691 }
22692
22693 if let Some(offset) = &subquery.offset {
22694 self.write_space();
22695 self.write_keyword("OFFSET");
22696 self.write_space();
22697 self.generate_expression(&offset.this)?;
22698 }
22699 }
22700
22701 if !skip_outer_parens {
22702 if self.config.pretty && is_statement {
22703 self.write_newline();
22704 self.indent_level -= 1;
22705 self.write_indent();
22706 }
22707 self.write(")");
22708 }
22709
22710 if !subquery.modifiers_inside {
22712 if let Some(order_by) = &subquery.order_by {
22713 self.write_space();
22714 self.write_keyword("ORDER BY");
22715 self.write_space();
22716 for (i, ord) in order_by.expressions.iter().enumerate() {
22717 if i > 0 {
22718 self.write(", ");
22719 }
22720 self.generate_ordered(ord)?;
22721 }
22722 }
22723
22724 if let Some(limit) = &subquery.limit {
22725 self.write_space();
22726 self.write_keyword("LIMIT");
22727 self.write_space();
22728 self.generate_expression(&limit.this)?;
22729 if limit.percent {
22730 self.write_space();
22731 self.write_keyword("PERCENT");
22732 }
22733 }
22734
22735 if let Some(offset) = &subquery.offset {
22736 self.write_space();
22737 self.write_keyword("OFFSET");
22738 self.write_space();
22739 self.generate_expression(&offset.this)?;
22740 }
22741
22742 if let Some(distribute_by) = &subquery.distribute_by {
22744 self.write_space();
22745 self.write_keyword("DISTRIBUTE BY");
22746 self.write_space();
22747 for (i, expr) in distribute_by.expressions.iter().enumerate() {
22748 if i > 0 {
22749 self.write(", ");
22750 }
22751 self.generate_expression(expr)?;
22752 }
22753 }
22754
22755 if let Some(sort_by) = &subquery.sort_by {
22757 self.write_space();
22758 self.write_keyword("SORT BY");
22759 self.write_space();
22760 for (i, ord) in sort_by.expressions.iter().enumerate() {
22761 if i > 0 {
22762 self.write(", ");
22763 }
22764 self.generate_ordered(ord)?;
22765 }
22766 }
22767
22768 if let Some(cluster_by) = &subquery.cluster_by {
22770 self.write_space();
22771 self.write_keyword("CLUSTER BY");
22772 self.write_space();
22773 for (i, ord) in cluster_by.expressions.iter().enumerate() {
22774 if i > 0 {
22775 self.write(", ");
22776 }
22777 self.generate_ordered(ord)?;
22778 }
22779 }
22780 }
22781
22782 if let Some(alias) = &subquery.alias {
22783 self.write_space();
22784 let skip_as = matches!(self.config.dialect, Some(DialectType::Oracle))
22785 || (matches!(self.config.dialect, Some(DialectType::ClickHouse))
22786 && !subquery.alias_explicit_as);
22787 if !skip_as {
22788 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22789 self.write(subquery.alias_keyword.as_deref().unwrap_or("AS"));
22790 } else {
22791 self.write_keyword("AS");
22792 }
22793 self.write_space();
22794 }
22795 self.generate_identifier(alias)?;
22796 if !subquery.column_aliases.is_empty() {
22797 self.write("(");
22798 for (i, col) in subquery.column_aliases.iter().enumerate() {
22799 if i > 0 {
22800 self.write(", ");
22801 }
22802 self.generate_identifier(col)?;
22803 }
22804 self.write(")");
22805 }
22806 }
22807 for comment in &subquery.trailing_comments {
22809 self.write(" ");
22810 self.write_formatted_comment(comment);
22811 }
22812 Ok(())
22813 }
22814
22815 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
22816 if let Some(ref with) = pivot.with {
22818 self.generate_with(with)?;
22819 self.write_space();
22820 }
22821
22822 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
22823
22824 let is_redshift_unpivot = pivot.unpivot
22828 && pivot.expressions.is_empty()
22829 && pivot.fields.is_empty()
22830 && pivot.using.is_empty()
22831 && pivot.into.is_none()
22832 && !matches!(&pivot.this, Expression::Null(_));
22833
22834 if is_redshift_unpivot {
22835 self.write_keyword("UNPIVOT");
22837 self.write_space();
22838 self.generate_expression(&pivot.this)?;
22839 if let Some(alias) = &pivot.alias {
22841 self.write_space();
22842 self.write_keyword("AS");
22843 self.write_space();
22844 self.write(&alias.name);
22846 }
22847 return Ok(());
22848 }
22849
22850 let is_simplified = !pivot.using.is_empty()
22852 || pivot.into.is_some()
22853 || (pivot.fields.is_empty()
22854 && !pivot.expressions.is_empty()
22855 && !matches!(&pivot.this, Expression::Null(_)));
22856
22857 if is_simplified {
22858 self.write_keyword(direction);
22862 self.write_space();
22863 self.generate_expression(&pivot.this)?;
22864
22865 if !pivot.expressions.is_empty() {
22866 self.write_space();
22867 self.write_keyword("ON");
22868 self.write_space();
22869 for (i, expr) in pivot.expressions.iter().enumerate() {
22870 if i > 0 {
22871 self.write(", ");
22872 }
22873 self.generate_expression(expr)?;
22874 }
22875 }
22876
22877 if let Some(into) = &pivot.into {
22879 self.write_space();
22880 self.write_keyword("INTO");
22881 self.write_space();
22882 self.generate_expression(into)?;
22883 }
22884
22885 if !pivot.using.is_empty() {
22887 self.write_space();
22888 self.write_keyword("USING");
22889 self.write_space();
22890 for (i, expr) in pivot.using.iter().enumerate() {
22891 if i > 0 {
22892 self.write(", ");
22893 }
22894 self.generate_expression(expr)?;
22895 }
22896 }
22897
22898 if let Some(group) = &pivot.group {
22900 self.write_space();
22901 self.generate_expression(group)?;
22902 }
22903 } else {
22904 if !matches!(&pivot.this, Expression::Null(_)) {
22909 self.generate_expression(&pivot.this)?;
22910 self.write_space();
22911 }
22912 self.write_keyword(direction);
22913 self.write("(");
22914
22915 for (i, expr) in pivot.expressions.iter().enumerate() {
22917 if i > 0 {
22918 self.write(", ");
22919 }
22920 self.generate_expression(expr)?;
22921 }
22922
22923 if !pivot.fields.is_empty() {
22925 if !pivot.expressions.is_empty() {
22926 self.write_space();
22927 }
22928 self.write_keyword("FOR");
22929 self.write_space();
22930 for (i, field) in pivot.fields.iter().enumerate() {
22931 if i > 0 {
22932 self.write_space();
22933 }
22934 self.generate_expression(field)?;
22936 }
22937 }
22938
22939 if let Some(default_val) = &pivot.default_on_null {
22941 self.write_space();
22942 self.write_keyword("DEFAULT ON NULL");
22943 self.write(" (");
22944 self.generate_expression(default_val)?;
22945 self.write(")");
22946 }
22947
22948 if let Some(group) = &pivot.group {
22950 self.write_space();
22951 self.generate_expression(group)?;
22952 }
22953
22954 self.write(")");
22955 }
22956
22957 if let Some(alias) = &pivot.alias {
22959 self.write_space();
22960 self.write_keyword("AS");
22961 self.write_space();
22962 self.generate_identifier(alias)?;
22963 }
22964
22965 Ok(())
22966 }
22967
22968 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
22969 self.generate_expression(&unpivot.this)?;
22970 self.write_space();
22971 self.write_keyword("UNPIVOT");
22972 if let Some(include) = unpivot.include_nulls {
22974 self.write_space();
22975 if include {
22976 self.write_keyword("INCLUDE NULLS");
22977 } else {
22978 self.write_keyword("EXCLUDE NULLS");
22979 }
22980 self.write_space();
22981 }
22982 self.write("(");
22983 if unpivot.value_column_parenthesized {
22984 self.write("(");
22985 }
22986 self.generate_identifier(&unpivot.value_column)?;
22987 for extra_col in &unpivot.extra_value_columns {
22989 self.write(", ");
22990 self.generate_identifier(extra_col)?;
22991 }
22992 if unpivot.value_column_parenthesized {
22993 self.write(")");
22994 }
22995 self.write_space();
22996 self.write_keyword("FOR");
22997 self.write_space();
22998 self.generate_identifier(&unpivot.name_column)?;
22999 self.write_space();
23000 self.write_keyword("IN");
23001 self.write(" (");
23002 for (i, col) in unpivot.columns.iter().enumerate() {
23003 if i > 0 {
23004 self.write(", ");
23005 }
23006 self.generate_expression(col)?;
23007 }
23008 self.write("))");
23009 if let Some(alias) = &unpivot.alias {
23010 self.write_space();
23011 self.write_keyword("AS");
23012 self.write_space();
23013 self.generate_identifier(alias)?;
23014 }
23015 Ok(())
23016 }
23017
23018 fn generate_values(&mut self, values: &Values) -> Result<()> {
23019 self.write_keyword("VALUES");
23020 for (i, row) in values.expressions.iter().enumerate() {
23021 if i > 0 {
23022 self.write(",");
23023 }
23024 self.write(" (");
23025 for (j, expr) in row.expressions.iter().enumerate() {
23026 if j > 0 {
23027 self.write(", ");
23028 }
23029 self.generate_expression(expr)?;
23030 }
23031 self.write(")");
23032 }
23033 if let Some(alias) = &values.alias {
23034 self.write_space();
23035 self.write_keyword("AS");
23036 self.write_space();
23037 self.generate_identifier(alias)?;
23038 if !values.column_aliases.is_empty() {
23039 self.write("(");
23040 for (i, col) in values.column_aliases.iter().enumerate() {
23041 if i > 0 {
23042 self.write(", ");
23043 }
23044 self.generate_identifier(col)?;
23045 }
23046 self.write(")");
23047 }
23048 }
23049 Ok(())
23050 }
23051
23052 fn generate_array(&mut self, arr: &Array) -> Result<()> {
23053 let needs_inheritance = matches!(
23055 self.config.dialect,
23056 Some(DialectType::DuckDB)
23057 | Some(DialectType::Spark)
23058 | Some(DialectType::Databricks)
23059 | Some(DialectType::Hive)
23060 | Some(DialectType::Snowflake)
23061 | Some(DialectType::Presto)
23062 | Some(DialectType::Trino)
23063 );
23064 let propagated: Vec<Expression>;
23065 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
23066 propagated = Self::inherit_struct_field_names(&arr.expressions);
23067 &propagated
23068 } else {
23069 &arr.expressions
23070 };
23071
23072 let use_parens =
23075 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
23076 if !self.config.array_bracket_only {
23077 self.write_keyword("ARRAY");
23078 }
23079 if use_parens {
23080 self.write("(");
23081 } else {
23082 self.write("[");
23083 }
23084 for (i, expr) in expressions.iter().enumerate() {
23085 if i > 0 {
23086 self.write(", ");
23087 }
23088 self.generate_expression(expr)?;
23089 }
23090 if use_parens {
23091 self.write(")");
23092 } else {
23093 self.write("]");
23094 }
23095 Ok(())
23096 }
23097
23098 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
23099 if tuple.expressions.len() == 2 {
23102 if let Expression::TableAlias(_) = &tuple.expressions[1] {
23103 self.generate_expression(&tuple.expressions[0])?;
23105 self.write_space();
23106 self.write_keyword("AS");
23107 self.write_space();
23108 self.generate_expression(&tuple.expressions[1])?;
23109 return Ok(());
23110 }
23111 }
23112
23113 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
23116 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
23117 for expr in &tuple.expressions {
23118 expr_strings.push(self.generate_to_string(expr)?);
23119 }
23120 self.too_wide(&expr_strings)
23121 } else {
23122 false
23123 };
23124
23125 if expand_tuple {
23126 self.write("(");
23127 self.write_newline();
23128 self.indent_level += 1;
23129 for (i, expr) in tuple.expressions.iter().enumerate() {
23130 if i > 0 {
23131 self.write(",");
23132 self.write_newline();
23133 }
23134 self.write_indent();
23135 self.generate_expression(expr)?;
23136 }
23137 self.indent_level -= 1;
23138 self.write_newline();
23139 self.write_indent();
23140 self.write(")");
23141 } else {
23142 self.write("(");
23143 for (i, expr) in tuple.expressions.iter().enumerate() {
23144 if i > 0 {
23145 self.write(", ");
23146 }
23147 self.generate_expression(expr)?;
23148 }
23149 self.write(")");
23150 }
23151 Ok(())
23152 }
23153
23154 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
23155 self.generate_expression(&pipe.this)?;
23156 self.write(" |> ");
23157 self.generate_expression(&pipe.expression)?;
23158 Ok(())
23159 }
23160
23161 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
23162 self.generate_expression(&ordered.this)?;
23163 if ordered.desc {
23164 self.write_space();
23165 self.write_keyword("DESC");
23166 } else if ordered.explicit_asc {
23167 self.write_space();
23168 self.write_keyword("ASC");
23169 }
23170 if let Some(nulls_first) = ordered.nulls_first {
23171 if self.config.null_ordering_supported
23172 || !matches!(self.config.dialect, Some(DialectType::Fabric))
23173 {
23174 let is_asc = !ordered.desc;
23188 let is_nulls_are_large = matches!(
23189 self.config.dialect,
23190 Some(DialectType::Oracle)
23191 | Some(DialectType::PostgreSQL)
23192 | Some(DialectType::Redshift)
23193 | Some(DialectType::Snowflake)
23194 );
23195 let is_nulls_are_last = matches!(
23196 self.config.dialect,
23197 Some(DialectType::Dremio)
23198 | Some(DialectType::DuckDB)
23199 | Some(DialectType::Presto)
23200 | Some(DialectType::Trino)
23201 | Some(DialectType::Athena)
23202 | Some(DialectType::ClickHouse)
23203 | Some(DialectType::Drill)
23204 | Some(DialectType::Exasol)
23205 );
23206
23207 let is_default_nulls = if is_nulls_are_large {
23209 (is_asc && !nulls_first) || (!is_asc && nulls_first)
23211 } else if is_nulls_are_last {
23212 !nulls_first
23214 } else {
23215 false
23216 };
23217
23218 if !is_default_nulls {
23219 self.write_space();
23220 self.write_keyword("NULLS");
23221 self.write_space();
23222 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
23223 }
23224 }
23225 }
23226 if let Some(ref with_fill) = ordered.with_fill {
23228 self.write_space();
23229 self.generate_with_fill(with_fill)?;
23230 }
23231 Ok(())
23232 }
23233
23234 fn write_clickhouse_type(&mut self, type_str: &str) {
23236 if self.clickhouse_nullable_depth < 0 {
23237 self.write(type_str);
23239 } else {
23240 self.write(&format!("Nullable({})", type_str));
23241 }
23242 }
23243
23244 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
23245 use crate::dialects::DialectType;
23246
23247 match dt {
23248 DataType::Boolean => {
23249 match self.config.dialect {
23251 Some(DialectType::TSQL) => self.write_keyword("BIT"),
23252 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
23254 self.write_keyword("NUMBER(1)")
23256 }
23257 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
23259 }
23260 }
23261 DataType::TinyInt { length } => {
23262 match self.config.dialect {
23266 Some(DialectType::PostgreSQL)
23267 | Some(DialectType::Redshift)
23268 | Some(DialectType::Oracle)
23269 | Some(DialectType::Exasol) => {
23270 self.write_keyword("SMALLINT");
23271 }
23272 Some(DialectType::Teradata) => {
23273 self.write_keyword("BYTEINT");
23275 }
23276 Some(DialectType::Dremio) => {
23277 self.write_keyword("INT");
23279 }
23280 Some(DialectType::ClickHouse) => {
23281 self.write_clickhouse_type("Int8");
23282 }
23283 _ => {
23284 self.write_keyword("TINYINT");
23285 }
23286 }
23287 if let Some(n) = length {
23288 if !matches!(
23289 self.config.dialect,
23290 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
23291 ) {
23292 self.write(&format!("({})", n));
23293 }
23294 }
23295 }
23296 DataType::SmallInt { length } => {
23297 match self.config.dialect {
23299 Some(DialectType::Dremio) => {
23300 self.write_keyword("INT");
23301 }
23302 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
23303 self.write_keyword("INTEGER");
23304 }
23305 Some(DialectType::BigQuery) => {
23306 self.write_keyword("INT64");
23307 }
23308 Some(DialectType::ClickHouse) => {
23309 self.write_clickhouse_type("Int16");
23310 }
23311 _ => {
23312 self.write_keyword("SMALLINT");
23313 if let Some(n) = length {
23314 self.write(&format!("({})", n));
23315 }
23316 }
23317 }
23318 }
23319 DataType::Int {
23320 length,
23321 integer_spelling: _,
23322 } => {
23323 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
23325 self.write_keyword("INT64");
23326 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23327 self.write_clickhouse_type("Int32");
23328 } else {
23329 let use_integer = match self.config.dialect {
23331 Some(DialectType::TSQL)
23332 | Some(DialectType::Fabric)
23333 | Some(DialectType::Presto)
23334 | Some(DialectType::Trino)
23335 | Some(DialectType::SQLite)
23336 | Some(DialectType::Redshift) => true,
23337 _ => false,
23338 };
23339 if use_integer {
23340 self.write_keyword("INTEGER");
23341 } else {
23342 self.write_keyword("INT");
23343 }
23344 if let Some(n) = length {
23345 self.write(&format!("({})", n));
23346 }
23347 }
23348 }
23349 DataType::BigInt { length } => {
23350 match self.config.dialect {
23352 Some(DialectType::Oracle) => {
23353 self.write_keyword("INT");
23355 }
23356 Some(DialectType::ClickHouse) => {
23357 self.write_clickhouse_type("Int64");
23358 }
23359 _ => {
23360 self.write_keyword("BIGINT");
23361 if let Some(n) = length {
23362 self.write(&format!("({})", n));
23363 }
23364 }
23365 }
23366 }
23367 DataType::Float {
23368 precision,
23369 scale,
23370 real_spelling,
23371 } => {
23372 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23376 self.write_clickhouse_type("Float32");
23377 } else if *real_spelling
23378 && !matches!(
23379 self.config.dialect,
23380 Some(DialectType::Spark)
23381 | Some(DialectType::Databricks)
23382 | Some(DialectType::Hive)
23383 | Some(DialectType::Snowflake)
23384 | Some(DialectType::MySQL)
23385 | Some(DialectType::BigQuery)
23386 )
23387 {
23388 self.write_keyword("REAL")
23389 } else {
23390 match self.config.dialect {
23391 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
23392 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23393 _ => self.write_keyword("FLOAT"),
23394 }
23395 }
23396 if !matches!(
23399 self.config.dialect,
23400 Some(DialectType::Spark)
23401 | Some(DialectType::Databricks)
23402 | Some(DialectType::Hive)
23403 | Some(DialectType::Presto)
23404 | Some(DialectType::Trino)
23405 ) {
23406 if let Some(p) = precision {
23407 self.write(&format!("({}", p));
23408 if let Some(s) = scale {
23409 self.write(&format!(", {})", s));
23410 } else {
23411 self.write(")");
23412 }
23413 }
23414 }
23415 }
23416 DataType::Double { precision, scale } => {
23417 match self.config.dialect {
23419 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23420 self.write_keyword("FLOAT")
23421 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
23423 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
23424 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
23425 Some(DialectType::SQLite) => self.write_keyword("REAL"),
23426 Some(DialectType::PostgreSQL)
23427 | Some(DialectType::Redshift)
23428 | Some(DialectType::Teradata)
23429 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
23430 _ => self.write_keyword("DOUBLE"),
23431 }
23432 if let Some(p) = precision {
23434 self.write(&format!("({}", p));
23435 if let Some(s) = scale {
23436 self.write(&format!(", {})", s));
23437 } else {
23438 self.write(")");
23439 }
23440 }
23441 }
23442 DataType::Decimal { precision, scale } => {
23443 match self.config.dialect {
23445 Some(DialectType::ClickHouse) => {
23446 self.write("Decimal");
23447 if let Some(p) = precision {
23448 self.write(&format!("({}", p));
23449 if let Some(s) = scale {
23450 self.write(&format!(", {}", s));
23451 }
23452 self.write(")");
23453 }
23454 }
23455 Some(DialectType::Oracle) => {
23456 self.write_keyword("NUMBER");
23458 if let Some(p) = precision {
23459 self.write(&format!("({}", p));
23460 if let Some(s) = scale {
23461 self.write(&format!(", {}", s));
23462 }
23463 self.write(")");
23464 }
23465 }
23466 Some(DialectType::BigQuery) => {
23467 self.write_keyword("NUMERIC");
23469 if let Some(p) = precision {
23470 self.write(&format!("({}", p));
23471 if let Some(s) = scale {
23472 self.write(&format!(", {}", s));
23473 }
23474 self.write(")");
23475 }
23476 }
23477 _ => {
23478 self.write_keyword("DECIMAL");
23479 if let Some(p) = precision {
23480 self.write(&format!("({}", p));
23481 if let Some(s) = scale {
23482 self.write(&format!(", {}", s));
23483 }
23484 self.write(")");
23485 }
23486 }
23487 }
23488 }
23489 DataType::Char { length } => {
23490 match self.config.dialect {
23492 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
23493 self.write_keyword("TEXT");
23495 }
23496 Some(DialectType::Hive)
23497 | Some(DialectType::Spark)
23498 | Some(DialectType::Databricks) => {
23499 if length.is_some()
23502 && !matches!(self.config.dialect, Some(DialectType::Hive))
23503 {
23504 self.write_keyword("CHAR");
23505 if let Some(n) = length {
23506 self.write(&format!("({})", n));
23507 }
23508 } else {
23509 self.write_keyword("STRING");
23510 }
23511 }
23512 Some(DialectType::Dremio) => {
23513 self.write_keyword("VARCHAR");
23515 if let Some(n) = length {
23516 self.write(&format!("({})", n));
23517 }
23518 }
23519 _ => {
23520 self.write_keyword("CHAR");
23521 if let Some(n) = length {
23522 self.write(&format!("({})", n));
23523 }
23524 }
23525 }
23526 }
23527 DataType::VarChar {
23528 length,
23529 parenthesized_length,
23530 } => {
23531 match self.config.dialect {
23533 Some(DialectType::Oracle) => {
23534 self.write_keyword("VARCHAR2");
23535 if let Some(n) = length {
23536 self.write(&format!("({})", n));
23537 }
23538 }
23539 Some(DialectType::DuckDB) => {
23540 self.write_keyword("TEXT");
23542 if let Some(n) = length {
23543 self.write(&format!("({})", n));
23544 }
23545 }
23546 Some(DialectType::SQLite) => {
23547 self.write_keyword("TEXT");
23549 if let Some(n) = length {
23550 self.write(&format!("({})", n));
23551 }
23552 }
23553 Some(DialectType::MySQL) if length.is_none() => {
23554 self.write_keyword("TEXT");
23556 }
23557 Some(DialectType::Hive)
23558 | Some(DialectType::Spark)
23559 | Some(DialectType::Databricks)
23560 if length.is_none() =>
23561 {
23562 self.write_keyword("STRING");
23564 }
23565 _ => {
23566 self.write_keyword("VARCHAR");
23567 if let Some(n) = length {
23568 if *parenthesized_length {
23570 self.write(&format!("(({}))", n));
23571 } else {
23572 self.write(&format!("({})", n));
23573 }
23574 }
23575 }
23576 }
23577 }
23578 DataType::Text => {
23579 match self.config.dialect {
23581 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
23582 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23583 self.write_keyword("VARCHAR(MAX)")
23584 }
23585 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
23586 Some(DialectType::Snowflake)
23587 | Some(DialectType::Dremio)
23588 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
23589 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
23590 Some(DialectType::Presto)
23591 | Some(DialectType::Trino)
23592 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
23593 Some(DialectType::Spark)
23594 | Some(DialectType::Databricks)
23595 | Some(DialectType::Hive) => self.write_keyword("STRING"),
23596 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
23597 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23598 self.write_keyword("STRING")
23599 }
23600 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23601 _ => self.write_keyword("TEXT"),
23602 }
23603 }
23604 DataType::TextWithLength { length } => {
23605 match self.config.dialect {
23607 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
23608 Some(DialectType::Hive)
23609 | Some(DialectType::Spark)
23610 | Some(DialectType::Databricks) => {
23611 self.write(&format!("VARCHAR({})", length));
23612 }
23613 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
23614 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
23615 Some(DialectType::Snowflake)
23616 | Some(DialectType::Presto)
23617 | Some(DialectType::Trino)
23618 | Some(DialectType::Athena)
23619 | Some(DialectType::Drill)
23620 | Some(DialectType::Dremio) => {
23621 self.write(&format!("VARCHAR({})", length));
23622 }
23623 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23624 self.write(&format!("VARCHAR({})", length))
23625 }
23626 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
23627 self.write(&format!("STRING({})", length))
23628 }
23629 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
23630 _ => self.write(&format!("TEXT({})", length)),
23631 }
23632 }
23633 DataType::String { length } => {
23634 match self.config.dialect {
23636 Some(DialectType::ClickHouse) => {
23637 self.write("String");
23639 if let Some(n) = length {
23640 self.write(&format!("({})", n));
23641 }
23642 }
23643 Some(DialectType::BigQuery)
23644 | Some(DialectType::Hive)
23645 | Some(DialectType::Spark)
23646 | Some(DialectType::Databricks)
23647 | Some(DialectType::StarRocks)
23648 | Some(DialectType::Doris) => {
23649 self.write_keyword("STRING");
23650 if let Some(n) = length {
23651 self.write(&format!("({})", n));
23652 }
23653 }
23654 Some(DialectType::PostgreSQL) => {
23655 if let Some(n) = length {
23657 self.write_keyword("VARCHAR");
23658 self.write(&format!("({})", n));
23659 } else {
23660 self.write_keyword("TEXT");
23661 }
23662 }
23663 Some(DialectType::Redshift) => {
23664 if let Some(n) = length {
23666 self.write_keyword("VARCHAR");
23667 self.write(&format!("({})", n));
23668 } else {
23669 self.write_keyword("VARCHAR(MAX)");
23670 }
23671 }
23672 Some(DialectType::MySQL) => {
23673 if let Some(n) = length {
23675 self.write_keyword("VARCHAR");
23676 self.write(&format!("({})", n));
23677 } else {
23678 self.write_keyword("TEXT");
23679 }
23680 }
23681 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23682 if let Some(n) = length {
23684 self.write_keyword("VARCHAR");
23685 self.write(&format!("({})", n));
23686 } else {
23687 self.write_keyword("VARCHAR(MAX)");
23688 }
23689 }
23690 Some(DialectType::Oracle) => {
23691 self.write_keyword("CLOB");
23693 }
23694 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
23695 self.write_keyword("TEXT");
23697 if let Some(n) = length {
23698 self.write(&format!("({})", n));
23699 }
23700 }
23701 Some(DialectType::Presto)
23702 | Some(DialectType::Trino)
23703 | Some(DialectType::Drill)
23704 | Some(DialectType::Dremio) => {
23705 self.write_keyword("VARCHAR");
23707 if let Some(n) = length {
23708 self.write(&format!("({})", n));
23709 }
23710 }
23711 Some(DialectType::Snowflake) => {
23712 self.write_keyword("STRING");
23715 if let Some(n) = length {
23716 self.write(&format!("({})", n));
23717 }
23718 }
23719 _ => {
23720 self.write_keyword("STRING");
23722 if let Some(n) = length {
23723 self.write(&format!("({})", n));
23724 }
23725 }
23726 }
23727 }
23728 DataType::Binary { length } => {
23729 match self.config.dialect {
23731 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23732 self.write_keyword("BYTEA");
23733 if let Some(n) = length {
23734 self.write(&format!("({})", n));
23735 }
23736 }
23737 Some(DialectType::Redshift) => {
23738 self.write_keyword("VARBYTE");
23739 if let Some(n) = length {
23740 self.write(&format!("({})", n));
23741 }
23742 }
23743 Some(DialectType::DuckDB)
23744 | Some(DialectType::SQLite)
23745 | Some(DialectType::Oracle) => {
23746 self.write_keyword("BLOB");
23748 if let Some(n) = length {
23749 self.write(&format!("({})", n));
23750 }
23751 }
23752 Some(DialectType::Presto)
23753 | Some(DialectType::Trino)
23754 | Some(DialectType::Athena)
23755 | Some(DialectType::Drill)
23756 | Some(DialectType::Dremio) => {
23757 self.write_keyword("VARBINARY");
23759 if let Some(n) = length {
23760 self.write(&format!("({})", n));
23761 }
23762 }
23763 Some(DialectType::ClickHouse) => {
23764 if self.clickhouse_nullable_depth < 0 {
23766 self.write("BINARY");
23767 } else {
23768 self.write("Nullable(BINARY");
23769 }
23770 if let Some(n) = length {
23771 self.write(&format!("({})", n));
23772 }
23773 if self.clickhouse_nullable_depth >= 0 {
23774 self.write(")");
23775 }
23776 }
23777 _ => {
23778 self.write_keyword("BINARY");
23779 if let Some(n) = length {
23780 self.write(&format!("({})", n));
23781 }
23782 }
23783 }
23784 }
23785 DataType::VarBinary { length } => {
23786 match self.config.dialect {
23788 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23789 self.write_keyword("BYTEA");
23790 if let Some(n) = length {
23791 self.write(&format!("({})", n));
23792 }
23793 }
23794 Some(DialectType::Redshift) => {
23795 self.write_keyword("VARBYTE");
23796 if let Some(n) = length {
23797 self.write(&format!("({})", n));
23798 }
23799 }
23800 Some(DialectType::DuckDB)
23801 | Some(DialectType::SQLite)
23802 | Some(DialectType::Oracle) => {
23803 self.write_keyword("BLOB");
23805 if let Some(n) = length {
23806 self.write(&format!("({})", n));
23807 }
23808 }
23809 Some(DialectType::Exasol) => {
23810 self.write_keyword("VARCHAR");
23812 }
23813 Some(DialectType::Spark)
23814 | Some(DialectType::Hive)
23815 | Some(DialectType::Databricks) => {
23816 self.write_keyword("BINARY");
23818 if let Some(n) = length {
23819 self.write(&format!("({})", n));
23820 }
23821 }
23822 Some(DialectType::ClickHouse) => {
23823 self.write_clickhouse_type("String");
23825 }
23826 _ => {
23827 self.write_keyword("VARBINARY");
23828 if let Some(n) = length {
23829 self.write(&format!("({})", n));
23830 }
23831 }
23832 }
23833 }
23834 DataType::Blob => {
23835 match self.config.dialect {
23837 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
23838 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
23839 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23840 self.write_keyword("VARBINARY")
23841 }
23842 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23843 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
23844 Some(DialectType::Presto)
23845 | Some(DialectType::Trino)
23846 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23847 Some(DialectType::DuckDB) => {
23848 self.write_keyword("VARBINARY");
23851 }
23852 Some(DialectType::Spark)
23853 | Some(DialectType::Databricks)
23854 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
23855 Some(DialectType::ClickHouse) => {
23856 self.write("Nullable(String)");
23860 }
23861 _ => self.write_keyword("BLOB"),
23862 }
23863 }
23864 DataType::Bit { length } => {
23865 match self.config.dialect {
23867 Some(DialectType::Dremio)
23868 | Some(DialectType::Spark)
23869 | Some(DialectType::Databricks)
23870 | Some(DialectType::Hive)
23871 | Some(DialectType::Snowflake)
23872 | Some(DialectType::BigQuery)
23873 | Some(DialectType::Presto)
23874 | Some(DialectType::Trino)
23875 | Some(DialectType::ClickHouse)
23876 | Some(DialectType::Redshift) => {
23877 self.write_keyword("BOOLEAN");
23879 }
23880 _ => {
23881 self.write_keyword("BIT");
23882 if let Some(n) = length {
23883 self.write(&format!("({})", n));
23884 }
23885 }
23886 }
23887 }
23888 DataType::VarBit { length } => {
23889 self.write_keyword("VARBIT");
23890 if let Some(n) = length {
23891 self.write(&format!("({})", n));
23892 }
23893 }
23894 DataType::Date => self.write_keyword("DATE"),
23895 DataType::Time {
23896 precision,
23897 timezone,
23898 } => {
23899 if *timezone {
23900 match self.config.dialect {
23902 Some(DialectType::DuckDB) => {
23903 self.write_keyword("TIMETZ");
23905 }
23906 Some(DialectType::PostgreSQL) => {
23907 self.write_keyword("TIMETZ");
23909 if let Some(p) = precision {
23910 self.write(&format!("({})", p));
23911 }
23912 }
23913 _ => {
23914 self.write_keyword("TIME");
23916 if let Some(p) = precision {
23917 self.write(&format!("({})", p));
23918 }
23919 self.write_keyword(" WITH TIME ZONE");
23920 }
23921 }
23922 } else {
23923 if matches!(
23925 self.config.dialect,
23926 Some(DialectType::Spark)
23927 | Some(DialectType::Databricks)
23928 | Some(DialectType::Hive)
23929 ) {
23930 self.write_keyword("TIMESTAMP");
23931 } else {
23932 self.write_keyword("TIME");
23933 if let Some(p) = precision {
23934 self.write(&format!("({})", p));
23935 }
23936 }
23937 }
23938 }
23939 DataType::Timestamp {
23940 precision,
23941 timezone,
23942 } => {
23943 match self.config.dialect {
23945 Some(DialectType::ClickHouse) => {
23946 self.write("DateTime");
23947 if let Some(p) = precision {
23948 self.write(&format!("({})", p));
23949 }
23950 }
23951 Some(DialectType::TSQL) => {
23952 if *timezone {
23953 self.write_keyword("DATETIMEOFFSET");
23954 } else {
23955 self.write_keyword("DATETIME2");
23956 }
23957 if let Some(p) = precision {
23958 self.write(&format!("({})", p));
23959 }
23960 }
23961 Some(DialectType::MySQL) => {
23962 self.write_keyword("TIMESTAMP");
23964 if let Some(p) = precision {
23965 self.write(&format!("({})", p));
23966 }
23967 }
23968 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
23969 self.write_keyword("DATETIME");
23971 if let Some(p) = precision {
23972 self.write(&format!("({})", p));
23973 }
23974 }
23975 Some(DialectType::BigQuery) => {
23976 if *timezone {
23978 self.write_keyword("TIMESTAMP");
23979 } else {
23980 self.write_keyword("DATETIME");
23981 }
23982 }
23983 Some(DialectType::DuckDB) => {
23984 if *timezone {
23986 self.write_keyword("TIMESTAMPTZ");
23987 } else {
23988 self.write_keyword("TIMESTAMP");
23989 if let Some(p) = precision {
23990 self.write(&format!("({})", p));
23991 }
23992 }
23993 }
23994 _ => {
23995 if *timezone && !self.config.tz_to_with_time_zone {
23996 self.write_keyword("TIMESTAMPTZ");
23998 if let Some(p) = precision {
23999 self.write(&format!("({})", p));
24000 }
24001 } else {
24002 self.write_keyword("TIMESTAMP");
24003 if let Some(p) = precision {
24004 self.write(&format!("({})", p));
24005 }
24006 if *timezone {
24007 self.write_space();
24008 self.write_keyword("WITH TIME ZONE");
24009 }
24010 }
24011 }
24012 }
24013 }
24014 DataType::Interval { unit, to } => {
24015 self.write_keyword("INTERVAL");
24016 if let Some(u) = unit {
24017 self.write_space();
24018 self.write_keyword(u);
24019 }
24020 if let Some(t) = to {
24022 self.write_space();
24023 self.write_keyword("TO");
24024 self.write_space();
24025 self.write_keyword(t);
24026 }
24027 }
24028 DataType::Json => {
24029 match self.config.dialect {
24031 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
24034 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24035 _ => self.write_keyword("JSON"),
24036 }
24037 }
24038 DataType::JsonB => {
24039 match self.config.dialect {
24041 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
24042 Some(DialectType::Doris) => self.write_keyword("JSONB"),
24043 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
24044 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24045 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
24048 }
24049 DataType::Uuid => {
24050 match self.config.dialect {
24052 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
24053 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
24054 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
24055 Some(DialectType::BigQuery)
24056 | Some(DialectType::Spark)
24057 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
24058 _ => self.write_keyword("UUID"),
24059 }
24060 }
24061 DataType::Array {
24062 element_type,
24063 dimension,
24064 } => {
24065 match self.config.dialect {
24067 Some(DialectType::PostgreSQL)
24068 | Some(DialectType::Redshift)
24069 | Some(DialectType::DuckDB) => {
24070 self.generate_data_type(element_type)?;
24072 if let Some(dim) = dimension {
24073 self.write(&format!("[{}]", dim));
24074 } else {
24075 self.write("[]");
24076 }
24077 }
24078 Some(DialectType::BigQuery) => {
24079 self.write_keyword("ARRAY<");
24080 self.generate_data_type(element_type)?;
24081 self.write(">");
24082 }
24083 Some(DialectType::Snowflake)
24084 | Some(DialectType::Presto)
24085 | Some(DialectType::Trino)
24086 | Some(DialectType::ClickHouse) => {
24087 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24089 self.write("Array(");
24090 } else {
24091 self.write_keyword("ARRAY(");
24092 }
24093 self.generate_data_type(element_type)?;
24094 self.write(")");
24095 }
24096 Some(DialectType::TSQL)
24097 | Some(DialectType::MySQL)
24098 | Some(DialectType::Oracle) => {
24099 match self.config.dialect {
24102 Some(DialectType::MySQL) => self.write_keyword("JSON"),
24103 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
24104 _ => self.write_keyword("JSON"),
24105 }
24106 }
24107 _ => {
24108 self.write_keyword("ARRAY<");
24110 self.generate_data_type(element_type)?;
24111 self.write(">");
24112 }
24113 }
24114 }
24115 DataType::List { element_type } => {
24116 self.generate_data_type(element_type)?;
24118 self.write_keyword(" LIST");
24119 }
24120 DataType::Map {
24121 key_type,
24122 value_type,
24123 } => {
24124 match self.config.dialect {
24126 Some(DialectType::Materialize) => {
24127 self.write_keyword("MAP[");
24129 self.generate_data_type(key_type)?;
24130 self.write(" => ");
24131 self.generate_data_type(value_type)?;
24132 self.write("]");
24133 }
24134 Some(DialectType::Snowflake)
24135 | Some(DialectType::RisingWave)
24136 | Some(DialectType::DuckDB)
24137 | Some(DialectType::Presto)
24138 | Some(DialectType::Trino)
24139 | Some(DialectType::Athena) => {
24140 self.write_keyword("MAP(");
24141 self.generate_data_type(key_type)?;
24142 self.write(", ");
24143 self.generate_data_type(value_type)?;
24144 self.write(")");
24145 }
24146 Some(DialectType::ClickHouse) => {
24147 self.write("Map(");
24150 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
24152 self.clickhouse_nullable_depth = 0;
24153 self.write(", ");
24154 self.generate_data_type(value_type)?;
24155 self.write(")");
24156 }
24157 _ => {
24158 self.write_keyword("MAP<");
24159 self.generate_data_type(key_type)?;
24160 self.write(", ");
24161 self.generate_data_type(value_type)?;
24162 self.write(">");
24163 }
24164 }
24165 }
24166 DataType::Vector {
24167 element_type,
24168 dimension,
24169 } => {
24170 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
24171 self.write_keyword("VECTOR(");
24173 if let Some(dim) = dimension {
24174 self.write(&dim.to_string());
24175 }
24176 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
24178 DataType::TinyInt { .. } => Some("I8"),
24179 DataType::SmallInt { .. } => Some("I16"),
24180 DataType::Int { .. } => Some("I32"),
24181 DataType::BigInt { .. } => Some("I64"),
24182 DataType::Float { .. } => Some("F32"),
24183 DataType::Double { .. } => Some("F64"),
24184 _ => None,
24185 });
24186 if let Some(alias) = type_alias {
24187 if dimension.is_some() {
24188 self.write(", ");
24189 }
24190 self.write(alias);
24191 }
24192 self.write(")");
24193 } else {
24194 self.write_keyword("VECTOR(");
24196 if let Some(ref et) = element_type {
24197 self.generate_data_type(et)?;
24198 if dimension.is_some() {
24199 self.write(", ");
24200 }
24201 }
24202 if let Some(dim) = dimension {
24203 self.write(&dim.to_string());
24204 }
24205 self.write(")");
24206 }
24207 }
24208 DataType::Object { fields, modifier } => {
24209 self.write_keyword("OBJECT(");
24210 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
24211 if i > 0 {
24212 self.write(", ");
24213 }
24214 self.write(name);
24215 self.write(" ");
24216 self.generate_data_type(dt)?;
24217 if *not_null {
24218 self.write_keyword(" NOT NULL");
24219 }
24220 }
24221 self.write(")");
24222 if let Some(mod_str) = modifier {
24223 self.write(" ");
24224 self.write_keyword(mod_str);
24225 }
24226 }
24227 DataType::Struct { fields, nested } => {
24228 match self.config.dialect {
24230 Some(DialectType::Snowflake) => {
24231 self.write_keyword("OBJECT(");
24233 for (i, field) in fields.iter().enumerate() {
24234 if i > 0 {
24235 self.write(", ");
24236 }
24237 if !field.name.is_empty() {
24238 self.write(&field.name);
24239 self.write(" ");
24240 }
24241 self.generate_data_type(&field.data_type)?;
24242 }
24243 self.write(")");
24244 }
24245 Some(DialectType::Presto) | Some(DialectType::Trino) => {
24246 self.write_keyword("ROW(");
24248 for (i, field) in fields.iter().enumerate() {
24249 if i > 0 {
24250 self.write(", ");
24251 }
24252 if !field.name.is_empty() {
24253 self.write(&field.name);
24254 self.write(" ");
24255 }
24256 self.generate_data_type(&field.data_type)?;
24257 }
24258 self.write(")");
24259 }
24260 Some(DialectType::DuckDB) => {
24261 self.write_keyword("STRUCT(");
24263 for (i, field) in fields.iter().enumerate() {
24264 if i > 0 {
24265 self.write(", ");
24266 }
24267 if !field.name.is_empty() {
24268 self.write(&field.name);
24269 self.write(" ");
24270 }
24271 self.generate_data_type(&field.data_type)?;
24272 }
24273 self.write(")");
24274 }
24275 Some(DialectType::ClickHouse) => {
24276 self.write("Tuple(");
24278 for (i, field) in fields.iter().enumerate() {
24279 if i > 0 {
24280 self.write(", ");
24281 }
24282 if !field.name.is_empty() {
24283 self.write(&field.name);
24284 self.write(" ");
24285 }
24286 self.generate_data_type(&field.data_type)?;
24287 }
24288 self.write(")");
24289 }
24290 Some(DialectType::SingleStore) => {
24291 self.write_keyword("RECORD(");
24293 for (i, field) in fields.iter().enumerate() {
24294 if i > 0 {
24295 self.write(", ");
24296 }
24297 if !field.name.is_empty() {
24298 self.write(&field.name);
24299 self.write(" ");
24300 }
24301 self.generate_data_type(&field.data_type)?;
24302 }
24303 self.write(")");
24304 }
24305 _ => {
24306 let force_angle_brackets = matches!(
24308 self.config.dialect,
24309 Some(DialectType::Hive)
24310 | Some(DialectType::Spark)
24311 | Some(DialectType::Databricks)
24312 );
24313 if *nested && !force_angle_brackets {
24314 self.write_keyword("STRUCT(");
24315 for (i, field) in fields.iter().enumerate() {
24316 if i > 0 {
24317 self.write(", ");
24318 }
24319 if !field.name.is_empty() {
24320 self.write(&field.name);
24321 self.write(" ");
24322 }
24323 self.generate_data_type(&field.data_type)?;
24324 }
24325 self.write(")");
24326 } else {
24327 self.write_keyword("STRUCT<");
24328 for (i, field) in fields.iter().enumerate() {
24329 if i > 0 {
24330 self.write(", ");
24331 }
24332 if !field.name.is_empty() {
24333 self.write(&field.name);
24335 self.write(self.config.struct_field_sep);
24336 }
24337 self.generate_data_type(&field.data_type)?;
24339 if let Some(comment) = &field.comment {
24341 self.write(" COMMENT '");
24342 self.write(comment);
24343 self.write("'");
24344 }
24345 if !field.options.is_empty() {
24347 self.write(" ");
24348 self.generate_options_clause(&field.options)?;
24349 }
24350 }
24351 self.write(">");
24352 }
24353 }
24354 }
24355 }
24356 DataType::Enum {
24357 values,
24358 assignments,
24359 } => {
24360 if self.config.dialect == Some(DialectType::ClickHouse) {
24363 self.write("Enum(");
24364 } else {
24365 self.write_keyword("ENUM(");
24366 }
24367 for (i, val) in values.iter().enumerate() {
24368 if i > 0 {
24369 self.write(", ");
24370 }
24371 self.write("'");
24372 self.write(val);
24373 self.write("'");
24374 if let Some(Some(assignment)) = assignments.get(i) {
24375 self.write(" = ");
24376 self.write(assignment);
24377 }
24378 }
24379 self.write(")");
24380 }
24381 DataType::Set { values } => {
24382 self.write_keyword("SET(");
24384 for (i, val) in values.iter().enumerate() {
24385 if i > 0 {
24386 self.write(", ");
24387 }
24388 self.write("'");
24389 self.write(val);
24390 self.write("'");
24391 }
24392 self.write(")");
24393 }
24394 DataType::Union { fields } => {
24395 self.write_keyword("UNION(");
24397 for (i, (name, dt)) in fields.iter().enumerate() {
24398 if i > 0 {
24399 self.write(", ");
24400 }
24401 if !name.is_empty() {
24402 self.write(name);
24403 self.write(" ");
24404 }
24405 self.generate_data_type(dt)?;
24406 }
24407 self.write(")");
24408 }
24409 DataType::Nullable { inner } => {
24410 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
24412 self.write("Nullable(");
24413 let saved_depth = self.clickhouse_nullable_depth;
24415 self.clickhouse_nullable_depth = -1;
24416 self.generate_data_type(inner)?;
24417 self.clickhouse_nullable_depth = saved_depth;
24418 self.write(")");
24419 } else {
24420 match inner.as_ref() {
24422 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
24423 self.generate_data_type(&DataType::Timestamp {
24424 precision: None,
24425 timezone: false,
24426 })?;
24427 }
24428 _ => {
24429 self.generate_data_type(inner)?;
24430 }
24431 }
24432 }
24433 }
24434 DataType::Custom { name } => {
24435 let name_upper = name.to_ascii_uppercase();
24437 match self.config.dialect {
24438 Some(DialectType::ClickHouse) => {
24439 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
24440 (name_upper[..idx].to_string(), &name[idx..])
24441 } else {
24442 (name_upper.clone(), "")
24443 };
24444 let mapped = match base_upper.as_str() {
24445 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
24446 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
24447 "DATETIME64" => "DateTime64",
24448 "DATE32" => "Date32",
24449 "INT" => "Int32",
24450 "MEDIUMINT" => "Int32",
24451 "INT8" => "Int8",
24452 "INT16" => "Int16",
24453 "INT32" => "Int32",
24454 "INT64" => "Int64",
24455 "INT128" => "Int128",
24456 "INT256" => "Int256",
24457 "UINT8" => "UInt8",
24458 "UINT16" => "UInt16",
24459 "UINT32" => "UInt32",
24460 "UINT64" => "UInt64",
24461 "UINT128" => "UInt128",
24462 "UINT256" => "UInt256",
24463 "FLOAT32" => "Float32",
24464 "FLOAT64" => "Float64",
24465 "DECIMAL32" => "Decimal32",
24466 "DECIMAL64" => "Decimal64",
24467 "DECIMAL128" => "Decimal128",
24468 "DECIMAL256" => "Decimal256",
24469 "ENUM" => "Enum",
24470 "ENUM8" => "Enum8",
24471 "ENUM16" => "Enum16",
24472 "FIXEDSTRING" => "FixedString",
24473 "NESTED" => "Nested",
24474 "LOWCARDINALITY" => "LowCardinality",
24475 "NULLABLE" => "Nullable",
24476 "IPV4" => "IPv4",
24477 "IPV6" => "IPv6",
24478 "POINT" => "Point",
24479 "RING" => "Ring",
24480 "LINESTRING" => "LineString",
24481 "MULTILINESTRING" => "MultiLineString",
24482 "POLYGON" => "Polygon",
24483 "MULTIPOLYGON" => "MultiPolygon",
24484 "AGGREGATEFUNCTION" => "AggregateFunction",
24485 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
24486 "DYNAMIC" => "Dynamic",
24487 _ => "",
24488 };
24489 if mapped.is_empty() {
24490 self.write(name);
24491 } else {
24492 self.write(mapped);
24493 if matches!(base_upper.as_str(), "ENUM8" | "ENUM16")
24494 && !suffix.is_empty()
24495 {
24496 let escaped_suffix = suffix
24497 .replace('\\', "\\\\")
24498 .replace('\t', "\\t")
24499 .replace('\n', "\\n")
24500 .replace('\r', "\\r");
24501 self.write(&escaped_suffix);
24502 } else {
24503 self.write(suffix);
24504 }
24505 }
24506 }
24507 Some(DialectType::MySQL)
24508 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
24509 {
24510 self.write_keyword("TIMESTAMP");
24512 }
24513 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
24514 self.write_keyword("SQL_VARIANT");
24515 }
24516 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
24517 self.write_keyword("DECIMAL(38, 5)");
24518 }
24519 Some(DialectType::Exasol) => {
24520 match name_upper.as_str() {
24522 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
24524 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
24526 "MEDIUMINT" => self.write_keyword("INT"),
24528 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
24530 self.write_keyword("DECIMAL")
24531 }
24532 "DATETIME" => self.write_keyword("TIMESTAMP"),
24534 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
24535 _ => self.write(name),
24536 }
24537 }
24538 Some(DialectType::Dremio) => {
24539 match name_upper.as_str() {
24541 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
24542 "ARRAY" => self.write_keyword("LIST"),
24543 "NCHAR" => self.write_keyword("VARCHAR"),
24544 _ => self.write(name),
24545 }
24546 }
24547 _ => {
24549 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
24551 (name_upper[..idx].to_string(), Some(&name[idx..]))
24552 } else {
24553 (name_upper.clone(), None)
24554 };
24555
24556 match base_upper.as_str() {
24557 "INT64"
24558 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24559 {
24560 self.write_keyword("BIGINT");
24561 }
24562 "FLOAT64"
24563 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24564 {
24565 self.write_keyword("DOUBLE");
24566 }
24567 "BOOL"
24568 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24569 {
24570 self.write_keyword("BOOLEAN");
24571 }
24572 "BYTES"
24573 if matches!(
24574 self.config.dialect,
24575 Some(DialectType::Spark)
24576 | Some(DialectType::Hive)
24577 | Some(DialectType::Databricks)
24578 ) =>
24579 {
24580 self.write_keyword("BINARY");
24581 }
24582 "BYTES"
24583 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
24584 {
24585 self.write_keyword("VARBINARY");
24586 }
24587 "DATETIME2" | "SMALLDATETIME"
24589 if !matches!(
24590 self.config.dialect,
24591 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24592 ) =>
24593 {
24594 if matches!(
24596 self.config.dialect,
24597 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24598 ) {
24599 self.write_keyword("TIMESTAMP");
24600 if let Some(args) = _args_str {
24601 self.write(args);
24602 }
24603 } else {
24604 self.write_keyword("TIMESTAMP");
24605 }
24606 }
24607 "DATETIMEOFFSET"
24609 if !matches!(
24610 self.config.dialect,
24611 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24612 ) =>
24613 {
24614 if matches!(
24615 self.config.dialect,
24616 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
24617 ) {
24618 self.write_keyword("TIMESTAMPTZ");
24619 if let Some(args) = _args_str {
24620 self.write(args);
24621 }
24622 } else {
24623 self.write_keyword("TIMESTAMPTZ");
24624 }
24625 }
24626 "UNIQUEIDENTIFIER"
24628 if !matches!(
24629 self.config.dialect,
24630 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24631 ) =>
24632 {
24633 match self.config.dialect {
24634 Some(DialectType::Spark)
24635 | Some(DialectType::Databricks)
24636 | Some(DialectType::Hive) => self.write_keyword("STRING"),
24637 _ => self.write_keyword("UUID"),
24638 }
24639 }
24640 "BIT"
24642 if !matches!(
24643 self.config.dialect,
24644 Some(DialectType::TSQL)
24645 | Some(DialectType::Fabric)
24646 | Some(DialectType::PostgreSQL)
24647 | Some(DialectType::MySQL)
24648 | Some(DialectType::DuckDB)
24649 ) =>
24650 {
24651 self.write_keyword("BOOLEAN");
24652 }
24653 "NVARCHAR"
24655 if !matches!(
24656 self.config.dialect,
24657 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24658 ) =>
24659 {
24660 match self.config.dialect {
24661 Some(DialectType::Oracle) => {
24662 self.write_keyword("NVARCHAR2");
24664 if let Some(args) = _args_str {
24665 self.write(args);
24666 }
24667 }
24668 Some(DialectType::BigQuery) => {
24669 self.write_keyword("STRING");
24671 }
24672 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24673 self.write_keyword("TEXT");
24674 if let Some(args) = _args_str {
24675 self.write(args);
24676 }
24677 }
24678 Some(DialectType::Hive) => {
24679 self.write_keyword("STRING");
24681 }
24682 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24683 if _args_str.is_some() {
24684 self.write_keyword("VARCHAR");
24685 self.write(_args_str.unwrap());
24686 } else {
24687 self.write_keyword("STRING");
24688 }
24689 }
24690 _ => {
24691 self.write_keyword("VARCHAR");
24692 if let Some(args) = _args_str {
24693 self.write(args);
24694 }
24695 }
24696 }
24697 }
24698 "NCHAR"
24700 if !matches!(
24701 self.config.dialect,
24702 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24703 ) =>
24704 {
24705 match self.config.dialect {
24706 Some(DialectType::Oracle) => {
24707 self.write_keyword("NCHAR");
24709 if let Some(args) = _args_str {
24710 self.write(args);
24711 }
24712 }
24713 Some(DialectType::BigQuery) => {
24714 self.write_keyword("STRING");
24716 }
24717 Some(DialectType::Hive) => {
24718 self.write_keyword("STRING");
24720 }
24721 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24722 self.write_keyword("TEXT");
24723 if let Some(args) = _args_str {
24724 self.write(args);
24725 }
24726 }
24727 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24728 if _args_str.is_some() {
24729 self.write_keyword("CHAR");
24730 self.write(_args_str.unwrap());
24731 } else {
24732 self.write_keyword("STRING");
24733 }
24734 }
24735 _ => {
24736 self.write_keyword("CHAR");
24737 if let Some(args) = _args_str {
24738 self.write(args);
24739 }
24740 }
24741 }
24742 }
24743 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
24746 Some(DialectType::MySQL)
24747 | Some(DialectType::SingleStore)
24748 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24749 Some(DialectType::Spark)
24750 | Some(DialectType::Databricks)
24751 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
24752 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24753 Some(DialectType::Presto)
24754 | Some(DialectType::Trino)
24755 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24756 Some(DialectType::Snowflake)
24757 | Some(DialectType::Redshift)
24758 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
24759 _ => self.write_keyword("TEXT"),
24760 },
24761 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
24764 Some(DialectType::MySQL)
24765 | Some(DialectType::SingleStore)
24766 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24767 Some(DialectType::Spark)
24768 | Some(DialectType::Databricks)
24769 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
24770 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
24771 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24772 Some(DialectType::Presto)
24773 | Some(DialectType::Trino)
24774 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24775 Some(DialectType::Snowflake)
24776 | Some(DialectType::Redshift)
24777 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
24778 _ => self.write_keyword("BLOB"),
24779 },
24780 "LONGVARCHAR" => match self.config.dialect {
24782 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
24783 _ => self.write_keyword("VARCHAR"),
24784 },
24785 "DATETIME" => {
24787 match self.config.dialect {
24788 Some(DialectType::MySQL)
24789 | Some(DialectType::Doris)
24790 | Some(DialectType::StarRocks)
24791 | Some(DialectType::TSQL)
24792 | Some(DialectType::Fabric)
24793 | Some(DialectType::BigQuery)
24794 | Some(DialectType::SQLite)
24795 | Some(DialectType::Snowflake) => {
24796 self.write_keyword("DATETIME");
24797 if let Some(args) = _args_str {
24798 self.write(args);
24799 }
24800 }
24801 Some(_) => {
24802 self.write_keyword("TIMESTAMP");
24804 if let Some(args) = _args_str {
24805 self.write(args);
24806 }
24807 }
24808 None => {
24809 self.write(name);
24811 }
24812 }
24813 }
24814 "VARCHAR2"
24816 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24817 {
24818 match self.config.dialect {
24819 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24820 self.write_keyword("TEXT");
24821 }
24822 Some(DialectType::Hive)
24823 | Some(DialectType::Spark)
24824 | Some(DialectType::Databricks)
24825 | Some(DialectType::BigQuery)
24826 | Some(DialectType::ClickHouse)
24827 | Some(DialectType::StarRocks)
24828 | Some(DialectType::Doris) => {
24829 self.write_keyword("STRING");
24830 }
24831 _ => {
24832 self.write_keyword("VARCHAR");
24833 if let Some(args) = _args_str {
24834 self.write(args);
24835 }
24836 }
24837 }
24838 }
24839 "NVARCHAR2"
24840 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24841 {
24842 match self.config.dialect {
24843 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24844 self.write_keyword("TEXT");
24845 }
24846 Some(DialectType::Hive)
24847 | Some(DialectType::Spark)
24848 | Some(DialectType::Databricks)
24849 | Some(DialectType::BigQuery)
24850 | Some(DialectType::ClickHouse)
24851 | Some(DialectType::StarRocks)
24852 | Some(DialectType::Doris) => {
24853 self.write_keyword("STRING");
24854 }
24855 _ => {
24856 self.write_keyword("VARCHAR");
24857 if let Some(args) = _args_str {
24858 self.write(args);
24859 }
24860 }
24861 }
24862 }
24863 _ => self.write(name),
24864 }
24865 }
24866 }
24867 }
24868 DataType::Geometry { subtype, srid } => {
24869 match self.config.dialect {
24871 Some(DialectType::MySQL) => {
24872 if let Some(sub) = subtype {
24874 self.write_keyword(sub);
24875 if let Some(s) = srid {
24876 self.write(" SRID ");
24877 self.write(&s.to_string());
24878 }
24879 } else {
24880 self.write_keyword("GEOMETRY");
24881 }
24882 }
24883 Some(DialectType::BigQuery) => {
24884 self.write_keyword("GEOGRAPHY");
24886 }
24887 Some(DialectType::Teradata) => {
24888 self.write_keyword("ST_GEOMETRY");
24890 if subtype.is_some() || srid.is_some() {
24891 self.write("(");
24892 if let Some(sub) = subtype {
24893 self.write_keyword(sub);
24894 }
24895 if let Some(s) = srid {
24896 if subtype.is_some() {
24897 self.write(", ");
24898 }
24899 self.write(&s.to_string());
24900 }
24901 self.write(")");
24902 }
24903 }
24904 _ => {
24905 self.write_keyword("GEOMETRY");
24907 if subtype.is_some() || srid.is_some() {
24908 self.write("(");
24909 if let Some(sub) = subtype {
24910 self.write_keyword(sub);
24911 }
24912 if let Some(s) = srid {
24913 if subtype.is_some() {
24914 self.write(", ");
24915 }
24916 self.write(&s.to_string());
24917 }
24918 self.write(")");
24919 }
24920 }
24921 }
24922 }
24923 DataType::Geography { subtype, srid } => {
24924 match self.config.dialect {
24926 Some(DialectType::MySQL) => {
24927 if let Some(sub) = subtype {
24929 self.write_keyword(sub);
24930 } else {
24931 self.write_keyword("GEOMETRY");
24932 }
24933 let effective_srid = srid.unwrap_or(4326);
24935 self.write(" SRID ");
24936 self.write(&effective_srid.to_string());
24937 }
24938 Some(DialectType::BigQuery) => {
24939 self.write_keyword("GEOGRAPHY");
24941 }
24942 Some(DialectType::Snowflake) => {
24943 self.write_keyword("GEOGRAPHY");
24945 }
24946 _ => {
24947 self.write_keyword("GEOGRAPHY");
24949 if subtype.is_some() || srid.is_some() {
24950 self.write("(");
24951 if let Some(sub) = subtype {
24952 self.write_keyword(sub);
24953 }
24954 if let Some(s) = srid {
24955 if subtype.is_some() {
24956 self.write(", ");
24957 }
24958 self.write(&s.to_string());
24959 }
24960 self.write(")");
24961 }
24962 }
24963 }
24964 }
24965 DataType::CharacterSet { name } => {
24966 self.write_keyword("CHAR CHARACTER SET ");
24968 self.write(name);
24969 }
24970 _ => self.write("UNKNOWN"),
24971 }
24972 Ok(())
24973 }
24974
24975 #[inline]
24978 fn write(&mut self, s: &str) {
24979 self.output.push_str(s);
24980 }
24981
24982 #[inline]
24983 fn write_space(&mut self) {
24984 self.output.push(' ');
24985 }
24986
24987 #[inline]
24988 fn write_keyword(&mut self, keyword: &str) {
24989 if self.config.uppercase_keywords {
24990 self.output.push_str(keyword);
24991 } else {
24992 for b in keyword.bytes() {
24993 self.output.push(b.to_ascii_lowercase() as char);
24994 }
24995 }
24996 }
24997
24998 fn write_func_name(&mut self, name: &str) {
25000 let normalized = self.normalize_func_name(name);
25001 self.output.push_str(normalized.as_ref());
25002 }
25003
25004 fn convert_strptime_to_exasol_format(format: &str) -> String {
25008 let mut result = String::new();
25009 let chars: Vec<char> = format.chars().collect();
25010 let mut i = 0;
25011 while i < chars.len() {
25012 if chars[i] == '%' && i + 1 < chars.len() {
25013 let spec = chars[i + 1];
25014 let exasol_spec = match spec {
25015 'Y' => "YYYY",
25016 'y' => "YY",
25017 'm' => "MM",
25018 'd' => "DD",
25019 'H' => "HH",
25020 'M' => "MI",
25021 'S' => "SS",
25022 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
25034 result.push('%');
25036 result.push(spec);
25037 i += 2;
25038 continue;
25039 }
25040 };
25041 result.push_str(exasol_spec);
25042 i += 2;
25043 } else {
25044 result.push(chars[i]);
25045 i += 1;
25046 }
25047 }
25048 result
25049 }
25050
25051 fn convert_strptime_to_postgres_format(format: &str) -> String {
25055 let mut result = String::new();
25056 let chars: Vec<char> = format.chars().collect();
25057 let mut i = 0;
25058 while i < chars.len() {
25059 if chars[i] == '%' && i + 1 < chars.len() {
25060 if chars[i + 1] == '-' && i + 2 < chars.len() {
25062 let spec = chars[i + 2];
25063 let pg_spec = match spec {
25064 'd' => "FMDD",
25065 'm' => "FMMM",
25066 'H' => "FMHH24",
25067 'M' => "FMMI",
25068 'S' => "FMSS",
25069 _ => {
25070 result.push('%');
25071 result.push('-');
25072 result.push(spec);
25073 i += 3;
25074 continue;
25075 }
25076 };
25077 result.push_str(pg_spec);
25078 i += 3;
25079 continue;
25080 }
25081 let spec = chars[i + 1];
25082 let pg_spec = match spec {
25083 'Y' => "YYYY",
25084 'y' => "YY",
25085 'm' => "MM",
25086 'd' => "DD",
25087 'H' => "HH24",
25088 'I' => "HH12",
25089 'M' => "MI",
25090 'S' => "SS",
25091 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
25102 result.push('%');
25104 result.push(spec);
25105 i += 2;
25106 continue;
25107 }
25108 };
25109 result.push_str(pg_spec);
25110 i += 2;
25111 } else {
25112 result.push(chars[i]);
25113 i += 1;
25114 }
25115 }
25116 result
25117 }
25118
25119 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
25121 if self.config.limit_only_literals {
25122 if let Some(value) = Self::try_evaluate_constant(expr) {
25123 self.write(&value.to_string());
25124 return Ok(());
25125 }
25126 }
25127 self.generate_expression(expr)
25128 }
25129
25130 fn write_formatted_comment(&mut self, comment: &str) {
25134 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
25137 &comment[2..comment.len() - 2]
25140 } else if comment.starts_with("--") {
25141 &comment[2..]
25144 } else {
25145 comment
25147 };
25148 if content.trim().is_empty() {
25150 return;
25151 }
25152 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
25155 let content = &sanitized;
25156 self.output.push_str("/*");
25158 if !content.starts_with(' ') {
25159 self.output.push(' ');
25160 }
25161 self.output.push_str(content);
25162 if !content.ends_with(' ') {
25163 self.output.push(' ');
25164 }
25165 self.output.push_str("*/");
25166 }
25167
25168 fn escape_block_for_single_quote(&self, block: &str) -> String {
25171 let escape_backslash = matches!(
25172 self.config.dialect,
25173 Some(crate::dialects::DialectType::Snowflake)
25174 );
25175 let mut escaped = String::with_capacity(block.len() + 4);
25176 for ch in block.chars() {
25177 if ch == '\'' {
25178 escaped.push('\\');
25179 escaped.push('\'');
25180 } else if escape_backslash && ch == '\\' {
25181 escaped.push('\\');
25182 escaped.push('\\');
25183 } else {
25184 escaped.push(ch);
25185 }
25186 }
25187 escaped
25188 }
25189
25190 fn write_newline(&mut self) {
25191 self.output.push('\n');
25192 }
25193
25194 fn write_indent(&mut self) {
25195 for _ in 0..self.indent_level {
25196 self.output.push_str(self.config.indent);
25197 }
25198 }
25199
25200 fn too_wide(&self, args: &[String]) -> bool {
25206 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
25207 }
25208
25209 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
25212 let config = GeneratorConfig {
25213 pretty: false,
25214 dialect: self.config.dialect,
25215 ..Default::default()
25216 };
25217 let mut gen = Generator::with_config(config);
25218 gen.generate_expression(expr)?;
25219 Ok(gen.output)
25220 }
25221
25222 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
25225 if self.config.pretty {
25226 self.write_newline();
25227 self.write_indent();
25228 self.write_keyword(keyword);
25229 self.write_newline();
25230 self.indent_level += 1;
25231 self.write_indent();
25232 self.generate_expression(condition)?;
25233 self.indent_level -= 1;
25234 } else {
25235 self.write_space();
25236 self.write_keyword(keyword);
25237 self.write_space();
25238 self.generate_expression(condition)?;
25239 }
25240 Ok(())
25241 }
25242
25243 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
25246 if exprs.is_empty() {
25247 return Ok(());
25248 }
25249
25250 if self.config.pretty {
25251 self.write_newline();
25252 self.write_indent();
25253 self.write_keyword(keyword);
25254 self.write_newline();
25255 self.indent_level += 1;
25256 for (i, expr) in exprs.iter().enumerate() {
25257 if i > 0 {
25258 self.write(",");
25259 self.write_newline();
25260 }
25261 self.write_indent();
25262 self.generate_expression(expr)?;
25263 }
25264 self.indent_level -= 1;
25265 } else {
25266 self.write_space();
25267 self.write_keyword(keyword);
25268 self.write_space();
25269 for (i, expr) in exprs.iter().enumerate() {
25270 if i > 0 {
25271 self.write(", ");
25272 }
25273 self.generate_expression(expr)?;
25274 }
25275 }
25276 Ok(())
25277 }
25278
25279 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
25281 if orderings.is_empty() {
25282 return Ok(());
25283 }
25284
25285 if self.config.pretty {
25286 self.write_newline();
25287 self.write_indent();
25288 self.write_keyword(keyword);
25289 self.write_newline();
25290 self.indent_level += 1;
25291 for (i, ordered) in orderings.iter().enumerate() {
25292 if i > 0 {
25293 self.write(",");
25294 self.write_newline();
25295 }
25296 self.write_indent();
25297 self.generate_ordered(ordered)?;
25298 }
25299 self.indent_level -= 1;
25300 } else {
25301 self.write_space();
25302 self.write_keyword(keyword);
25303 self.write_space();
25304 for (i, ordered) in orderings.iter().enumerate() {
25305 if i > 0 {
25306 self.write(", ");
25307 }
25308 self.generate_ordered(ordered)?;
25309 }
25310 }
25311 Ok(())
25312 }
25313
25314 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
25316 if windows.is_empty() {
25317 return Ok(());
25318 }
25319
25320 if self.config.pretty {
25321 self.write_newline();
25322 self.write_indent();
25323 self.write_keyword("WINDOW");
25324 self.write_newline();
25325 self.indent_level += 1;
25326 for (i, named_window) in windows.iter().enumerate() {
25327 if i > 0 {
25328 self.write(",");
25329 self.write_newline();
25330 }
25331 self.write_indent();
25332 self.generate_identifier(&named_window.name)?;
25333 self.write_space();
25334 self.write_keyword("AS");
25335 self.write(" (");
25336 self.generate_over(&named_window.spec)?;
25337 self.write(")");
25338 }
25339 self.indent_level -= 1;
25340 } else {
25341 self.write_space();
25342 self.write_keyword("WINDOW");
25343 self.write_space();
25344 for (i, named_window) in windows.iter().enumerate() {
25345 if i > 0 {
25346 self.write(", ");
25347 }
25348 self.generate_identifier(&named_window.name)?;
25349 self.write_space();
25350 self.write_keyword("AS");
25351 self.write(" (");
25352 self.generate_over(&named_window.spec)?;
25353 self.write(")");
25354 }
25355 }
25356 Ok(())
25357 }
25358
25359 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
25361 self.write_keyword("AI_AGG");
25363 self.write("(");
25364 self.generate_expression(&e.this)?;
25365 self.write(", ");
25366 self.generate_expression(&e.expression)?;
25367 self.write(")");
25368 Ok(())
25369 }
25370
25371 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
25372 self.write_keyword("AI_CLASSIFY");
25374 self.write("(");
25375 self.generate_expression(&e.this)?;
25376 if let Some(categories) = &e.categories {
25377 self.write(", ");
25378 self.generate_expression(categories)?;
25379 }
25380 if let Some(config) = &e.config {
25381 self.write(", ");
25382 self.generate_expression(config)?;
25383 }
25384 self.write(")");
25385 Ok(())
25386 }
25387
25388 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
25389 self.write_keyword("ADD");
25391 self.write_space();
25392 if e.exists {
25393 self.write_keyword("IF NOT EXISTS");
25394 self.write_space();
25395 }
25396 self.generate_expression(&e.this)?;
25397 if let Some(location) = &e.location {
25398 self.write_space();
25399 self.generate_expression(location)?;
25400 }
25401 Ok(())
25402 }
25403
25404 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
25405 self.write_keyword("ALGORITHM");
25407 self.write("=");
25408 self.generate_expression(&e.this)?;
25409 Ok(())
25410 }
25411
25412 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
25413 self.generate_expression(&e.this)?;
25415 self.write_space();
25416 self.write_keyword("AS");
25417 self.write(" (");
25418 for (i, expr) in e.expressions.iter().enumerate() {
25419 if i > 0 {
25420 self.write(", ");
25421 }
25422 self.generate_expression(expr)?;
25423 }
25424 self.write(")");
25425 Ok(())
25426 }
25427
25428 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
25429 self.write_keyword("ALLOWED_VALUES");
25431 self.write_space();
25432 for (i, expr) in e.expressions.iter().enumerate() {
25433 if i > 0 {
25434 self.write(", ");
25435 }
25436 self.generate_expression(expr)?;
25437 }
25438 Ok(())
25439 }
25440
25441 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
25442 self.write_keyword("ALTER COLUMN");
25444 self.write_space();
25445 self.generate_expression(&e.this)?;
25446
25447 if let Some(dtype) = &e.dtype {
25448 self.write_space();
25449 self.write_keyword("SET DATA TYPE");
25450 self.write_space();
25451 self.generate_expression(dtype)?;
25452 if let Some(collate) = &e.collate {
25453 self.write_space();
25454 self.write_keyword("COLLATE");
25455 self.write_space();
25456 self.generate_expression(collate)?;
25457 }
25458 if let Some(using) = &e.using {
25459 self.write_space();
25460 self.write_keyword("USING");
25461 self.write_space();
25462 self.generate_expression(using)?;
25463 }
25464 } else if let Some(default) = &e.default {
25465 self.write_space();
25466 self.write_keyword("SET DEFAULT");
25467 self.write_space();
25468 self.generate_expression(default)?;
25469 } else if let Some(comment) = &e.comment {
25470 self.write_space();
25471 self.write_keyword("COMMENT");
25472 self.write_space();
25473 self.generate_expression(comment)?;
25474 } else if let Some(drop) = &e.drop {
25475 self.write_space();
25476 self.write_keyword("DROP");
25477 self.write_space();
25478 self.generate_expression(drop)?;
25479 } else if let Some(visible) = &e.visible {
25480 self.write_space();
25481 self.generate_expression(visible)?;
25482 } else if let Some(rename_to) = &e.rename_to {
25483 self.write_space();
25484 self.write_keyword("RENAME TO");
25485 self.write_space();
25486 self.generate_expression(rename_to)?;
25487 } else if let Some(allow_null) = &e.allow_null {
25488 self.write_space();
25489 self.generate_expression(allow_null)?;
25490 }
25491 Ok(())
25492 }
25493
25494 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
25495 self.write_keyword("ALTER SESSION");
25497 self.write_space();
25498 if e.unset.is_some() {
25499 self.write_keyword("UNSET");
25500 } else {
25501 self.write_keyword("SET");
25502 }
25503 self.write_space();
25504 for (i, expr) in e.expressions.iter().enumerate() {
25505 if i > 0 {
25506 self.write(", ");
25507 }
25508 self.generate_expression(expr)?;
25509 }
25510 Ok(())
25511 }
25512
25513 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
25514 self.write_keyword("SET");
25516
25517 if let Some(opt) = &e.option {
25519 self.write_space();
25520 self.generate_expression(opt)?;
25521 }
25522
25523 if !e.expressions.is_empty() {
25526 let is_properties = e
25528 .expressions
25529 .iter()
25530 .any(|expr| matches!(expr, Expression::Eq(_)));
25531 if is_properties && e.option.is_none() {
25532 self.write_space();
25533 self.write_keyword("PROPERTIES");
25534 }
25535 self.write_space();
25536 for (i, expr) in e.expressions.iter().enumerate() {
25537 if i > 0 {
25538 self.write(", ");
25539 }
25540 self.generate_expression(expr)?;
25541 }
25542 }
25543
25544 if let Some(file_format) = &e.file_format {
25546 self.write(" ");
25547 self.write_keyword("STAGE_FILE_FORMAT");
25548 self.write(" = (");
25549 self.generate_space_separated_properties(file_format)?;
25550 self.write(")");
25551 }
25552
25553 if let Some(copy_options) = &e.copy_options {
25555 self.write(" ");
25556 self.write_keyword("STAGE_COPY_OPTIONS");
25557 self.write(" = (");
25558 self.generate_space_separated_properties(copy_options)?;
25559 self.write(")");
25560 }
25561
25562 if let Some(tag) = &e.tag {
25564 self.write(" ");
25565 self.write_keyword("TAG");
25566 self.write(" ");
25567 self.generate_expression(tag)?;
25568 }
25569
25570 Ok(())
25571 }
25572
25573 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
25575 match expr {
25576 Expression::Tuple(t) => {
25577 for (i, prop) in t.expressions.iter().enumerate() {
25578 if i > 0 {
25579 self.write(" ");
25580 }
25581 self.generate_expression(prop)?;
25582 }
25583 }
25584 _ => {
25585 self.generate_expression(expr)?;
25586 }
25587 }
25588 Ok(())
25589 }
25590
25591 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
25592 self.write_keyword("ALTER");
25594 if e.compound.is_some() {
25595 self.write_space();
25596 self.write_keyword("COMPOUND");
25597 }
25598 self.write_space();
25599 self.write_keyword("SORTKEY");
25600 self.write_space();
25601 if let Some(this) = &e.this {
25602 self.generate_expression(this)?;
25603 } else if !e.expressions.is_empty() {
25604 self.write("(");
25605 for (i, expr) in e.expressions.iter().enumerate() {
25606 if i > 0 {
25607 self.write(", ");
25608 }
25609 self.generate_expression(expr)?;
25610 }
25611 self.write(")");
25612 }
25613 Ok(())
25614 }
25615
25616 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
25617 self.write_keyword("ANALYZE");
25619 if !e.options.is_empty() {
25620 self.write_space();
25621 for (i, opt) in e.options.iter().enumerate() {
25622 if i > 0 {
25623 self.write_space();
25624 }
25625 if let Expression::Identifier(id) = opt {
25627 self.write_keyword(&id.name);
25628 } else {
25629 self.generate_expression(opt)?;
25630 }
25631 }
25632 }
25633 if let Some(kind) = &e.kind {
25634 self.write_space();
25635 self.write_keyword(kind);
25636 }
25637 if let Some(this) = &e.this {
25638 self.write_space();
25639 self.generate_expression(this)?;
25640 }
25641 if !e.columns.is_empty() {
25643 self.write("(");
25644 for (i, col) in e.columns.iter().enumerate() {
25645 if i > 0 {
25646 self.write(", ");
25647 }
25648 self.write(col);
25649 }
25650 self.write(")");
25651 }
25652 if let Some(partition) = &e.partition {
25653 self.write_space();
25654 self.generate_expression(partition)?;
25655 }
25656 if let Some(mode) = &e.mode {
25657 self.write_space();
25658 self.generate_expression(mode)?;
25659 }
25660 if let Some(expression) = &e.expression {
25661 self.write_space();
25662 self.generate_expression(expression)?;
25663 }
25664 if !e.properties.is_empty() {
25665 self.write_space();
25666 self.write_keyword(self.config.with_properties_prefix);
25667 self.write(" (");
25668 for (i, prop) in e.properties.iter().enumerate() {
25669 if i > 0 {
25670 self.write(", ");
25671 }
25672 self.generate_expression(prop)?;
25673 }
25674 self.write(")");
25675 }
25676 Ok(())
25677 }
25678
25679 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
25680 self.write_keyword("DELETE");
25682 if let Some(kind) = &e.kind {
25683 self.write_space();
25684 self.write_keyword(kind);
25685 }
25686 self.write_space();
25687 self.write_keyword("STATISTICS");
25688 Ok(())
25689 }
25690
25691 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
25692 if let Expression::Identifier(id) = e.this.as_ref() {
25695 self.write_keyword(&id.name);
25696 } else {
25697 self.generate_expression(&e.this)?;
25698 }
25699 self.write_space();
25700 self.write_keyword("HISTOGRAM ON");
25701 self.write_space();
25702 for (i, expr) in e.expressions.iter().enumerate() {
25703 if i > 0 {
25704 self.write(", ");
25705 }
25706 self.generate_expression(expr)?;
25707 }
25708 if let Some(expression) = &e.expression {
25709 self.write_space();
25710 self.generate_expression(expression)?;
25711 }
25712 if let Some(update_options) = &e.update_options {
25713 self.write_space();
25714 self.generate_expression(update_options)?;
25715 self.write_space();
25716 self.write_keyword("UPDATE");
25717 }
25718 Ok(())
25719 }
25720
25721 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
25722 self.write_keyword("LIST CHAINED ROWS");
25724 if let Some(expression) = &e.expression {
25725 self.write_space();
25726 self.write_keyword("INTO");
25727 self.write_space();
25728 self.generate_expression(expression)?;
25729 }
25730 Ok(())
25731 }
25732
25733 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
25734 self.write_keyword("SAMPLE");
25736 self.write_space();
25737 if let Some(sample) = &e.sample {
25738 self.generate_expression(sample)?;
25739 self.write_space();
25740 }
25741 self.write_keyword(&e.kind);
25742 Ok(())
25743 }
25744
25745 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
25746 self.write_keyword(&e.kind);
25748 if let Some(option) = &e.option {
25749 self.write_space();
25750 self.generate_expression(option)?;
25751 }
25752 self.write_space();
25753 self.write_keyword("STATISTICS");
25754 if let Some(this) = &e.this {
25755 self.write_space();
25756 self.generate_expression(this)?;
25757 }
25758 if !e.expressions.is_empty() {
25759 self.write_space();
25760 for (i, expr) in e.expressions.iter().enumerate() {
25761 if i > 0 {
25762 self.write(", ");
25763 }
25764 self.generate_expression(expr)?;
25765 }
25766 }
25767 Ok(())
25768 }
25769
25770 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
25771 self.write_keyword("VALIDATE");
25773 self.write_space();
25774 self.write_keyword(&e.kind);
25775 if let Some(this) = &e.this {
25776 self.write_space();
25777 if let Expression::Identifier(id) = this.as_ref() {
25779 self.write_keyword(&id.name);
25780 } else {
25781 self.generate_expression(this)?;
25782 }
25783 }
25784 if let Some(expression) = &e.expression {
25785 self.write_space();
25786 self.write_keyword("INTO");
25787 self.write_space();
25788 self.generate_expression(expression)?;
25789 }
25790 Ok(())
25791 }
25792
25793 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
25794 self.write_keyword("WITH");
25796 self.write_space();
25797 for (i, expr) in e.expressions.iter().enumerate() {
25798 if i > 0 {
25799 self.write(", ");
25800 }
25801 self.generate_expression(expr)?;
25802 }
25803 Ok(())
25804 }
25805
25806 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
25807 self.generate_expression(&e.this)?;
25810 self.write("(");
25811 for (i, arg) in e.expressions.iter().enumerate() {
25812 if i > 0 {
25813 self.write(", ");
25814 }
25815 self.generate_expression(arg)?;
25816 }
25817 self.write(")");
25818 Ok(())
25819 }
25820
25821 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
25822 self.generate_expression(&e.this)?;
25824 self.write("(");
25825 for (i, arg) in e.expressions.iter().enumerate() {
25826 if i > 0 {
25827 self.write(", ");
25828 }
25829 self.generate_expression(arg)?;
25830 }
25831 self.write(")");
25832 Ok(())
25833 }
25834
25835 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
25836 self.generate_expression(&e.this)?;
25838 self.write_space();
25839 self.write_keyword("APPLY");
25840 self.write("(");
25841 self.generate_expression(&e.expression)?;
25842 self.write(")");
25843 Ok(())
25844 }
25845
25846 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
25847 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
25849 self.write("(");
25850 self.generate_expression(&e.this)?;
25851 if let Some(percentile) = &e.percentile {
25852 self.write(", ");
25853 self.generate_expression(percentile)?;
25854 }
25855 self.write(")");
25856 Ok(())
25857 }
25858
25859 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
25860 self.write_keyword("APPROX_QUANTILE");
25862 self.write("(");
25863 self.generate_expression(&e.this)?;
25864 if let Some(quantile) = &e.quantile {
25865 self.write(", ");
25866 self.generate_expression(quantile)?;
25867 }
25868 if let Some(accuracy) = &e.accuracy {
25869 self.write(", ");
25870 self.generate_expression(accuracy)?;
25871 }
25872 if let Some(weight) = &e.weight {
25873 self.write(", ");
25874 self.generate_expression(weight)?;
25875 }
25876 self.write(")");
25877 Ok(())
25878 }
25879
25880 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
25881 self.write_keyword("APPROX_QUANTILES");
25883 self.write("(");
25884 self.generate_expression(&e.this)?;
25885 if let Some(expression) = &e.expression {
25886 self.write(", ");
25887 self.generate_expression(expression)?;
25888 }
25889 self.write(")");
25890 Ok(())
25891 }
25892
25893 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
25894 self.write_keyword("APPROX_TOP_K");
25896 self.write("(");
25897 self.generate_expression(&e.this)?;
25898 if let Some(expression) = &e.expression {
25899 self.write(", ");
25900 self.generate_expression(expression)?;
25901 }
25902 if let Some(counters) = &e.counters {
25903 self.write(", ");
25904 self.generate_expression(counters)?;
25905 }
25906 self.write(")");
25907 Ok(())
25908 }
25909
25910 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
25911 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
25913 self.write("(");
25914 self.generate_expression(&e.this)?;
25915 if let Some(expression) = &e.expression {
25916 self.write(", ");
25917 self.generate_expression(expression)?;
25918 }
25919 self.write(")");
25920 Ok(())
25921 }
25922
25923 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
25924 self.write_keyword("APPROX_TOP_K_COMBINE");
25926 self.write("(");
25927 self.generate_expression(&e.this)?;
25928 if let Some(expression) = &e.expression {
25929 self.write(", ");
25930 self.generate_expression(expression)?;
25931 }
25932 self.write(")");
25933 Ok(())
25934 }
25935
25936 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
25937 self.write_keyword("APPROX_TOP_K_ESTIMATE");
25939 self.write("(");
25940 self.generate_expression(&e.this)?;
25941 if let Some(expression) = &e.expression {
25942 self.write(", ");
25943 self.generate_expression(expression)?;
25944 }
25945 self.write(")");
25946 Ok(())
25947 }
25948
25949 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
25950 self.write_keyword("APPROX_TOP_SUM");
25952 self.write("(");
25953 self.generate_expression(&e.this)?;
25954 self.write(", ");
25955 self.generate_expression(&e.expression)?;
25956 if let Some(count) = &e.count {
25957 self.write(", ");
25958 self.generate_expression(count)?;
25959 }
25960 self.write(")");
25961 Ok(())
25962 }
25963
25964 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
25965 self.write_keyword("ARG_MAX");
25967 self.write("(");
25968 self.generate_expression(&e.this)?;
25969 self.write(", ");
25970 self.generate_expression(&e.expression)?;
25971 if let Some(count) = &e.count {
25972 self.write(", ");
25973 self.generate_expression(count)?;
25974 }
25975 self.write(")");
25976 Ok(())
25977 }
25978
25979 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
25980 self.write_keyword("ARG_MIN");
25982 self.write("(");
25983 self.generate_expression(&e.this)?;
25984 self.write(", ");
25985 self.generate_expression(&e.expression)?;
25986 if let Some(count) = &e.count {
25987 self.write(", ");
25988 self.generate_expression(count)?;
25989 }
25990 self.write(")");
25991 Ok(())
25992 }
25993
25994 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
25995 self.write_keyword("ARRAY_ALL");
25997 self.write("(");
25998 self.generate_expression(&e.this)?;
25999 self.write(", ");
26000 self.generate_expression(&e.expression)?;
26001 self.write(")");
26002 Ok(())
26003 }
26004
26005 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
26006 self.write_keyword("ARRAY_ANY");
26008 self.write("(");
26009 self.generate_expression(&e.this)?;
26010 self.write(", ");
26011 self.generate_expression(&e.expression)?;
26012 self.write(")");
26013 Ok(())
26014 }
26015
26016 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
26017 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
26019 self.write("(");
26020 for (i, expr) in e.expressions.iter().enumerate() {
26021 if i > 0 {
26022 self.write(", ");
26023 }
26024 self.generate_expression(expr)?;
26025 }
26026 self.write(")");
26027 Ok(())
26028 }
26029
26030 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
26031 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
26033 self.write("arraySum");
26034 } else {
26035 self.write_keyword("ARRAY_SUM");
26036 }
26037 self.write("(");
26038 self.generate_expression(&e.this)?;
26039 if let Some(expression) = &e.expression {
26040 self.write(", ");
26041 self.generate_expression(expression)?;
26042 }
26043 self.write(")");
26044 Ok(())
26045 }
26046
26047 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
26048 self.generate_expression(&e.this)?;
26050 self.write_space();
26051 self.write_keyword("AT");
26052 self.write_space();
26053 self.generate_expression(&e.expression)?;
26054 Ok(())
26055 }
26056
26057 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
26058 self.write_keyword("ATTACH");
26060 if e.exists {
26061 self.write_space();
26062 self.write_keyword("IF NOT EXISTS");
26063 }
26064 self.write_space();
26065 self.generate_expression(&e.this)?;
26066 if !e.expressions.is_empty() {
26067 self.write(" (");
26068 for (i, expr) in e.expressions.iter().enumerate() {
26069 if i > 0 {
26070 self.write(", ");
26071 }
26072 self.generate_expression(expr)?;
26073 }
26074 self.write(")");
26075 }
26076 Ok(())
26077 }
26078
26079 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
26080 self.generate_expression(&e.this)?;
26083 if let Some(expression) = &e.expression {
26084 self.write_space();
26085 self.generate_expression(expression)?;
26086 }
26087 Ok(())
26088 }
26089
26090 fn generate_auto_increment_keyword(
26094 &mut self,
26095 col: &crate::expressions::ColumnDef,
26096 ) -> Result<()> {
26097 use crate::dialects::DialectType;
26098 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
26099 self.write_keyword("IDENTITY");
26100 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26101 self.write("(");
26102 if let Some(ref start) = col.auto_increment_start {
26103 self.generate_expression(start)?;
26104 } else {
26105 self.write("0");
26106 }
26107 self.write(", ");
26108 if let Some(ref inc) = col.auto_increment_increment {
26109 self.generate_expression(inc)?;
26110 } else {
26111 self.write("1");
26112 }
26113 self.write(")");
26114 }
26115 } else if matches!(
26116 self.config.dialect,
26117 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
26118 ) {
26119 self.write_keyword("AUTOINCREMENT");
26120 if let Some(ref start) = col.auto_increment_start {
26121 self.write_space();
26122 self.write_keyword("START");
26123 self.write_space();
26124 self.generate_expression(start)?;
26125 }
26126 if let Some(ref inc) = col.auto_increment_increment {
26127 self.write_space();
26128 self.write_keyword("INCREMENT");
26129 self.write_space();
26130 self.generate_expression(inc)?;
26131 }
26132 if let Some(order) = col.auto_increment_order {
26133 self.write_space();
26134 if order {
26135 self.write_keyword("ORDER");
26136 } else {
26137 self.write_keyword("NOORDER");
26138 }
26139 }
26140 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
26141 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26142 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26143 self.write(" (");
26144 let mut first = true;
26145 if let Some(ref start) = col.auto_increment_start {
26146 self.write_keyword("START WITH");
26147 self.write_space();
26148 self.generate_expression(start)?;
26149 first = false;
26150 }
26151 if let Some(ref inc) = col.auto_increment_increment {
26152 if !first {
26153 self.write_space();
26154 }
26155 self.write_keyword("INCREMENT BY");
26156 self.write_space();
26157 self.generate_expression(inc)?;
26158 }
26159 self.write(")");
26160 }
26161 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
26162 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26165 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
26166 } else {
26167 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
26168 }
26169 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26170 self.write(" (");
26171 let mut first = true;
26172 if let Some(ref start) = col.auto_increment_start {
26173 self.write_keyword("START WITH");
26174 self.write_space();
26175 self.generate_expression(start)?;
26176 first = false;
26177 }
26178 if let Some(ref inc) = col.auto_increment_increment {
26179 if !first {
26180 self.write_space();
26181 }
26182 self.write_keyword("INCREMENT BY");
26183 self.write_space();
26184 self.generate_expression(inc)?;
26185 }
26186 self.write(")");
26187 }
26188 } else if matches!(
26189 self.config.dialect,
26190 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26191 ) {
26192 self.write_keyword("IDENTITY");
26193 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
26194 self.write("(");
26195 if let Some(ref start) = col.auto_increment_start {
26196 self.generate_expression(start)?;
26197 } else {
26198 self.write("0");
26199 }
26200 self.write(", ");
26201 if let Some(ref inc) = col.auto_increment_increment {
26202 self.generate_expression(inc)?;
26203 } else {
26204 self.write("1");
26205 }
26206 self.write(")");
26207 }
26208 } else {
26209 self.write_keyword("AUTO_INCREMENT");
26210 if let Some(ref start) = col.auto_increment_start {
26211 self.write_space();
26212 self.write_keyword("START");
26213 self.write_space();
26214 self.generate_expression(start)?;
26215 }
26216 if let Some(ref inc) = col.auto_increment_increment {
26217 self.write_space();
26218 self.write_keyword("INCREMENT");
26219 self.write_space();
26220 self.generate_expression(inc)?;
26221 }
26222 if let Some(order) = col.auto_increment_order {
26223 self.write_space();
26224 if order {
26225 self.write_keyword("ORDER");
26226 } else {
26227 self.write_keyword("NOORDER");
26228 }
26229 }
26230 }
26231 Ok(())
26232 }
26233
26234 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
26235 self.write_keyword("AUTO_INCREMENT");
26237 self.write("=");
26238 self.generate_expression(&e.this)?;
26239 Ok(())
26240 }
26241
26242 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
26243 self.write_keyword("AUTO_REFRESH");
26245 self.write("=");
26246 self.generate_expression(&e.this)?;
26247 Ok(())
26248 }
26249
26250 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
26251 self.write_keyword("BACKUP");
26253 self.write_space();
26254 self.generate_expression(&e.this)?;
26255 Ok(())
26256 }
26257
26258 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
26259 self.write_keyword("BASE64_DECODE_BINARY");
26261 self.write("(");
26262 self.generate_expression(&e.this)?;
26263 if let Some(alphabet) = &e.alphabet {
26264 self.write(", ");
26265 self.generate_expression(alphabet)?;
26266 }
26267 self.write(")");
26268 Ok(())
26269 }
26270
26271 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
26272 self.write_keyword("BASE64_DECODE_STRING");
26274 self.write("(");
26275 self.generate_expression(&e.this)?;
26276 if let Some(alphabet) = &e.alphabet {
26277 self.write(", ");
26278 self.generate_expression(alphabet)?;
26279 }
26280 self.write(")");
26281 Ok(())
26282 }
26283
26284 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
26285 self.write_keyword("BASE64_ENCODE");
26287 self.write("(");
26288 self.generate_expression(&e.this)?;
26289 if let Some(max_line_length) = &e.max_line_length {
26290 self.write(", ");
26291 self.generate_expression(max_line_length)?;
26292 }
26293 if let Some(alphabet) = &e.alphabet {
26294 self.write(", ");
26295 self.generate_expression(alphabet)?;
26296 }
26297 self.write(")");
26298 Ok(())
26299 }
26300
26301 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
26302 self.write_keyword("BLOCKCOMPRESSION");
26304 self.write("=");
26305 if let Some(autotemp) = &e.autotemp {
26306 self.write_keyword("AUTOTEMP");
26307 self.write("(");
26308 self.generate_expression(autotemp)?;
26309 self.write(")");
26310 }
26311 if let Some(always) = &e.always {
26312 self.generate_expression(always)?;
26313 }
26314 if let Some(default) = &e.default {
26315 self.generate_expression(default)?;
26316 }
26317 if let Some(manual) = &e.manual {
26318 self.generate_expression(manual)?;
26319 }
26320 if let Some(never) = &e.never {
26321 self.generate_expression(never)?;
26322 }
26323 Ok(())
26324 }
26325
26326 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
26327 self.write("((");
26329 self.generate_expression(&e.this)?;
26330 self.write(") ");
26331 self.write_keyword("AND");
26332 self.write(" (");
26333 self.generate_expression(&e.expression)?;
26334 self.write("))");
26335 Ok(())
26336 }
26337
26338 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
26339 self.write("((");
26341 self.generate_expression(&e.this)?;
26342 self.write(") ");
26343 self.write_keyword("OR");
26344 self.write(" (");
26345 self.generate_expression(&e.expression)?;
26346 self.write("))");
26347 Ok(())
26348 }
26349
26350 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
26351 self.write_keyword("BUILD");
26353 self.write_space();
26354 self.generate_expression(&e.this)?;
26355 Ok(())
26356 }
26357
26358 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
26359 self.generate_expression(&e.this)?;
26361 Ok(())
26362 }
26363
26364 fn generate_case_specific_column_constraint(
26365 &mut self,
26366 e: &CaseSpecificColumnConstraint,
26367 ) -> Result<()> {
26368 if e.not_.is_some() {
26370 self.write_keyword("NOT");
26371 self.write_space();
26372 }
26373 self.write_keyword("CASESPECIFIC");
26374 Ok(())
26375 }
26376
26377 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
26378 self.write_keyword("CAST");
26380 self.write("(");
26381 self.generate_expression(&e.this)?;
26382 if self.config.dialect == Some(DialectType::ClickHouse) {
26383 self.write(", ");
26385 } else {
26386 self.write_space();
26387 self.write_keyword("AS");
26388 self.write_space();
26389 }
26390 if let Some(to) = &e.to {
26391 self.generate_expression(to)?;
26392 }
26393 self.write(")");
26394 Ok(())
26395 }
26396
26397 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
26398 self.write_keyword("CHANGES");
26401 self.write(" (");
26402 if let Some(information) = &e.information {
26403 self.write_keyword("INFORMATION");
26404 self.write(" => ");
26405 self.generate_expression(information)?;
26406 }
26407 self.write(")");
26408 if let Some(at_before) = &e.at_before {
26410 self.write(" ");
26411 self.generate_expression(at_before)?;
26412 }
26413 if let Some(end) = &e.end {
26414 self.write(" ");
26415 self.generate_expression(end)?;
26416 }
26417 Ok(())
26418 }
26419
26420 fn generate_character_set_column_constraint(
26421 &mut self,
26422 e: &CharacterSetColumnConstraint,
26423 ) -> Result<()> {
26424 self.write_keyword("CHARACTER SET");
26426 self.write_space();
26427 self.generate_expression(&e.this)?;
26428 Ok(())
26429 }
26430
26431 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
26432 if e.default.is_some() {
26434 self.write_keyword("DEFAULT");
26435 self.write_space();
26436 }
26437 self.write_keyword("CHARACTER SET");
26438 self.write("=");
26439 self.generate_expression(&e.this)?;
26440 Ok(())
26441 }
26442
26443 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
26444 self.write_keyword("CHECK");
26446 self.write(" (");
26447 self.generate_expression(&e.this)?;
26448 self.write(")");
26449 if e.enforced.is_some() {
26450 self.write_space();
26451 self.write_keyword("ENFORCED");
26452 }
26453 Ok(())
26454 }
26455
26456 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
26457 self.write_keyword("ASSUME");
26459 self.write(" (");
26460 self.generate_expression(&e.this)?;
26461 self.write(")");
26462 Ok(())
26463 }
26464
26465 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
26466 self.write_keyword("CHECK_JSON");
26468 self.write("(");
26469 self.generate_expression(&e.this)?;
26470 self.write(")");
26471 Ok(())
26472 }
26473
26474 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
26475 self.write_keyword("CHECK_XML");
26477 self.write("(");
26478 self.generate_expression(&e.this)?;
26479 self.write(")");
26480 Ok(())
26481 }
26482
26483 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
26484 self.write_keyword("CHECKSUM");
26486 self.write("=");
26487 if e.on.is_some() {
26488 self.write_keyword("ON");
26489 } else if e.default.is_some() {
26490 self.write_keyword("DEFAULT");
26491 } else {
26492 self.write_keyword("OFF");
26493 }
26494 Ok(())
26495 }
26496
26497 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
26498 if e.shallow.is_some() {
26500 self.write_keyword("SHALLOW");
26501 self.write_space();
26502 }
26503 if e.copy.is_some() {
26504 self.write_keyword("COPY");
26505 } else {
26506 self.write_keyword("CLONE");
26507 }
26508 self.write_space();
26509 self.generate_expression(&e.this)?;
26510 Ok(())
26511 }
26512
26513 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
26514 self.write_keyword("CLUSTER BY");
26516 self.write(" (");
26517 for (i, ord) in e.expressions.iter().enumerate() {
26518 if i > 0 {
26519 self.write(", ");
26520 }
26521 self.generate_ordered(ord)?;
26522 }
26523 self.write(")");
26524 Ok(())
26525 }
26526
26527 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
26528 self.write_keyword("CLUSTER BY");
26530 self.write_space();
26531 for (i, col) in e.columns.iter().enumerate() {
26532 if i > 0 {
26533 self.write(", ");
26534 }
26535 self.generate_identifier(col)?;
26536 }
26537 Ok(())
26538 }
26539
26540 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
26541 self.write_keyword("CLUSTERED BY");
26543 self.write(" (");
26544 for (i, expr) in e.expressions.iter().enumerate() {
26545 if i > 0 {
26546 self.write(", ");
26547 }
26548 self.generate_expression(expr)?;
26549 }
26550 self.write(")");
26551 if let Some(sorted_by) = &e.sorted_by {
26552 self.write_space();
26553 self.write_keyword("SORTED BY");
26554 self.write(" (");
26555 if let Expression::Tuple(t) = sorted_by.as_ref() {
26557 for (i, expr) in t.expressions.iter().enumerate() {
26558 if i > 0 {
26559 self.write(", ");
26560 }
26561 self.generate_expression(expr)?;
26562 }
26563 } else {
26564 self.generate_expression(sorted_by)?;
26565 }
26566 self.write(")");
26567 }
26568 if let Some(buckets) = &e.buckets {
26569 self.write_space();
26570 self.write_keyword("INTO");
26571 self.write_space();
26572 self.generate_expression(buckets)?;
26573 self.write_space();
26574 self.write_keyword("BUCKETS");
26575 }
26576 Ok(())
26577 }
26578
26579 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
26580 if e.default.is_some() {
26584 self.write_keyword("DEFAULT");
26585 self.write_space();
26586 }
26587 self.write_keyword("COLLATE");
26588 match self.config.dialect {
26590 Some(DialectType::BigQuery) => self.write_space(),
26591 _ => self.write("="),
26592 }
26593 self.generate_expression(&e.this)?;
26594 Ok(())
26595 }
26596
26597 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
26598 match e {
26600 ColumnConstraint::NotNull => {
26601 self.write_keyword("NOT NULL");
26602 }
26603 ColumnConstraint::Null => {
26604 self.write_keyword("NULL");
26605 }
26606 ColumnConstraint::Unique => {
26607 self.write_keyword("UNIQUE");
26608 }
26609 ColumnConstraint::PrimaryKey => {
26610 self.write_keyword("PRIMARY KEY");
26611 }
26612 ColumnConstraint::Default(expr) => {
26613 self.write_keyword("DEFAULT");
26614 self.write_space();
26615 self.generate_expression(expr)?;
26616 }
26617 ColumnConstraint::Check(expr) => {
26618 self.write_keyword("CHECK");
26619 self.write(" (");
26620 self.generate_expression(expr)?;
26621 self.write(")");
26622 }
26623 ColumnConstraint::References(fk_ref) => {
26624 if fk_ref.has_foreign_key_keywords {
26625 self.write_keyword("FOREIGN KEY");
26626 self.write_space();
26627 }
26628 self.write_keyword("REFERENCES");
26629 self.write_space();
26630 self.generate_table(&fk_ref.table)?;
26631 if !fk_ref.columns.is_empty() {
26632 self.write(" (");
26633 for (i, col) in fk_ref.columns.iter().enumerate() {
26634 if i > 0 {
26635 self.write(", ");
26636 }
26637 self.generate_identifier(col)?;
26638 }
26639 self.write(")");
26640 }
26641 }
26642 ColumnConstraint::GeneratedAsIdentity(gen) => {
26643 self.write_keyword("GENERATED");
26644 self.write_space();
26645 if gen.always {
26646 self.write_keyword("ALWAYS");
26647 } else {
26648 self.write_keyword("BY DEFAULT");
26649 if gen.on_null {
26650 self.write_space();
26651 self.write_keyword("ON NULL");
26652 }
26653 }
26654 self.write_space();
26655 self.write_keyword("AS IDENTITY");
26656 }
26657 ColumnConstraint::Collate(collation) => {
26658 self.write_keyword("COLLATE");
26659 self.write_space();
26660 self.generate_identifier(collation)?;
26661 }
26662 ColumnConstraint::Comment(comment) => {
26663 self.write_keyword("COMMENT");
26664 self.write(" '");
26665 self.write(comment);
26666 self.write("'");
26667 }
26668 ColumnConstraint::ComputedColumn(cc) => {
26669 self.generate_computed_column_inline(cc)?;
26670 }
26671 ColumnConstraint::GeneratedAsRow(gar) => {
26672 self.generate_generated_as_row_inline(gar)?;
26673 }
26674 ColumnConstraint::Tags(tags) => {
26675 self.write_keyword("TAG");
26676 self.write(" (");
26677 for (i, expr) in tags.expressions.iter().enumerate() {
26678 if i > 0 {
26679 self.write(", ");
26680 }
26681 self.generate_expression(expr)?;
26682 }
26683 self.write(")");
26684 }
26685 ColumnConstraint::Path(path_expr) => {
26686 self.write_keyword("PATH");
26687 self.write_space();
26688 self.generate_expression(path_expr)?;
26689 }
26690 }
26691 Ok(())
26692 }
26693
26694 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
26695 match e {
26697 ColumnPosition::First => {
26698 self.write_keyword("FIRST");
26699 }
26700 ColumnPosition::After(ident) => {
26701 self.write_keyword("AFTER");
26702 self.write_space();
26703 self.generate_identifier(ident)?;
26704 }
26705 }
26706 Ok(())
26707 }
26708
26709 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
26710 self.generate_expression(&e.this)?;
26712 self.write("(");
26713 self.generate_expression(&e.expression)?;
26714 self.write(")");
26715 Ok(())
26716 }
26717
26718 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
26719 if let Some(ref unpack) = e.unpack {
26722 if let Expression::Boolean(b) = unpack.as_ref() {
26723 if b.value {
26724 self.write("*");
26725 }
26726 }
26727 }
26728 self.write_keyword("COLUMNS");
26729 self.write("(");
26730 self.generate_expression(&e.this)?;
26731 self.write(")");
26732 Ok(())
26733 }
26734
26735 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
26736 self.generate_expression(&e.this)?;
26738 self.write("(");
26739 for (i, expr) in e.expressions.iter().enumerate() {
26740 if i > 0 {
26741 self.write(", ");
26742 }
26743 self.generate_expression(expr)?;
26744 }
26745 self.write(")");
26746 Ok(())
26747 }
26748
26749 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
26750 self.generate_expression(&e.this)?;
26752 self.write("(");
26753 for (i, param) in e.params.iter().enumerate() {
26754 if i > 0 {
26755 self.write(", ");
26756 }
26757 self.generate_expression(param)?;
26758 }
26759 self.write(")(");
26760 for (i, expr) in e.expressions.iter().enumerate() {
26761 if i > 0 {
26762 self.write(", ");
26763 }
26764 self.generate_expression(expr)?;
26765 }
26766 self.write(")");
26767 Ok(())
26768 }
26769
26770 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
26771 self.write_keyword("COMMIT");
26773
26774 if e.this.is_none()
26776 && matches!(
26777 self.config.dialect,
26778 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26779 )
26780 {
26781 self.write_space();
26782 self.write_keyword("TRANSACTION");
26783 }
26784
26785 if let Some(this) = &e.this {
26787 let is_transaction_marker = matches!(
26789 this.as_ref(),
26790 Expression::Identifier(id) if id.name == "TRANSACTION"
26791 );
26792
26793 self.write_space();
26794 self.write_keyword("TRANSACTION");
26795
26796 if !is_transaction_marker {
26798 self.write_space();
26799 self.generate_expression(this)?;
26800 }
26801 }
26802
26803 if let Some(durability) = &e.durability {
26805 self.write_space();
26806 self.write_keyword("WITH");
26807 self.write(" (");
26808 self.write_keyword("DELAYED_DURABILITY");
26809 self.write(" = ");
26810 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
26811 self.write_keyword("ON");
26812 } else {
26813 self.write_keyword("OFF");
26814 }
26815 self.write(")");
26816 }
26817
26818 if let Some(chain) = &e.chain {
26820 self.write_space();
26821 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
26822 self.write_keyword("AND NO CHAIN");
26823 } else {
26824 self.write_keyword("AND CHAIN");
26825 }
26826 }
26827 Ok(())
26828 }
26829
26830 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
26831 self.write("[");
26833 self.generate_expression(&e.this)?;
26834 self.write_space();
26835 self.write_keyword("FOR");
26836 self.write_space();
26837 self.generate_expression(&e.expression)?;
26838 if let Some(pos) = &e.position {
26840 self.write(", ");
26841 self.generate_expression(pos)?;
26842 }
26843 if let Some(iterator) = &e.iterator {
26844 self.write_space();
26845 self.write_keyword("IN");
26846 self.write_space();
26847 self.generate_expression(iterator)?;
26848 }
26849 if let Some(condition) = &e.condition {
26850 self.write_space();
26851 self.write_keyword("IF");
26852 self.write_space();
26853 self.generate_expression(condition)?;
26854 }
26855 self.write("]");
26856 Ok(())
26857 }
26858
26859 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
26860 self.write_keyword("COMPRESS");
26862 self.write("(");
26863 self.generate_expression(&e.this)?;
26864 if let Some(method) = &e.method {
26865 self.write(", '");
26866 self.write(method);
26867 self.write("'");
26868 }
26869 self.write(")");
26870 Ok(())
26871 }
26872
26873 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
26874 self.write_keyword("COMPRESS");
26876 if let Some(this) = &e.this {
26877 self.write_space();
26878 self.generate_expression(this)?;
26879 }
26880 Ok(())
26881 }
26882
26883 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
26884 self.write_keyword("AS");
26886 self.write_space();
26887 self.generate_expression(&e.this)?;
26888 if e.not_null.is_some() {
26889 self.write_space();
26890 self.write_keyword("PERSISTED NOT NULL");
26891 } else if e.persisted.is_some() {
26892 self.write_space();
26893 self.write_keyword("PERSISTED");
26894 }
26895 Ok(())
26896 }
26897
26898 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
26902 let computed_expr = if matches!(
26903 self.config.dialect,
26904 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26905 ) {
26906 match &*cc.expression {
26907 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26908 {
26909 let wrapped = Expression::Cast(Box::new(Cast {
26910 this: y.this.clone(),
26911 to: DataType::Date,
26912 trailing_comments: Vec::new(),
26913 double_colon_syntax: false,
26914 format: None,
26915 default: None,
26916 inferred_type: None,
26917 }));
26918 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
26919 }
26920 Expression::Function(f)
26921 if f.name.eq_ignore_ascii_case("YEAR")
26922 && f.args.len() == 1
26923 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26924 {
26925 let wrapped = Expression::Cast(Box::new(Cast {
26926 this: f.args[0].clone(),
26927 to: DataType::Date,
26928 trailing_comments: Vec::new(),
26929 double_colon_syntax: false,
26930 format: None,
26931 default: None,
26932 inferred_type: None,
26933 }));
26934 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
26935 }
26936 _ => *cc.expression.clone(),
26937 }
26938 } else {
26939 *cc.expression.clone()
26940 };
26941
26942 match cc.persistence_kind.as_deref() {
26943 Some("STORED") | Some("VIRTUAL") => {
26944 self.write_keyword("GENERATED ALWAYS AS");
26946 self.write(" (");
26947 self.generate_expression(&computed_expr)?;
26948 self.write(")");
26949 self.write_space();
26950 if cc.persisted {
26951 self.write_keyword("STORED");
26952 } else {
26953 self.write_keyword("VIRTUAL");
26954 }
26955 }
26956 Some("PERSISTED") => {
26957 self.write_keyword("AS");
26959 self.write(" (");
26960 self.generate_expression(&computed_expr)?;
26961 self.write(")");
26962 self.write_space();
26963 self.write_keyword("PERSISTED");
26964 if let Some(ref dt) = cc.data_type {
26966 self.write_space();
26967 self.generate_data_type(dt)?;
26968 }
26969 if cc.not_null {
26970 self.write_space();
26971 self.write_keyword("NOT NULL");
26972 }
26973 }
26974 _ => {
26975 if matches!(
26978 self.config.dialect,
26979 Some(DialectType::Spark)
26980 | Some(DialectType::Databricks)
26981 | Some(DialectType::Hive)
26982 ) {
26983 self.write_keyword("GENERATED ALWAYS AS");
26984 self.write(" (");
26985 self.generate_expression(&computed_expr)?;
26986 self.write(")");
26987 } else if matches!(
26988 self.config.dialect,
26989 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26990 ) {
26991 self.write_keyword("AS");
26992 let omit_parens = matches!(computed_expr, Expression::Year(_))
26993 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
26994 if omit_parens {
26995 self.write_space();
26996 self.generate_expression(&computed_expr)?;
26997 } else {
26998 self.write(" (");
26999 self.generate_expression(&computed_expr)?;
27000 self.write(")");
27001 }
27002 } else {
27003 self.write_keyword("AS");
27004 self.write(" (");
27005 self.generate_expression(&computed_expr)?;
27006 self.write(")");
27007 }
27008 }
27009 }
27010 Ok(())
27011 }
27012
27013 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
27016 self.write_keyword("GENERATED ALWAYS AS ROW ");
27017 if gar.start {
27018 self.write_keyword("START");
27019 } else {
27020 self.write_keyword("END");
27021 }
27022 if gar.hidden {
27023 self.write_space();
27024 self.write_keyword("HIDDEN");
27025 }
27026 Ok(())
27027 }
27028
27029 fn generate_system_versioning_content(
27031 &mut self,
27032 e: &WithSystemVersioningProperty,
27033 ) -> Result<()> {
27034 let mut parts = Vec::new();
27035
27036 if let Some(this) = &e.this {
27037 let mut s = String::from("HISTORY_TABLE=");
27038 let mut gen = Generator::with_arc_config(self.config.clone());
27039 gen.generate_expression(this)?;
27040 s.push_str(&gen.output);
27041 parts.push(s);
27042 }
27043
27044 if let Some(data_consistency) = &e.data_consistency {
27045 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
27046 let mut gen = Generator::with_arc_config(self.config.clone());
27047 gen.generate_expression(data_consistency)?;
27048 s.push_str(&gen.output);
27049 parts.push(s);
27050 }
27051
27052 if let Some(retention_period) = &e.retention_period {
27053 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
27054 let mut gen = Generator::with_arc_config(self.config.clone());
27055 gen.generate_expression(retention_period)?;
27056 s.push_str(&gen.output);
27057 parts.push(s);
27058 }
27059
27060 self.write_keyword("SYSTEM_VERSIONING");
27061 self.write("=");
27062
27063 if !parts.is_empty() {
27064 self.write_keyword("ON");
27065 self.write("(");
27066 self.write(&parts.join(", "));
27067 self.write(")");
27068 } else if e.on.is_some() {
27069 self.write_keyword("ON");
27070 } else {
27071 self.write_keyword("OFF");
27072 }
27073
27074 Ok(())
27075 }
27076
27077 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
27078 if e.else_.is_some() {
27081 self.write_keyword("ELSE");
27082 self.write_space();
27083 } else if let Some(expression) = &e.expression {
27084 self.write_keyword("WHEN");
27085 self.write_space();
27086 self.generate_expression(expression)?;
27087 self.write_space();
27088 self.write_keyword("THEN");
27089 self.write_space();
27090 }
27091
27092 if let Expression::Insert(insert) = e.this.as_ref() {
27095 self.write_keyword("INTO");
27096 self.write_space();
27097 self.generate_table(&insert.table)?;
27098
27099 if !insert.columns.is_empty() {
27101 self.write(" (");
27102 for (i, col) in insert.columns.iter().enumerate() {
27103 if i > 0 {
27104 self.write(", ");
27105 }
27106 self.generate_identifier(col)?;
27107 }
27108 self.write(")");
27109 }
27110
27111 if !insert.values.is_empty() {
27113 self.write_space();
27114 self.write_keyword("VALUES");
27115 for (row_idx, row) in insert.values.iter().enumerate() {
27116 if row_idx > 0 {
27117 self.write(", ");
27118 }
27119 self.write(" (");
27120 for (i, val) in row.iter().enumerate() {
27121 if i > 0 {
27122 self.write(", ");
27123 }
27124 self.generate_expression(val)?;
27125 }
27126 self.write(")");
27127 }
27128 }
27129 } else {
27130 self.generate_expression(&e.this)?;
27132 }
27133 Ok(())
27134 }
27135
27136 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
27137 self.write_keyword("CONSTRAINT");
27139 self.write_space();
27140 self.generate_expression(&e.this)?;
27141 if !e.expressions.is_empty() {
27142 self.write_space();
27143 for (i, expr) in e.expressions.iter().enumerate() {
27144 if i > 0 {
27145 self.write_space();
27146 }
27147 self.generate_expression(expr)?;
27148 }
27149 }
27150 Ok(())
27151 }
27152
27153 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
27154 self.write_keyword("CONVERT_TIMEZONE");
27156 self.write("(");
27157 let mut first = true;
27158 if let Some(source_tz) = &e.source_tz {
27159 self.generate_expression(source_tz)?;
27160 first = false;
27161 }
27162 if let Some(target_tz) = &e.target_tz {
27163 if !first {
27164 self.write(", ");
27165 }
27166 self.generate_expression(target_tz)?;
27167 first = false;
27168 }
27169 if let Some(timestamp) = &e.timestamp {
27170 if !first {
27171 self.write(", ");
27172 }
27173 self.generate_expression(timestamp)?;
27174 }
27175 self.write(")");
27176 Ok(())
27177 }
27178
27179 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
27180 self.write_keyword("CONVERT");
27182 self.write("(");
27183 self.generate_expression(&e.this)?;
27184 if let Some(dest) = &e.dest {
27185 self.write_space();
27186 self.write_keyword("USING");
27187 self.write_space();
27188 self.generate_expression(dest)?;
27189 }
27190 self.write(")");
27191 Ok(())
27192 }
27193
27194 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
27195 self.write_keyword("COPY");
27196 if e.is_into {
27197 self.write_space();
27198 self.write_keyword("INTO");
27199 }
27200 self.write_space();
27201
27202 if let Expression::Literal(lit) = &e.this {
27204 if let Literal::String(s) = lit.as_ref() {
27205 if s.starts_with('@') {
27206 self.write(s);
27207 } else {
27208 self.generate_expression(&e.this)?;
27209 }
27210 }
27211 } else {
27212 self.generate_expression(&e.this)?;
27213 }
27214
27215 if e.kind {
27217 if self.config.pretty {
27219 self.write_newline();
27220 } else {
27221 self.write_space();
27222 }
27223 self.write_keyword("FROM");
27224 self.write_space();
27225 } else if !e.files.is_empty() {
27226 if self.config.pretty {
27228 self.write_newline();
27229 } else {
27230 self.write_space();
27231 }
27232 self.write_keyword("TO");
27233 self.write_space();
27234 }
27235
27236 for (i, file) in e.files.iter().enumerate() {
27238 if i > 0 {
27239 self.write_space();
27240 }
27241 if let Expression::Literal(lit) = file {
27243 if let Literal::String(s) = lit.as_ref() {
27244 if s.starts_with('@') {
27245 self.write(s);
27246 } else {
27247 self.generate_expression(file)?;
27248 }
27249 }
27250 } else if let Expression::Identifier(id) = file {
27251 if id.quoted {
27253 self.write("`");
27254 self.write(&id.name);
27255 self.write("`");
27256 } else {
27257 self.generate_expression(file)?;
27258 }
27259 } else {
27260 self.generate_expression(file)?;
27261 }
27262 }
27263
27264 if !e.with_wrapped {
27266 if let Some(ref creds) = e.credentials {
27267 if let Some(ref storage) = creds.storage {
27268 if self.config.pretty {
27269 self.write_newline();
27270 } else {
27271 self.write_space();
27272 }
27273 self.write_keyword("STORAGE_INTEGRATION");
27274 self.write(" = ");
27275 self.write(storage);
27276 }
27277 if creds.credentials.is_empty() {
27278 if self.config.pretty {
27280 self.write_newline();
27281 } else {
27282 self.write_space();
27283 }
27284 self.write_keyword("CREDENTIALS");
27285 self.write(" = ()");
27286 } else {
27287 if self.config.pretty {
27288 self.write_newline();
27289 } else {
27290 self.write_space();
27291 }
27292 self.write_keyword("CREDENTIALS");
27293 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
27296 self.write(" '");
27298 self.write(&creds.credentials[0].1);
27299 self.write("'");
27300 } else {
27301 self.write(" = (");
27303 for (i, (k, v)) in creds.credentials.iter().enumerate() {
27304 if i > 0 {
27305 self.write_space();
27306 }
27307 self.write(k);
27308 self.write("='");
27309 self.write(v);
27310 self.write("'");
27311 }
27312 self.write(")");
27313 }
27314 }
27315 if let Some(ref encryption) = creds.encryption {
27316 self.write_space();
27317 self.write_keyword("ENCRYPTION");
27318 self.write(" = ");
27319 self.write(encryption);
27320 }
27321 }
27322 }
27323
27324 if !e.params.is_empty() {
27326 if e.with_wrapped {
27327 self.write_space();
27329 self.write_keyword("WITH");
27330 self.write(" (");
27331 for (i, param) in e.params.iter().enumerate() {
27332 if i > 0 {
27333 self.write(", ");
27334 }
27335 self.generate_copy_param_with_format(param)?;
27336 }
27337 self.write(")");
27338 } else {
27339 for param in &e.params {
27343 if self.config.pretty {
27344 self.write_newline();
27345 } else {
27346 self.write_space();
27347 }
27348 self.write(¶m.name);
27350 if let Some(ref value) = param.value {
27351 if param.eq {
27353 self.write(" = ");
27354 } else {
27355 self.write(" ");
27356 }
27357 if !param.values.is_empty() {
27358 self.write("(");
27359 for (i, v) in param.values.iter().enumerate() {
27360 if i > 0 {
27361 self.write_space();
27362 }
27363 self.generate_copy_nested_param(v)?;
27364 }
27365 self.write(")");
27366 } else {
27367 self.generate_copy_param_value(value)?;
27369 }
27370 } else if !param.values.is_empty() {
27371 if param.eq {
27373 self.write(" = (");
27374 } else {
27375 self.write(" (");
27376 }
27377 let is_key_value_pairs = param
27382 .values
27383 .first()
27384 .map_or(false, |v| matches!(v, Expression::Eq(_)));
27385 let sep = if is_key_value_pairs && param.eq {
27386 " "
27387 } else {
27388 ", "
27389 };
27390 for (i, v) in param.values.iter().enumerate() {
27391 if i > 0 {
27392 self.write(sep);
27393 }
27394 self.generate_copy_nested_param(v)?;
27395 }
27396 self.write(")");
27397 }
27398 }
27399 }
27400 }
27401
27402 Ok(())
27403 }
27404
27405 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
27408 self.write_keyword(¶m.name);
27409 if !param.values.is_empty() {
27410 self.write(" = (");
27412 for (i, v) in param.values.iter().enumerate() {
27413 if i > 0 {
27414 self.write(", ");
27415 }
27416 self.generate_copy_nested_param(v)?;
27417 }
27418 self.write(")");
27419 } else if let Some(ref value) = param.value {
27420 if param.eq {
27421 self.write(" = ");
27422 } else {
27423 self.write(" ");
27424 }
27425 self.generate_expression(value)?;
27426 }
27427 Ok(())
27428 }
27429
27430 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
27432 match expr {
27433 Expression::Eq(eq) => {
27434 match &eq.left {
27436 Expression::Column(c) => self.write(&c.name.name),
27437 _ => self.generate_expression(&eq.left)?,
27438 }
27439 self.write("=");
27440 match &eq.right {
27442 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27443 let Literal::String(s) = lit.as_ref() else {
27444 unreachable!()
27445 };
27446 self.write("'");
27447 self.write(s);
27448 self.write("'");
27449 }
27450 Expression::Tuple(t) => {
27451 self.write("(");
27453 if self.config.pretty {
27454 self.write_newline();
27455 self.indent_level += 1;
27456 for (i, item) in t.expressions.iter().enumerate() {
27457 if i > 0 {
27458 self.write(", ");
27459 }
27460 self.write_indent();
27461 self.generate_expression(item)?;
27462 }
27463 self.write_newline();
27464 self.indent_level -= 1;
27465 } else {
27466 for (i, item) in t.expressions.iter().enumerate() {
27467 if i > 0 {
27468 self.write(", ");
27469 }
27470 self.generate_expression(item)?;
27471 }
27472 }
27473 self.write(")");
27474 }
27475 _ => self.generate_expression(&eq.right)?,
27476 }
27477 Ok(())
27478 }
27479 Expression::Column(c) => {
27480 self.write(&c.name.name);
27482 Ok(())
27483 }
27484 _ => self.generate_expression(expr),
27485 }
27486 }
27487
27488 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
27491 match expr {
27492 Expression::Column(c) => {
27493 if c.name.quoted {
27495 self.write("\"");
27496 self.write(&c.name.name);
27497 self.write("\"");
27498 } else {
27499 self.write(&c.name.name);
27500 }
27501 Ok(())
27502 }
27503 Expression::Identifier(id) => {
27504 if id.quoted {
27506 self.write("\"");
27507 self.write(&id.name);
27508 self.write("\"");
27509 } else {
27510 self.write(&id.name);
27511 }
27512 Ok(())
27513 }
27514 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27515 let Literal::String(s) = lit.as_ref() else {
27516 unreachable!()
27517 };
27518 self.write("'");
27520 self.write(s);
27521 self.write("'");
27522 Ok(())
27523 }
27524 _ => self.generate_expression(expr),
27525 }
27526 }
27527
27528 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
27529 self.write_keyword(&e.name);
27530 if let Some(ref value) = e.value {
27531 if e.eq {
27532 self.write(" = ");
27533 } else {
27534 self.write(" ");
27535 }
27536 self.generate_expression(value)?;
27537 }
27538 if !e.values.is_empty() {
27539 if e.eq {
27540 self.write(" = ");
27541 } else {
27542 self.write(" ");
27543 }
27544 self.write("(");
27545 for (i, v) in e.values.iter().enumerate() {
27546 if i > 0 {
27547 self.write(", ");
27548 }
27549 self.generate_expression(v)?;
27550 }
27551 self.write(")");
27552 }
27553 Ok(())
27554 }
27555
27556 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
27557 self.write_keyword("CORR");
27559 self.write("(");
27560 self.generate_expression(&e.this)?;
27561 self.write(", ");
27562 self.generate_expression(&e.expression)?;
27563 self.write(")");
27564 Ok(())
27565 }
27566
27567 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
27568 self.write_keyword("COSINE_DISTANCE");
27570 self.write("(");
27571 self.generate_expression(&e.this)?;
27572 self.write(", ");
27573 self.generate_expression(&e.expression)?;
27574 self.write(")");
27575 Ok(())
27576 }
27577
27578 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
27579 self.write_keyword("COVAR_POP");
27581 self.write("(");
27582 self.generate_expression(&e.this)?;
27583 self.write(", ");
27584 self.generate_expression(&e.expression)?;
27585 self.write(")");
27586 Ok(())
27587 }
27588
27589 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
27590 self.write_keyword("COVAR_SAMP");
27592 self.write("(");
27593 self.generate_expression(&e.this)?;
27594 self.write(", ");
27595 self.generate_expression(&e.expression)?;
27596 self.write(")");
27597 Ok(())
27598 }
27599
27600 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
27601 self.write_keyword("CREDENTIALS");
27603 self.write(" (");
27604 for (i, (key, value)) in e.credentials.iter().enumerate() {
27605 if i > 0 {
27606 self.write(", ");
27607 }
27608 self.write(key);
27609 self.write("='");
27610 self.write(value);
27611 self.write("'");
27612 }
27613 self.write(")");
27614 Ok(())
27615 }
27616
27617 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
27618 self.write_keyword("CREDENTIALS");
27620 self.write("=(");
27621 for (i, expr) in e.expressions.iter().enumerate() {
27622 if i > 0 {
27623 self.write(", ");
27624 }
27625 self.generate_expression(expr)?;
27626 }
27627 self.write(")");
27628 Ok(())
27629 }
27630
27631 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
27632 use crate::dialects::DialectType;
27633
27634 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
27637 self.generate_expression(&e.this)?;
27638 self.write_space();
27639 self.write_keyword("AS");
27640 self.write_space();
27641 self.generate_identifier(&e.alias)?;
27642 return Ok(());
27643 }
27644 self.write(&e.alias.name);
27645
27646 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
27648
27649 if !e.columns.is_empty() && !skip_cte_columns {
27650 self.write("(");
27651 for (i, col) in e.columns.iter().enumerate() {
27652 if i > 0 {
27653 self.write(", ");
27654 }
27655 self.write(&col.name);
27656 }
27657 self.write(")");
27658 }
27659 if !e.key_expressions.is_empty() {
27661 self.write_space();
27662 self.write_keyword("USING KEY");
27663 self.write(" (");
27664 for (i, key) in e.key_expressions.iter().enumerate() {
27665 if i > 0 {
27666 self.write(", ");
27667 }
27668 self.write(&key.name);
27669 }
27670 self.write(")");
27671 }
27672 self.write_space();
27673 self.write_keyword("AS");
27674 self.write_space();
27675 if let Some(materialized) = e.materialized {
27676 if materialized {
27677 self.write_keyword("MATERIALIZED");
27678 } else {
27679 self.write_keyword("NOT MATERIALIZED");
27680 }
27681 self.write_space();
27682 }
27683 self.write("(");
27684 self.generate_expression(&e.this)?;
27685 self.write(")");
27686 Ok(())
27687 }
27688
27689 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
27690 if e.expressions.is_empty() {
27692 self.write_keyword("WITH CUBE");
27693 } else {
27694 self.write_keyword("CUBE");
27695 self.write("(");
27696 for (i, expr) in e.expressions.iter().enumerate() {
27697 if i > 0 {
27698 self.write(", ");
27699 }
27700 self.generate_expression(expr)?;
27701 }
27702 self.write(")");
27703 }
27704 Ok(())
27705 }
27706
27707 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
27708 self.write_keyword("CURRENT_DATETIME");
27710 if let Some(this) = &e.this {
27711 self.write("(");
27712 self.generate_expression(this)?;
27713 self.write(")");
27714 }
27715 Ok(())
27716 }
27717
27718 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
27719 self.write_keyword("CURRENT_SCHEMA");
27721 Ok(())
27722 }
27723
27724 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
27725 self.write_keyword("CURRENT_SCHEMAS");
27727 self.write("(");
27728 if !matches!(
27730 self.config.dialect,
27731 Some(crate::dialects::DialectType::Snowflake)
27732 ) {
27733 if let Some(this) = &e.this {
27734 self.generate_expression(this)?;
27735 }
27736 }
27737 self.write(")");
27738 Ok(())
27739 }
27740
27741 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
27742 self.write_keyword("CURRENT_USER");
27744 let needs_parens = e.this.is_some()
27746 || matches!(
27747 self.config.dialect,
27748 Some(DialectType::Snowflake)
27749 | Some(DialectType::Spark)
27750 | Some(DialectType::Hive)
27751 | Some(DialectType::DuckDB)
27752 | Some(DialectType::BigQuery)
27753 | Some(DialectType::MySQL)
27754 | Some(DialectType::Databricks)
27755 );
27756 if needs_parens {
27757 self.write("()");
27758 }
27759 Ok(())
27760 }
27761
27762 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
27763 if self.config.dialect == Some(DialectType::Solr) {
27765 self.generate_expression(&e.this)?;
27766 self.write(" ");
27767 self.write_keyword("OR");
27768 self.write(" ");
27769 self.generate_expression(&e.expression)?;
27770 } else if self.config.dialect == Some(DialectType::MySQL) {
27771 self.generate_mysql_concat_from_dpipe(e)?;
27772 } else {
27773 self.generate_expression(&e.this)?;
27775 self.write(" || ");
27776 self.generate_expression(&e.expression)?;
27777 }
27778 Ok(())
27779 }
27780
27781 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
27782 self.write_keyword("DATABLOCKSIZE");
27784 self.write("=");
27785 if let Some(size) = e.size {
27786 self.write(&size.to_string());
27787 if let Some(units) = &e.units {
27788 self.write_space();
27789 self.generate_expression(units)?;
27790 }
27791 } else if e.minimum.is_some() {
27792 self.write_keyword("MINIMUM");
27793 } else if e.maximum.is_some() {
27794 self.write_keyword("MAXIMUM");
27795 } else if e.default.is_some() {
27796 self.write_keyword("DEFAULT");
27797 }
27798 Ok(())
27799 }
27800
27801 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
27802 self.write_keyword("DATA_DELETION");
27804 self.write("=");
27805
27806 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
27807 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
27808
27809 if is_on {
27810 self.write_keyword("ON");
27811 if has_options {
27812 self.write("(");
27813 let mut first = true;
27814 if let Some(filter_column) = &e.filter_column {
27815 self.write_keyword("FILTER_COLUMN");
27816 self.write("=");
27817 self.generate_expression(filter_column)?;
27818 first = false;
27819 }
27820 if let Some(retention_period) = &e.retention_period {
27821 if !first {
27822 self.write(", ");
27823 }
27824 self.write_keyword("RETENTION_PERIOD");
27825 self.write("=");
27826 self.generate_expression(retention_period)?;
27827 }
27828 self.write(")");
27829 }
27830 } else {
27831 self.write_keyword("OFF");
27832 }
27833 Ok(())
27834 }
27835
27836 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
27840 use crate::dialects::DialectType;
27841 use crate::expressions::Literal;
27842
27843 match self.config.dialect {
27844 Some(DialectType::Exasol) => {
27846 self.write_keyword("TO_DATE");
27847 self.write("(");
27848 match &e.this {
27850 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27851 let Literal::String(s) = lit.as_ref() else {
27852 unreachable!()
27853 };
27854 self.write("'");
27855 self.write(s);
27856 self.write("'");
27857 }
27858 _ => {
27859 self.generate_expression(&e.this)?;
27860 }
27861 }
27862 self.write(")");
27863 }
27864 _ => {
27866 self.write_keyword("DATE");
27867 self.write("(");
27868 self.generate_expression(&e.this)?;
27869 self.write(")");
27870 }
27871 }
27872 Ok(())
27873 }
27874
27875 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
27876 self.write_keyword("DATE_BIN");
27878 self.write("(");
27879 self.generate_expression(&e.this)?;
27880 self.write(", ");
27881 self.generate_expression(&e.expression)?;
27882 if let Some(origin) = &e.origin {
27883 self.write(", ");
27884 self.generate_expression(origin)?;
27885 }
27886 self.write(")");
27887 Ok(())
27888 }
27889
27890 fn generate_date_format_column_constraint(
27891 &mut self,
27892 e: &DateFormatColumnConstraint,
27893 ) -> Result<()> {
27894 self.write_keyword("FORMAT");
27896 self.write_space();
27897 self.generate_expression(&e.this)?;
27898 Ok(())
27899 }
27900
27901 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
27902 self.write_keyword("DATE_FROM_PARTS");
27904 self.write("(");
27905 let mut first = true;
27906 if let Some(year) = &e.year {
27907 self.generate_expression(year)?;
27908 first = false;
27909 }
27910 if let Some(month) = &e.month {
27911 if !first {
27912 self.write(", ");
27913 }
27914 self.generate_expression(month)?;
27915 first = false;
27916 }
27917 if let Some(day) = &e.day {
27918 if !first {
27919 self.write(", ");
27920 }
27921 self.generate_expression(day)?;
27922 }
27923 self.write(")");
27924 Ok(())
27925 }
27926
27927 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
27928 self.write_keyword("DATETIME");
27930 self.write("(");
27931 self.generate_expression(&e.this)?;
27932 if let Some(expr) = &e.expression {
27933 self.write(", ");
27934 self.generate_expression(expr)?;
27935 }
27936 self.write(")");
27937 Ok(())
27938 }
27939
27940 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
27941 self.write_keyword("DATETIME_ADD");
27943 self.write("(");
27944 self.generate_expression(&e.this)?;
27945 self.write(", ");
27946 self.generate_expression(&e.expression)?;
27947 if let Some(unit) = &e.unit {
27948 self.write(", ");
27949 self.write_keyword(unit);
27950 }
27951 self.write(")");
27952 Ok(())
27953 }
27954
27955 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
27956 self.write_keyword("DATETIME_DIFF");
27958 self.write("(");
27959 self.generate_expression(&e.this)?;
27960 self.write(", ");
27961 self.generate_expression(&e.expression)?;
27962 if let Some(unit) = &e.unit {
27963 self.write(", ");
27964 self.write_keyword(unit);
27965 }
27966 self.write(")");
27967 Ok(())
27968 }
27969
27970 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
27971 self.write_keyword("DATETIME_SUB");
27973 self.write("(");
27974 self.generate_expression(&e.this)?;
27975 self.write(", ");
27976 self.generate_expression(&e.expression)?;
27977 if let Some(unit) = &e.unit {
27978 self.write(", ");
27979 self.write_keyword(unit);
27980 }
27981 self.write(")");
27982 Ok(())
27983 }
27984
27985 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
27986 self.write_keyword("DATETIME_TRUNC");
27988 self.write("(");
27989 self.generate_expression(&e.this)?;
27990 self.write(", ");
27991 self.write_keyword(&e.unit);
27992 if let Some(zone) = &e.zone {
27993 self.write(", ");
27994 self.generate_expression(zone)?;
27995 }
27996 self.write(")");
27997 Ok(())
27998 }
27999
28000 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
28001 self.write_keyword("DAYNAME");
28003 self.write("(");
28004 self.generate_expression(&e.this)?;
28005 self.write(")");
28006 Ok(())
28007 }
28008
28009 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
28010 self.write_keyword("DECLARE");
28012 self.write_space();
28013 if e.replace {
28014 self.write_keyword("OR");
28015 self.write_space();
28016 self.write_keyword("REPLACE");
28017 self.write_space();
28018 }
28019 for (i, expr) in e.expressions.iter().enumerate() {
28020 if i > 0 {
28021 self.write(", ");
28022 }
28023 self.generate_expression(expr)?;
28024 }
28025 Ok(())
28026 }
28027
28028 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
28029 use crate::dialects::DialectType;
28030
28031 self.generate_expression(&e.this)?;
28033 for name in &e.additional_names {
28035 self.write(", ");
28036 self.generate_expression(name)?;
28037 }
28038 if let Some(kind) = &e.kind {
28039 self.write_space();
28040 match self.config.dialect {
28044 Some(DialectType::BigQuery) => {
28045 self.write(kind);
28046 }
28047 Some(DialectType::TSQL) => {
28048 let is_complex_table = kind.starts_with("TABLE")
28052 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
28053 if is_complex_table {
28054 self.write(kind);
28055 } else if kind == "INT" {
28056 self.write("INTEGER");
28057 } else if kind.starts_with("TABLE") {
28058 let normalized = kind
28060 .replace(" INT ", " INTEGER ")
28061 .replace(" INT,", " INTEGER,")
28062 .replace(" INT)", " INTEGER)")
28063 .replace("(INT ", "(INTEGER ");
28064 self.write(&normalized);
28065 } else {
28066 self.write(kind);
28067 }
28068 }
28069 _ => {
28070 if e.has_as {
28071 self.write_keyword("AS");
28072 self.write_space();
28073 }
28074 self.write(kind);
28075 }
28076 }
28077 }
28078 if let Some(default) = &e.default {
28079 match self.config.dialect {
28081 Some(DialectType::BigQuery) => {
28082 self.write_space();
28083 self.write_keyword("DEFAULT");
28084 self.write_space();
28085 }
28086 _ => {
28087 self.write(" = ");
28088 }
28089 }
28090 self.generate_expression(default)?;
28091 }
28092 Ok(())
28093 }
28094
28095 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
28096 self.write_keyword("DECODE");
28098 self.write("(");
28099 for (i, expr) in e.expressions.iter().enumerate() {
28100 if i > 0 {
28101 self.write(", ");
28102 }
28103 self.generate_expression(expr)?;
28104 }
28105 self.write(")");
28106 Ok(())
28107 }
28108
28109 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
28110 self.write_keyword("DECOMPRESS");
28112 self.write("(");
28113 self.generate_expression(&e.this)?;
28114 self.write(", '");
28115 self.write(&e.method);
28116 self.write("')");
28117 Ok(())
28118 }
28119
28120 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
28121 self.write_keyword("DECOMPRESS");
28123 self.write("(");
28124 self.generate_expression(&e.this)?;
28125 self.write(", '");
28126 self.write(&e.method);
28127 self.write("')");
28128 Ok(())
28129 }
28130
28131 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
28132 self.write_keyword("DECRYPT");
28134 self.write("(");
28135 self.generate_expression(&e.this)?;
28136 if let Some(passphrase) = &e.passphrase {
28137 self.write(", ");
28138 self.generate_expression(passphrase)?;
28139 }
28140 if let Some(aad) = &e.aad {
28141 self.write(", ");
28142 self.generate_expression(aad)?;
28143 }
28144 if let Some(method) = &e.encryption_method {
28145 self.write(", ");
28146 self.generate_expression(method)?;
28147 }
28148 self.write(")");
28149 Ok(())
28150 }
28151
28152 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
28153 self.write_keyword("DECRYPT_RAW");
28155 self.write("(");
28156 self.generate_expression(&e.this)?;
28157 if let Some(key) = &e.key {
28158 self.write(", ");
28159 self.generate_expression(key)?;
28160 }
28161 if let Some(iv) = &e.iv {
28162 self.write(", ");
28163 self.generate_expression(iv)?;
28164 }
28165 if let Some(aad) = &e.aad {
28166 self.write(", ");
28167 self.generate_expression(aad)?;
28168 }
28169 if let Some(method) = &e.encryption_method {
28170 self.write(", ");
28171 self.generate_expression(method)?;
28172 }
28173 self.write(")");
28174 Ok(())
28175 }
28176
28177 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
28178 self.write_keyword("DEFINER");
28180 self.write(" = ");
28181 self.generate_expression(&e.this)?;
28182 Ok(())
28183 }
28184
28185 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
28186 self.write_keyword("DETACH");
28188 if e.exists {
28189 self.write_keyword(" DATABASE IF EXISTS");
28190 }
28191 self.write_space();
28192 self.generate_expression(&e.this)?;
28193 Ok(())
28194 }
28195
28196 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
28197 let property_name = match e.this.as_ref() {
28198 Expression::Identifier(id) => id.name.as_str(),
28199 Expression::Var(v) => v.this.as_str(),
28200 _ => "DICTIONARY",
28201 };
28202 self.write_keyword(property_name);
28203 self.write("(");
28204 self.write(&e.kind);
28205 if let Some(settings) = &e.settings {
28206 self.write("(");
28207 if let Expression::Tuple(t) = settings.as_ref() {
28208 if self.config.pretty && !t.expressions.is_empty() {
28209 self.write_newline();
28210 self.indent_level += 1;
28211 for (i, pair) in t.expressions.iter().enumerate() {
28212 if i > 0 {
28213 self.write(",");
28214 self.write_newline();
28215 }
28216 self.write_indent();
28217 if let Expression::Tuple(pair_tuple) = pair {
28218 if let Some(k) = pair_tuple.expressions.first() {
28219 self.generate_expression(k)?;
28220 }
28221 if let Some(v) = pair_tuple.expressions.get(1) {
28222 self.write(" ");
28223 self.generate_expression(v)?;
28224 }
28225 } else {
28226 self.generate_expression(pair)?;
28227 }
28228 }
28229 self.indent_level -= 1;
28230 self.write_newline();
28231 self.write_indent();
28232 } else {
28233 for (i, pair) in t.expressions.iter().enumerate() {
28234 if i > 0 {
28235 self.write(" ");
28237 }
28238 if let Expression::Tuple(pair_tuple) = pair {
28239 if let Some(k) = pair_tuple.expressions.first() {
28240 self.generate_expression(k)?;
28241 }
28242 if let Some(v) = pair_tuple.expressions.get(1) {
28243 self.write(" ");
28244 self.generate_expression(v)?;
28245 }
28246 } else {
28247 self.generate_expression(pair)?;
28248 }
28249 }
28250 }
28251 } else {
28252 self.generate_expression(settings)?;
28253 }
28254 self.write(")");
28255 } else {
28256 self.write("()");
28258 }
28259 self.write(")");
28260 Ok(())
28261 }
28262
28263 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
28264 let property_name = match e.this.as_ref() {
28265 Expression::Identifier(id) => id.name.as_str(),
28266 Expression::Var(v) => v.this.as_str(),
28267 _ => "RANGE",
28268 };
28269 self.write_keyword(property_name);
28270 self.write("(");
28271 if let Some(min) = &e.min {
28272 self.write_keyword("MIN");
28273 self.write_space();
28274 self.generate_expression(min)?;
28275 }
28276 if let Some(max) = &e.max {
28277 self.write_space();
28278 self.write_keyword("MAX");
28279 self.write_space();
28280 self.generate_expression(max)?;
28281 }
28282 self.write(")");
28283 Ok(())
28284 }
28285
28286 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
28287 if e.local.is_some() {
28289 self.write_keyword("LOCAL ");
28290 }
28291 self.write_keyword("DIRECTORY");
28292 self.write_space();
28293 self.generate_expression(&e.this)?;
28294 if let Some(row_format) = &e.row_format {
28295 self.write_space();
28296 self.generate_expression(row_format)?;
28297 }
28298 Ok(())
28299 }
28300
28301 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
28302 self.write_keyword("DISTKEY");
28304 self.write("(");
28305 self.generate_expression(&e.this)?;
28306 self.write(")");
28307 Ok(())
28308 }
28309
28310 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
28311 self.write_keyword("DISTSTYLE");
28313 self.write_space();
28314 self.generate_expression(&e.this)?;
28315 Ok(())
28316 }
28317
28318 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
28319 self.write_keyword("DISTRIBUTE BY");
28321 self.write_space();
28322 for (i, expr) in e.expressions.iter().enumerate() {
28323 if i > 0 {
28324 self.write(", ");
28325 }
28326 self.generate_expression(expr)?;
28327 }
28328 Ok(())
28329 }
28330
28331 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
28332 self.write_keyword("DISTRIBUTED BY");
28334 self.write_space();
28335 self.write(&e.kind);
28336 if !e.expressions.is_empty() {
28337 self.write(" (");
28338 for (i, expr) in e.expressions.iter().enumerate() {
28339 if i > 0 {
28340 self.write(", ");
28341 }
28342 self.generate_expression(expr)?;
28343 }
28344 self.write(")");
28345 }
28346 if let Some(buckets) = &e.buckets {
28347 self.write_space();
28348 self.write_keyword("BUCKETS");
28349 self.write_space();
28350 self.generate_expression(buckets)?;
28351 }
28352 if let Some(order) = &e.order {
28353 self.write_space();
28354 self.generate_expression(order)?;
28355 }
28356 Ok(())
28357 }
28358
28359 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
28360 self.write_keyword("DOT_PRODUCT");
28362 self.write("(");
28363 self.generate_expression(&e.this)?;
28364 self.write(", ");
28365 self.generate_expression(&e.expression)?;
28366 self.write(")");
28367 Ok(())
28368 }
28369
28370 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
28371 self.write_keyword("DROP");
28373 if e.exists {
28374 self.write_keyword(" IF EXISTS ");
28375 } else {
28376 self.write_space();
28377 }
28378 for (i, expr) in e.expressions.iter().enumerate() {
28379 if i > 0 {
28380 self.write(", ");
28381 }
28382 self.generate_expression(expr)?;
28383 }
28384 Ok(())
28385 }
28386
28387 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
28388 self.write_keyword("DUPLICATE KEY");
28390 self.write(" (");
28391 for (i, expr) in e.expressions.iter().enumerate() {
28392 if i > 0 {
28393 self.write(", ");
28394 }
28395 self.generate_expression(expr)?;
28396 }
28397 self.write(")");
28398 Ok(())
28399 }
28400
28401 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
28402 self.write_keyword("ELT");
28404 self.write("(");
28405 self.generate_expression(&e.this)?;
28406 for expr in &e.expressions {
28407 self.write(", ");
28408 self.generate_expression(expr)?;
28409 }
28410 self.write(")");
28411 Ok(())
28412 }
28413
28414 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
28415 self.write_keyword("ENCODE");
28417 self.write("(");
28418 self.generate_expression(&e.this)?;
28419 if let Some(charset) = &e.charset {
28420 self.write(", ");
28421 self.generate_expression(charset)?;
28422 }
28423 self.write(")");
28424 Ok(())
28425 }
28426
28427 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
28428 if e.key.is_some() {
28430 self.write_keyword("KEY ");
28431 }
28432 self.write_keyword("ENCODE");
28433 self.write_space();
28434 self.generate_expression(&e.this)?;
28435 if !e.properties.is_empty() {
28436 self.write(" (");
28437 for (i, prop) in e.properties.iter().enumerate() {
28438 if i > 0 {
28439 self.write(", ");
28440 }
28441 self.generate_expression(prop)?;
28442 }
28443 self.write(")");
28444 }
28445 Ok(())
28446 }
28447
28448 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
28449 self.write_keyword("ENCRYPT");
28451 self.write("(");
28452 self.generate_expression(&e.this)?;
28453 if let Some(passphrase) = &e.passphrase {
28454 self.write(", ");
28455 self.generate_expression(passphrase)?;
28456 }
28457 if let Some(aad) = &e.aad {
28458 self.write(", ");
28459 self.generate_expression(aad)?;
28460 }
28461 if let Some(method) = &e.encryption_method {
28462 self.write(", ");
28463 self.generate_expression(method)?;
28464 }
28465 self.write(")");
28466 Ok(())
28467 }
28468
28469 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
28470 self.write_keyword("ENCRYPT_RAW");
28472 self.write("(");
28473 self.generate_expression(&e.this)?;
28474 if let Some(key) = &e.key {
28475 self.write(", ");
28476 self.generate_expression(key)?;
28477 }
28478 if let Some(iv) = &e.iv {
28479 self.write(", ");
28480 self.generate_expression(iv)?;
28481 }
28482 if let Some(aad) = &e.aad {
28483 self.write(", ");
28484 self.generate_expression(aad)?;
28485 }
28486 if let Some(method) = &e.encryption_method {
28487 self.write(", ");
28488 self.generate_expression(method)?;
28489 }
28490 self.write(")");
28491 Ok(())
28492 }
28493
28494 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
28495 self.write_keyword("ENGINE");
28497 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28498 self.write("=");
28499 } else {
28500 self.write(" = ");
28501 }
28502 self.generate_expression(&e.this)?;
28503 Ok(())
28504 }
28505
28506 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
28507 self.write_keyword("ENVIRONMENT");
28509 self.write(" (");
28510 for (i, expr) in e.expressions.iter().enumerate() {
28511 if i > 0 {
28512 self.write(", ");
28513 }
28514 self.generate_expression(expr)?;
28515 }
28516 self.write(")");
28517 Ok(())
28518 }
28519
28520 fn generate_ephemeral_column_constraint(
28521 &mut self,
28522 e: &EphemeralColumnConstraint,
28523 ) -> Result<()> {
28524 self.write_keyword("EPHEMERAL");
28526 if let Some(this) = &e.this {
28527 self.write_space();
28528 self.generate_expression(this)?;
28529 }
28530 Ok(())
28531 }
28532
28533 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
28534 self.write_keyword("EQUAL_NULL");
28536 self.write("(");
28537 self.generate_expression(&e.this)?;
28538 self.write(", ");
28539 self.generate_expression(&e.expression)?;
28540 self.write(")");
28541 Ok(())
28542 }
28543
28544 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
28545 use crate::dialects::DialectType;
28546
28547 match self.config.dialect {
28549 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
28550 self.generate_expression(&e.this)?;
28551 self.write(" <-> ");
28552 self.generate_expression(&e.expression)?;
28553 }
28554 _ => {
28555 self.write_keyword("EUCLIDEAN_DISTANCE");
28557 self.write("(");
28558 self.generate_expression(&e.this)?;
28559 self.write(", ");
28560 self.generate_expression(&e.expression)?;
28561 self.write(")");
28562 }
28563 }
28564 Ok(())
28565 }
28566
28567 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
28568 self.write_keyword("EXECUTE AS");
28570 self.write_space();
28571 self.generate_expression(&e.this)?;
28572 Ok(())
28573 }
28574
28575 fn generate_export(&mut self, e: &Export) -> Result<()> {
28576 self.write_keyword("EXPORT DATA");
28578 if let Some(connection) = &e.connection {
28579 self.write_space();
28580 self.write_keyword("WITH CONNECTION");
28581 self.write_space();
28582 self.generate_expression(connection)?;
28583 }
28584 if !e.options.is_empty() {
28585 self.write_space();
28586 self.generate_options_clause(&e.options)?;
28587 }
28588 self.write_space();
28589 self.write_keyword("AS");
28590 self.write_space();
28591 self.generate_expression(&e.this)?;
28592 Ok(())
28593 }
28594
28595 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
28596 self.write_keyword("EXTERNAL");
28598 if let Some(this) = &e.this {
28599 self.write_space();
28600 self.generate_expression(this)?;
28601 }
28602 Ok(())
28603 }
28604
28605 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
28606 if e.no.is_some() {
28608 self.write_keyword("NO ");
28609 }
28610 self.write_keyword("FALLBACK");
28611 if e.protection.is_some() {
28612 self.write_keyword(" PROTECTION");
28613 }
28614 Ok(())
28615 }
28616
28617 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
28618 self.write_keyword("FARM_FINGERPRINT");
28620 self.write("(");
28621 for (i, expr) in e.expressions.iter().enumerate() {
28622 if i > 0 {
28623 self.write(", ");
28624 }
28625 self.generate_expression(expr)?;
28626 }
28627 self.write(")");
28628 Ok(())
28629 }
28630
28631 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
28632 self.write_keyword("FEATURES_AT_TIME");
28634 self.write("(");
28635 self.generate_expression(&e.this)?;
28636 if let Some(time) = &e.time {
28637 self.write(", ");
28638 self.generate_expression(time)?;
28639 }
28640 if let Some(num_rows) = &e.num_rows {
28641 self.write(", ");
28642 self.generate_expression(num_rows)?;
28643 }
28644 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
28645 self.write(", ");
28646 self.generate_expression(ignore_nulls)?;
28647 }
28648 self.write(")");
28649 Ok(())
28650 }
28651
28652 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
28653 let use_limit = !e.percent
28655 && !e.with_ties
28656 && e.count.is_some()
28657 && matches!(
28658 self.config.dialect,
28659 Some(DialectType::Spark)
28660 | Some(DialectType::Hive)
28661 | Some(DialectType::DuckDB)
28662 | Some(DialectType::SQLite)
28663 | Some(DialectType::MySQL)
28664 | Some(DialectType::BigQuery)
28665 | Some(DialectType::Databricks)
28666 | Some(DialectType::StarRocks)
28667 | Some(DialectType::Doris)
28668 | Some(DialectType::Athena)
28669 | Some(DialectType::ClickHouse)
28670 );
28671
28672 if use_limit {
28673 self.write_keyword("LIMIT");
28674 self.write_space();
28675 self.generate_expression(e.count.as_ref().unwrap())?;
28676 return Ok(());
28677 }
28678
28679 self.write_keyword("FETCH");
28681 if !e.direction.is_empty() {
28682 self.write_space();
28683 self.write_keyword(&e.direction);
28684 }
28685 if let Some(count) = &e.count {
28686 self.write_space();
28687 self.generate_expression(count)?;
28688 }
28689 if e.percent {
28691 self.write_keyword(" PERCENT");
28692 }
28693 if e.rows {
28694 self.write_keyword(" ROWS");
28695 }
28696 if e.with_ties {
28697 self.write_keyword(" WITH TIES");
28698 } else if e.rows {
28699 self.write_keyword(" ONLY");
28700 } else {
28701 self.write_keyword(" ROWS ONLY");
28702 }
28703 Ok(())
28704 }
28705
28706 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
28707 if e.hive_format.is_some() {
28711 self.write_keyword("STORED AS");
28713 self.write_space();
28714 if let Some(this) = &e.this {
28715 if let Expression::Identifier(id) = this.as_ref() {
28717 self.write_keyword(&id.name.to_ascii_uppercase());
28718 } else {
28719 self.generate_expression(this)?;
28720 }
28721 }
28722 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
28723 self.write_keyword("STORED AS");
28725 self.write_space();
28726 if let Some(this) = &e.this {
28727 if let Expression::Identifier(id) = this.as_ref() {
28728 self.write_keyword(&id.name.to_ascii_uppercase());
28729 } else {
28730 self.generate_expression(this)?;
28731 }
28732 }
28733 } else if matches!(
28734 self.config.dialect,
28735 Some(DialectType::Spark) | Some(DialectType::Databricks)
28736 ) {
28737 self.write_keyword("USING");
28739 self.write_space();
28740 if let Some(this) = &e.this {
28741 self.generate_expression(this)?;
28742 }
28743 } else {
28744 self.write_keyword("FILE_FORMAT");
28746 self.write(" = ");
28747 if let Some(this) = &e.this {
28748 self.generate_expression(this)?;
28749 } else if !e.expressions.is_empty() {
28750 self.write("(");
28751 for (i, expr) in e.expressions.iter().enumerate() {
28752 if i > 0 {
28753 self.write(", ");
28754 }
28755 self.generate_expression(expr)?;
28756 }
28757 self.write(")");
28758 }
28759 }
28760 Ok(())
28761 }
28762
28763 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
28764 self.generate_expression(&e.this)?;
28766 self.write_space();
28767 self.write_keyword("FILTER");
28768 self.write("(");
28769 self.write_keyword("WHERE");
28770 self.write_space();
28771 self.generate_expression(&e.expression)?;
28772 self.write(")");
28773 Ok(())
28774 }
28775
28776 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
28777 self.write_keyword("FLOAT64");
28779 self.write("(");
28780 self.generate_expression(&e.this)?;
28781 if let Some(expr) = &e.expression {
28782 self.write(", ");
28783 self.generate_expression(expr)?;
28784 }
28785 self.write(")");
28786 Ok(())
28787 }
28788
28789 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
28790 self.write_keyword("FOR");
28792 self.write_space();
28793 self.generate_expression(&e.this)?;
28794 self.write_space();
28795 self.write_keyword("DO");
28796 self.write_space();
28797 self.generate_expression(&e.expression)?;
28798 Ok(())
28799 }
28800
28801 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
28802 self.write_keyword("FOREIGN KEY");
28804 if !e.expressions.is_empty() {
28805 self.write(" (");
28806 for (i, expr) in e.expressions.iter().enumerate() {
28807 if i > 0 {
28808 self.write(", ");
28809 }
28810 self.generate_expression(expr)?;
28811 }
28812 self.write(")");
28813 }
28814 if let Some(reference) = &e.reference {
28815 self.write_space();
28816 self.generate_expression(reference)?;
28817 }
28818 if let Some(delete) = &e.delete {
28819 self.write_space();
28820 self.write_keyword("ON DELETE");
28821 self.write_space();
28822 self.generate_expression(delete)?;
28823 }
28824 if let Some(update) = &e.update {
28825 self.write_space();
28826 self.write_keyword("ON UPDATE");
28827 self.write_space();
28828 self.generate_expression(update)?;
28829 }
28830 if !e.options.is_empty() {
28831 self.write_space();
28832 for (i, opt) in e.options.iter().enumerate() {
28833 if i > 0 {
28834 self.write_space();
28835 }
28836 self.generate_expression(opt)?;
28837 }
28838 }
28839 Ok(())
28840 }
28841
28842 fn generate_format(&mut self, e: &Format) -> Result<()> {
28843 self.write_keyword("FORMAT");
28845 self.write("(");
28846 self.generate_expression(&e.this)?;
28847 for expr in &e.expressions {
28848 self.write(", ");
28849 self.generate_expression(expr)?;
28850 }
28851 self.write(")");
28852 Ok(())
28853 }
28854
28855 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
28856 self.generate_expression(&e.this)?;
28858 self.write(" (");
28859 self.write_keyword("FORMAT");
28860 self.write(" '");
28861 self.write(&e.format);
28862 self.write("')");
28863 Ok(())
28864 }
28865
28866 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
28867 self.write_keyword("FREESPACE");
28869 self.write("=");
28870 self.generate_expression(&e.this)?;
28871 if e.percent.is_some() {
28872 self.write_keyword(" PERCENT");
28873 }
28874 Ok(())
28875 }
28876
28877 fn generate_from(&mut self, e: &From) -> Result<()> {
28878 self.write_keyword("FROM");
28880 self.write_space();
28881
28882 use crate::dialects::DialectType;
28886 let has_tablesample = e
28887 .expressions
28888 .iter()
28889 .any(|expr| matches!(expr, Expression::TableSample(_)));
28890 let is_cross_join_dialect = matches!(
28891 self.config.dialect,
28892 Some(DialectType::BigQuery)
28893 | Some(DialectType::Hive)
28894 | Some(DialectType::Spark)
28895 | Some(DialectType::Databricks)
28896 | Some(DialectType::SQLite)
28897 | Some(DialectType::ClickHouse)
28898 );
28899 let source_is_same_as_target2 = self.config.source_dialect.is_some()
28900 && self.config.source_dialect == self.config.dialect;
28901 let source_is_cross_join_dialect2 = matches!(
28902 self.config.source_dialect,
28903 Some(DialectType::BigQuery)
28904 | Some(DialectType::Hive)
28905 | Some(DialectType::Spark)
28906 | Some(DialectType::Databricks)
28907 | Some(DialectType::SQLite)
28908 | Some(DialectType::ClickHouse)
28909 );
28910 let use_cross_join = !has_tablesample
28911 && is_cross_join_dialect
28912 && (source_is_same_as_target2
28913 || source_is_cross_join_dialect2
28914 || self.config.source_dialect.is_none());
28915
28916 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
28918
28919 for (i, expr) in e.expressions.iter().enumerate() {
28920 if i > 0 {
28921 if use_cross_join {
28922 self.write(" CROSS JOIN ");
28923 } else {
28924 self.write(", ");
28925 }
28926 }
28927 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
28928 self.write("(");
28929 self.generate_expression(expr)?;
28930 self.write(")");
28931 } else {
28932 self.generate_expression(expr)?;
28933 }
28934 let leading = Self::extract_table_leading_comments(expr);
28937 for comment in &leading {
28938 self.write_space();
28939 self.write_formatted_comment(comment);
28940 }
28941 }
28942 Ok(())
28943 }
28944
28945 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
28947 match expr {
28948 Expression::Table(t) => t.leading_comments.clone(),
28949 Expression::Pivot(p) => {
28950 if let Expression::Table(t) = &p.this {
28951 t.leading_comments.clone()
28952 } else {
28953 Vec::new()
28954 }
28955 }
28956 _ => Vec::new(),
28957 }
28958 }
28959
28960 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
28961 self.write_keyword("FROM_BASE");
28963 self.write("(");
28964 self.generate_expression(&e.this)?;
28965 self.write(", ");
28966 self.generate_expression(&e.expression)?;
28967 self.write(")");
28968 Ok(())
28969 }
28970
28971 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
28972 self.generate_expression(&e.this)?;
28974 if let Some(zone) = &e.zone {
28975 self.write_space();
28976 self.write_keyword("AT TIME ZONE");
28977 self.write_space();
28978 self.generate_expression(zone)?;
28979 self.write_space();
28980 self.write_keyword("AT TIME ZONE");
28981 self.write(" 'UTC'");
28982 }
28983 Ok(())
28984 }
28985
28986 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
28987 self.write_keyword("GAP_FILL");
28989 self.write("(");
28990 self.generate_expression(&e.this)?;
28991 if let Some(ts_column) = &e.ts_column {
28992 self.write(", ");
28993 self.generate_expression(ts_column)?;
28994 }
28995 if let Some(bucket_width) = &e.bucket_width {
28996 self.write(", ");
28997 self.generate_expression(bucket_width)?;
28998 }
28999 if let Some(partitioning_columns) = &e.partitioning_columns {
29000 self.write(", ");
29001 self.generate_expression(partitioning_columns)?;
29002 }
29003 if let Some(value_columns) = &e.value_columns {
29004 self.write(", ");
29005 self.generate_expression(value_columns)?;
29006 }
29007 self.write(")");
29008 Ok(())
29009 }
29010
29011 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
29012 self.write_keyword("GENERATE_DATE_ARRAY");
29014 self.write("(");
29015 let mut first = true;
29016 if let Some(start) = &e.start {
29017 self.generate_expression(start)?;
29018 first = false;
29019 }
29020 if let Some(end) = &e.end {
29021 if !first {
29022 self.write(", ");
29023 }
29024 self.generate_expression(end)?;
29025 first = false;
29026 }
29027 if let Some(step) = &e.step {
29028 if !first {
29029 self.write(", ");
29030 }
29031 self.generate_expression(step)?;
29032 }
29033 self.write(")");
29034 Ok(())
29035 }
29036
29037 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
29038 self.write_keyword("ML.GENERATE_EMBEDDING");
29040 self.write("(");
29041 self.generate_expression(&e.this)?;
29042 self.write(", ");
29043 self.generate_expression(&e.expression)?;
29044 if let Some(params) = &e.params_struct {
29045 self.write(", ");
29046 self.generate_expression(params)?;
29047 }
29048 self.write(")");
29049 Ok(())
29050 }
29051
29052 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
29053 let fn_name = match self.config.dialect {
29055 Some(DialectType::Presto)
29056 | Some(DialectType::Trino)
29057 | Some(DialectType::Athena)
29058 | Some(DialectType::Spark)
29059 | Some(DialectType::Databricks)
29060 | Some(DialectType::Hive) => "SEQUENCE",
29061 _ => "GENERATE_SERIES",
29062 };
29063 self.write_keyword(fn_name);
29064 self.write("(");
29065 let mut first = true;
29066 if let Some(start) = &e.start {
29067 self.generate_expression(start)?;
29068 first = false;
29069 }
29070 if let Some(end) = &e.end {
29071 if !first {
29072 self.write(", ");
29073 }
29074 self.generate_expression(end)?;
29075 first = false;
29076 }
29077 if let Some(step) = &e.step {
29078 if !first {
29079 self.write(", ");
29080 }
29081 if matches!(
29084 self.config.dialect,
29085 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
29086 ) {
29087 if let Some(converted) = self.convert_week_interval_to_day(step) {
29088 self.generate_expression(&converted)?;
29089 } else {
29090 self.generate_expression(step)?;
29091 }
29092 } else {
29093 self.generate_expression(step)?;
29094 }
29095 }
29096 self.write(")");
29097 Ok(())
29098 }
29099
29100 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
29103 use crate::expressions::*;
29104 if let Expression::Interval(ref iv) = expr {
29105 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
29107 unit: IntervalUnit::Week,
29108 ..
29109 }) = &iv.unit
29110 {
29111 let count = match &iv.this {
29113 Some(Expression::Literal(lit)) => match lit.as_ref() {
29114 Literal::String(s) | Literal::Number(s) => s.clone(),
29115 _ => return None,
29116 },
29117 _ => return None,
29118 };
29119 (true, count)
29120 } else if iv.unit.is_none() {
29121 if let Some(Expression::Literal(lit)) = &iv.this {
29123 if let Literal::String(s) = lit.as_ref() {
29124 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
29125 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
29126 (true, parts[0].to_string())
29127 } else {
29128 (false, String::new())
29129 }
29130 } else {
29131 (false, String::new())
29132 }
29133 } else {
29134 (false, String::new())
29135 }
29136 } else {
29137 (false, String::new())
29138 };
29139
29140 if is_week {
29141 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
29143 let day_interval = Expression::Interval(Box::new(Interval {
29144 this: Some(Expression::Literal(Box::new(Literal::String(
29145 "7".to_string(),
29146 )))),
29147 unit: Some(IntervalUnitSpec::Simple {
29148 unit: IntervalUnit::Day,
29149 use_plural: false,
29150 }),
29151 }));
29152 let mul = Expression::Mul(Box::new(BinaryOp {
29153 left: count_expr,
29154 right: day_interval,
29155 left_comments: vec![],
29156 operator_comments: vec![],
29157 trailing_comments: vec![],
29158 inferred_type: None,
29159 }));
29160 return Some(Expression::Paren(Box::new(Paren {
29161 this: mul,
29162 trailing_comments: vec![],
29163 })));
29164 }
29165 }
29166 None
29167 }
29168
29169 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
29170 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
29172 self.write("(");
29173 let mut first = true;
29174 if let Some(start) = &e.start {
29175 self.generate_expression(start)?;
29176 first = false;
29177 }
29178 if let Some(end) = &e.end {
29179 if !first {
29180 self.write(", ");
29181 }
29182 self.generate_expression(end)?;
29183 first = false;
29184 }
29185 if let Some(step) = &e.step {
29186 if !first {
29187 self.write(", ");
29188 }
29189 self.generate_expression(step)?;
29190 }
29191 self.write(")");
29192 Ok(())
29193 }
29194
29195 fn generate_generated_as_identity_column_constraint(
29196 &mut self,
29197 e: &GeneratedAsIdentityColumnConstraint,
29198 ) -> Result<()> {
29199 use crate::dialects::DialectType;
29200
29201 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29203 self.write_keyword("AUTOINCREMENT");
29204 if let Some(start) = &e.start {
29205 self.write_keyword(" START ");
29206 self.generate_expression(start)?;
29207 }
29208 if let Some(increment) = &e.increment {
29209 self.write_keyword(" INCREMENT ");
29210 self.generate_expression(increment)?;
29211 }
29212 return Ok(());
29213 }
29214
29215 self.write_keyword("GENERATED");
29217 if let Some(this) = &e.this {
29218 if let Expression::Boolean(b) = this.as_ref() {
29220 if b.value {
29221 self.write_keyword(" ALWAYS");
29222 } else {
29223 self.write_keyword(" BY DEFAULT");
29224 if e.on_null.is_some() {
29225 self.write_keyword(" ON NULL");
29226 }
29227 }
29228 } else {
29229 self.write_keyword(" ALWAYS");
29230 }
29231 }
29232 self.write_keyword(" AS IDENTITY");
29233 let has_options = e.start.is_some()
29235 || e.increment.is_some()
29236 || e.minvalue.is_some()
29237 || e.maxvalue.is_some();
29238 if has_options {
29239 self.write(" (");
29240 let mut first = true;
29241 if let Some(start) = &e.start {
29242 self.write_keyword("START WITH ");
29243 self.generate_expression(start)?;
29244 first = false;
29245 }
29246 if let Some(increment) = &e.increment {
29247 if !first {
29248 self.write(" ");
29249 }
29250 self.write_keyword("INCREMENT BY ");
29251 self.generate_expression(increment)?;
29252 first = false;
29253 }
29254 if let Some(minvalue) = &e.minvalue {
29255 if !first {
29256 self.write(" ");
29257 }
29258 self.write_keyword("MINVALUE ");
29259 self.generate_expression(minvalue)?;
29260 first = false;
29261 }
29262 if let Some(maxvalue) = &e.maxvalue {
29263 if !first {
29264 self.write(" ");
29265 }
29266 self.write_keyword("MAXVALUE ");
29267 self.generate_expression(maxvalue)?;
29268 }
29269 self.write(")");
29270 }
29271 Ok(())
29272 }
29273
29274 fn generate_generated_as_row_column_constraint(
29275 &mut self,
29276 e: &GeneratedAsRowColumnConstraint,
29277 ) -> Result<()> {
29278 self.write_keyword("GENERATED ALWAYS AS ROW ");
29280 if e.start.is_some() {
29281 self.write_keyword("START");
29282 } else {
29283 self.write_keyword("END");
29284 }
29285 if e.hidden.is_some() {
29286 self.write_keyword(" HIDDEN");
29287 }
29288 Ok(())
29289 }
29290
29291 fn generate_get(&mut self, e: &Get) -> Result<()> {
29292 self.write_keyword("GET");
29294 self.write_space();
29295 self.generate_expression(&e.this)?;
29296 if let Some(target) = &e.target {
29297 self.write_space();
29298 self.generate_expression(target)?;
29299 }
29300 for prop in &e.properties {
29301 self.write_space();
29302 self.generate_expression(prop)?;
29303 }
29304 Ok(())
29305 }
29306
29307 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
29308 self.generate_expression(&e.this)?;
29310 self.write("[");
29311 self.generate_expression(&e.expression)?;
29312 self.write("]");
29313 Ok(())
29314 }
29315
29316 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
29317 self.write_keyword("GETBIT");
29319 self.write("(");
29320 self.generate_expression(&e.this)?;
29321 self.write(", ");
29322 self.generate_expression(&e.expression)?;
29323 self.write(")");
29324 Ok(())
29325 }
29326
29327 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
29328 if e.is_role {
29330 self.write_keyword("ROLE");
29331 self.write_space();
29332 } else if e.is_group {
29333 self.write_keyword("GROUP");
29334 self.write_space();
29335 } else if e.is_share {
29336 self.write_keyword("SHARE");
29337 self.write_space();
29338 }
29339 self.write(&e.name.name);
29340 Ok(())
29341 }
29342
29343 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
29344 self.generate_expression(&e.this)?;
29346 if !e.expressions.is_empty() {
29347 self.write("(");
29348 for (i, expr) in e.expressions.iter().enumerate() {
29349 if i > 0 {
29350 self.write(", ");
29351 }
29352 self.generate_expression(expr)?;
29353 }
29354 self.write(")");
29355 }
29356 Ok(())
29357 }
29358
29359 fn generate_group(&mut self, e: &Group) -> Result<()> {
29360 self.write_keyword("GROUP BY");
29362 match e.all {
29364 Some(true) => {
29365 self.write_space();
29366 self.write_keyword("ALL");
29367 }
29368 Some(false) => {
29369 self.write_space();
29370 self.write_keyword("DISTINCT");
29371 }
29372 None => {}
29373 }
29374 if !e.expressions.is_empty() {
29375 self.write_space();
29376 for (i, expr) in e.expressions.iter().enumerate() {
29377 if i > 0 {
29378 self.write(", ");
29379 }
29380 self.generate_expression(expr)?;
29381 }
29382 }
29383 if let Some(cube) = &e.cube {
29385 if !e.expressions.is_empty() {
29386 self.write(", ");
29387 } else {
29388 self.write_space();
29389 }
29390 self.generate_expression(cube)?;
29391 }
29392 if let Some(rollup) = &e.rollup {
29393 if !e.expressions.is_empty() || e.cube.is_some() {
29394 self.write(", ");
29395 } else {
29396 self.write_space();
29397 }
29398 self.generate_expression(rollup)?;
29399 }
29400 if let Some(grouping_sets) = &e.grouping_sets {
29401 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
29402 self.write(", ");
29403 } else {
29404 self.write_space();
29405 }
29406 self.generate_expression(grouping_sets)?;
29407 }
29408 if let Some(totals) = &e.totals {
29409 self.write_space();
29410 self.write_keyword("WITH TOTALS");
29411 self.generate_expression(totals)?;
29412 }
29413 Ok(())
29414 }
29415
29416 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
29417 self.write_keyword("GROUP BY");
29419 match e.all {
29421 Some(true) => {
29422 self.write_space();
29423 self.write_keyword("ALL");
29424 }
29425 Some(false) => {
29426 self.write_space();
29427 self.write_keyword("DISTINCT");
29428 }
29429 None => {}
29430 }
29431
29432 let mut trailing_cube = false;
29435 let mut trailing_rollup = false;
29436 let mut regular_expressions: Vec<&Expression> = Vec::new();
29437
29438 for expr in &e.expressions {
29439 match expr {
29440 Expression::Cube(c) if c.expressions.is_empty() => {
29441 trailing_cube = true;
29442 }
29443 Expression::Rollup(r) if r.expressions.is_empty() => {
29444 trailing_rollup = true;
29445 }
29446 _ => {
29447 regular_expressions.push(expr);
29448 }
29449 }
29450 }
29451
29452 if self.config.pretty {
29454 self.write_newline();
29455 self.indent_level += 1;
29456 for (i, expr) in regular_expressions.iter().enumerate() {
29457 if i > 0 {
29458 self.write(",");
29459 self.write_newline();
29460 }
29461 self.write_indent();
29462 self.generate_expression(expr)?;
29463 }
29464 self.indent_level -= 1;
29465 } else {
29466 self.write_space();
29467 for (i, expr) in regular_expressions.iter().enumerate() {
29468 if i > 0 {
29469 self.write(", ");
29470 }
29471 self.generate_expression(expr)?;
29472 }
29473 }
29474
29475 if trailing_cube {
29477 self.write_space();
29478 self.write_keyword("WITH CUBE");
29479 } else if trailing_rollup {
29480 self.write_space();
29481 self.write_keyword("WITH ROLLUP");
29482 }
29483
29484 if e.totals {
29486 self.write_space();
29487 self.write_keyword("WITH TOTALS");
29488 }
29489
29490 Ok(())
29491 }
29492
29493 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
29494 self.write_keyword("GROUPING");
29496 self.write("(");
29497 for (i, expr) in e.expressions.iter().enumerate() {
29498 if i > 0 {
29499 self.write(", ");
29500 }
29501 self.generate_expression(expr)?;
29502 }
29503 self.write(")");
29504 Ok(())
29505 }
29506
29507 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
29508 self.write_keyword("GROUPING_ID");
29510 self.write("(");
29511 for (i, expr) in e.expressions.iter().enumerate() {
29512 if i > 0 {
29513 self.write(", ");
29514 }
29515 self.generate_expression(expr)?;
29516 }
29517 self.write(")");
29518 Ok(())
29519 }
29520
29521 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
29522 self.write_keyword("GROUPING SETS");
29524 self.write(" (");
29525 for (i, expr) in e.expressions.iter().enumerate() {
29526 if i > 0 {
29527 self.write(", ");
29528 }
29529 self.generate_expression(expr)?;
29530 }
29531 self.write(")");
29532 Ok(())
29533 }
29534
29535 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
29536 self.write_keyword("HASH_AGG");
29538 self.write("(");
29539 self.generate_expression(&e.this)?;
29540 for expr in &e.expressions {
29541 self.write(", ");
29542 self.generate_expression(expr)?;
29543 }
29544 self.write(")");
29545 Ok(())
29546 }
29547
29548 fn generate_having(&mut self, e: &Having) -> Result<()> {
29549 self.write_keyword("HAVING");
29551 self.write_space();
29552 self.generate_expression(&e.this)?;
29553 Ok(())
29554 }
29555
29556 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
29557 self.generate_expression(&e.this)?;
29559 self.write_space();
29560 self.write_keyword("HAVING");
29561 self.write_space();
29562 if e.max.is_some() {
29563 self.write_keyword("MAX");
29564 } else {
29565 self.write_keyword("MIN");
29566 }
29567 self.write_space();
29568 self.generate_expression(&e.expression)?;
29569 Ok(())
29570 }
29571
29572 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
29573 use crate::dialects::DialectType;
29574 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
29576 if let Expression::Literal(ref lit) = *e.this {
29578 if let Literal::String(ref s) = lit.as_ref() {
29579 return self.generate_string_literal(s);
29580 }
29581 }
29582 }
29583 if matches!(
29585 self.config.dialect,
29586 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
29587 ) {
29588 self.write("$");
29589 if let Some(tag) = &e.tag {
29590 self.generate_expression(tag)?;
29591 }
29592 self.write("$");
29593 self.generate_expression(&e.this)?;
29594 self.write("$");
29595 if let Some(tag) = &e.tag {
29596 self.generate_expression(tag)?;
29597 }
29598 self.write("$");
29599 return Ok(());
29600 }
29601 self.write("$");
29603 if let Some(tag) = &e.tag {
29604 self.generate_expression(tag)?;
29605 }
29606 self.write("$");
29607 self.generate_expression(&e.this)?;
29608 self.write("$");
29609 if let Some(tag) = &e.tag {
29610 self.generate_expression(tag)?;
29611 }
29612 self.write("$");
29613 Ok(())
29614 }
29615
29616 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
29617 self.write_keyword("HEX_ENCODE");
29619 self.write("(");
29620 self.generate_expression(&e.this)?;
29621 self.write(")");
29622 Ok(())
29623 }
29624
29625 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
29626 match e.this.as_ref() {
29629 Expression::Identifier(id) => self.write(&id.name),
29630 other => self.generate_expression(other)?,
29631 }
29632 self.write(" (");
29633 self.write(&e.kind);
29634 self.write(" => ");
29635 self.generate_expression(&e.expression)?;
29636 self.write(")");
29637 Ok(())
29638 }
29639
29640 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
29641 self.write_keyword("HLL");
29643 self.write("(");
29644 self.generate_expression(&e.this)?;
29645 for expr in &e.expressions {
29646 self.write(", ");
29647 self.generate_expression(expr)?;
29648 }
29649 self.write(")");
29650 Ok(())
29651 }
29652
29653 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
29654 if e.input_.is_some() && e.output.is_some() {
29656 self.write_keyword("IN OUT");
29657 } else if e.input_.is_some() {
29658 self.write_keyword("IN");
29659 } else if e.output.is_some() {
29660 self.write_keyword("OUT");
29661 }
29662 Ok(())
29663 }
29664
29665 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
29666 self.write_keyword("INCLUDE");
29668 self.write_space();
29669 self.generate_expression(&e.this)?;
29670 if let Some(column_def) = &e.column_def {
29671 self.write_space();
29672 self.generate_expression(column_def)?;
29673 }
29674 if let Some(alias) = &e.alias {
29675 self.write_space();
29676 self.write_keyword("AS");
29677 self.write_space();
29678 self.write(alias);
29679 }
29680 Ok(())
29681 }
29682
29683 fn generate_index(&mut self, e: &Index) -> Result<()> {
29684 if e.unique {
29686 self.write_keyword("UNIQUE");
29687 self.write_space();
29688 }
29689 if e.primary.is_some() {
29690 self.write_keyword("PRIMARY");
29691 self.write_space();
29692 }
29693 if e.amp.is_some() {
29694 self.write_keyword("AMP");
29695 self.write_space();
29696 }
29697 if e.table.is_none() {
29698 self.write_keyword("INDEX");
29699 self.write_space();
29700 }
29701 if let Some(name) = &e.this {
29702 self.generate_expression(name)?;
29703 self.write_space();
29704 }
29705 if let Some(table) = &e.table {
29706 self.write_keyword("ON");
29707 self.write_space();
29708 self.generate_expression(table)?;
29709 }
29710 if !e.params.is_empty() {
29711 self.write("(");
29712 for (i, param) in e.params.iter().enumerate() {
29713 if i > 0 {
29714 self.write(", ");
29715 }
29716 self.generate_expression(param)?;
29717 }
29718 self.write(")");
29719 }
29720 Ok(())
29721 }
29722
29723 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
29724 if let Some(kind) = &e.kind {
29726 self.write(kind);
29727 self.write_space();
29728 }
29729 self.write_keyword("INDEX");
29730 if let Some(this) = &e.this {
29731 self.write_space();
29732 self.generate_expression(this)?;
29733 }
29734 if let Some(index_type) = &e.index_type {
29735 self.write_space();
29736 self.write_keyword("USING");
29737 self.write_space();
29738 self.generate_expression(index_type)?;
29739 }
29740 if !e.expressions.is_empty() {
29741 self.write(" (");
29742 for (i, expr) in e.expressions.iter().enumerate() {
29743 if i > 0 {
29744 self.write(", ");
29745 }
29746 self.generate_expression(expr)?;
29747 }
29748 self.write(")");
29749 }
29750 for opt in &e.options {
29751 self.write_space();
29752 self.generate_expression(opt)?;
29753 }
29754 Ok(())
29755 }
29756
29757 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
29758 if let Some(key_block_size) = &e.key_block_size {
29760 self.write_keyword("KEY_BLOCK_SIZE");
29761 self.write(" = ");
29762 self.generate_expression(key_block_size)?;
29763 } else if let Some(using) = &e.using {
29764 self.write_keyword("USING");
29765 self.write_space();
29766 self.generate_expression(using)?;
29767 } else if let Some(parser) = &e.parser {
29768 self.write_keyword("WITH PARSER");
29769 self.write_space();
29770 self.generate_expression(parser)?;
29771 } else if let Some(comment) = &e.comment {
29772 self.write_keyword("COMMENT");
29773 self.write_space();
29774 self.generate_expression(comment)?;
29775 } else if let Some(visible) = &e.visible {
29776 self.generate_expression(visible)?;
29777 } else if let Some(engine_attr) = &e.engine_attr {
29778 self.write_keyword("ENGINE_ATTRIBUTE");
29779 self.write(" = ");
29780 self.generate_expression(engine_attr)?;
29781 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
29782 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
29783 self.write(" = ");
29784 self.generate_expression(secondary_engine_attr)?;
29785 }
29786 Ok(())
29787 }
29788
29789 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
29790 if let Some(using) = &e.using {
29792 self.write_keyword("USING");
29793 self.write_space();
29794 self.generate_expression(using)?;
29795 }
29796 if !e.columns.is_empty() {
29797 self.write("(");
29798 for (i, col) in e.columns.iter().enumerate() {
29799 if i > 0 {
29800 self.write(", ");
29801 }
29802 self.generate_expression(col)?;
29803 }
29804 self.write(")");
29805 }
29806 if let Some(partition_by) = &e.partition_by {
29807 self.write_space();
29808 self.write_keyword("PARTITION BY");
29809 self.write_space();
29810 self.generate_expression(partition_by)?;
29811 }
29812 if let Some(where_) = &e.where_ {
29813 self.write_space();
29814 self.generate_expression(where_)?;
29815 }
29816 if let Some(include) = &e.include {
29817 self.write_space();
29818 self.write_keyword("INCLUDE");
29819 self.write(" (");
29820 self.generate_expression(include)?;
29821 self.write(")");
29822 }
29823 if let Some(with_storage) = &e.with_storage {
29824 self.write_space();
29825 self.write_keyword("WITH");
29826 self.write(" (");
29827 self.generate_expression(with_storage)?;
29828 self.write(")");
29829 }
29830 if let Some(tablespace) = &e.tablespace {
29831 self.write_space();
29832 self.write_keyword("USING INDEX TABLESPACE");
29833 self.write_space();
29834 self.generate_expression(tablespace)?;
29835 }
29836 Ok(())
29837 }
29838
29839 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
29840 if let Expression::Identifier(id) = &*e.this {
29844 self.write_keyword(&id.name);
29845 } else {
29846 self.generate_expression(&e.this)?;
29847 }
29848 self.write_space();
29849 self.write_keyword("INDEX");
29850 if let Some(target) = &e.target {
29851 self.write_space();
29852 self.write_keyword("FOR");
29853 self.write_space();
29854 if let Expression::Identifier(id) = &**target {
29855 self.write_keyword(&id.name);
29856 } else {
29857 self.generate_expression(target)?;
29858 }
29859 }
29860 self.write(" (");
29862 for (i, expr) in e.expressions.iter().enumerate() {
29863 if i > 0 {
29864 self.write(", ");
29865 }
29866 self.generate_expression(expr)?;
29867 }
29868 self.write(")");
29869 Ok(())
29870 }
29871
29872 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
29873 self.write_keyword("INHERITS");
29875 self.write(" (");
29876 for (i, expr) in e.expressions.iter().enumerate() {
29877 if i > 0 {
29878 self.write(", ");
29879 }
29880 self.generate_expression(expr)?;
29881 }
29882 self.write(")");
29883 Ok(())
29884 }
29885
29886 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
29887 self.write_keyword("INPUT");
29889 self.write("(");
29890 self.generate_expression(&e.this)?;
29891 self.write(")");
29892 Ok(())
29893 }
29894
29895 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
29896 if let Some(input_format) = &e.input_format {
29898 self.write_keyword("INPUTFORMAT");
29899 self.write_space();
29900 self.generate_expression(input_format)?;
29901 }
29902 if let Some(output_format) = &e.output_format {
29903 if e.input_format.is_some() {
29904 self.write(" ");
29905 }
29906 self.write_keyword("OUTPUTFORMAT");
29907 self.write_space();
29908 self.generate_expression(output_format)?;
29909 }
29910 Ok(())
29911 }
29912
29913 fn generate_install(&mut self, e: &Install) -> Result<()> {
29914 if e.force.is_some() {
29916 self.write_keyword("FORCE");
29917 self.write_space();
29918 }
29919 self.write_keyword("INSTALL");
29920 self.write_space();
29921 self.generate_expression(&e.this)?;
29922 if let Some(from) = &e.from_ {
29923 self.write_space();
29924 self.write_keyword("FROM");
29925 self.write_space();
29926 self.generate_expression(from)?;
29927 }
29928 Ok(())
29929 }
29930
29931 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
29932 self.write_keyword("INTERVAL");
29934 self.write_space();
29935 self.generate_expression(&e.expression)?;
29937 if let Some(unit) = &e.unit {
29938 self.write_space();
29939 self.write(unit);
29940 }
29941 Ok(())
29942 }
29943
29944 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
29945 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
29947 self.write_space();
29948 self.write_keyword("TO");
29949 self.write_space();
29950 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
29951 Ok(())
29952 }
29953
29954 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
29955 self.write_keyword("INTO");
29957 if e.temporary {
29958 self.write_keyword(" TEMPORARY");
29959 }
29960 if e.unlogged.is_some() {
29961 self.write_keyword(" UNLOGGED");
29962 }
29963 if let Some(this) = &e.this {
29964 self.write_space();
29965 self.generate_expression(this)?;
29966 }
29967 if !e.expressions.is_empty() {
29968 self.write(" (");
29969 for (i, expr) in e.expressions.iter().enumerate() {
29970 if i > 0 {
29971 self.write(", ");
29972 }
29973 self.generate_expression(expr)?;
29974 }
29975 self.write(")");
29976 }
29977 Ok(())
29978 }
29979
29980 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
29981 self.generate_expression(&e.this)?;
29983 self.write_space();
29984 self.generate_expression(&e.expression)?;
29985 Ok(())
29986 }
29987
29988 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
29989 self.write_keyword("WITH");
29991 if e.no.is_some() {
29992 self.write_keyword(" NO");
29993 }
29994 if e.concurrent.is_some() {
29995 self.write_keyword(" CONCURRENT");
29996 }
29997 self.write_keyword(" ISOLATED LOADING");
29998 if let Some(target) = &e.target {
29999 self.write_space();
30000 self.generate_expression(target)?;
30001 }
30002 Ok(())
30003 }
30004
30005 fn generate_json(&mut self, e: &JSON) -> Result<()> {
30006 self.write_keyword("JSON");
30008 if let Some(this) = &e.this {
30009 self.write_space();
30010 self.generate_expression(this)?;
30011 }
30012 if let Some(with_) = &e.with_ {
30013 if let Expression::Boolean(b) = with_.as_ref() {
30015 if b.value {
30016 self.write_keyword(" WITH");
30017 } else {
30018 self.write_keyword(" WITHOUT");
30019 }
30020 }
30021 }
30022 if e.unique {
30023 self.write_keyword(" UNIQUE KEYS");
30024 }
30025 Ok(())
30026 }
30027
30028 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
30029 self.write_keyword("JSON_ARRAY");
30031 self.write("(");
30032 for (i, expr) in e.expressions.iter().enumerate() {
30033 if i > 0 {
30034 self.write(", ");
30035 }
30036 self.generate_expression(expr)?;
30037 }
30038 if let Some(null_handling) = &e.null_handling {
30039 self.write_space();
30040 self.generate_expression(null_handling)?;
30041 }
30042 if let Some(return_type) = &e.return_type {
30043 self.write_space();
30044 self.write_keyword("RETURNING");
30045 self.write_space();
30046 self.generate_expression(return_type)?;
30047 }
30048 if e.strict.is_some() {
30049 self.write_space();
30050 self.write_keyword("STRICT");
30051 }
30052 self.write(")");
30053 Ok(())
30054 }
30055
30056 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
30057 self.write_keyword("JSON_ARRAYAGG");
30059 self.write("(");
30060 self.generate_expression(&e.this)?;
30061 if let Some(order) = &e.order {
30062 self.write_space();
30063 if let Expression::OrderBy(ob) = order.as_ref() {
30065 self.write_keyword("ORDER BY");
30066 self.write_space();
30067 for (i, ord) in ob.expressions.iter().enumerate() {
30068 if i > 0 {
30069 self.write(", ");
30070 }
30071 self.generate_ordered(ord)?;
30072 }
30073 } else {
30074 self.generate_expression(order)?;
30076 }
30077 }
30078 if let Some(null_handling) = &e.null_handling {
30079 self.write_space();
30080 self.generate_expression(null_handling)?;
30081 }
30082 if let Some(return_type) = &e.return_type {
30083 self.write_space();
30084 self.write_keyword("RETURNING");
30085 self.write_space();
30086 self.generate_expression(return_type)?;
30087 }
30088 if e.strict.is_some() {
30089 self.write_space();
30090 self.write_keyword("STRICT");
30091 }
30092 self.write(")");
30093 Ok(())
30094 }
30095
30096 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
30097 self.write_keyword("JSON_OBJECTAGG");
30099 self.write("(");
30100 for (i, expr) in e.expressions.iter().enumerate() {
30101 if i > 0 {
30102 self.write(", ");
30103 }
30104 self.generate_expression(expr)?;
30105 }
30106 if let Some(null_handling) = &e.null_handling {
30107 self.write_space();
30108 self.generate_expression(null_handling)?;
30109 }
30110 if let Some(unique_keys) = &e.unique_keys {
30111 self.write_space();
30112 if let Expression::Boolean(b) = unique_keys.as_ref() {
30113 if b.value {
30114 self.write_keyword("WITH UNIQUE KEYS");
30115 } else {
30116 self.write_keyword("WITHOUT UNIQUE KEYS");
30117 }
30118 }
30119 }
30120 if let Some(return_type) = &e.return_type {
30121 self.write_space();
30122 self.write_keyword("RETURNING");
30123 self.write_space();
30124 self.generate_expression(return_type)?;
30125 }
30126 self.write(")");
30127 Ok(())
30128 }
30129
30130 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
30131 self.write_keyword("JSON_ARRAY_APPEND");
30133 self.write("(");
30134 self.generate_expression(&e.this)?;
30135 for expr in &e.expressions {
30136 self.write(", ");
30137 self.generate_expression(expr)?;
30138 }
30139 self.write(")");
30140 Ok(())
30141 }
30142
30143 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
30144 self.write_keyword("JSON_ARRAY_CONTAINS");
30146 self.write("(");
30147 self.generate_expression(&e.this)?;
30148 self.write(", ");
30149 self.generate_expression(&e.expression)?;
30150 self.write(")");
30151 Ok(())
30152 }
30153
30154 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
30155 self.write_keyword("JSON_ARRAY_INSERT");
30157 self.write("(");
30158 self.generate_expression(&e.this)?;
30159 for expr in &e.expressions {
30160 self.write(", ");
30161 self.generate_expression(expr)?;
30162 }
30163 self.write(")");
30164 Ok(())
30165 }
30166
30167 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
30168 self.write_keyword("JSONB_EXISTS");
30170 self.write("(");
30171 self.generate_expression(&e.this)?;
30172 if let Some(path) = &e.path {
30173 self.write(", ");
30174 self.generate_expression(path)?;
30175 }
30176 self.write(")");
30177 Ok(())
30178 }
30179
30180 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
30181 self.write_keyword("JSONB_EXTRACT_SCALAR");
30183 self.write("(");
30184 self.generate_expression(&e.this)?;
30185 self.write(", ");
30186 self.generate_expression(&e.expression)?;
30187 self.write(")");
30188 Ok(())
30189 }
30190
30191 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
30192 self.write_keyword("JSONB_OBJECT_AGG");
30194 self.write("(");
30195 self.generate_expression(&e.this)?;
30196 self.write(", ");
30197 self.generate_expression(&e.expression)?;
30198 self.write(")");
30199 Ok(())
30200 }
30201
30202 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
30203 if let Some(nested_schema) = &e.nested_schema {
30205 self.write_keyword("NESTED");
30206 if let Some(path) = &e.path {
30207 self.write_space();
30208 self.write_keyword("PATH");
30209 self.write_space();
30210 self.generate_expression(path)?;
30211 }
30212 self.write_space();
30213 self.generate_expression(nested_schema)?;
30214 } else {
30215 if let Some(this) = &e.this {
30216 self.generate_expression(this)?;
30217 }
30218 if let Some(kind) = &e.kind {
30219 self.write_space();
30220 self.write(kind);
30221 }
30222 if e.format_json {
30223 self.write_space();
30224 self.write_keyword("FORMAT JSON");
30225 }
30226 if let Some(path) = &e.path {
30227 self.write_space();
30228 self.write_keyword("PATH");
30229 self.write_space();
30230 self.generate_expression(path)?;
30231 }
30232 if e.ordinality.is_some() {
30233 self.write_keyword(" FOR ORDINALITY");
30234 }
30235 }
30236 Ok(())
30237 }
30238
30239 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
30240 self.write_keyword("JSON_EXISTS");
30242 self.write("(");
30243 self.generate_expression(&e.this)?;
30244 if let Some(path) = &e.path {
30245 self.write(", ");
30246 self.generate_expression(path)?;
30247 }
30248 if let Some(passing) = &e.passing {
30249 self.write_space();
30250 self.write_keyword("PASSING");
30251 self.write_space();
30252 self.generate_expression(passing)?;
30253 }
30254 if let Some(on_condition) = &e.on_condition {
30255 self.write_space();
30256 self.generate_expression(on_condition)?;
30257 }
30258 self.write(")");
30259 Ok(())
30260 }
30261
30262 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
30263 self.generate_expression(&e.this)?;
30264 self.write(".:");
30265 if Self::data_type_has_nested_expressions(&e.to) {
30269 let saved = std::mem::take(&mut self.output);
30271 self.generate_data_type(&e.to)?;
30272 let type_sql = std::mem::replace(&mut self.output, saved);
30273 self.write("\"");
30274 self.write(&type_sql);
30275 self.write("\"");
30276 } else {
30277 self.generate_data_type(&e.to)?;
30278 }
30279 Ok(())
30280 }
30281
30282 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
30285 matches!(
30286 dt,
30287 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
30288 )
30289 }
30290
30291 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
30292 self.write_keyword("JSON_EXTRACT_ARRAY");
30294 self.write("(");
30295 self.generate_expression(&e.this)?;
30296 if let Some(expr) = &e.expression {
30297 self.write(", ");
30298 self.generate_expression(expr)?;
30299 }
30300 self.write(")");
30301 Ok(())
30302 }
30303
30304 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
30305 if let Some(option) = &e.option {
30307 self.generate_expression(option)?;
30308 self.write_space();
30309 }
30310 self.write_keyword("QUOTES");
30311 if e.scalar.is_some() {
30312 self.write_keyword(" SCALAR_ONLY");
30313 }
30314 Ok(())
30315 }
30316
30317 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
30318 self.write_keyword("JSON_EXTRACT_SCALAR");
30320 self.write("(");
30321 self.generate_expression(&e.this)?;
30322 self.write(", ");
30323 self.generate_expression(&e.expression)?;
30324 self.write(")");
30325 Ok(())
30326 }
30327
30328 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
30329 if e.variant_extract.is_some() {
30333 use crate::dialects::DialectType;
30334 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
30335 self.generate_expression(&e.this)?;
30339 self.write(":");
30340 match e.expression.as_ref() {
30341 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
30342 let Literal::String(s) = lit.as_ref() else {
30343 unreachable!()
30344 };
30345 self.write_databricks_json_path(s);
30346 }
30347 _ => {
30348 self.generate_expression(&e.expression)?;
30350 }
30351 }
30352 } else {
30353 self.write_keyword("GET_PATH");
30355 self.write("(");
30356 self.generate_expression(&e.this)?;
30357 self.write(", ");
30358 self.generate_expression(&e.expression)?;
30359 self.write(")");
30360 }
30361 } else {
30362 self.write_keyword("JSON_EXTRACT");
30363 self.write("(");
30364 self.generate_expression(&e.this)?;
30365 self.write(", ");
30366 self.generate_expression(&e.expression)?;
30367 for expr in &e.expressions {
30368 self.write(", ");
30369 self.generate_expression(expr)?;
30370 }
30371 self.write(")");
30372 }
30373 Ok(())
30374 }
30375
30376 fn write_databricks_json_path(&mut self, path: &str) {
30380 if path.starts_with("[\"") || path.starts_with("['") {
30383 self.write(path);
30384 return;
30385 }
30386 let mut first = true;
30390 for segment in path.split('.') {
30391 if !first {
30392 self.write(".");
30393 }
30394 first = false;
30395 if let Some(bracket_pos) = segment.find('[') {
30397 let key = &segment[..bracket_pos];
30398 let subscript = &segment[bracket_pos..];
30399 if key.is_empty() {
30400 self.write(segment);
30402 } else if Self::is_safe_json_path_key(key) {
30403 self.write(key);
30404 self.write(subscript);
30405 } else {
30406 self.write("[\"");
30407 self.write(key);
30408 self.write("\"]");
30409 self.write(subscript);
30410 }
30411 } else if Self::is_safe_json_path_key(segment) {
30412 self.write(segment);
30413 } else {
30414 self.write("[\"");
30415 self.write(segment);
30416 self.write("\"]");
30417 }
30418 }
30419 }
30420
30421 fn is_safe_json_path_key(key: &str) -> bool {
30424 if key.is_empty() {
30425 return false;
30426 }
30427 let mut chars = key.chars();
30428 let first = chars.next().unwrap();
30429 if first != '_' && !first.is_ascii_alphabetic() {
30430 return false;
30431 }
30432 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
30433 }
30434
30435 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
30436 if let Some(this) = &e.this {
30439 self.generate_expression(this)?;
30440 self.write_space();
30441 }
30442 self.write_keyword("FORMAT JSON");
30443 Ok(())
30444 }
30445
30446 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
30447 self.generate_expression(&e.this)?;
30449 self.write(": ");
30450 self.generate_expression(&e.expression)?;
30451 Ok(())
30452 }
30453
30454 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
30455 self.write_keyword("JSON_KEYS");
30457 self.write("(");
30458 self.generate_expression(&e.this)?;
30459 if let Some(expr) = &e.expression {
30460 self.write(", ");
30461 self.generate_expression(expr)?;
30462 }
30463 for expr in &e.expressions {
30464 self.write(", ");
30465 self.generate_expression(expr)?;
30466 }
30467 self.write(")");
30468 Ok(())
30469 }
30470
30471 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
30472 self.write_keyword("JSON_KEYS");
30474 self.write("(");
30475 self.generate_expression(&e.this)?;
30476 if let Some(expr) = &e.expression {
30477 self.write(", ");
30478 self.generate_expression(expr)?;
30479 }
30480 self.write(")");
30481 Ok(())
30482 }
30483
30484 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
30485 let mut path_str = String::new();
30488 for expr in &e.expressions {
30489 match expr {
30490 Expression::JSONPathRoot(_) => {
30491 path_str.push('$');
30492 }
30493 Expression::JSONPathKey(k) => {
30494 if let Expression::Literal(lit) = k.this.as_ref() {
30496 if let crate::expressions::Literal::String(s) = lit.as_ref() {
30497 path_str.push('.');
30498 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
30500 if needs_quoting {
30501 path_str.push('"');
30502 path_str.push_str(s);
30503 path_str.push('"');
30504 } else {
30505 path_str.push_str(s);
30506 }
30507 }
30508 }
30509 }
30510 Expression::JSONPathSubscript(s) => {
30511 if let Expression::Literal(lit) = s.this.as_ref() {
30513 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
30514 path_str.push('[');
30515 path_str.push_str(n);
30516 path_str.push(']');
30517 }
30518 }
30519 }
30520 _ => {
30521 let mut temp_gen = Self::with_arc_config(self.config.clone());
30523 temp_gen.generate_expression(expr)?;
30524 path_str.push_str(&temp_gen.output);
30525 }
30526 }
30527 }
30528 self.write("'");
30530 self.write(&path_str);
30531 self.write("'");
30532 Ok(())
30533 }
30534
30535 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
30536 self.write("?(");
30538 self.generate_expression(&e.this)?;
30539 self.write(")");
30540 Ok(())
30541 }
30542
30543 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
30544 self.write(".");
30546 self.generate_expression(&e.this)?;
30547 Ok(())
30548 }
30549
30550 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
30551 self.write("..");
30553 if let Some(this) = &e.this {
30554 self.generate_expression(this)?;
30555 }
30556 Ok(())
30557 }
30558
30559 fn generate_json_path_root(&mut self) -> Result<()> {
30560 self.write("$");
30562 Ok(())
30563 }
30564
30565 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
30566 self.write("(");
30568 self.generate_expression(&e.this)?;
30569 self.write(")");
30570 Ok(())
30571 }
30572
30573 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
30574 self.generate_expression(&e.this)?;
30576 Ok(())
30577 }
30578
30579 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
30580 self.write("[");
30582 if let Some(start) = &e.start {
30583 self.generate_expression(start)?;
30584 }
30585 self.write(":");
30586 if let Some(end) = &e.end {
30587 self.generate_expression(end)?;
30588 }
30589 if let Some(step) = &e.step {
30590 self.write(":");
30591 self.generate_expression(step)?;
30592 }
30593 self.write("]");
30594 Ok(())
30595 }
30596
30597 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
30598 self.write("[");
30600 self.generate_expression(&e.this)?;
30601 self.write("]");
30602 Ok(())
30603 }
30604
30605 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
30606 self.write("[");
30608 for (i, expr) in e.expressions.iter().enumerate() {
30609 if i > 0 {
30610 self.write(", ");
30611 }
30612 self.generate_expression(expr)?;
30613 }
30614 self.write("]");
30615 Ok(())
30616 }
30617
30618 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
30619 self.write_keyword("JSON_REMOVE");
30621 self.write("(");
30622 self.generate_expression(&e.this)?;
30623 for expr in &e.expressions {
30624 self.write(", ");
30625 self.generate_expression(expr)?;
30626 }
30627 self.write(")");
30628 Ok(())
30629 }
30630
30631 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
30632 self.write_keyword("COLUMNS");
30635 self.write("(");
30636
30637 if self.config.pretty && !e.expressions.is_empty() {
30638 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
30640 for expr in &e.expressions {
30641 let mut temp_gen = Generator::with_arc_config(self.config.clone());
30642 temp_gen.generate_expression(expr)?;
30643 expr_strings.push(temp_gen.output);
30644 }
30645
30646 if self.too_wide(&expr_strings) {
30648 self.write_newline();
30650 self.indent_level += 1;
30651 for (i, expr_str) in expr_strings.iter().enumerate() {
30652 if i > 0 {
30653 self.write(",");
30654 self.write_newline();
30655 }
30656 self.write_indent();
30657 self.write(expr_str);
30658 }
30659 self.write_newline();
30660 self.indent_level -= 1;
30661 self.write_indent();
30662 } else {
30663 for (i, expr_str) in expr_strings.iter().enumerate() {
30665 if i > 0 {
30666 self.write(", ");
30667 }
30668 self.write(expr_str);
30669 }
30670 }
30671 } else {
30672 for (i, expr) in e.expressions.iter().enumerate() {
30674 if i > 0 {
30675 self.write(", ");
30676 }
30677 self.generate_expression(expr)?;
30678 }
30679 }
30680 self.write(")");
30681 Ok(())
30682 }
30683
30684 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
30685 self.write_keyword("JSON_SET");
30687 self.write("(");
30688 self.generate_expression(&e.this)?;
30689 for expr in &e.expressions {
30690 self.write(", ");
30691 self.generate_expression(expr)?;
30692 }
30693 self.write(")");
30694 Ok(())
30695 }
30696
30697 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
30698 self.write_keyword("JSON_STRIP_NULLS");
30700 self.write("(");
30701 self.generate_expression(&e.this)?;
30702 if let Some(expr) = &e.expression {
30703 self.write(", ");
30704 self.generate_expression(expr)?;
30705 }
30706 self.write(")");
30707 Ok(())
30708 }
30709
30710 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
30711 self.write_keyword("JSON_TABLE");
30713 self.write("(");
30714 self.generate_expression(&e.this)?;
30715 if let Some(path) = &e.path {
30716 self.write(", ");
30717 self.generate_expression(path)?;
30718 }
30719 if let Some(error_handling) = &e.error_handling {
30720 self.write_space();
30721 self.generate_expression(error_handling)?;
30722 }
30723 if let Some(empty_handling) = &e.empty_handling {
30724 self.write_space();
30725 self.generate_expression(empty_handling)?;
30726 }
30727 if let Some(schema) = &e.schema {
30728 self.write_space();
30729 self.generate_expression(schema)?;
30730 }
30731 self.write(")");
30732 Ok(())
30733 }
30734
30735 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
30736 self.write_keyword("JSON_TYPE");
30738 self.write("(");
30739 self.generate_expression(&e.this)?;
30740 self.write(")");
30741 Ok(())
30742 }
30743
30744 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
30745 self.write_keyword("JSON_VALUE");
30747 self.write("(");
30748 self.generate_expression(&e.this)?;
30749 if let Some(path) = &e.path {
30750 self.write(", ");
30751 self.generate_expression(path)?;
30752 }
30753 if let Some(returning) = &e.returning {
30754 self.write_space();
30755 self.write_keyword("RETURNING");
30756 self.write_space();
30757 self.generate_expression(returning)?;
30758 }
30759 if let Some(on_condition) = &e.on_condition {
30760 self.write_space();
30761 self.generate_expression(on_condition)?;
30762 }
30763 self.write(")");
30764 Ok(())
30765 }
30766
30767 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
30768 self.write_keyword("JSON_VALUE_ARRAY");
30770 self.write("(");
30771 self.generate_expression(&e.this)?;
30772 self.write(")");
30773 Ok(())
30774 }
30775
30776 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
30777 self.write_keyword("JAROWINKLER_SIMILARITY");
30779 self.write("(");
30780 self.generate_expression(&e.this)?;
30781 self.write(", ");
30782 self.generate_expression(&e.expression)?;
30783 self.write(")");
30784 Ok(())
30785 }
30786
30787 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
30788 self.generate_expression(&e.this)?;
30790 self.write("(");
30791 for (i, expr) in e.expressions.iter().enumerate() {
30792 if i > 0 {
30793 self.write(", ");
30794 }
30795 self.generate_expression(expr)?;
30796 }
30797 self.write(")");
30798 Ok(())
30799 }
30800
30801 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
30802 if e.no.is_some() {
30804 self.write_keyword("NO ");
30805 }
30806 if let Some(local) = &e.local {
30807 self.generate_expression(local)?;
30808 self.write_space();
30809 }
30810 if e.dual.is_some() {
30811 self.write_keyword("DUAL ");
30812 }
30813 if e.before.is_some() {
30814 self.write_keyword("BEFORE ");
30815 }
30816 if e.after.is_some() {
30817 self.write_keyword("AFTER ");
30818 }
30819 self.write_keyword("JOURNAL");
30820 Ok(())
30821 }
30822
30823 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
30824 self.write_keyword("LANGUAGE");
30826 self.write_space();
30827 self.generate_expression(&e.this)?;
30828 Ok(())
30829 }
30830
30831 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
30832 if e.view.is_some() {
30834 self.write_keyword("LATERAL VIEW");
30836 if e.outer.is_some() {
30837 self.write_space();
30838 self.write_keyword("OUTER");
30839 }
30840 self.write_space();
30841 self.generate_expression(&e.this)?;
30842 if let Some(alias) = &e.alias {
30843 self.write_space();
30844 self.write(alias);
30845 }
30846 } else {
30847 self.write_keyword("LATERAL");
30849 self.write_space();
30850 self.generate_expression(&e.this)?;
30851 if e.ordinality.is_some() {
30852 self.write_space();
30853 self.write_keyword("WITH ORDINALITY");
30854 }
30855 if let Some(alias) = &e.alias {
30856 self.write_space();
30857 self.write_keyword("AS");
30858 self.write_space();
30859 self.write(alias);
30860 if !e.column_aliases.is_empty() {
30861 self.write("(");
30862 for (i, col) in e.column_aliases.iter().enumerate() {
30863 if i > 0 {
30864 self.write(", ");
30865 }
30866 self.write(col);
30867 }
30868 self.write(")");
30869 }
30870 }
30871 }
30872 Ok(())
30873 }
30874
30875 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
30876 self.write_keyword("LIKE");
30878 self.write_space();
30879 self.generate_expression(&e.this)?;
30880 for expr in &e.expressions {
30881 self.write_space();
30882 self.generate_expression(expr)?;
30883 }
30884 Ok(())
30885 }
30886
30887 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
30888 self.write_keyword("LIMIT");
30889 self.write_space();
30890 self.write_limit_expr(&e.this)?;
30891 if e.percent {
30892 self.write_space();
30893 self.write_keyword("PERCENT");
30894 }
30895 for comment in &e.comments {
30897 self.write(" ");
30898 self.write_formatted_comment(comment);
30899 }
30900 Ok(())
30901 }
30902
30903 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
30904 if e.percent.is_some() {
30906 self.write_keyword(" PERCENT");
30907 }
30908 if e.rows.is_some() {
30909 self.write_keyword(" ROWS");
30910 }
30911 if e.with_ties.is_some() {
30912 self.write_keyword(" WITH TIES");
30913 } else if e.rows.is_some() {
30914 self.write_keyword(" ONLY");
30915 }
30916 Ok(())
30917 }
30918
30919 fn generate_list(&mut self, e: &List) -> Result<()> {
30920 use crate::dialects::DialectType;
30921 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
30922
30923 if e.expressions.len() == 1 {
30925 if let Expression::Select(_) = &e.expressions[0] {
30926 self.write_keyword("LIST");
30927 self.write("(");
30928 self.generate_expression(&e.expressions[0])?;
30929 self.write(")");
30930 return Ok(());
30931 }
30932 }
30933
30934 if is_materialize {
30936 self.write_keyword("LIST");
30937 self.write("[");
30938 for (i, expr) in e.expressions.iter().enumerate() {
30939 if i > 0 {
30940 self.write(", ");
30941 }
30942 self.generate_expression(expr)?;
30943 }
30944 self.write("]");
30945 } else {
30946 self.write_keyword("LIST");
30948 self.write("(");
30949 for (i, expr) in e.expressions.iter().enumerate() {
30950 if i > 0 {
30951 self.write(", ");
30952 }
30953 self.generate_expression(expr)?;
30954 }
30955 self.write(")");
30956 }
30957 Ok(())
30958 }
30959
30960 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
30961 if let Expression::Select(_) = &*e.this {
30963 self.write_keyword("MAP");
30964 self.write("(");
30965 self.generate_expression(&e.this)?;
30966 self.write(")");
30967 return Ok(());
30968 }
30969
30970 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
30971
30972 self.write_keyword("MAP");
30974 if is_duckdb {
30975 self.write(" {");
30976 } else {
30977 self.write("[");
30978 }
30979 if let Expression::Struct(s) = &*e.this {
30980 for (i, (_, expr)) in s.fields.iter().enumerate() {
30981 if i > 0 {
30982 self.write(", ");
30983 }
30984 if let Expression::PropertyEQ(op) = expr {
30985 self.generate_expression(&op.left)?;
30986 if is_duckdb {
30987 self.write(": ");
30988 } else {
30989 self.write(" => ");
30990 }
30991 self.generate_expression(&op.right)?;
30992 } else {
30993 self.generate_expression(expr)?;
30994 }
30995 }
30996 }
30997 if is_duckdb {
30998 self.write("}");
30999 } else {
31000 self.write("]");
31001 }
31002 Ok(())
31003 }
31004
31005 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
31006 self.write_keyword("LOCALTIME");
31008 if let Some(precision) = &e.this {
31009 self.write("(");
31010 self.generate_expression(precision)?;
31011 self.write(")");
31012 }
31013 Ok(())
31014 }
31015
31016 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
31017 self.write_keyword("LOCALTIMESTAMP");
31019 if let Some(precision) = &e.this {
31020 self.write("(");
31021 self.generate_expression(precision)?;
31022 self.write(")");
31023 }
31024 Ok(())
31025 }
31026
31027 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
31028 self.write_keyword("LOCATION");
31030 self.write_space();
31031 self.generate_expression(&e.this)?;
31032 Ok(())
31033 }
31034
31035 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
31036 if e.update.is_some() {
31038 if e.key.is_some() {
31039 self.write_keyword("FOR NO KEY UPDATE");
31040 } else {
31041 self.write_keyword("FOR UPDATE");
31042 }
31043 } else {
31044 if e.key.is_some() {
31045 self.write_keyword("FOR KEY SHARE");
31046 } else {
31047 self.write_keyword("FOR SHARE");
31048 }
31049 }
31050 if !e.expressions.is_empty() {
31051 self.write_keyword(" OF ");
31052 for (i, expr) in e.expressions.iter().enumerate() {
31053 if i > 0 {
31054 self.write(", ");
31055 }
31056 self.generate_expression(expr)?;
31057 }
31058 }
31059 if let Some(wait) = &e.wait {
31064 match wait.as_ref() {
31065 Expression::Boolean(b) => {
31066 if b.value {
31067 self.write_keyword(" NOWAIT");
31068 } else {
31069 self.write_keyword(" SKIP LOCKED");
31070 }
31071 }
31072 _ => {
31073 self.write_keyword(" WAIT ");
31075 self.generate_expression(wait)?;
31076 }
31077 }
31078 }
31079 Ok(())
31080 }
31081
31082 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
31083 self.write_keyword("LOCK");
31085 self.write_space();
31086 self.generate_expression(&e.this)?;
31087 Ok(())
31088 }
31089
31090 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
31091 self.write_keyword("LOCKING");
31093 self.write_space();
31094 self.write(&e.kind);
31095 if let Some(this) = &e.this {
31096 self.write_space();
31097 self.generate_expression(this)?;
31098 }
31099 if let Some(for_or_in) = &e.for_or_in {
31100 self.write_space();
31101 self.generate_expression(for_or_in)?;
31102 }
31103 if let Some(lock_type) = &e.lock_type {
31104 self.write_space();
31105 self.generate_expression(lock_type)?;
31106 }
31107 if e.override_.is_some() {
31108 self.write_keyword(" OVERRIDE");
31109 }
31110 Ok(())
31111 }
31112
31113 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
31114 self.generate_expression(&e.this)?;
31116 self.write_space();
31117 self.generate_expression(&e.expression)?;
31118 Ok(())
31119 }
31120
31121 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
31122 if e.no.is_some() {
31124 self.write_keyword("NO ");
31125 }
31126 self.write_keyword("LOG");
31127 Ok(())
31128 }
31129
31130 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
31131 self.write_keyword("MD5");
31133 self.write("(");
31134 self.generate_expression(&e.this)?;
31135 for expr in &e.expressions {
31136 self.write(", ");
31137 self.generate_expression(expr)?;
31138 }
31139 self.write(")");
31140 Ok(())
31141 }
31142
31143 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
31144 self.write_keyword("ML.FORECAST");
31146 self.write("(");
31147 self.generate_expression(&e.this)?;
31148 if let Some(expression) = &e.expression {
31149 self.write(", ");
31150 self.generate_expression(expression)?;
31151 }
31152 if let Some(params) = &e.params_struct {
31153 self.write(", ");
31154 self.generate_expression(params)?;
31155 }
31156 self.write(")");
31157 Ok(())
31158 }
31159
31160 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
31161 self.write_keyword("ML.TRANSLATE");
31163 self.write("(");
31164 self.generate_expression(&e.this)?;
31165 self.write(", ");
31166 self.generate_expression(&e.expression)?;
31167 if let Some(params) = &e.params_struct {
31168 self.write(", ");
31169 self.generate_expression(params)?;
31170 }
31171 self.write(")");
31172 Ok(())
31173 }
31174
31175 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
31176 self.write_keyword("MAKE_INTERVAL");
31178 self.write("(");
31179 let mut first = true;
31180 if let Some(year) = &e.year {
31181 self.write("years => ");
31182 self.generate_expression(year)?;
31183 first = false;
31184 }
31185 if let Some(month) = &e.month {
31186 if !first {
31187 self.write(", ");
31188 }
31189 self.write("months => ");
31190 self.generate_expression(month)?;
31191 first = false;
31192 }
31193 if let Some(week) = &e.week {
31194 if !first {
31195 self.write(", ");
31196 }
31197 self.write("weeks => ");
31198 self.generate_expression(week)?;
31199 first = false;
31200 }
31201 if let Some(day) = &e.day {
31202 if !first {
31203 self.write(", ");
31204 }
31205 self.write("days => ");
31206 self.generate_expression(day)?;
31207 first = false;
31208 }
31209 if let Some(hour) = &e.hour {
31210 if !first {
31211 self.write(", ");
31212 }
31213 self.write("hours => ");
31214 self.generate_expression(hour)?;
31215 first = false;
31216 }
31217 if let Some(minute) = &e.minute {
31218 if !first {
31219 self.write(", ");
31220 }
31221 self.write("mins => ");
31222 self.generate_expression(minute)?;
31223 first = false;
31224 }
31225 if let Some(second) = &e.second {
31226 if !first {
31227 self.write(", ");
31228 }
31229 self.write("secs => ");
31230 self.generate_expression(second)?;
31231 }
31232 self.write(")");
31233 Ok(())
31234 }
31235
31236 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
31237 self.write_keyword("MANHATTAN_DISTANCE");
31239 self.write("(");
31240 self.generate_expression(&e.this)?;
31241 self.write(", ");
31242 self.generate_expression(&e.expression)?;
31243 self.write(")");
31244 Ok(())
31245 }
31246
31247 fn generate_map(&mut self, e: &Map) -> Result<()> {
31248 self.write_keyword("MAP");
31250 self.write("(");
31251 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
31252 if i > 0 {
31253 self.write(", ");
31254 }
31255 self.generate_expression(key)?;
31256 self.write(", ");
31257 self.generate_expression(value)?;
31258 }
31259 self.write(")");
31260 Ok(())
31261 }
31262
31263 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
31264 self.write_keyword("MAP_CAT");
31266 self.write("(");
31267 self.generate_expression(&e.this)?;
31268 self.write(", ");
31269 self.generate_expression(&e.expression)?;
31270 self.write(")");
31271 Ok(())
31272 }
31273
31274 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
31275 self.write_keyword("MAP_DELETE");
31277 self.write("(");
31278 self.generate_expression(&e.this)?;
31279 for expr in &e.expressions {
31280 self.write(", ");
31281 self.generate_expression(expr)?;
31282 }
31283 self.write(")");
31284 Ok(())
31285 }
31286
31287 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
31288 self.write_keyword("MAP_INSERT");
31290 self.write("(");
31291 self.generate_expression(&e.this)?;
31292 if let Some(key) = &e.key {
31293 self.write(", ");
31294 self.generate_expression(key)?;
31295 }
31296 if let Some(value) = &e.value {
31297 self.write(", ");
31298 self.generate_expression(value)?;
31299 }
31300 if let Some(update_flag) = &e.update_flag {
31301 self.write(", ");
31302 self.generate_expression(update_flag)?;
31303 }
31304 self.write(")");
31305 Ok(())
31306 }
31307
31308 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
31309 self.write_keyword("MAP_PICK");
31311 self.write("(");
31312 self.generate_expression(&e.this)?;
31313 for expr in &e.expressions {
31314 self.write(", ");
31315 self.generate_expression(expr)?;
31316 }
31317 self.write(")");
31318 Ok(())
31319 }
31320
31321 fn generate_masking_policy_column_constraint(
31322 &mut self,
31323 e: &MaskingPolicyColumnConstraint,
31324 ) -> Result<()> {
31325 self.write_keyword("MASKING POLICY");
31327 self.write_space();
31328 self.generate_expression(&e.this)?;
31329 if !e.expressions.is_empty() {
31330 self.write_keyword(" USING");
31331 self.write(" (");
31332 for (i, expr) in e.expressions.iter().enumerate() {
31333 if i > 0 {
31334 self.write(", ");
31335 }
31336 self.generate_expression(expr)?;
31337 }
31338 self.write(")");
31339 }
31340 Ok(())
31341 }
31342
31343 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
31344 if matches!(
31345 self.config.dialect,
31346 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
31347 ) {
31348 if e.expressions.len() > 1 {
31349 self.write("(");
31350 }
31351 for (i, expr) in e.expressions.iter().enumerate() {
31352 if i > 0 {
31353 self.write_keyword(" OR ");
31354 }
31355 self.generate_expression(expr)?;
31356 self.write_space();
31357 self.write("@@");
31358 self.write_space();
31359 self.generate_expression(&e.this)?;
31360 }
31361 if e.expressions.len() > 1 {
31362 self.write(")");
31363 }
31364 return Ok(());
31365 }
31366
31367 self.write_keyword("MATCH");
31369 self.write("(");
31370 for (i, expr) in e.expressions.iter().enumerate() {
31371 if i > 0 {
31372 self.write(", ");
31373 }
31374 self.generate_expression(expr)?;
31375 }
31376 self.write(")");
31377 self.write_keyword(" AGAINST");
31378 self.write("(");
31379 self.generate_expression(&e.this)?;
31380 if let Some(modifier) = &e.modifier {
31381 self.write_space();
31382 self.generate_expression(modifier)?;
31383 }
31384 self.write(")");
31385 Ok(())
31386 }
31387
31388 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
31389 if let Some(window_frame) = &e.window_frame {
31391 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
31392 self.write_space();
31393 }
31394 self.generate_expression(&e.this)?;
31395 Ok(())
31396 }
31397
31398 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
31399 self.write_keyword("MATERIALIZED");
31401 if let Some(this) = &e.this {
31402 self.write_space();
31403 self.generate_expression(this)?;
31404 }
31405 Ok(())
31406 }
31407
31408 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
31409 if let Some(with_) = &e.with_ {
31412 if let Expression::With(with_clause) = with_.as_ref() {
31413 self.generate_with(with_clause)?;
31414 self.write_space();
31415 } else {
31416 self.generate_expression(with_)?;
31417 self.write_space();
31418 }
31419 }
31420 self.write_keyword("MERGE INTO");
31421 self.write_space();
31422 if matches!(self.config.dialect, Some(crate::DialectType::Oracle)) {
31423 if let Expression::Alias(alias) = e.this.as_ref() {
31424 self.generate_expression(&alias.this)?;
31425 self.write_space();
31426 self.generate_identifier(&alias.alias)?;
31427 } else {
31428 self.generate_expression(&e.this)?;
31429 }
31430 } else {
31431 self.generate_expression(&e.this)?;
31432 }
31433
31434 if self.config.pretty {
31436 self.write_newline();
31437 self.write_indent();
31438 } else {
31439 self.write_space();
31440 }
31441 self.write_keyword("USING");
31442 self.write_space();
31443 self.generate_expression(&e.using)?;
31444
31445 if let Some(on) = &e.on {
31447 if self.config.pretty {
31448 self.write_newline();
31449 self.write_indent();
31450 } else {
31451 self.write_space();
31452 }
31453 self.write_keyword("ON");
31454 self.write_space();
31455 self.generate_expression(on)?;
31456 }
31457 if let Some(using_cond) = &e.using_cond {
31459 self.write_space();
31460 self.write_keyword("USING");
31461 self.write_space();
31462 self.write("(");
31463 if let Expression::Tuple(tuple) = using_cond.as_ref() {
31465 for (i, col) in tuple.expressions.iter().enumerate() {
31466 if i > 0 {
31467 self.write(", ");
31468 }
31469 self.generate_expression(col)?;
31470 }
31471 } else {
31472 self.generate_expression(using_cond)?;
31473 }
31474 self.write(")");
31475 }
31476 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
31478 if matches!(
31479 self.config.dialect,
31480 Some(crate::DialectType::PostgreSQL)
31481 | Some(crate::DialectType::Redshift)
31482 | Some(crate::DialectType::Trino)
31483 | Some(crate::DialectType::Presto)
31484 | Some(crate::DialectType::Athena)
31485 ) {
31486 let mut names = Vec::new();
31487 match e.this.as_ref() {
31488 Expression::Alias(a) => {
31489 if let Expression::Table(t) = &a.this {
31491 names.push(t.name.name.clone());
31492 } else if let Expression::Identifier(id) = &a.this {
31493 names.push(id.name.clone());
31494 }
31495 names.push(a.alias.name.clone());
31496 }
31497 Expression::Table(t) => {
31498 names.push(t.name.name.clone());
31499 }
31500 Expression::Identifier(id) => {
31501 names.push(id.name.clone());
31502 }
31503 _ => {}
31504 }
31505 self.merge_strip_qualifiers = names;
31506 }
31507
31508 if let Some(whens) = &e.whens {
31510 if self.config.pretty {
31511 self.write_newline();
31512 self.write_indent();
31513 } else {
31514 self.write_space();
31515 }
31516 self.generate_expression(whens)?;
31517 }
31518
31519 self.merge_strip_qualifiers = saved_merge_strip;
31521
31522 if let Some(returning) = &e.returning {
31524 if self.config.pretty {
31525 self.write_newline();
31526 self.write_indent();
31527 } else {
31528 self.write_space();
31529 }
31530 self.generate_expression(returning)?;
31531 }
31532 Ok(())
31533 }
31534
31535 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
31536 if e.no.is_some() {
31538 self.write_keyword("NO MERGEBLOCKRATIO");
31539 } else if e.default.is_some() {
31540 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
31541 } else {
31542 self.write_keyword("MERGEBLOCKRATIO");
31543 self.write("=");
31544 if let Some(this) = &e.this {
31545 self.generate_expression(this)?;
31546 }
31547 if e.percent.is_some() {
31548 self.write_keyword(" PERCENT");
31549 }
31550 }
31551 Ok(())
31552 }
31553
31554 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
31555 self.write_keyword("TTL");
31557 let pretty_clickhouse = self.config.pretty
31558 && matches!(
31559 self.config.dialect,
31560 Some(crate::dialects::DialectType::ClickHouse)
31561 );
31562
31563 if pretty_clickhouse {
31564 self.write_newline();
31565 self.indent_level += 1;
31566 for (i, expr) in e.expressions.iter().enumerate() {
31567 if i > 0 {
31568 self.write(",");
31569 self.write_newline();
31570 }
31571 self.write_indent();
31572 self.generate_expression(expr)?;
31573 }
31574 self.indent_level -= 1;
31575 } else {
31576 self.write_space();
31577 for (i, expr) in e.expressions.iter().enumerate() {
31578 if i > 0 {
31579 self.write(", ");
31580 }
31581 self.generate_expression(expr)?;
31582 }
31583 }
31584
31585 if let Some(where_) = &e.where_ {
31586 if pretty_clickhouse {
31587 self.write_newline();
31588 if let Expression::Where(w) = where_.as_ref() {
31589 self.write_indent();
31590 self.write_keyword("WHERE");
31591 self.write_newline();
31592 self.indent_level += 1;
31593 self.write_indent();
31594 self.generate_expression(&w.this)?;
31595 self.indent_level -= 1;
31596 } else {
31597 self.write_indent();
31598 self.generate_expression(where_)?;
31599 }
31600 } else {
31601 self.write_space();
31602 self.generate_expression(where_)?;
31603 }
31604 }
31605 if let Some(group) = &e.group {
31606 if pretty_clickhouse {
31607 self.write_newline();
31608 if let Expression::Group(g) = group.as_ref() {
31609 self.write_indent();
31610 self.write_keyword("GROUP BY");
31611 self.write_newline();
31612 self.indent_level += 1;
31613 for (i, expr) in g.expressions.iter().enumerate() {
31614 if i > 0 {
31615 self.write(",");
31616 self.write_newline();
31617 }
31618 self.write_indent();
31619 self.generate_expression(expr)?;
31620 }
31621 self.indent_level -= 1;
31622 } else {
31623 self.write_indent();
31624 self.generate_expression(group)?;
31625 }
31626 } else {
31627 self.write_space();
31628 self.generate_expression(group)?;
31629 }
31630 }
31631 if let Some(aggregates) = &e.aggregates {
31632 if pretty_clickhouse {
31633 self.write_newline();
31634 self.write_indent();
31635 self.write_keyword("SET");
31636 self.write_newline();
31637 self.indent_level += 1;
31638 if let Expression::Tuple(t) = aggregates.as_ref() {
31639 for (i, agg) in t.expressions.iter().enumerate() {
31640 if i > 0 {
31641 self.write(",");
31642 self.write_newline();
31643 }
31644 self.write_indent();
31645 self.generate_expression(agg)?;
31646 }
31647 } else {
31648 self.write_indent();
31649 self.generate_expression(aggregates)?;
31650 }
31651 self.indent_level -= 1;
31652 } else {
31653 self.write_space();
31654 self.write_keyword("SET");
31655 self.write_space();
31656 if let Expression::Tuple(t) = aggregates.as_ref() {
31657 for (i, agg) in t.expressions.iter().enumerate() {
31658 if i > 0 {
31659 self.write(", ");
31660 }
31661 self.generate_expression(agg)?;
31662 }
31663 } else {
31664 self.generate_expression(aggregates)?;
31665 }
31666 }
31667 }
31668 Ok(())
31669 }
31670
31671 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
31672 self.generate_expression(&e.this)?;
31674 if e.delete.is_some() {
31675 self.write_keyword(" DELETE");
31676 }
31677 if let Some(recompress) = &e.recompress {
31678 self.write_keyword(" RECOMPRESS ");
31679 self.generate_expression(recompress)?;
31680 }
31681 if let Some(to_disk) = &e.to_disk {
31682 self.write_keyword(" TO DISK ");
31683 self.generate_expression(to_disk)?;
31684 }
31685 if let Some(to_volume) = &e.to_volume {
31686 self.write_keyword(" TO VOLUME ");
31687 self.generate_expression(to_volume)?;
31688 }
31689 Ok(())
31690 }
31691
31692 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
31693 self.write_keyword("MINHASH");
31695 self.write("(");
31696 self.generate_expression(&e.this)?;
31697 for expr in &e.expressions {
31698 self.write(", ");
31699 self.generate_expression(expr)?;
31700 }
31701 self.write(")");
31702 Ok(())
31703 }
31704
31705 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
31706 self.generate_expression(&e.this)?;
31708 self.write("!");
31709 self.generate_expression(&e.expression)?;
31710 Ok(())
31711 }
31712
31713 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
31714 self.write_keyword("MONTHNAME");
31716 self.write("(");
31717 self.generate_expression(&e.this)?;
31718 self.write(")");
31719 Ok(())
31720 }
31721
31722 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
31723 for comment in &e.leading_comments {
31725 self.write_formatted_comment(comment);
31726 if self.config.pretty {
31727 self.write_newline();
31728 self.write_indent();
31729 } else {
31730 self.write_space();
31731 }
31732 }
31733 self.write_keyword("INSERT");
31735 if e.overwrite {
31736 self.write_space();
31737 self.write_keyword("OVERWRITE");
31738 }
31739 self.write_space();
31740 self.write(&e.kind);
31741 if self.config.pretty {
31742 self.indent_level += 1;
31743 for expr in &e.expressions {
31744 self.write_newline();
31745 self.write_indent();
31746 self.generate_expression(expr)?;
31747 }
31748 self.indent_level -= 1;
31749 } else {
31750 for expr in &e.expressions {
31751 self.write_space();
31752 self.generate_expression(expr)?;
31753 }
31754 }
31755 if let Some(source) = &e.source {
31756 if self.config.pretty {
31757 self.write_newline();
31758 self.write_indent();
31759 } else {
31760 self.write_space();
31761 }
31762 self.generate_expression(source)?;
31763 }
31764 Ok(())
31765 }
31766
31767 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
31768 self.write_keyword("NEXT VALUE FOR");
31770 self.write_space();
31771 self.generate_expression(&e.this)?;
31772 if let Some(order) = &e.order {
31773 self.write_space();
31774 self.write_keyword("OVER");
31775 self.write(" (");
31776 self.generate_expression(order)?;
31777 self.write(")");
31778 }
31779 Ok(())
31780 }
31781
31782 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
31783 self.write_keyword("NORMAL");
31785 self.write("(");
31786 self.generate_expression(&e.this)?;
31787 if let Some(stddev) = &e.stddev {
31788 self.write(", ");
31789 self.generate_expression(stddev)?;
31790 }
31791 if let Some(gen) = &e.gen {
31792 self.write(", ");
31793 self.generate_expression(gen)?;
31794 }
31795 self.write(")");
31796 Ok(())
31797 }
31798
31799 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
31800 if e.is_casefold.is_some() {
31802 self.write_keyword("NORMALIZE_AND_CASEFOLD");
31803 } else {
31804 self.write_keyword("NORMALIZE");
31805 }
31806 self.write("(");
31807 self.generate_expression(&e.this)?;
31808 if let Some(form) = &e.form {
31809 self.write(", ");
31810 self.generate_expression(form)?;
31811 }
31812 self.write(")");
31813 Ok(())
31814 }
31815
31816 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
31817 if e.allow_null.is_none() {
31819 self.write_keyword("NOT ");
31820 }
31821 self.write_keyword("NULL");
31822 Ok(())
31823 }
31824
31825 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
31826 self.write_keyword("NULLIF");
31828 self.write("(");
31829 self.generate_expression(&e.this)?;
31830 self.write(", ");
31831 self.generate_expression(&e.expression)?;
31832 self.write(")");
31833 Ok(())
31834 }
31835
31836 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
31837 self.write_keyword("FORMAT");
31839 self.write("(");
31840 self.generate_expression(&e.this)?;
31841 self.write(", '");
31842 self.write(&e.format);
31843 self.write("'");
31844 if let Some(culture) = &e.culture {
31845 self.write(", ");
31846 self.generate_expression(culture)?;
31847 }
31848 self.write(")");
31849 Ok(())
31850 }
31851
31852 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
31853 self.write_keyword("OBJECT_AGG");
31855 self.write("(");
31856 self.generate_expression(&e.this)?;
31857 self.write(", ");
31858 self.generate_expression(&e.expression)?;
31859 self.write(")");
31860 Ok(())
31861 }
31862
31863 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
31864 self.generate_expression(&e.this)?;
31866 Ok(())
31867 }
31868
31869 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
31870 self.write_keyword("OBJECT_INSERT");
31872 self.write("(");
31873 self.generate_expression(&e.this)?;
31874 if let Some(key) = &e.key {
31875 self.write(", ");
31876 self.generate_expression(key)?;
31877 }
31878 if let Some(value) = &e.value {
31879 self.write(", ");
31880 self.generate_expression(value)?;
31881 }
31882 if let Some(update_flag) = &e.update_flag {
31883 self.write(", ");
31884 self.generate_expression(update_flag)?;
31885 }
31886 self.write(")");
31887 Ok(())
31888 }
31889
31890 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
31891 self.write_keyword("OFFSET");
31893 self.write_space();
31894 self.generate_expression(&e.this)?;
31895 if e.rows == Some(true)
31897 && matches!(
31898 self.config.dialect,
31899 Some(crate::dialects::DialectType::TSQL)
31900 | Some(crate::dialects::DialectType::Oracle)
31901 )
31902 {
31903 self.write_space();
31904 self.write_keyword("ROWS");
31905 }
31906 Ok(())
31907 }
31908
31909 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
31910 self.write_keyword("QUALIFY");
31912 self.write_space();
31913 self.generate_expression(&e.this)?;
31914 Ok(())
31915 }
31916
31917 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
31918 self.write_keyword("ON CLUSTER");
31920 self.write_space();
31921 self.generate_expression(&e.this)?;
31922 Ok(())
31923 }
31924
31925 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
31926 self.write_keyword("ON COMMIT");
31928 if e.delete.is_some() {
31929 self.write_keyword(" DELETE ROWS");
31930 } else {
31931 self.write_keyword(" PRESERVE ROWS");
31932 }
31933 Ok(())
31934 }
31935
31936 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
31937 if let Some(empty) = &e.empty {
31939 self.generate_expression(empty)?;
31940 self.write_keyword(" ON EMPTY");
31941 }
31942 if let Some(error) = &e.error {
31943 if e.empty.is_some() {
31944 self.write_space();
31945 }
31946 self.generate_expression(error)?;
31947 self.write_keyword(" ON ERROR");
31948 }
31949 if let Some(null) = &e.null {
31950 if e.empty.is_some() || e.error.is_some() {
31951 self.write_space();
31952 }
31953 self.generate_expression(null)?;
31954 self.write_keyword(" ON NULL");
31955 }
31956 Ok(())
31957 }
31958
31959 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
31960 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
31962 return Ok(());
31963 }
31964 if e.duplicate.is_some() {
31966 self.write_keyword("ON DUPLICATE KEY UPDATE");
31968 for (i, expr) in e.expressions.iter().enumerate() {
31969 if i > 0 {
31970 self.write(",");
31971 }
31972 self.write_space();
31973 self.generate_expression(expr)?;
31974 }
31975 return Ok(());
31976 } else {
31977 self.write_keyword("ON CONFLICT");
31978 }
31979 if let Some(constraint) = &e.constraint {
31980 self.write_keyword(" ON CONSTRAINT ");
31981 self.generate_expression(constraint)?;
31982 }
31983 if let Some(conflict_keys) = &e.conflict_keys {
31984 if let Expression::Tuple(t) = conflict_keys.as_ref() {
31986 self.write("(");
31987 for (i, expr) in t.expressions.iter().enumerate() {
31988 if i > 0 {
31989 self.write(", ");
31990 }
31991 self.generate_expression(expr)?;
31992 }
31993 self.write(")");
31994 } else {
31995 self.write("(");
31996 self.generate_expression(conflict_keys)?;
31997 self.write(")");
31998 }
31999 }
32000 if let Some(index_predicate) = &e.index_predicate {
32001 self.write_keyword(" WHERE ");
32002 self.generate_expression(index_predicate)?;
32003 }
32004 if let Some(action) = &e.action {
32005 if let Expression::Identifier(id) = action.as_ref() {
32007 if id.name.eq_ignore_ascii_case("NOTHING") {
32008 self.write_keyword(" DO NOTHING");
32009 } else {
32010 self.write_keyword(" DO ");
32011 self.generate_expression(action)?;
32012 }
32013 } else if let Expression::Tuple(t) = action.as_ref() {
32014 self.write_keyword(" DO UPDATE SET ");
32016 for (i, expr) in t.expressions.iter().enumerate() {
32017 if i > 0 {
32018 self.write(", ");
32019 }
32020 self.generate_expression(expr)?;
32021 }
32022 } else {
32023 self.write_keyword(" DO ");
32024 self.generate_expression(action)?;
32025 }
32026 }
32027 if let Some(where_) = &e.where_ {
32029 self.write_keyword(" WHERE ");
32030 self.generate_expression(where_)?;
32031 }
32032 Ok(())
32033 }
32034
32035 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
32036 self.write_keyword("ON");
32038 self.write_space();
32039 self.generate_expression(&e.this)?;
32040 Ok(())
32041 }
32042
32043 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
32044 self.generate_expression(&e.this)?;
32046 self.write_space();
32047 self.generate_expression(&e.expression)?;
32048 Ok(())
32049 }
32050
32051 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
32052 self.write_keyword("OPENJSON");
32054 self.write("(");
32055 self.generate_expression(&e.this)?;
32056 if let Some(path) = &e.path {
32057 self.write(", ");
32058 self.generate_expression(path)?;
32059 }
32060 self.write(")");
32061 if !e.expressions.is_empty() {
32062 self.write_keyword(" WITH");
32063 if self.config.pretty {
32064 self.write(" (\n");
32065 self.indent_level += 2;
32066 for (i, expr) in e.expressions.iter().enumerate() {
32067 if i > 0 {
32068 self.write(",\n");
32069 }
32070 self.write_indent();
32071 self.generate_expression(expr)?;
32072 }
32073 self.write("\n");
32074 self.indent_level -= 2;
32075 self.write(")");
32076 } else {
32077 self.write(" (");
32078 for (i, expr) in e.expressions.iter().enumerate() {
32079 if i > 0 {
32080 self.write(", ");
32081 }
32082 self.generate_expression(expr)?;
32083 }
32084 self.write(")");
32085 }
32086 }
32087 Ok(())
32088 }
32089
32090 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
32091 self.generate_expression(&e.this)?;
32093 self.write_space();
32094 if let Some(ref dt) = e.data_type {
32096 self.generate_data_type(dt)?;
32097 } else if !e.kind.is_empty() {
32098 self.write(&e.kind);
32099 }
32100 if let Some(path) = &e.path {
32101 self.write_space();
32102 self.generate_expression(path)?;
32103 }
32104 if e.as_json.is_some() {
32105 self.write_keyword(" AS JSON");
32106 }
32107 Ok(())
32108 }
32109
32110 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
32111 self.generate_expression(&e.this)?;
32113 self.write_space();
32114 if let Some(op) = &e.operator {
32115 self.write_keyword("OPERATOR");
32116 self.write("(");
32117 self.generate_expression(op)?;
32118 self.write(")");
32119 }
32120 for comment in &e.comments {
32122 self.write_space();
32123 self.write_formatted_comment(comment);
32124 }
32125 self.write_space();
32126 self.generate_expression(&e.expression)?;
32127 Ok(())
32128 }
32129
32130 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
32131 self.write_keyword("ORDER BY");
32133 let pretty_clickhouse_single_paren = self.config.pretty
32134 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
32135 && e.expressions.len() == 1
32136 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
32137 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
32138 && e.expressions.len() == 1
32139 && matches!(e.expressions[0].this, Expression::Tuple(_))
32140 && !e.expressions[0].desc
32141 && e.expressions[0].nulls_first.is_none();
32142
32143 if pretty_clickhouse_single_paren {
32144 self.write_space();
32145 if let Expression::Paren(p) = &e.expressions[0].this {
32146 self.write("(");
32147 self.write_newline();
32148 self.indent_level += 1;
32149 self.write_indent();
32150 self.generate_expression(&p.this)?;
32151 self.indent_level -= 1;
32152 self.write_newline();
32153 self.write(")");
32154 }
32155 return Ok(());
32156 }
32157
32158 if clickhouse_single_tuple {
32159 self.write_space();
32160 if let Expression::Tuple(t) = &e.expressions[0].this {
32161 self.write("(");
32162 for (i, expr) in t.expressions.iter().enumerate() {
32163 if i > 0 {
32164 self.write(", ");
32165 }
32166 self.generate_expression(expr)?;
32167 }
32168 self.write(")");
32169 }
32170 return Ok(());
32171 }
32172
32173 self.write_space();
32174 for (i, ordered) in e.expressions.iter().enumerate() {
32175 if i > 0 {
32176 self.write(", ");
32177 }
32178 self.generate_expression(&ordered.this)?;
32179 if ordered.desc {
32180 self.write_space();
32181 self.write_keyword("DESC");
32182 } else if ordered.explicit_asc {
32183 self.write_space();
32184 self.write_keyword("ASC");
32185 }
32186 if let Some(nulls_first) = ordered.nulls_first {
32187 let skip_nulls_last =
32189 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
32190 if !skip_nulls_last {
32191 self.write_space();
32192 self.write_keyword("NULLS");
32193 self.write_space();
32194 if nulls_first {
32195 self.write_keyword("FIRST");
32196 } else {
32197 self.write_keyword("LAST");
32198 }
32199 }
32200 }
32201 }
32202 Ok(())
32203 }
32204
32205 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
32206 self.write_keyword("OUTPUT");
32208 self.write("(");
32209 if self.config.pretty {
32210 self.indent_level += 1;
32211 self.write_newline();
32212 self.write_indent();
32213 self.generate_expression(&e.this)?;
32214 self.indent_level -= 1;
32215 self.write_newline();
32216 } else {
32217 self.generate_expression(&e.this)?;
32218 }
32219 self.write(")");
32220 Ok(())
32221 }
32222
32223 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
32224 self.write_keyword("TRUNCATE");
32226 if let Some(this) = &e.this {
32227 self.write_space();
32228 self.generate_expression(this)?;
32229 }
32230 if e.with_count.is_some() {
32231 self.write_keyword(" WITH COUNT");
32232 } else {
32233 self.write_keyword(" WITHOUT COUNT");
32234 }
32235 Ok(())
32236 }
32237
32238 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
32239 self.generate_expression(&e.this)?;
32241 self.write("(");
32242 for (i, expr) in e.expressions.iter().enumerate() {
32243 if i > 0 {
32244 self.write(", ");
32245 }
32246 self.generate_expression(expr)?;
32247 }
32248 self.write(")(");
32249 for (i, param) in e.params.iter().enumerate() {
32250 if i > 0 {
32251 self.write(", ");
32252 }
32253 self.generate_expression(param)?;
32254 }
32255 self.write(")");
32256 Ok(())
32257 }
32258
32259 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
32260 self.write_keyword("PARSE_DATETIME");
32262 self.write("(");
32263 if let Some(format) = &e.format {
32264 self.write("'");
32265 self.write(format);
32266 self.write("', ");
32267 }
32268 self.generate_expression(&e.this)?;
32269 if let Some(zone) = &e.zone {
32270 self.write(", ");
32271 self.generate_expression(zone)?;
32272 }
32273 self.write(")");
32274 Ok(())
32275 }
32276
32277 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
32278 self.write_keyword("PARSE_IP");
32280 self.write("(");
32281 self.generate_expression(&e.this)?;
32282 if let Some(type_) = &e.type_ {
32283 self.write(", ");
32284 self.generate_expression(type_)?;
32285 }
32286 if let Some(permissive) = &e.permissive {
32287 self.write(", ");
32288 self.generate_expression(permissive)?;
32289 }
32290 self.write(")");
32291 Ok(())
32292 }
32293
32294 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
32295 self.write_keyword("PARSE_JSON");
32297 self.write("(");
32298 self.generate_expression(&e.this)?;
32299 if let Some(expression) = &e.expression {
32300 self.write(", ");
32301 self.generate_expression(expression)?;
32302 }
32303 self.write(")");
32304 Ok(())
32305 }
32306
32307 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
32308 self.write_keyword("PARSE_TIME");
32310 self.write("(");
32311 self.write(&format!("'{}'", e.format));
32312 self.write(", ");
32313 self.generate_expression(&e.this)?;
32314 self.write(")");
32315 Ok(())
32316 }
32317
32318 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
32319 self.write_keyword("PARSE_URL");
32321 self.write("(");
32322 self.generate_expression(&e.this)?;
32323 if let Some(part) = &e.part_to_extract {
32324 self.write(", ");
32325 self.generate_expression(part)?;
32326 }
32327 if let Some(key) = &e.key {
32328 self.write(", ");
32329 self.generate_expression(key)?;
32330 }
32331 if let Some(permissive) = &e.permissive {
32332 self.write(", ");
32333 self.generate_expression(permissive)?;
32334 }
32335 self.write(")");
32336 Ok(())
32337 }
32338
32339 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
32340 if e.subpartition {
32342 self.write_keyword("SUBPARTITION");
32343 } else {
32344 self.write_keyword("PARTITION");
32345 }
32346 self.write("(");
32347 for (i, expr) in e.expressions.iter().enumerate() {
32348 if i > 0 {
32349 self.write(", ");
32350 }
32351 self.generate_expression(expr)?;
32352 }
32353 self.write(")");
32354 Ok(())
32355 }
32356
32357 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
32358 if let Some(this) = &e.this {
32360 if let Some(expression) = &e.expression {
32361 self.write_keyword("WITH");
32363 self.write(" (");
32364 self.write_keyword("MODULUS");
32365 self.write_space();
32366 self.generate_expression(this)?;
32367 self.write(", ");
32368 self.write_keyword("REMAINDER");
32369 self.write_space();
32370 self.generate_expression(expression)?;
32371 self.write(")");
32372 } else {
32373 self.write_keyword("IN");
32375 self.write(" (");
32376 self.generate_partition_bound_values(this)?;
32377 self.write(")");
32378 }
32379 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
32380 self.write_keyword("FROM");
32382 self.write(" (");
32383 self.generate_partition_bound_values(from)?;
32384 self.write(") ");
32385 self.write_keyword("TO");
32386 self.write(" (");
32387 self.generate_partition_bound_values(to)?;
32388 self.write(")");
32389 }
32390 Ok(())
32391 }
32392
32393 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
32396 if let Expression::Tuple(t) = expr {
32397 for (i, e) in t.expressions.iter().enumerate() {
32398 if i > 0 {
32399 self.write(", ");
32400 }
32401 self.generate_expression(e)?;
32402 }
32403 Ok(())
32404 } else {
32405 self.generate_expression(expr)
32406 }
32407 }
32408
32409 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
32410 self.write_keyword("PARTITION BY LIST");
32412 if let Some(partition_exprs) = &e.partition_expressions {
32413 self.write(" (");
32414 self.generate_doris_partition_expressions(partition_exprs)?;
32416 self.write(")");
32417 }
32418 if let Some(create_exprs) = &e.create_expressions {
32419 self.write(" (");
32420 self.generate_doris_partition_definitions(create_exprs)?;
32422 self.write(")");
32423 }
32424 Ok(())
32425 }
32426
32427 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
32428 self.write_keyword("PARTITION BY RANGE");
32430 if let Some(partition_exprs) = &e.partition_expressions {
32431 self.write(" (");
32432 self.generate_doris_partition_expressions(partition_exprs)?;
32434 self.write(")");
32435 }
32436 if let Some(create_exprs) = &e.create_expressions {
32437 self.write(" (");
32438 self.generate_doris_partition_definitions(create_exprs)?;
32440 self.write(")");
32441 }
32442 Ok(())
32443 }
32444
32445 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
32447 if let Expression::Tuple(t) = expr {
32448 for (i, e) in t.expressions.iter().enumerate() {
32449 if i > 0 {
32450 self.write(", ");
32451 }
32452 self.generate_expression(e)?;
32453 }
32454 } else {
32455 self.generate_expression(expr)?;
32456 }
32457 Ok(())
32458 }
32459
32460 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
32462 match expr {
32463 Expression::Tuple(t) => {
32464 for (i, part) in t.expressions.iter().enumerate() {
32466 if i > 0 {
32467 self.write(", ");
32468 }
32469 if let Expression::Partition(p) = part {
32471 for (j, inner) in p.expressions.iter().enumerate() {
32472 if j > 0 {
32473 self.write(", ");
32474 }
32475 self.generate_expression(inner)?;
32476 }
32477 } else {
32478 self.generate_expression(part)?;
32479 }
32480 }
32481 }
32482 Expression::PartitionByRangePropertyDynamic(_) => {
32483 self.generate_expression(expr)?;
32485 }
32486 _ => {
32487 self.generate_expression(expr)?;
32488 }
32489 }
32490 Ok(())
32491 }
32492
32493 fn generate_partition_by_range_property_dynamic(
32494 &mut self,
32495 e: &PartitionByRangePropertyDynamic,
32496 ) -> Result<()> {
32497 if e.use_start_end {
32498 if let Some(start) = &e.start {
32500 self.write_keyword("START");
32501 self.write(" (");
32502 self.generate_expression(start)?;
32503 self.write(")");
32504 }
32505 if let Some(end) = &e.end {
32506 self.write_space();
32507 self.write_keyword("END");
32508 self.write(" (");
32509 self.generate_expression(end)?;
32510 self.write(")");
32511 }
32512 if let Some(every) = &e.every {
32513 self.write_space();
32514 self.write_keyword("EVERY");
32515 self.write(" (");
32516 self.generate_doris_interval(every)?;
32518 self.write(")");
32519 }
32520 } else {
32521 if let Some(start) = &e.start {
32523 self.write_keyword("FROM");
32524 self.write(" (");
32525 self.generate_expression(start)?;
32526 self.write(")");
32527 }
32528 if let Some(end) = &e.end {
32529 self.write_space();
32530 self.write_keyword("TO");
32531 self.write(" (");
32532 self.generate_expression(end)?;
32533 self.write(")");
32534 }
32535 if let Some(every) = &e.every {
32536 self.write_space();
32537 self.generate_doris_interval(every)?;
32539 }
32540 }
32541 Ok(())
32542 }
32543
32544 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
32546 if let Expression::Interval(interval) = expr {
32547 self.write_keyword("INTERVAL");
32548 if let Some(ref value) = interval.this {
32549 self.write_space();
32550 match value {
32554 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()) => {
32555 if let Literal::String(s) = lit.as_ref() {
32556 self.write(s);
32557 }
32558 }
32559 _ => {
32560 self.generate_expression(value)?;
32561 }
32562 }
32563 }
32564 if let Some(ref unit_spec) = interval.unit {
32565 self.write_space();
32566 self.write_interval_unit_spec(unit_spec)?;
32567 }
32568 Ok(())
32569 } else {
32570 self.generate_expression(expr)
32571 }
32572 }
32573
32574 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
32575 self.write_keyword("TRUNCATE");
32577 self.write("(");
32578 self.generate_expression(&e.expression)?;
32579 self.write(", ");
32580 self.generate_expression(&e.this)?;
32581 self.write(")");
32582 Ok(())
32583 }
32584
32585 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
32586 self.write_keyword("PARTITION");
32588 self.write_space();
32589 self.generate_expression(&e.this)?;
32590 self.write_space();
32591 self.write_keyword("VALUES IN");
32592 self.write(" (");
32593 for (i, expr) in e.expressions.iter().enumerate() {
32594 if i > 0 {
32595 self.write(", ");
32596 }
32597 self.generate_expression(expr)?;
32598 }
32599 self.write(")");
32600 Ok(())
32601 }
32602
32603 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
32604 if e.expressions.is_empty() && e.expression.is_some() {
32607 self.generate_expression(&e.this)?;
32609 self.write_space();
32610 self.write_keyword("TO");
32611 self.write_space();
32612 self.generate_expression(e.expression.as_ref().unwrap())?;
32613 return Ok(());
32614 }
32615
32616 self.write_keyword("PARTITION");
32618 self.write_space();
32619 self.generate_expression(&e.this)?;
32620 self.write_space();
32621
32622 if e.expressions.len() == 1 {
32624 self.write_keyword("VALUES LESS THAN");
32626 self.write(" (");
32627 self.generate_expression(&e.expressions[0])?;
32628 self.write(")");
32629 } else if !e.expressions.is_empty() {
32630 self.write_keyword("VALUES");
32632 self.write(" [");
32633 for (i, expr) in e.expressions.iter().enumerate() {
32634 if i > 0 {
32635 self.write(", ");
32636 }
32637 if let Expression::Tuple(t) = expr {
32639 self.write("(");
32640 for (j, inner) in t.expressions.iter().enumerate() {
32641 if j > 0 {
32642 self.write(", ");
32643 }
32644 self.generate_expression(inner)?;
32645 }
32646 self.write(")");
32647 } else {
32648 self.write("(");
32649 self.generate_expression(expr)?;
32650 self.write(")");
32651 }
32652 }
32653 self.write(")");
32654 }
32655 Ok(())
32656 }
32657
32658 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
32659 self.write_keyword("BUCKET");
32661 self.write("(");
32662 self.generate_expression(&e.this)?;
32663 self.write(", ");
32664 self.generate_expression(&e.expression)?;
32665 self.write(")");
32666 Ok(())
32667 }
32668
32669 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
32670 self.write_keyword("PARTITION BY");
32672 self.write_space();
32673 for (i, expr) in e.expressions.iter().enumerate() {
32674 if i > 0 {
32675 self.write(", ");
32676 }
32677 self.generate_expression(expr)?;
32678 }
32679 Ok(())
32680 }
32681
32682 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
32683 if matches!(
32685 self.config.dialect,
32686 Some(crate::dialects::DialectType::Teradata)
32687 | Some(crate::dialects::DialectType::ClickHouse)
32688 ) {
32689 self.write_keyword("PARTITION BY");
32690 } else {
32691 self.write_keyword("PARTITIONED BY");
32692 }
32693 self.write_space();
32694 if self.config.pretty {
32696 if let Expression::Tuple(ref tuple) = *e.this {
32697 self.write("(");
32698 self.write_newline();
32699 self.indent_level += 1;
32700 for (i, expr) in tuple.expressions.iter().enumerate() {
32701 if i > 0 {
32702 self.write(",");
32703 self.write_newline();
32704 }
32705 self.write_indent();
32706 self.generate_expression(expr)?;
32707 }
32708 self.indent_level -= 1;
32709 self.write_newline();
32710 self.write(")");
32711 } else {
32712 self.generate_expression(&e.this)?;
32713 }
32714 } else {
32715 self.generate_expression(&e.this)?;
32716 }
32717 Ok(())
32718 }
32719
32720 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
32721 self.write_keyword("PARTITION OF");
32723 self.write_space();
32724 self.generate_expression(&e.this)?;
32725 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
32727 self.write_space();
32728 self.write_keyword("FOR VALUES");
32729 self.write_space();
32730 self.generate_expression(&e.expression)?;
32731 } else {
32732 self.write_space();
32733 self.write_keyword("DEFAULT");
32734 }
32735 Ok(())
32736 }
32737
32738 fn generate_period_for_system_time_constraint(
32739 &mut self,
32740 e: &PeriodForSystemTimeConstraint,
32741 ) -> Result<()> {
32742 self.write_keyword("PERIOD FOR SYSTEM_TIME");
32744 self.write(" (");
32745 self.generate_expression(&e.this)?;
32746 self.write(", ");
32747 self.generate_expression(&e.expression)?;
32748 self.write(")");
32749 Ok(())
32750 }
32751
32752 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
32753 self.generate_expression(&e.this)?;
32756 self.write_space();
32757 self.write_keyword("AS");
32758 self.write_space();
32759 if self.config.unpivot_aliases_are_identifiers {
32761 match &e.alias {
32762 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
32763 let Literal::String(s) = lit.as_ref() else {
32764 unreachable!()
32765 };
32766 self.generate_identifier(&Identifier::new(s.clone()))?;
32768 }
32769 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
32770 let Literal::Number(n) = lit.as_ref() else {
32771 unreachable!()
32772 };
32773 let mut id = Identifier::new(n.clone());
32775 id.quoted = true;
32776 self.generate_identifier(&id)?;
32777 }
32778 other => {
32779 self.generate_expression(other)?;
32780 }
32781 }
32782 } else {
32783 self.generate_expression(&e.alias)?;
32784 }
32785 Ok(())
32786 }
32787
32788 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
32789 self.write_keyword("ANY");
32791 if let Some(this) = &e.this {
32792 self.write_space();
32793 self.generate_expression(this)?;
32794 }
32795 Ok(())
32796 }
32797
32798 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
32799 self.write_keyword("ML.PREDICT");
32801 self.write("(");
32802 self.write_keyword("MODEL");
32803 self.write_space();
32804 self.generate_expression(&e.this)?;
32805 self.write(", ");
32806 self.generate_expression(&e.expression)?;
32807 if let Some(params) = &e.params_struct {
32808 self.write(", ");
32809 self.generate_expression(params)?;
32810 }
32811 self.write(")");
32812 Ok(())
32813 }
32814
32815 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
32816 self.write_keyword("PREVIOUS_DAY");
32818 self.write("(");
32819 self.generate_expression(&e.this)?;
32820 self.write(", ");
32821 self.generate_expression(&e.expression)?;
32822 self.write(")");
32823 Ok(())
32824 }
32825
32826 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
32827 self.write_keyword("PRIMARY KEY");
32829 if let Some(name) = &e.this {
32830 self.write_space();
32831 self.generate_expression(name)?;
32832 }
32833 if !e.expressions.is_empty() {
32834 self.write(" (");
32835 for (i, expr) in e.expressions.iter().enumerate() {
32836 if i > 0 {
32837 self.write(", ");
32838 }
32839 self.generate_expression(expr)?;
32840 }
32841 self.write(")");
32842 }
32843 if let Some(include) = &e.include {
32844 self.write_space();
32845 self.generate_expression(include)?;
32846 }
32847 if !e.options.is_empty() {
32848 self.write_space();
32849 for (i, opt) in e.options.iter().enumerate() {
32850 if i > 0 {
32851 self.write_space();
32852 }
32853 self.generate_expression(opt)?;
32854 }
32855 }
32856 Ok(())
32857 }
32858
32859 fn generate_primary_key_column_constraint(
32860 &mut self,
32861 _e: &PrimaryKeyColumnConstraint,
32862 ) -> Result<()> {
32863 self.write_keyword("PRIMARY KEY");
32865 Ok(())
32866 }
32867
32868 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
32869 self.write_keyword("PATH");
32871 self.write_space();
32872 self.generate_expression(&e.this)?;
32873 Ok(())
32874 }
32875
32876 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
32877 self.write_keyword("PROJECTION");
32879 self.write_space();
32880 self.generate_expression(&e.this)?;
32881 self.write(" (");
32882 self.generate_expression(&e.expression)?;
32883 self.write(")");
32884 Ok(())
32885 }
32886
32887 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
32888 for (i, prop) in e.expressions.iter().enumerate() {
32890 if i > 0 {
32891 self.write(", ");
32892 }
32893 self.generate_expression(prop)?;
32894 }
32895 Ok(())
32896 }
32897
32898 fn generate_property(&mut self, e: &Property) -> Result<()> {
32899 self.generate_expression(&e.this)?;
32901 if let Some(value) = &e.value {
32902 self.write("=");
32903 self.generate_expression(value)?;
32904 }
32905 Ok(())
32906 }
32907
32908 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
32909 self.write_keyword("OPTIONS");
32910 if e.entries.is_empty() {
32911 self.write(" ()");
32912 return Ok(());
32913 }
32914
32915 if self.config.pretty {
32916 self.write(" (");
32917 self.write_newline();
32918 self.indent_level += 1;
32919 for (i, entry) in e.entries.iter().enumerate() {
32920 if i > 0 {
32921 self.write(",");
32922 self.write_newline();
32923 }
32924 self.write_indent();
32925 self.generate_identifier(&entry.key)?;
32926 self.write("=");
32927 self.generate_expression(&entry.value)?;
32928 }
32929 self.indent_level -= 1;
32930 self.write_newline();
32931 self.write(")");
32932 } else {
32933 self.write(" (");
32934 for (i, entry) in e.entries.iter().enumerate() {
32935 if i > 0 {
32936 self.write(", ");
32937 }
32938 self.generate_identifier(&entry.key)?;
32939 self.write("=");
32940 self.generate_expression(&entry.value)?;
32941 }
32942 self.write(")");
32943 }
32944 Ok(())
32945 }
32946
32947 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
32949 self.write_keyword("OPTIONS");
32950 self.write(" (");
32951 for (i, opt) in options.iter().enumerate() {
32952 if i > 0 {
32953 self.write(", ");
32954 }
32955 self.generate_option_expression(opt)?;
32956 }
32957 self.write(")");
32958 Ok(())
32959 }
32960
32961 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
32963 self.write_keyword("PROPERTIES");
32964 self.write(" (");
32965 for (i, prop) in properties.iter().enumerate() {
32966 if i > 0 {
32967 self.write(", ");
32968 }
32969 self.generate_option_expression(prop)?;
32970 }
32971 self.write(")");
32972 Ok(())
32973 }
32974
32975 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
32977 self.write_keyword("ENVIRONMENT");
32978 self.write(" (");
32979 for (i, env_item) in environment.iter().enumerate() {
32980 if i > 0 {
32981 self.write(", ");
32982 }
32983 self.generate_environment_expression(env_item)?;
32984 }
32985 self.write(")");
32986 Ok(())
32987 }
32988
32989 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
32991 match expr {
32992 Expression::Eq(eq) => {
32993 self.generate_expression(&eq.left)?;
32995 self.write(" = ");
32996 self.generate_expression(&eq.right)?;
32997 Ok(())
32998 }
32999 _ => self.generate_expression(expr),
33000 }
33001 }
33002
33003 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
33005 self.write_keyword("TBLPROPERTIES");
33006 if self.config.pretty {
33007 self.write(" (");
33008 self.write_newline();
33009 self.indent_level += 1;
33010 for (i, opt) in options.iter().enumerate() {
33011 if i > 0 {
33012 self.write(",");
33013 self.write_newline();
33014 }
33015 self.write_indent();
33016 self.generate_option_expression(opt)?;
33017 }
33018 self.indent_level -= 1;
33019 self.write_newline();
33020 self.write(")");
33021 } else {
33022 self.write(" (");
33023 for (i, opt) in options.iter().enumerate() {
33024 if i > 0 {
33025 self.write(", ");
33026 }
33027 self.generate_option_expression(opt)?;
33028 }
33029 self.write(")");
33030 }
33031 Ok(())
33032 }
33033
33034 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
33036 match expr {
33037 Expression::Eq(eq) => {
33038 self.generate_expression(&eq.left)?;
33040 self.write("=");
33041 self.generate_expression(&eq.right)?;
33042 Ok(())
33043 }
33044 _ => self.generate_expression(expr),
33045 }
33046 }
33047
33048 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
33049 self.generate_expression(&e.this)?;
33051 Ok(())
33052 }
33053
33054 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
33055 self.write_keyword("PUT");
33057 self.write_space();
33058
33059 if e.source_quoted {
33061 self.write("'");
33062 self.write(&e.source);
33063 self.write("'");
33064 } else {
33065 self.write(&e.source);
33066 }
33067
33068 self.write_space();
33069
33070 if let Expression::Literal(lit) = &e.target {
33072 if let Literal::String(s) = lit.as_ref() {
33073 self.write(s);
33074 }
33075 } else {
33076 self.generate_expression(&e.target)?;
33077 }
33078
33079 for param in &e.params {
33081 self.write_space();
33082 self.write(¶m.name);
33083 if let Some(ref value) = param.value {
33084 self.write("=");
33085 self.generate_expression(value)?;
33086 }
33087 }
33088
33089 Ok(())
33090 }
33091
33092 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
33093 self.write_keyword("QUANTILE");
33095 self.write("(");
33096 self.generate_expression(&e.this)?;
33097 if let Some(quantile) = &e.quantile {
33098 self.write(", ");
33099 self.generate_expression(quantile)?;
33100 }
33101 self.write(")");
33102 Ok(())
33103 }
33104
33105 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
33106 if matches!(
33108 self.config.dialect,
33109 Some(crate::dialects::DialectType::Teradata)
33110 ) {
33111 self.write_keyword("SET");
33112 self.write_space();
33113 }
33114 self.write_keyword("QUERY_BAND");
33115 self.write(" = ");
33116 self.generate_expression(&e.this)?;
33117 if e.update.is_some() {
33118 self.write_space();
33119 self.write_keyword("UPDATE");
33120 }
33121 if let Some(scope) = &e.scope {
33122 self.write_space();
33123 self.write_keyword("FOR");
33124 self.write_space();
33125 self.generate_expression(scope)?;
33126 }
33127 Ok(())
33128 }
33129
33130 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
33131 self.generate_expression(&e.this)?;
33133 if let Some(expression) = &e.expression {
33134 self.write(" = ");
33135 self.generate_expression(expression)?;
33136 }
33137 Ok(())
33138 }
33139
33140 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
33141 self.write_keyword("TRANSFORM");
33143 self.write("(");
33144 for (i, expr) in e.expressions.iter().enumerate() {
33145 if i > 0 {
33146 self.write(", ");
33147 }
33148 self.generate_expression(expr)?;
33149 }
33150 self.write(")");
33151 if let Some(row_format_before) = &e.row_format_before {
33152 self.write_space();
33153 self.generate_expression(row_format_before)?;
33154 }
33155 if let Some(record_writer) = &e.record_writer {
33156 self.write_space();
33157 self.write_keyword("RECORDWRITER");
33158 self.write_space();
33159 self.generate_expression(record_writer)?;
33160 }
33161 if let Some(command_script) = &e.command_script {
33162 self.write_space();
33163 self.write_keyword("USING");
33164 self.write_space();
33165 self.generate_expression(command_script)?;
33166 }
33167 if let Some(schema) = &e.schema {
33168 self.write_space();
33169 self.write_keyword("AS");
33170 self.write_space();
33171 self.generate_expression(schema)?;
33172 }
33173 if let Some(row_format_after) = &e.row_format_after {
33174 self.write_space();
33175 self.generate_expression(row_format_after)?;
33176 }
33177 if let Some(record_reader) = &e.record_reader {
33178 self.write_space();
33179 self.write_keyword("RECORDREADER");
33180 self.write_space();
33181 self.generate_expression(record_reader)?;
33182 }
33183 Ok(())
33184 }
33185
33186 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
33187 self.write_keyword("RANDN");
33189 self.write("(");
33190 if let Some(this) = &e.this {
33191 self.generate_expression(this)?;
33192 }
33193 self.write(")");
33194 Ok(())
33195 }
33196
33197 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
33198 self.write_keyword("RANDSTR");
33200 self.write("(");
33201 self.generate_expression(&e.this)?;
33202 if let Some(generator) = &e.generator {
33203 self.write(", ");
33204 self.generate_expression(generator)?;
33205 }
33206 self.write(")");
33207 Ok(())
33208 }
33209
33210 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
33211 self.write_keyword("RANGE_BUCKET");
33213 self.write("(");
33214 self.generate_expression(&e.this)?;
33215 self.write(", ");
33216 self.generate_expression(&e.expression)?;
33217 self.write(")");
33218 Ok(())
33219 }
33220
33221 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
33222 self.write_keyword("RANGE_N");
33224 self.write("(");
33225 self.generate_expression(&e.this)?;
33226 self.write_space();
33227 self.write_keyword("BETWEEN");
33228 self.write_space();
33229 for (i, expr) in e.expressions.iter().enumerate() {
33230 if i > 0 {
33231 self.write(", ");
33232 }
33233 self.generate_expression(expr)?;
33234 }
33235 if let Some(each) = &e.each {
33236 self.write_space();
33237 self.write_keyword("EACH");
33238 self.write_space();
33239 self.generate_expression(each)?;
33240 }
33241 self.write(")");
33242 Ok(())
33243 }
33244
33245 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
33246 self.write_keyword("READ_CSV");
33248 self.write("(");
33249 self.generate_expression(&e.this)?;
33250 for expr in &e.expressions {
33251 self.write(", ");
33252 self.generate_expression(expr)?;
33253 }
33254 self.write(")");
33255 Ok(())
33256 }
33257
33258 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
33259 self.write_keyword("READ_PARQUET");
33261 self.write("(");
33262 for (i, expr) in e.expressions.iter().enumerate() {
33263 if i > 0 {
33264 self.write(", ");
33265 }
33266 self.generate_expression(expr)?;
33267 }
33268 self.write(")");
33269 Ok(())
33270 }
33271
33272 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
33273 if e.kind == "CYCLE" {
33276 self.write_keyword("CYCLE");
33277 } else {
33278 self.write_keyword("SEARCH");
33279 self.write_space();
33280 self.write(&e.kind);
33281 self.write_space();
33282 self.write_keyword("FIRST BY");
33283 }
33284 self.write_space();
33285 self.generate_expression(&e.this)?;
33286 self.write_space();
33287 self.write_keyword("SET");
33288 self.write_space();
33289 self.generate_expression(&e.expression)?;
33290 if let Some(using) = &e.using {
33291 self.write_space();
33292 self.write_keyword("USING");
33293 self.write_space();
33294 self.generate_expression(using)?;
33295 }
33296 Ok(())
33297 }
33298
33299 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
33300 self.write_keyword("REDUCE");
33302 self.write("(");
33303 self.generate_expression(&e.this)?;
33304 if let Some(initial) = &e.initial {
33305 self.write(", ");
33306 self.generate_expression(initial)?;
33307 }
33308 if let Some(merge) = &e.merge {
33309 self.write(", ");
33310 self.generate_expression(merge)?;
33311 }
33312 if let Some(finish) = &e.finish {
33313 self.write(", ");
33314 self.generate_expression(finish)?;
33315 }
33316 self.write(")");
33317 Ok(())
33318 }
33319
33320 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
33321 self.write_keyword("REFERENCES");
33323 self.write_space();
33324 self.generate_expression(&e.this)?;
33325 if !e.expressions.is_empty() {
33326 self.write(" (");
33327 for (i, expr) in e.expressions.iter().enumerate() {
33328 if i > 0 {
33329 self.write(", ");
33330 }
33331 self.generate_expression(expr)?;
33332 }
33333 self.write(")");
33334 }
33335 for opt in &e.options {
33336 self.write_space();
33337 self.generate_expression(opt)?;
33338 }
33339 Ok(())
33340 }
33341
33342 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
33343 self.write_keyword("REFRESH");
33345 if !e.kind.is_empty() {
33346 self.write_space();
33347 self.write_keyword(&e.kind);
33348 }
33349 self.write_space();
33350 self.generate_expression(&e.this)?;
33351 Ok(())
33352 }
33353
33354 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
33355 self.write_keyword("REFRESH");
33357 self.write_space();
33358 self.write_keyword(&e.method);
33359
33360 if let Some(ref kind) = e.kind {
33361 self.write_space();
33362 self.write_keyword("ON");
33363 self.write_space();
33364 self.write_keyword(kind);
33365
33366 if let Some(ref every) = e.every {
33368 self.write_space();
33369 self.write_keyword("EVERY");
33370 self.write_space();
33371 self.generate_expression(every)?;
33372 if let Some(ref unit) = e.unit {
33373 self.write_space();
33374 self.write_keyword(unit);
33375 }
33376 }
33377
33378 if let Some(ref starts) = e.starts {
33380 self.write_space();
33381 self.write_keyword("STARTS");
33382 self.write_space();
33383 self.generate_expression(starts)?;
33384 }
33385 }
33386 Ok(())
33387 }
33388
33389 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
33390 self.write_keyword("REGEXP_COUNT");
33392 self.write("(");
33393 self.generate_expression(&e.this)?;
33394 self.write(", ");
33395 self.generate_expression(&e.expression)?;
33396 if let Some(position) = &e.position {
33397 self.write(", ");
33398 self.generate_expression(position)?;
33399 }
33400 if let Some(parameters) = &e.parameters {
33401 self.write(", ");
33402 self.generate_expression(parameters)?;
33403 }
33404 self.write(")");
33405 Ok(())
33406 }
33407
33408 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
33409 self.write_keyword("REGEXP_EXTRACT_ALL");
33411 self.write("(");
33412 self.generate_expression(&e.this)?;
33413 self.write(", ");
33414 self.generate_expression(&e.expression)?;
33415 if let Some(group) = &e.group {
33416 self.write(", ");
33417 self.generate_expression(group)?;
33418 }
33419 self.write(")");
33420 Ok(())
33421 }
33422
33423 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
33424 self.write_keyword("REGEXP_FULL_MATCH");
33426 self.write("(");
33427 self.generate_expression(&e.this)?;
33428 self.write(", ");
33429 self.generate_expression(&e.expression)?;
33430 self.write(")");
33431 Ok(())
33432 }
33433
33434 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
33435 use crate::dialects::DialectType;
33436 if matches!(
33438 self.config.dialect,
33439 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
33440 ) && e.flag.is_none()
33441 {
33442 self.generate_expression(&e.this)?;
33443 self.write(" ~* ");
33444 self.generate_expression(&e.expression)?;
33445 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33446 self.write_keyword("REGEXP_LIKE");
33448 self.write("(");
33449 self.generate_expression(&e.this)?;
33450 self.write(", ");
33451 self.generate_expression(&e.expression)?;
33452 self.write(", ");
33453 if let Some(flag) = &e.flag {
33454 self.generate_expression(flag)?;
33455 } else {
33456 self.write("'i'");
33457 }
33458 self.write(")");
33459 } else {
33460 self.generate_expression(&e.this)?;
33462 self.write_space();
33463 self.write_keyword("REGEXP_ILIKE");
33464 self.write_space();
33465 self.generate_expression(&e.expression)?;
33466 if let Some(flag) = &e.flag {
33467 self.write(", ");
33468 self.generate_expression(flag)?;
33469 }
33470 }
33471 Ok(())
33472 }
33473
33474 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
33475 self.write_keyword("REGEXP_INSTR");
33477 self.write("(");
33478 self.generate_expression(&e.this)?;
33479 self.write(", ");
33480 self.generate_expression(&e.expression)?;
33481 if let Some(position) = &e.position {
33482 self.write(", ");
33483 self.generate_expression(position)?;
33484 }
33485 if let Some(occurrence) = &e.occurrence {
33486 self.write(", ");
33487 self.generate_expression(occurrence)?;
33488 }
33489 if let Some(option) = &e.option {
33490 self.write(", ");
33491 self.generate_expression(option)?;
33492 }
33493 if let Some(parameters) = &e.parameters {
33494 self.write(", ");
33495 self.generate_expression(parameters)?;
33496 }
33497 if let Some(group) = &e.group {
33498 self.write(", ");
33499 self.generate_expression(group)?;
33500 }
33501 self.write(")");
33502 Ok(())
33503 }
33504
33505 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
33506 self.write_keyword("REGEXP_SPLIT");
33508 self.write("(");
33509 self.generate_expression(&e.this)?;
33510 self.write(", ");
33511 self.generate_expression(&e.expression)?;
33512 if let Some(limit) = &e.limit {
33513 self.write(", ");
33514 self.generate_expression(limit)?;
33515 }
33516 self.write(")");
33517 Ok(())
33518 }
33519
33520 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
33521 self.write_keyword("REGR_AVGX");
33523 self.write("(");
33524 self.generate_expression(&e.this)?;
33525 self.write(", ");
33526 self.generate_expression(&e.expression)?;
33527 self.write(")");
33528 Ok(())
33529 }
33530
33531 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
33532 self.write_keyword("REGR_AVGY");
33534 self.write("(");
33535 self.generate_expression(&e.this)?;
33536 self.write(", ");
33537 self.generate_expression(&e.expression)?;
33538 self.write(")");
33539 Ok(())
33540 }
33541
33542 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
33543 self.write_keyword("REGR_COUNT");
33545 self.write("(");
33546 self.generate_expression(&e.this)?;
33547 self.write(", ");
33548 self.generate_expression(&e.expression)?;
33549 self.write(")");
33550 Ok(())
33551 }
33552
33553 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
33554 self.write_keyword("REGR_INTERCEPT");
33556 self.write("(");
33557 self.generate_expression(&e.this)?;
33558 self.write(", ");
33559 self.generate_expression(&e.expression)?;
33560 self.write(")");
33561 Ok(())
33562 }
33563
33564 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
33565 self.write_keyword("REGR_R2");
33567 self.write("(");
33568 self.generate_expression(&e.this)?;
33569 self.write(", ");
33570 self.generate_expression(&e.expression)?;
33571 self.write(")");
33572 Ok(())
33573 }
33574
33575 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
33576 self.write_keyword("REGR_SLOPE");
33578 self.write("(");
33579 self.generate_expression(&e.this)?;
33580 self.write(", ");
33581 self.generate_expression(&e.expression)?;
33582 self.write(")");
33583 Ok(())
33584 }
33585
33586 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
33587 self.write_keyword("REGR_SXX");
33589 self.write("(");
33590 self.generate_expression(&e.this)?;
33591 self.write(", ");
33592 self.generate_expression(&e.expression)?;
33593 self.write(")");
33594 Ok(())
33595 }
33596
33597 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
33598 self.write_keyword("REGR_SXY");
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_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
33609 self.write_keyword("REGR_SYY");
33611 self.write("(");
33612 self.generate_expression(&e.this)?;
33613 self.write(", ");
33614 self.generate_expression(&e.expression)?;
33615 self.write(")");
33616 Ok(())
33617 }
33618
33619 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
33620 self.write_keyword("REGR_VALX");
33622 self.write("(");
33623 self.generate_expression(&e.this)?;
33624 self.write(", ");
33625 self.generate_expression(&e.expression)?;
33626 self.write(")");
33627 Ok(())
33628 }
33629
33630 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
33631 self.write_keyword("REGR_VALY");
33633 self.write("(");
33634 self.generate_expression(&e.this)?;
33635 self.write(", ");
33636 self.generate_expression(&e.expression)?;
33637 self.write(")");
33638 Ok(())
33639 }
33640
33641 fn generate_remote_with_connection_model_property(
33642 &mut self,
33643 e: &RemoteWithConnectionModelProperty,
33644 ) -> Result<()> {
33645 self.write_keyword("REMOTE WITH CONNECTION");
33647 self.write_space();
33648 self.generate_expression(&e.this)?;
33649 Ok(())
33650 }
33651
33652 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
33653 self.write_keyword("RENAME COLUMN");
33655 if e.exists {
33656 self.write_space();
33657 self.write_keyword("IF EXISTS");
33658 }
33659 self.write_space();
33660 self.generate_expression(&e.this)?;
33661 if let Some(to) = &e.to {
33662 self.write_space();
33663 self.write_keyword("TO");
33664 self.write_space();
33665 self.generate_expression(to)?;
33666 }
33667 Ok(())
33668 }
33669
33670 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
33671 self.write_keyword("REPLACE PARTITION");
33673 self.write_space();
33674 self.generate_expression(&e.expression)?;
33675 if let Some(source) = &e.source {
33676 self.write_space();
33677 self.write_keyword("FROM");
33678 self.write_space();
33679 self.generate_expression(source)?;
33680 }
33681 Ok(())
33682 }
33683
33684 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
33685 let keyword = match self.config.dialect {
33688 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
33689 _ => "RETURNING",
33690 };
33691 self.write_keyword(keyword);
33692 self.write_space();
33693 for (i, expr) in e.expressions.iter().enumerate() {
33694 if i > 0 {
33695 self.write(", ");
33696 }
33697 self.generate_expression(expr)?;
33698 }
33699 if let Some(into) = &e.into {
33700 self.write_space();
33701 self.write_keyword("INTO");
33702 self.write_space();
33703 self.generate_expression(into)?;
33704 }
33705 Ok(())
33706 }
33707
33708 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
33709 self.write_space();
33711 self.write_keyword("OUTPUT");
33712 self.write_space();
33713 for (i, expr) in output.columns.iter().enumerate() {
33714 if i > 0 {
33715 self.write(", ");
33716 }
33717 self.generate_expression(expr)?;
33718 }
33719 if let Some(into_table) = &output.into_table {
33720 self.write_space();
33721 self.write_keyword("INTO");
33722 self.write_space();
33723 self.generate_expression(into_table)?;
33724 }
33725 Ok(())
33726 }
33727
33728 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
33729 self.write_keyword("RETURNS");
33731 if e.is_table.is_some() {
33732 self.write_space();
33733 self.write_keyword("TABLE");
33734 }
33735 if let Some(table) = &e.table {
33736 self.write_space();
33737 self.generate_expression(table)?;
33738 } else if let Some(this) = &e.this {
33739 self.write_space();
33740 self.generate_expression(this)?;
33741 }
33742 if e.null.is_some() {
33743 self.write_space();
33744 self.write_keyword("NULL ON NULL INPUT");
33745 }
33746 Ok(())
33747 }
33748
33749 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
33750 self.write_keyword("ROLLBACK");
33752
33753 if e.this.is_none()
33755 && matches!(
33756 self.config.dialect,
33757 Some(DialectType::TSQL) | Some(DialectType::Fabric)
33758 )
33759 {
33760 self.write_space();
33761 self.write_keyword("TRANSACTION");
33762 }
33763
33764 if let Some(this) = &e.this {
33766 let is_transaction_marker = matches!(
33768 this.as_ref(),
33769 Expression::Identifier(id) if id.name == "TRANSACTION"
33770 );
33771
33772 self.write_space();
33773 self.write_keyword("TRANSACTION");
33774
33775 if !is_transaction_marker {
33777 self.write_space();
33778 self.generate_expression(this)?;
33779 }
33780 }
33781
33782 if let Some(savepoint) = &e.savepoint {
33784 self.write_space();
33785 self.write_keyword("TO");
33786 self.write_space();
33787 self.generate_expression(savepoint)?;
33788 }
33789 Ok(())
33790 }
33791
33792 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
33793 if e.expressions.is_empty() {
33795 self.write_keyword("WITH ROLLUP");
33796 } else {
33797 self.write_keyword("ROLLUP");
33798 self.write("(");
33799 for (i, expr) in e.expressions.iter().enumerate() {
33800 if i > 0 {
33801 self.write(", ");
33802 }
33803 self.generate_expression(expr)?;
33804 }
33805 self.write(")");
33806 }
33807 Ok(())
33808 }
33809
33810 fn generate_row_format_delimited_property(
33811 &mut self,
33812 e: &RowFormatDelimitedProperty,
33813 ) -> Result<()> {
33814 self.write_keyword("ROW FORMAT DELIMITED");
33816 if let Some(fields) = &e.fields {
33817 self.write_space();
33818 self.write_keyword("FIELDS TERMINATED BY");
33819 self.write_space();
33820 self.generate_expression(fields)?;
33821 }
33822 if let Some(escaped) = &e.escaped {
33823 self.write_space();
33824 self.write_keyword("ESCAPED BY");
33825 self.write_space();
33826 self.generate_expression(escaped)?;
33827 }
33828 if let Some(items) = &e.collection_items {
33829 self.write_space();
33830 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
33831 self.write_space();
33832 self.generate_expression(items)?;
33833 }
33834 if let Some(keys) = &e.map_keys {
33835 self.write_space();
33836 self.write_keyword("MAP KEYS TERMINATED BY");
33837 self.write_space();
33838 self.generate_expression(keys)?;
33839 }
33840 if let Some(lines) = &e.lines {
33841 self.write_space();
33842 self.write_keyword("LINES TERMINATED BY");
33843 self.write_space();
33844 self.generate_expression(lines)?;
33845 }
33846 if let Some(null) = &e.null {
33847 self.write_space();
33848 self.write_keyword("NULL DEFINED AS");
33849 self.write_space();
33850 self.generate_expression(null)?;
33851 }
33852 if let Some(serde) = &e.serde {
33853 self.write_space();
33854 self.generate_expression(serde)?;
33855 }
33856 Ok(())
33857 }
33858
33859 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
33860 self.write_keyword("ROW FORMAT");
33862 self.write_space();
33863 self.generate_expression(&e.this)?;
33864 Ok(())
33865 }
33866
33867 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
33868 self.write_keyword("ROW FORMAT SERDE");
33870 self.write_space();
33871 self.generate_expression(&e.this)?;
33872 if let Some(props) = &e.serde_properties {
33873 self.write_space();
33874 self.generate_expression(props)?;
33876 }
33877 Ok(())
33878 }
33879
33880 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
33881 self.write_keyword("SHA2");
33883 self.write("(");
33884 self.generate_expression(&e.this)?;
33885 if let Some(length) = e.length {
33886 self.write(", ");
33887 self.write(&length.to_string());
33888 }
33889 self.write(")");
33890 Ok(())
33891 }
33892
33893 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
33894 self.write_keyword("SHA2_DIGEST");
33896 self.write("(");
33897 self.generate_expression(&e.this)?;
33898 if let Some(length) = e.length {
33899 self.write(", ");
33900 self.write(&length.to_string());
33901 }
33902 self.write(")");
33903 Ok(())
33904 }
33905
33906 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
33907 let name = if matches!(
33908 self.config.dialect,
33909 Some(crate::dialects::DialectType::Spark)
33910 | Some(crate::dialects::DialectType::Databricks)
33911 ) {
33912 "TRY_ADD"
33913 } else {
33914 "SAFE_ADD"
33915 };
33916 self.write_keyword(name);
33917 self.write("(");
33918 self.generate_expression(&e.this)?;
33919 self.write(", ");
33920 self.generate_expression(&e.expression)?;
33921 self.write(")");
33922 Ok(())
33923 }
33924
33925 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
33926 self.write_keyword("SAFE_DIVIDE");
33928 self.write("(");
33929 self.generate_expression(&e.this)?;
33930 self.write(", ");
33931 self.generate_expression(&e.expression)?;
33932 self.write(")");
33933 Ok(())
33934 }
33935
33936 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
33937 let name = if matches!(
33938 self.config.dialect,
33939 Some(crate::dialects::DialectType::Spark)
33940 | Some(crate::dialects::DialectType::Databricks)
33941 ) {
33942 "TRY_MULTIPLY"
33943 } else {
33944 "SAFE_MULTIPLY"
33945 };
33946 self.write_keyword(name);
33947 self.write("(");
33948 self.generate_expression(&e.this)?;
33949 self.write(", ");
33950 self.generate_expression(&e.expression)?;
33951 self.write(")");
33952 Ok(())
33953 }
33954
33955 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
33956 let name = if matches!(
33957 self.config.dialect,
33958 Some(crate::dialects::DialectType::Spark)
33959 | Some(crate::dialects::DialectType::Databricks)
33960 ) {
33961 "TRY_SUBTRACT"
33962 } else {
33963 "SAFE_SUBTRACT"
33964 };
33965 self.write_keyword(name);
33966 self.write("(");
33967 self.generate_expression(&e.this)?;
33968 self.write(", ");
33969 self.generate_expression(&e.expression)?;
33970 self.write(")");
33971 Ok(())
33972 }
33973
33974 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
33977 if matches!(sample.method, SampleMethod::Bucket) {
33979 self.write(" (");
33980 self.write_keyword("BUCKET");
33981 self.write_space();
33982 if let Some(ref num) = sample.bucket_numerator {
33983 self.generate_expression(num)?;
33984 }
33985 self.write_space();
33986 self.write_keyword("OUT OF");
33987 self.write_space();
33988 if let Some(ref denom) = sample.bucket_denominator {
33989 self.generate_expression(denom)?;
33990 }
33991 if let Some(ref field) = sample.bucket_field {
33992 self.write_space();
33993 self.write_keyword("ON");
33994 self.write_space();
33995 self.generate_expression(field)?;
33996 }
33997 self.write(")");
33998 return Ok(());
33999 }
34000
34001 let is_snowflake = matches!(
34003 self.config.dialect,
34004 Some(crate::dialects::DialectType::Snowflake)
34005 );
34006 let is_postgres = matches!(
34007 self.config.dialect,
34008 Some(crate::dialects::DialectType::PostgreSQL)
34009 | Some(crate::dialects::DialectType::Redshift)
34010 );
34011 let is_databricks = matches!(
34013 self.config.dialect,
34014 Some(crate::dialects::DialectType::Databricks)
34015 );
34016 let is_spark = matches!(
34017 self.config.dialect,
34018 Some(crate::dialects::DialectType::Spark)
34019 );
34020 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
34021 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
34023 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
34024 self.write_space();
34025 if !sample.explicit_method && (is_snowflake || force_method) {
34026 self.write_keyword("BERNOULLI");
34028 } else {
34029 match sample.method {
34030 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
34031 SampleMethod::System => self.write_keyword("SYSTEM"),
34032 SampleMethod::Block => self.write_keyword("BLOCK"),
34033 SampleMethod::Row => self.write_keyword("ROW"),
34034 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
34035 SampleMethod::Percent => self.write_keyword("SYSTEM"),
34036 SampleMethod::Bucket => {} }
34038 }
34039 }
34040
34041 let emit_size_no_parens = !self.config.tablesample_requires_parens;
34043 if emit_size_no_parens {
34044 self.write_space();
34045 match &sample.size {
34046 Expression::Tuple(tuple) => {
34047 for (i, expr) in tuple.expressions.iter().enumerate() {
34048 if i > 0 {
34049 self.write(", ");
34050 }
34051 self.generate_expression(expr)?;
34052 }
34053 }
34054 expr => self.generate_expression(expr)?,
34055 }
34056 } else {
34057 self.write(" (");
34058 self.generate_expression(&sample.size)?;
34059 }
34060
34061 let is_rows_method = matches!(
34063 sample.method,
34064 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
34065 );
34066 let is_percent = matches!(
34067 sample.method,
34068 SampleMethod::Percent
34069 | SampleMethod::System
34070 | SampleMethod::Bernoulli
34071 | SampleMethod::Block
34072 );
34073
34074 let is_presto = matches!(
34078 self.config.dialect,
34079 Some(crate::dialects::DialectType::Presto)
34080 | Some(crate::dialects::DialectType::Trino)
34081 | Some(crate::dialects::DialectType::Athena)
34082 );
34083 let should_output_unit = if is_databricks || is_spark {
34084 is_percent || is_rows_method || sample.unit_after_size
34086 } else if is_snowflake || is_postgres || is_presto {
34087 sample.unit_after_size
34088 } else {
34089 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
34090 };
34091
34092 if should_output_unit {
34093 self.write_space();
34094 if sample.is_percent {
34095 self.write_keyword("PERCENT");
34096 } else if is_rows_method && !sample.unit_after_size {
34097 self.write_keyword("ROWS");
34098 } else if sample.unit_after_size {
34099 match sample.method {
34100 SampleMethod::Percent
34101 | SampleMethod::System
34102 | SampleMethod::Bernoulli
34103 | SampleMethod::Block => {
34104 self.write_keyword("PERCENT");
34105 }
34106 SampleMethod::Row | SampleMethod::Reservoir => {
34107 self.write_keyword("ROWS");
34108 }
34109 _ => self.write_keyword("ROWS"),
34110 }
34111 } else {
34112 self.write_keyword("PERCENT");
34113 }
34114 }
34115
34116 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34117 if let Some(ref offset) = sample.offset {
34118 self.write_space();
34119 self.write_keyword("OFFSET");
34120 self.write_space();
34121 self.generate_expression(offset)?;
34122 }
34123 }
34124 if !emit_size_no_parens {
34125 self.write(")");
34126 }
34127
34128 Ok(())
34129 }
34130
34131 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
34132 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34134 self.write_keyword("SAMPLE BY");
34135 } else {
34136 self.write_keyword("SAMPLE");
34137 }
34138 self.write_space();
34139 self.generate_expression(&e.this)?;
34140 Ok(())
34141 }
34142
34143 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
34144 if let Some(this) = &e.this {
34146 self.generate_expression(this)?;
34147 }
34148 if !e.expressions.is_empty() {
34149 if e.this.is_some() {
34151 self.write_space();
34152 }
34153 self.write("(");
34154 for (i, expr) in e.expressions.iter().enumerate() {
34155 if i > 0 {
34156 self.write(", ");
34157 }
34158 self.generate_expression(expr)?;
34159 }
34160 self.write(")");
34161 }
34162 Ok(())
34163 }
34164
34165 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
34166 self.write_keyword("COMMENT");
34168 self.write_space();
34169 self.generate_expression(&e.this)?;
34170 Ok(())
34171 }
34172
34173 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
34174 if let Some(this) = &e.this {
34176 self.generate_expression(this)?;
34177 self.write("::");
34178 }
34179 self.generate_expression(&e.expression)?;
34180 Ok(())
34181 }
34182
34183 fn generate_search(&mut self, e: &Search) -> Result<()> {
34184 self.write_keyword("SEARCH");
34186 self.write("(");
34187 self.generate_expression(&e.this)?;
34188 self.write(", ");
34189 self.generate_expression(&e.expression)?;
34190 if let Some(json_scope) = &e.json_scope {
34191 self.write(", ");
34192 self.generate_expression(json_scope)?;
34193 }
34194 if let Some(analyzer) = &e.analyzer {
34195 self.write(", ");
34196 self.generate_expression(analyzer)?;
34197 }
34198 if let Some(analyzer_options) = &e.analyzer_options {
34199 self.write(", ");
34200 self.generate_expression(analyzer_options)?;
34201 }
34202 if let Some(search_mode) = &e.search_mode {
34203 self.write(", ");
34204 self.generate_expression(search_mode)?;
34205 }
34206 self.write(")");
34207 Ok(())
34208 }
34209
34210 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
34211 self.write_keyword("SEARCH_IP");
34213 self.write("(");
34214 self.generate_expression(&e.this)?;
34215 self.write(", ");
34216 self.generate_expression(&e.expression)?;
34217 self.write(")");
34218 Ok(())
34219 }
34220
34221 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
34222 self.write_keyword("SECURITY");
34224 self.write_space();
34225 self.generate_expression(&e.this)?;
34226 Ok(())
34227 }
34228
34229 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
34230 self.write("SEMANTIC_VIEW(");
34232
34233 if self.config.pretty {
34234 self.write_newline();
34236 self.indent_level += 1;
34237 self.write_indent();
34238 self.generate_expression(&e.this)?;
34239
34240 if let Some(metrics) = &e.metrics {
34241 self.write_newline();
34242 self.write_indent();
34243 self.write_keyword("METRICS");
34244 self.write_space();
34245 self.generate_semantic_view_tuple(metrics)?;
34246 }
34247 if let Some(dimensions) = &e.dimensions {
34248 self.write_newline();
34249 self.write_indent();
34250 self.write_keyword("DIMENSIONS");
34251 self.write_space();
34252 self.generate_semantic_view_tuple(dimensions)?;
34253 }
34254 if let Some(facts) = &e.facts {
34255 self.write_newline();
34256 self.write_indent();
34257 self.write_keyword("FACTS");
34258 self.write_space();
34259 self.generate_semantic_view_tuple(facts)?;
34260 }
34261 if let Some(where_) = &e.where_ {
34262 self.write_newline();
34263 self.write_indent();
34264 self.write_keyword("WHERE");
34265 self.write_space();
34266 self.generate_expression(where_)?;
34267 }
34268 self.write_newline();
34269 self.indent_level -= 1;
34270 self.write_indent();
34271 } else {
34272 self.generate_expression(&e.this)?;
34274 if let Some(metrics) = &e.metrics {
34275 self.write_space();
34276 self.write_keyword("METRICS");
34277 self.write_space();
34278 self.generate_semantic_view_tuple(metrics)?;
34279 }
34280 if let Some(dimensions) = &e.dimensions {
34281 self.write_space();
34282 self.write_keyword("DIMENSIONS");
34283 self.write_space();
34284 self.generate_semantic_view_tuple(dimensions)?;
34285 }
34286 if let Some(facts) = &e.facts {
34287 self.write_space();
34288 self.write_keyword("FACTS");
34289 self.write_space();
34290 self.generate_semantic_view_tuple(facts)?;
34291 }
34292 if let Some(where_) = &e.where_ {
34293 self.write_space();
34294 self.write_keyword("WHERE");
34295 self.write_space();
34296 self.generate_expression(where_)?;
34297 }
34298 }
34299 self.write(")");
34300 Ok(())
34301 }
34302
34303 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
34305 if let Expression::Tuple(t) = expr {
34306 for (i, e) in t.expressions.iter().enumerate() {
34307 if i > 0 {
34308 self.write(", ");
34309 }
34310 self.generate_expression(e)?;
34311 }
34312 } else {
34313 self.generate_expression(expr)?;
34314 }
34315 Ok(())
34316 }
34317
34318 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
34319 if let Some(start) = &e.start {
34321 self.write_keyword("START WITH");
34322 self.write_space();
34323 self.generate_expression(start)?;
34324 }
34325 if let Some(increment) = &e.increment {
34326 self.write_space();
34327 self.write_keyword("INCREMENT BY");
34328 self.write_space();
34329 self.generate_expression(increment)?;
34330 }
34331 if let Some(minvalue) = &e.minvalue {
34332 self.write_space();
34333 self.write_keyword("MINVALUE");
34334 self.write_space();
34335 self.generate_expression(minvalue)?;
34336 }
34337 if let Some(maxvalue) = &e.maxvalue {
34338 self.write_space();
34339 self.write_keyword("MAXVALUE");
34340 self.write_space();
34341 self.generate_expression(maxvalue)?;
34342 }
34343 if let Some(cache) = &e.cache {
34344 self.write_space();
34345 self.write_keyword("CACHE");
34346 self.write_space();
34347 self.generate_expression(cache)?;
34348 }
34349 if let Some(owned) = &e.owned {
34350 self.write_space();
34351 self.write_keyword("OWNED BY");
34352 self.write_space();
34353 self.generate_expression(owned)?;
34354 }
34355 for opt in &e.options {
34356 self.write_space();
34357 self.generate_expression(opt)?;
34358 }
34359 Ok(())
34360 }
34361
34362 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
34363 if e.with_.is_some() {
34365 self.write_keyword("WITH");
34366 self.write_space();
34367 }
34368 self.write_keyword("SERDEPROPERTIES");
34369 self.write(" (");
34370 for (i, expr) in e.expressions.iter().enumerate() {
34371 if i > 0 {
34372 self.write(", ");
34373 }
34374 match expr {
34376 Expression::Eq(eq) => {
34377 self.generate_expression(&eq.left)?;
34378 self.write("=");
34379 self.generate_expression(&eq.right)?;
34380 }
34381 _ => self.generate_expression(expr)?,
34382 }
34383 }
34384 self.write(")");
34385 Ok(())
34386 }
34387
34388 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
34389 self.write("@@");
34391 if let Some(kind) = &e.kind {
34392 self.write(kind);
34393 self.write(".");
34394 }
34395 self.generate_expression(&e.this)?;
34396 Ok(())
34397 }
34398
34399 fn generate_set(&mut self, e: &Set) -> Result<()> {
34400 if e.unset.is_some() {
34402 self.write_keyword("UNSET");
34403 } else {
34404 self.write_keyword("SET");
34405 }
34406 if e.tag.is_some() {
34407 self.write_space();
34408 self.write_keyword("TAG");
34409 }
34410 if !e.expressions.is_empty() {
34411 self.write_space();
34412 for (i, expr) in e.expressions.iter().enumerate() {
34413 if i > 0 {
34414 self.write(", ");
34415 }
34416 self.generate_expression(expr)?;
34417 }
34418 }
34419 Ok(())
34420 }
34421
34422 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
34423 self.write_keyword("SET");
34425 self.write_space();
34426 self.generate_expression(&e.this)?;
34427 Ok(())
34428 }
34429
34430 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
34431 if let Some(kind) = &e.kind {
34433 self.write_keyword(kind);
34434 self.write_space();
34435 }
34436 self.generate_expression(&e.name)?;
34437 self.write(" = ");
34438 self.generate_expression(&e.value)?;
34439 Ok(())
34440 }
34441
34442 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
34443 if let Some(with_) = &e.with_ {
34445 self.generate_expression(with_)?;
34446 self.write_space();
34447 }
34448 self.generate_expression(&e.this)?;
34449 self.write_space();
34450 if let Some(kind) = &e.kind {
34452 self.write_keyword(kind);
34453 }
34454 if e.distinct {
34455 self.write_space();
34456 self.write_keyword("DISTINCT");
34457 } else {
34458 self.write_space();
34459 self.write_keyword("ALL");
34460 }
34461 if e.by_name.is_some() {
34462 self.write_space();
34463 self.write_keyword("BY NAME");
34464 }
34465 self.write_space();
34466 self.generate_expression(&e.expression)?;
34467 Ok(())
34468 }
34469
34470 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
34471 if e.multi.is_some() {
34473 self.write_keyword("MULTISET");
34474 } else {
34475 self.write_keyword("SET");
34476 }
34477 Ok(())
34478 }
34479
34480 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
34481 self.write_keyword("SETTINGS");
34483 if self.config.pretty && e.expressions.len() > 1 {
34484 self.indent_level += 1;
34486 for (i, expr) in e.expressions.iter().enumerate() {
34487 if i > 0 {
34488 self.write(",");
34489 }
34490 self.write_newline();
34491 self.write_indent();
34492 self.generate_expression(expr)?;
34493 }
34494 self.indent_level -= 1;
34495 } else {
34496 self.write_space();
34497 for (i, expr) in e.expressions.iter().enumerate() {
34498 if i > 0 {
34499 self.write(", ");
34500 }
34501 self.generate_expression(expr)?;
34502 }
34503 }
34504 Ok(())
34505 }
34506
34507 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
34508 self.write_keyword("SHARING");
34510 if let Some(this) = &e.this {
34511 self.write(" = ");
34512 self.generate_expression(this)?;
34513 }
34514 Ok(())
34515 }
34516
34517 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
34518 if let Some(begin) = &e.this {
34520 self.generate_expression(begin)?;
34521 }
34522 self.write(":");
34523 if let Some(end) = &e.expression {
34524 self.generate_expression(end)?;
34525 }
34526 if let Some(step) = &e.step {
34527 self.write(":");
34528 self.generate_expression(step)?;
34529 }
34530 Ok(())
34531 }
34532
34533 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
34534 self.write_keyword("SORT_ARRAY");
34536 self.write("(");
34537 self.generate_expression(&e.this)?;
34538 if let Some(asc) = &e.asc {
34539 self.write(", ");
34540 self.generate_expression(asc)?;
34541 }
34542 self.write(")");
34543 Ok(())
34544 }
34545
34546 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
34547 self.write_keyword("SORT BY");
34549 self.write_space();
34550 for (i, expr) in e.expressions.iter().enumerate() {
34551 if i > 0 {
34552 self.write(", ");
34553 }
34554 self.generate_ordered(expr)?;
34555 }
34556 Ok(())
34557 }
34558
34559 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
34560 if e.compound.is_some() {
34562 self.write_keyword("COMPOUND");
34563 self.write_space();
34564 }
34565 self.write_keyword("SORTKEY");
34566 self.write("(");
34567 if let Expression::Tuple(t) = e.this.as_ref() {
34569 for (i, expr) in t.expressions.iter().enumerate() {
34570 if i > 0 {
34571 self.write(", ");
34572 }
34573 self.generate_expression(expr)?;
34574 }
34575 } else {
34576 self.generate_expression(&e.this)?;
34577 }
34578 self.write(")");
34579 Ok(())
34580 }
34581
34582 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
34583 self.write_keyword("SPLIT_PART");
34585 self.write("(");
34586 self.generate_expression(&e.this)?;
34587 if let Some(delimiter) = &e.delimiter {
34588 self.write(", ");
34589 self.generate_expression(delimiter)?;
34590 }
34591 if let Some(part_index) = &e.part_index {
34592 self.write(", ");
34593 self.generate_expression(part_index)?;
34594 }
34595 self.write(")");
34596 Ok(())
34597 }
34598
34599 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
34600 self.generate_expression(&e.this)?;
34602 Ok(())
34603 }
34604
34605 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
34606 self.write_keyword("SQL SECURITY");
34608 self.write_space();
34609 self.generate_expression(&e.this)?;
34610 Ok(())
34611 }
34612
34613 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
34614 self.write_keyword("ST_DISTANCE");
34616 self.write("(");
34617 self.generate_expression(&e.this)?;
34618 self.write(", ");
34619 self.generate_expression(&e.expression)?;
34620 if let Some(use_spheroid) = &e.use_spheroid {
34621 self.write(", ");
34622 self.generate_expression(use_spheroid)?;
34623 }
34624 self.write(")");
34625 Ok(())
34626 }
34627
34628 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
34629 self.write_keyword("ST_POINT");
34631 self.write("(");
34632 self.generate_expression(&e.this)?;
34633 self.write(", ");
34634 self.generate_expression(&e.expression)?;
34635 self.write(")");
34636 Ok(())
34637 }
34638
34639 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
34640 self.generate_expression(&e.this)?;
34642 Ok(())
34643 }
34644
34645 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
34646 self.write_keyword("STANDARD_HASH");
34648 self.write("(");
34649 self.generate_expression(&e.this)?;
34650 if let Some(expression) = &e.expression {
34651 self.write(", ");
34652 self.generate_expression(expression)?;
34653 }
34654 self.write(")");
34655 Ok(())
34656 }
34657
34658 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
34659 self.write_keyword("STORED BY");
34661 self.write_space();
34662 self.generate_expression(&e.this)?;
34663 Ok(())
34664 }
34665
34666 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
34667 use crate::dialects::DialectType;
34670 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34671 self.write_keyword("CHARINDEX");
34673 self.write("(");
34674 if let Some(substr) = &e.substr {
34675 self.generate_expression(substr)?;
34676 self.write(", ");
34677 }
34678 self.generate_expression(&e.this)?;
34679 if let Some(position) = &e.position {
34680 self.write(", ");
34681 self.generate_expression(position)?;
34682 }
34683 self.write(")");
34684 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
34685 self.write_keyword("POSITION");
34686 self.write("(");
34687 self.generate_expression(&e.this)?;
34688 if let Some(substr) = &e.substr {
34689 self.write(", ");
34690 self.generate_expression(substr)?;
34691 }
34692 if let Some(position) = &e.position {
34693 self.write(", ");
34694 self.generate_expression(position)?;
34695 }
34696 if let Some(occurrence) = &e.occurrence {
34697 self.write(", ");
34698 self.generate_expression(occurrence)?;
34699 }
34700 self.write(")");
34701 } else if matches!(
34702 self.config.dialect,
34703 Some(DialectType::SQLite)
34704 | Some(DialectType::Oracle)
34705 | Some(DialectType::BigQuery)
34706 | Some(DialectType::Teradata)
34707 ) {
34708 self.write_keyword("INSTR");
34709 self.write("(");
34710 self.generate_expression(&e.this)?;
34711 if let Some(substr) = &e.substr {
34712 self.write(", ");
34713 self.generate_expression(substr)?;
34714 }
34715 if let Some(position) = &e.position {
34716 self.write(", ");
34717 self.generate_expression(position)?;
34718 } else if e.occurrence.is_some() {
34719 self.write(", 1");
34722 }
34723 if let Some(occurrence) = &e.occurrence {
34724 self.write(", ");
34725 self.generate_expression(occurrence)?;
34726 }
34727 self.write(")");
34728 } else if matches!(
34729 self.config.dialect,
34730 Some(DialectType::MySQL)
34731 | Some(DialectType::SingleStore)
34732 | Some(DialectType::Doris)
34733 | Some(DialectType::StarRocks)
34734 | Some(DialectType::Hive)
34735 | Some(DialectType::Spark)
34736 | Some(DialectType::Databricks)
34737 ) {
34738 self.write_keyword("LOCATE");
34740 self.write("(");
34741 if let Some(substr) = &e.substr {
34742 self.generate_expression(substr)?;
34743 self.write(", ");
34744 }
34745 self.generate_expression(&e.this)?;
34746 if let Some(position) = &e.position {
34747 self.write(", ");
34748 self.generate_expression(position)?;
34749 }
34750 self.write(")");
34751 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
34752 self.write_keyword("CHARINDEX");
34754 self.write("(");
34755 if let Some(substr) = &e.substr {
34756 self.generate_expression(substr)?;
34757 self.write(", ");
34758 }
34759 self.generate_expression(&e.this)?;
34760 if let Some(position) = &e.position {
34761 self.write(", ");
34762 self.generate_expression(position)?;
34763 }
34764 self.write(")");
34765 } else if matches!(
34766 self.config.dialect,
34767 Some(DialectType::PostgreSQL)
34768 | Some(DialectType::Materialize)
34769 | Some(DialectType::RisingWave)
34770 | Some(DialectType::Redshift)
34771 ) {
34772 self.write_keyword("POSITION");
34774 self.write("(");
34775 if let Some(substr) = &e.substr {
34776 self.generate_expression(substr)?;
34777 self.write(" IN ");
34778 }
34779 self.generate_expression(&e.this)?;
34780 self.write(")");
34781 } else {
34782 self.write_keyword("STRPOS");
34783 self.write("(");
34784 self.generate_expression(&e.this)?;
34785 if let Some(substr) = &e.substr {
34786 self.write(", ");
34787 self.generate_expression(substr)?;
34788 }
34789 if let Some(position) = &e.position {
34790 self.write(", ");
34791 self.generate_expression(position)?;
34792 }
34793 if let Some(occurrence) = &e.occurrence {
34794 self.write(", ");
34795 self.generate_expression(occurrence)?;
34796 }
34797 self.write(")");
34798 }
34799 Ok(())
34800 }
34801
34802 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
34803 match self.config.dialect {
34804 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
34805 self.write_keyword("TO_DATE");
34807 self.write("(");
34808 self.generate_expression(&e.this)?;
34809 if let Some(format) = &e.format {
34810 self.write(", '");
34811 self.write(&Self::strftime_to_java_format(format));
34812 self.write("'");
34813 }
34814 self.write(")");
34815 }
34816 Some(DialectType::DuckDB) => {
34817 self.write_keyword("CAST");
34819 self.write("(");
34820 self.write_keyword("STRPTIME");
34821 self.write("(");
34822 self.generate_expression(&e.this)?;
34823 if let Some(format) = &e.format {
34824 self.write(", '");
34825 self.write(format);
34826 self.write("'");
34827 }
34828 self.write(")");
34829 self.write_keyword(" AS ");
34830 self.write_keyword("DATE");
34831 self.write(")");
34832 }
34833 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
34834 self.write_keyword("TO_DATE");
34836 self.write("(");
34837 self.generate_expression(&e.this)?;
34838 if let Some(format) = &e.format {
34839 self.write(", '");
34840 self.write(&Self::strftime_to_postgres_format(format));
34841 self.write("'");
34842 }
34843 self.write(")");
34844 }
34845 Some(DialectType::BigQuery) => {
34846 self.write_keyword("PARSE_DATE");
34848 self.write("(");
34849 if let Some(format) = &e.format {
34850 self.write("'");
34851 self.write(format);
34852 self.write("'");
34853 self.write(", ");
34854 }
34855 self.generate_expression(&e.this)?;
34856 self.write(")");
34857 }
34858 Some(DialectType::Teradata) => {
34859 self.write_keyword("CAST");
34861 self.write("(");
34862 self.generate_expression(&e.this)?;
34863 self.write_keyword(" AS ");
34864 self.write_keyword("DATE");
34865 if let Some(format) = &e.format {
34866 self.write_keyword(" FORMAT ");
34867 self.write("'");
34868 self.write(&Self::strftime_to_teradata_format(format));
34869 self.write("'");
34870 }
34871 self.write(")");
34872 }
34873 _ => {
34874 self.write_keyword("STR_TO_DATE");
34876 self.write("(");
34877 self.generate_expression(&e.this)?;
34878 if let Some(format) = &e.format {
34879 self.write(", '");
34880 self.write(format);
34881 self.write("'");
34882 }
34883 self.write(")");
34884 }
34885 }
34886 Ok(())
34887 }
34888
34889 fn strftime_to_teradata_format(fmt: &str) -> String {
34891 let mut result = String::with_capacity(fmt.len() * 2);
34892 let bytes = fmt.as_bytes();
34893 let len = bytes.len();
34894 let mut i = 0;
34895 while i < len {
34896 if bytes[i] == b'%' && i + 1 < len {
34897 let replacement = match bytes[i + 1] {
34898 b'Y' => "YYYY",
34899 b'y' => "YY",
34900 b'm' => "MM",
34901 b'B' => "MMMM",
34902 b'b' => "MMM",
34903 b'd' => "DD",
34904 b'j' => "DDD",
34905 b'H' => "HH",
34906 b'M' => "MI",
34907 b'S' => "SS",
34908 b'f' => "SSSSSS",
34909 b'A' => "EEEE",
34910 b'a' => "EEE",
34911 _ => {
34912 result.push('%');
34913 i += 1;
34914 continue;
34915 }
34916 };
34917 result.push_str(replacement);
34918 i += 2;
34919 } else {
34920 result.push(bytes[i] as char);
34921 i += 1;
34922 }
34923 }
34924 result
34925 }
34926
34927 pub fn strftime_to_java_format_static(fmt: &str) -> String {
34930 Self::strftime_to_java_format(fmt)
34931 }
34932
34933 fn strftime_to_java_format(fmt: &str) -> String {
34935 let mut result = String::with_capacity(fmt.len() * 2);
34936 let bytes = fmt.as_bytes();
34937 let len = bytes.len();
34938 let mut i = 0;
34939 while i < len {
34940 if bytes[i] == b'%' && i + 1 < len {
34941 if bytes[i + 1] == b'-' && i + 2 < len {
34943 let replacement = match bytes[i + 2] {
34944 b'd' => "d",
34945 b'm' => "M",
34946 b'H' => "H",
34947 b'M' => "m",
34948 b'S' => "s",
34949 _ => {
34950 result.push('%');
34951 i += 1;
34952 continue;
34953 }
34954 };
34955 result.push_str(replacement);
34956 i += 3;
34957 } else {
34958 let replacement = match bytes[i + 1] {
34959 b'Y' => "yyyy",
34960 b'y' => "yy",
34961 b'm' => "MM",
34962 b'B' => "MMMM",
34963 b'b' => "MMM",
34964 b'd' => "dd",
34965 b'j' => "DDD",
34966 b'H' => "HH",
34967 b'M' => "mm",
34968 b'S' => "ss",
34969 b'f' => "SSSSSS",
34970 b'A' => "EEEE",
34971 b'a' => "EEE",
34972 _ => {
34973 result.push('%');
34974 i += 1;
34975 continue;
34976 }
34977 };
34978 result.push_str(replacement);
34979 i += 2;
34980 }
34981 } else {
34982 result.push(bytes[i] as char);
34983 i += 1;
34984 }
34985 }
34986 result
34987 }
34988
34989 fn strftime_to_tsql_format(fmt: &str) -> String {
34992 let mut result = String::with_capacity(fmt.len() * 2);
34993 let bytes = fmt.as_bytes();
34994 let len = bytes.len();
34995 let mut i = 0;
34996 while i < len {
34997 if bytes[i] == b'%' && i + 1 < len {
34998 if bytes[i + 1] == b'-' && i + 2 < len {
35000 let replacement = match bytes[i + 2] {
35001 b'd' => "d",
35002 b'm' => "M",
35003 b'H' => "H",
35004 b'M' => "m",
35005 b'S' => "s",
35006 _ => {
35007 result.push('%');
35008 i += 1;
35009 continue;
35010 }
35011 };
35012 result.push_str(replacement);
35013 i += 3;
35014 } else {
35015 let replacement = match bytes[i + 1] {
35016 b'Y' => "yyyy",
35017 b'y' => "yy",
35018 b'm' => "MM",
35019 b'B' => "MMMM",
35020 b'b' => "MMM",
35021 b'd' => "dd",
35022 b'j' => "DDD",
35023 b'H' => "HH",
35024 b'M' => "mm",
35025 b'S' => "ss",
35026 b'f' => "ffffff",
35027 b'A' => "dddd",
35028 b'a' => "ddd",
35029 _ => {
35030 result.push('%');
35031 i += 1;
35032 continue;
35033 }
35034 };
35035 result.push_str(replacement);
35036 i += 2;
35037 }
35038 } else {
35039 result.push(bytes[i] as char);
35040 i += 1;
35041 }
35042 }
35043 result
35044 }
35045
35046 fn decompose_json_path(path: &str) -> Vec<String> {
35049 let mut parts = Vec::new();
35050 let path = if path.starts_with("$.") {
35052 &path[2..]
35053 } else if path.starts_with('$') {
35054 &path[1..]
35055 } else {
35056 path
35057 };
35058 if path.is_empty() {
35059 return parts;
35060 }
35061 let mut current = String::new();
35062 let chars: Vec<char> = path.chars().collect();
35063 let mut i = 0;
35064 while i < chars.len() {
35065 match chars[i] {
35066 '.' => {
35067 if !current.is_empty() {
35068 parts.push(current.clone());
35069 current.clear();
35070 }
35071 i += 1;
35072 }
35073 '[' => {
35074 if !current.is_empty() {
35075 parts.push(current.clone());
35076 current.clear();
35077 }
35078 i += 1;
35079 let mut bracket_content = String::new();
35081 while i < chars.len() && chars[i] != ']' {
35082 if chars[i] == '"' || chars[i] == '\'' {
35084 let quote = chars[i];
35085 i += 1;
35086 while i < chars.len() && chars[i] != quote {
35087 bracket_content.push(chars[i]);
35088 i += 1;
35089 }
35090 if i < chars.len() {
35091 i += 1;
35092 } } else {
35094 bracket_content.push(chars[i]);
35095 i += 1;
35096 }
35097 }
35098 if i < chars.len() {
35099 i += 1;
35100 } if bracket_content != "*" {
35103 parts.push(bracket_content);
35104 }
35105 }
35106 _ => {
35107 current.push(chars[i]);
35108 i += 1;
35109 }
35110 }
35111 }
35112 if !current.is_empty() {
35113 parts.push(current);
35114 }
35115 parts
35116 }
35117
35118 fn strftime_to_postgres_format(fmt: &str) -> String {
35120 let mut result = String::with_capacity(fmt.len() * 2);
35121 let bytes = fmt.as_bytes();
35122 let len = bytes.len();
35123 let mut i = 0;
35124 while i < len {
35125 if bytes[i] == b'%' && i + 1 < len {
35126 if bytes[i + 1] == b'-' && i + 2 < len {
35128 let replacement = match bytes[i + 2] {
35129 b'd' => "FMDD",
35130 b'm' => "FMMM",
35131 b'H' => "FMHH24",
35132 b'M' => "FMMI",
35133 b'S' => "FMSS",
35134 _ => {
35135 result.push('%');
35136 i += 1;
35137 continue;
35138 }
35139 };
35140 result.push_str(replacement);
35141 i += 3;
35142 } else {
35143 let replacement = match bytes[i + 1] {
35144 b'Y' => "YYYY",
35145 b'y' => "YY",
35146 b'm' => "MM",
35147 b'B' => "Month",
35148 b'b' => "Mon",
35149 b'd' => "DD",
35150 b'j' => "DDD",
35151 b'H' => "HH24",
35152 b'M' => "MI",
35153 b'S' => "SS",
35154 b'f' => "US",
35155 b'A' => "Day",
35156 b'a' => "Dy",
35157 _ => {
35158 result.push('%');
35159 i += 1;
35160 continue;
35161 }
35162 };
35163 result.push_str(replacement);
35164 i += 2;
35165 }
35166 } else {
35167 result.push(bytes[i] as char);
35168 i += 1;
35169 }
35170 }
35171 result
35172 }
35173
35174 fn strftime_to_snowflake_format(fmt: &str) -> String {
35176 let mut result = String::with_capacity(fmt.len() * 2);
35177 let bytes = fmt.as_bytes();
35178 let len = bytes.len();
35179 let mut i = 0;
35180 while i < len {
35181 if bytes[i] == b'%' && i + 1 < len {
35182 if bytes[i + 1] == b'-' && i + 2 < len {
35184 let replacement = match bytes[i + 2] {
35185 b'd' => "dd",
35186 b'm' => "mm",
35187 _ => {
35188 result.push('%');
35189 i += 1;
35190 continue;
35191 }
35192 };
35193 result.push_str(replacement);
35194 i += 3;
35195 } else {
35196 let replacement = match bytes[i + 1] {
35197 b'Y' => "yyyy",
35198 b'y' => "yy",
35199 b'm' => "mm",
35200 b'd' => "DD",
35201 b'H' => "hh24",
35202 b'M' => "mi",
35203 b'S' => "ss",
35204 b'f' => "ff",
35205 _ => {
35206 result.push('%');
35207 i += 1;
35208 continue;
35209 }
35210 };
35211 result.push_str(replacement);
35212 i += 2;
35213 }
35214 } else {
35215 result.push(bytes[i] as char);
35216 i += 1;
35217 }
35218 }
35219 result
35220 }
35221
35222 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
35223 self.write_keyword("STR_TO_MAP");
35225 self.write("(");
35226 self.generate_expression(&e.this)?;
35227 let needs_defaults = matches!(
35229 self.config.dialect,
35230 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
35231 );
35232 if let Some(pair_delim) = &e.pair_delim {
35233 self.write(", ");
35234 self.generate_expression(pair_delim)?;
35235 } else if needs_defaults {
35236 self.write(", ','");
35237 }
35238 if let Some(key_value_delim) = &e.key_value_delim {
35239 self.write(", ");
35240 self.generate_expression(key_value_delim)?;
35241 } else if needs_defaults {
35242 self.write(", ':'");
35243 }
35244 self.write(")");
35245 Ok(())
35246 }
35247
35248 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
35249 let is_strftime = e.format.contains('%');
35251 let to_strftime = |f: &str| -> String {
35253 if is_strftime {
35254 f.to_string()
35255 } else {
35256 Self::snowflake_format_to_strftime(f)
35257 }
35258 };
35259 let to_java = |f: &str| -> String {
35261 if is_strftime {
35262 Self::strftime_to_java_format(f)
35263 } else {
35264 Self::snowflake_format_to_spark(f)
35265 }
35266 };
35267 let to_pg = |f: &str| -> String {
35269 if is_strftime {
35270 Self::strftime_to_postgres_format(f)
35271 } else {
35272 Self::convert_strptime_to_postgres_format(f)
35273 }
35274 };
35275
35276 match self.config.dialect {
35277 Some(DialectType::Exasol) => {
35278 self.write_keyword("TO_DATE");
35279 self.write("(");
35280 self.generate_expression(&e.this)?;
35281 self.write(", '");
35282 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35283 self.write("'");
35284 self.write(")");
35285 }
35286 Some(DialectType::BigQuery) => {
35287 let fmt = to_strftime(&e.format);
35289 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35291 self.write_keyword("PARSE_TIMESTAMP");
35292 self.write("('");
35293 self.write(&fmt);
35294 self.write("', ");
35295 self.generate_expression(&e.this)?;
35296 self.write(")");
35297 }
35298 Some(DialectType::Hive) => {
35299 let java_fmt = to_java(&e.format);
35302 if java_fmt == "yyyy-MM-dd HH:mm:ss"
35303 || java_fmt == "yyyy-MM-dd"
35304 || e.format == "yyyy-MM-dd HH:mm:ss"
35305 || e.format == "yyyy-MM-dd"
35306 {
35307 self.write_keyword("CAST");
35308 self.write("(");
35309 self.generate_expression(&e.this)?;
35310 self.write(" ");
35311 self.write_keyword("AS TIMESTAMP");
35312 self.write(")");
35313 } else {
35314 self.write_keyword("CAST");
35316 self.write("(");
35317 self.write_keyword("FROM_UNIXTIME");
35318 self.write("(");
35319 self.write_keyword("UNIX_TIMESTAMP");
35320 self.write("(");
35321 self.generate_expression(&e.this)?;
35322 self.write(", '");
35323 self.write(&java_fmt);
35324 self.write("')");
35325 self.write(") ");
35326 self.write_keyword("AS TIMESTAMP");
35327 self.write(")");
35328 }
35329 }
35330 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35331 let java_fmt = to_java(&e.format);
35333 self.write_keyword("TO_TIMESTAMP");
35334 self.write("(");
35335 self.generate_expression(&e.this)?;
35336 self.write(", '");
35337 self.write(&java_fmt);
35338 self.write("')");
35339 }
35340 Some(DialectType::MySQL) => {
35341 let mut fmt = to_strftime(&e.format);
35343 fmt = fmt.replace("%-d", "%e");
35345 fmt = fmt.replace("%-m", "%c");
35346 fmt = fmt.replace("%H:%M:%S", "%T");
35347 self.write_keyword("STR_TO_DATE");
35348 self.write("(");
35349 self.generate_expression(&e.this)?;
35350 self.write(", '");
35351 self.write(&fmt);
35352 self.write("')");
35353 }
35354 Some(DialectType::Drill) => {
35355 let java_fmt = to_java(&e.format);
35357 let java_fmt = java_fmt.replace('T', "''T''");
35359 self.write_keyword("TO_TIMESTAMP");
35360 self.write("(");
35361 self.generate_expression(&e.this)?;
35362 self.write(", '");
35363 self.write(&java_fmt);
35364 self.write("')");
35365 }
35366 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35367 let mut fmt = to_strftime(&e.format);
35369 fmt = fmt.replace("%-d", "%e");
35371 fmt = fmt.replace("%-m", "%c");
35372 fmt = fmt.replace("%H:%M:%S", "%T");
35373 self.write_keyword("DATE_PARSE");
35374 self.write("(");
35375 self.generate_expression(&e.this)?;
35376 self.write(", '");
35377 self.write(&fmt);
35378 self.write("')");
35379 }
35380 Some(DialectType::DuckDB) => {
35381 let fmt = to_strftime(&e.format);
35383 self.write_keyword("STRPTIME");
35384 self.write("(");
35385 self.generate_expression(&e.this)?;
35386 self.write(", '");
35387 self.write(&fmt);
35388 self.write("')");
35389 }
35390 Some(DialectType::PostgreSQL)
35391 | Some(DialectType::Redshift)
35392 | Some(DialectType::Materialize) => {
35393 let pg_fmt = to_pg(&e.format);
35395 self.write_keyword("TO_TIMESTAMP");
35396 self.write("(");
35397 self.generate_expression(&e.this)?;
35398 self.write(", '");
35399 self.write(&pg_fmt);
35400 self.write("')");
35401 }
35402 Some(DialectType::Oracle) => {
35403 let pg_fmt = to_pg(&e.format);
35405 self.write_keyword("TO_TIMESTAMP");
35406 self.write("(");
35407 self.generate_expression(&e.this)?;
35408 self.write(", '");
35409 self.write(&pg_fmt);
35410 self.write("')");
35411 }
35412 Some(DialectType::Snowflake) => {
35413 self.write_keyword("TO_TIMESTAMP");
35415 self.write("(");
35416 self.generate_expression(&e.this)?;
35417 self.write(", '");
35418 self.write(&e.format);
35419 self.write("')");
35420 }
35421 _ => {
35422 self.write_keyword("STR_TO_TIME");
35424 self.write("(");
35425 self.generate_expression(&e.this)?;
35426 self.write(", '");
35427 self.write(&e.format);
35428 self.write("'");
35429 self.write(")");
35430 }
35431 }
35432 Ok(())
35433 }
35434
35435 fn snowflake_format_to_strftime(format: &str) -> String {
35437 let mut result = String::new();
35438 let chars: Vec<char> = format.chars().collect();
35439 let mut i = 0;
35440 while i < chars.len() {
35441 let remaining = &format[i..];
35442 if remaining.starts_with("yyyy") {
35443 result.push_str("%Y");
35444 i += 4;
35445 } else if remaining.starts_with("yy") {
35446 result.push_str("%y");
35447 i += 2;
35448 } else if remaining.starts_with("mmmm") {
35449 result.push_str("%B"); i += 4;
35451 } else if remaining.starts_with("mon") {
35452 result.push_str("%b"); i += 3;
35454 } else if remaining.starts_with("mm") {
35455 result.push_str("%m");
35456 i += 2;
35457 } else if remaining.starts_with("DD") {
35458 result.push_str("%d");
35459 i += 2;
35460 } else if remaining.starts_with("dy") {
35461 result.push_str("%a"); i += 2;
35463 } else if remaining.starts_with("hh24") {
35464 result.push_str("%H");
35465 i += 4;
35466 } else if remaining.starts_with("hh12") {
35467 result.push_str("%I");
35468 i += 4;
35469 } else if remaining.starts_with("hh") {
35470 result.push_str("%H");
35471 i += 2;
35472 } else if remaining.starts_with("mi") {
35473 result.push_str("%M");
35474 i += 2;
35475 } else if remaining.starts_with("ss") {
35476 result.push_str("%S");
35477 i += 2;
35478 } else if remaining.starts_with("ff") {
35479 result.push_str("%f");
35481 i += 2;
35482 while i < chars.len() && chars[i].is_ascii_digit() {
35484 i += 1;
35485 }
35486 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
35487 result.push_str("%p");
35488 i += 2;
35489 } else if remaining.starts_with("tz") {
35490 result.push_str("%Z");
35491 i += 2;
35492 } else {
35493 result.push(chars[i]);
35494 i += 1;
35495 }
35496 }
35497 result
35498 }
35499
35500 fn snowflake_format_to_spark(format: &str) -> String {
35502 let mut result = String::new();
35503 let chars: Vec<char> = format.chars().collect();
35504 let mut i = 0;
35505 while i < chars.len() {
35506 let remaining = &format[i..];
35507 if remaining.starts_with("yyyy") {
35508 result.push_str("yyyy");
35509 i += 4;
35510 } else if remaining.starts_with("yy") {
35511 result.push_str("yy");
35512 i += 2;
35513 } else if remaining.starts_with("mmmm") {
35514 result.push_str("MMMM"); i += 4;
35516 } else if remaining.starts_with("mon") {
35517 result.push_str("MMM"); i += 3;
35519 } else if remaining.starts_with("mm") {
35520 result.push_str("MM");
35521 i += 2;
35522 } else if remaining.starts_with("DD") {
35523 result.push_str("dd");
35524 i += 2;
35525 } else if remaining.starts_with("dy") {
35526 result.push_str("EEE"); i += 2;
35528 } else if remaining.starts_with("hh24") {
35529 result.push_str("HH");
35530 i += 4;
35531 } else if remaining.starts_with("hh12") {
35532 result.push_str("hh");
35533 i += 4;
35534 } else if remaining.starts_with("hh") {
35535 result.push_str("HH");
35536 i += 2;
35537 } else if remaining.starts_with("mi") {
35538 result.push_str("mm");
35539 i += 2;
35540 } else if remaining.starts_with("ss") {
35541 result.push_str("ss");
35542 i += 2;
35543 } else if remaining.starts_with("ff") {
35544 result.push_str("SSS"); i += 2;
35546 while i < chars.len() && chars[i].is_ascii_digit() {
35548 i += 1;
35549 }
35550 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
35551 result.push_str("a");
35552 i += 2;
35553 } else if remaining.starts_with("tz") {
35554 result.push_str("z");
35555 i += 2;
35556 } else {
35557 result.push(chars[i]);
35558 i += 1;
35559 }
35560 }
35561 result
35562 }
35563
35564 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
35565 match self.config.dialect {
35566 Some(DialectType::DuckDB) => {
35567 self.write_keyword("EPOCH");
35569 self.write("(");
35570 self.write_keyword("STRPTIME");
35571 self.write("(");
35572 if let Some(this) = &e.this {
35573 self.generate_expression(this)?;
35574 }
35575 if let Some(format) = &e.format {
35576 self.write(", '");
35577 self.write(format);
35578 self.write("'");
35579 }
35580 self.write("))");
35581 }
35582 Some(DialectType::Hive) => {
35583 self.write_keyword("UNIX_TIMESTAMP");
35585 self.write("(");
35586 if let Some(this) = &e.this {
35587 self.generate_expression(this)?;
35588 }
35589 if let Some(format) = &e.format {
35590 let java_fmt = Self::strftime_to_java_format(format);
35591 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
35592 self.write(", '");
35593 self.write(&java_fmt);
35594 self.write("'");
35595 }
35596 }
35597 self.write(")");
35598 }
35599 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35600 self.write_keyword("UNIX_TIMESTAMP");
35602 self.write("(");
35603 if let Some(this) = &e.this {
35604 self.generate_expression(this)?;
35605 }
35606 if let Some(format) = &e.format {
35607 self.write(", '");
35608 self.write(format);
35609 self.write("'");
35610 }
35611 self.write(")");
35612 }
35613 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35614 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
35617 let java_fmt = Self::strftime_to_java_format(c_fmt);
35618 self.write_keyword("TO_UNIXTIME");
35619 self.write("(");
35620 self.write_keyword("COALESCE");
35621 self.write("(");
35622 self.write_keyword("TRY");
35623 self.write("(");
35624 self.write_keyword("DATE_PARSE");
35625 self.write("(");
35626 self.write_keyword("CAST");
35627 self.write("(");
35628 if let Some(this) = &e.this {
35629 self.generate_expression(this)?;
35630 }
35631 self.write(" ");
35632 self.write_keyword("AS VARCHAR");
35633 self.write("), '");
35634 self.write(c_fmt);
35635 self.write("')), ");
35636 self.write_keyword("PARSE_DATETIME");
35637 self.write("(");
35638 self.write_keyword("DATE_FORMAT");
35639 self.write("(");
35640 self.write_keyword("CAST");
35641 self.write("(");
35642 if let Some(this) = &e.this {
35643 self.generate_expression(this)?;
35644 }
35645 self.write(" ");
35646 self.write_keyword("AS TIMESTAMP");
35647 self.write("), '");
35648 self.write(c_fmt);
35649 self.write("'), '");
35650 self.write(&java_fmt);
35651 self.write("')))");
35652 }
35653 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35654 self.write_keyword("UNIX_TIMESTAMP");
35656 self.write("(");
35657 if let Some(this) = &e.this {
35658 self.generate_expression(this)?;
35659 }
35660 if let Some(format) = &e.format {
35661 let java_fmt = Self::strftime_to_java_format(format);
35662 self.write(", '");
35663 self.write(&java_fmt);
35664 self.write("'");
35665 }
35666 self.write(")");
35667 }
35668 _ => {
35669 self.write_keyword("STR_TO_UNIX");
35671 self.write("(");
35672 if let Some(this) = &e.this {
35673 self.generate_expression(this)?;
35674 }
35675 if let Some(format) = &e.format {
35676 self.write(", '");
35677 self.write(format);
35678 self.write("'");
35679 }
35680 self.write(")");
35681 }
35682 }
35683 Ok(())
35684 }
35685
35686 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
35687 self.write_keyword("STRING_TO_ARRAY");
35689 self.write("(");
35690 self.generate_expression(&e.this)?;
35691 if let Some(expression) = &e.expression {
35692 self.write(", ");
35693 self.generate_expression(expression)?;
35694 }
35695 if let Some(null_val) = &e.null {
35696 self.write(", ");
35697 self.generate_expression(null_val)?;
35698 }
35699 self.write(")");
35700 Ok(())
35701 }
35702
35703 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
35704 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35705 self.write_keyword("OBJECT_CONSTRUCT");
35707 self.write("(");
35708 for (i, (name, expr)) in e.fields.iter().enumerate() {
35709 if i > 0 {
35710 self.write(", ");
35711 }
35712 if let Some(name) = name {
35713 self.write("'");
35714 self.write(name);
35715 self.write("'");
35716 self.write(", ");
35717 } else {
35718 self.write("'_");
35719 self.write(&i.to_string());
35720 self.write("'");
35721 self.write(", ");
35722 }
35723 self.generate_expression(expr)?;
35724 }
35725 self.write(")");
35726 } else if self.config.struct_curly_brace_notation {
35727 self.write("{");
35729 for (i, (name, expr)) in e.fields.iter().enumerate() {
35730 if i > 0 {
35731 self.write(", ");
35732 }
35733 if let Some(name) = name {
35734 self.write("'");
35736 self.write(name);
35737 self.write("'");
35738 self.write(": ");
35739 } else {
35740 self.write("'_");
35742 self.write(&i.to_string());
35743 self.write("'");
35744 self.write(": ");
35745 }
35746 self.generate_expression(expr)?;
35747 }
35748 self.write("}");
35749 } else {
35750 let value_as_name = matches!(
35754 self.config.dialect,
35755 Some(DialectType::BigQuery)
35756 | Some(DialectType::Spark)
35757 | Some(DialectType::Databricks)
35758 | Some(DialectType::Hive)
35759 );
35760 self.write_keyword("STRUCT");
35761 self.write("(");
35762 for (i, (name, expr)) in e.fields.iter().enumerate() {
35763 if i > 0 {
35764 self.write(", ");
35765 }
35766 if let Some(name) = name {
35767 if value_as_name {
35768 self.generate_expression(expr)?;
35770 self.write_space();
35771 self.write_keyword("AS");
35772 self.write_space();
35773 let needs_quoting = name.contains(' ') || name.contains('-');
35775 if needs_quoting {
35776 if matches!(
35777 self.config.dialect,
35778 Some(DialectType::Spark)
35779 | Some(DialectType::Databricks)
35780 | Some(DialectType::Hive)
35781 ) {
35782 self.write("`");
35783 self.write(name);
35784 self.write("`");
35785 } else {
35786 self.write(name);
35787 }
35788 } else {
35789 self.write(name);
35790 }
35791 } else {
35792 self.write(name);
35794 self.write_space();
35795 self.write_keyword("AS");
35796 self.write_space();
35797 self.generate_expression(expr)?;
35798 }
35799 } else {
35800 self.generate_expression(expr)?;
35801 }
35802 }
35803 self.write(")");
35804 }
35805 Ok(())
35806 }
35807
35808 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
35809 self.write_keyword("STUFF");
35811 self.write("(");
35812 self.generate_expression(&e.this)?;
35813 if let Some(start) = &e.start {
35814 self.write(", ");
35815 self.generate_expression(start)?;
35816 }
35817 if let Some(length) = e.length {
35818 self.write(", ");
35819 self.write(&length.to_string());
35820 }
35821 self.write(", ");
35822 self.generate_expression(&e.expression)?;
35823 self.write(")");
35824 Ok(())
35825 }
35826
35827 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
35828 self.write_keyword("SUBSTRING_INDEX");
35830 self.write("(");
35831 self.generate_expression(&e.this)?;
35832 if let Some(delimiter) = &e.delimiter {
35833 self.write(", ");
35834 self.generate_expression(delimiter)?;
35835 }
35836 if let Some(count) = &e.count {
35837 self.write(", ");
35838 self.generate_expression(count)?;
35839 }
35840 self.write(")");
35841 Ok(())
35842 }
35843
35844 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
35845 self.write_keyword("SUMMARIZE");
35847 if e.table.is_some() {
35848 self.write_space();
35849 self.write_keyword("TABLE");
35850 }
35851 self.write_space();
35852 self.generate_expression(&e.this)?;
35853 Ok(())
35854 }
35855
35856 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
35857 self.write_keyword("SYSTIMESTAMP");
35859 Ok(())
35860 }
35861
35862 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
35863 if let Some(this) = &e.this {
35865 self.generate_expression(this)?;
35866 }
35867 if !e.columns.is_empty() {
35868 self.write("(");
35869 for (i, col) in e.columns.iter().enumerate() {
35870 if i > 0 {
35871 self.write(", ");
35872 }
35873 self.generate_expression(col)?;
35874 }
35875 self.write(")");
35876 }
35877 Ok(())
35878 }
35879
35880 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
35881 self.write_keyword("TABLE");
35883 self.write("(");
35884 self.generate_expression(&e.this)?;
35885 self.write(")");
35886 if let Some(alias) = &e.alias {
35887 self.write_space();
35888 self.write_keyword("AS");
35889 self.write_space();
35890 self.write(alias);
35891 }
35892 Ok(())
35893 }
35894
35895 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
35896 self.write_keyword("ROWS FROM");
35898 self.write(" (");
35899 for (i, expr) in e.expressions.iter().enumerate() {
35900 if i > 0 {
35901 self.write(", ");
35902 }
35903 match expr {
35907 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
35908 self.generate_expression(&tuple.expressions[0])?;
35910 self.write_space();
35911 self.write_keyword("AS");
35912 self.write_space();
35913 self.generate_expression(&tuple.expressions[1])?;
35914 }
35915 _ => {
35916 self.generate_expression(expr)?;
35917 }
35918 }
35919 }
35920 self.write(")");
35921 if e.ordinality {
35922 self.write_space();
35923 self.write_keyword("WITH ORDINALITY");
35924 }
35925 if let Some(alias) = &e.alias {
35926 self.write_space();
35927 self.write_keyword("AS");
35928 self.write_space();
35929 self.generate_expression(alias)?;
35930 }
35931 Ok(())
35932 }
35933
35934 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
35935 use crate::dialects::DialectType;
35936
35937 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
35939 if self.config.alias_post_tablesample {
35941 if let Expression::Subquery(ref s) = **this {
35943 if let Some(ref alias) = s.alias {
35944 let mut subquery_no_alias = (**s).clone();
35946 subquery_no_alias.alias = None;
35947 subquery_no_alias.column_aliases = Vec::new();
35948 self.generate_expression(&Expression::Subquery(Box::new(
35949 subquery_no_alias,
35950 )))?;
35951 self.write_space();
35952 self.write_keyword(self.config.tablesample_keywords);
35953 self.generate_sample_body(sample)?;
35954 if let Some(ref seed) = sample.seed {
35955 self.write_space();
35956 let use_seed = sample.use_seed_keyword
35957 && !matches!(
35958 self.config.dialect,
35959 Some(crate::dialects::DialectType::Databricks)
35960 | Some(crate::dialects::DialectType::Spark)
35961 );
35962 if use_seed {
35963 self.write_keyword("SEED");
35964 } else {
35965 self.write_keyword("REPEATABLE");
35966 }
35967 self.write(" (");
35968 self.generate_expression(seed)?;
35969 self.write(")");
35970 }
35971 self.write_space();
35972 self.write_keyword("AS");
35973 self.write_space();
35974 self.generate_identifier(alias)?;
35975 return Ok(());
35976 }
35977 } else if let Expression::Alias(ref a) = **this {
35978 self.generate_expression(&a.this)?;
35980 self.write_space();
35981 self.write_keyword(self.config.tablesample_keywords);
35982 self.generate_sample_body(sample)?;
35983 if let Some(ref seed) = sample.seed {
35984 self.write_space();
35985 let use_seed = sample.use_seed_keyword
35986 && !matches!(
35987 self.config.dialect,
35988 Some(crate::dialects::DialectType::Databricks)
35989 | Some(crate::dialects::DialectType::Spark)
35990 );
35991 if use_seed {
35992 self.write_keyword("SEED");
35993 } else {
35994 self.write_keyword("REPEATABLE");
35995 }
35996 self.write(" (");
35997 self.generate_expression(seed)?;
35998 self.write(")");
35999 }
36000 self.write_space();
36002 self.write_keyword("AS");
36003 self.write_space();
36004 self.generate_identifier(&a.alias)?;
36005 return Ok(());
36006 }
36007 }
36008 self.generate_expression(this)?;
36010 self.write_space();
36011 self.write_keyword(self.config.tablesample_keywords);
36012 self.generate_sample_body(sample)?;
36013 if let Some(ref seed) = sample.seed {
36015 self.write_space();
36016 let use_seed = sample.use_seed_keyword
36018 && !matches!(
36019 self.config.dialect,
36020 Some(crate::dialects::DialectType::Databricks)
36021 | Some(crate::dialects::DialectType::Spark)
36022 );
36023 if use_seed {
36024 self.write_keyword("SEED");
36025 } else {
36026 self.write_keyword("REPEATABLE");
36027 }
36028 self.write(" (");
36029 self.generate_expression(seed)?;
36030 self.write(")");
36031 }
36032 return Ok(());
36033 }
36034
36035 self.write_keyword(self.config.tablesample_keywords);
36037 if let Some(method) = &e.method {
36038 self.write_space();
36039 self.write_keyword(method);
36040 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
36041 self.write_space();
36043 self.write_keyword("BERNOULLI");
36044 }
36045 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
36046 self.write_space();
36047 self.write_keyword("BUCKET");
36048 self.write_space();
36049 self.generate_expression(numerator)?;
36050 self.write_space();
36051 self.write_keyword("OUT OF");
36052 self.write_space();
36053 self.generate_expression(denominator)?;
36054 if let Some(field) = &e.bucket_field {
36055 self.write_space();
36056 self.write_keyword("ON");
36057 self.write_space();
36058 self.generate_expression(field)?;
36059 }
36060 } else if !e.expressions.is_empty() {
36061 self.write(" (");
36062 for (i, expr) in e.expressions.iter().enumerate() {
36063 if i > 0 {
36064 self.write(", ");
36065 }
36066 self.generate_expression(expr)?;
36067 }
36068 self.write(")");
36069 } else if let Some(percent) = &e.percent {
36070 self.write(" (");
36071 self.generate_expression(percent)?;
36072 self.write_space();
36073 self.write_keyword("PERCENT");
36074 self.write(")");
36075 }
36076 Ok(())
36077 }
36078
36079 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
36080 if let Some(prefix) = &e.prefix {
36082 self.generate_expression(prefix)?;
36083 }
36084 if let Some(this) = &e.this {
36085 self.generate_expression(this)?;
36086 }
36087 if let Some(postfix) = &e.postfix {
36088 self.generate_expression(postfix)?;
36089 }
36090 Ok(())
36091 }
36092
36093 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
36094 self.write_keyword("TAG");
36096 self.write(" (");
36097 for (i, expr) in e.expressions.iter().enumerate() {
36098 if i > 0 {
36099 self.write(", ");
36100 }
36101 self.generate_expression(expr)?;
36102 }
36103 self.write(")");
36104 Ok(())
36105 }
36106
36107 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
36108 if let Some(this) = &e.this {
36110 self.generate_expression(this)?;
36111 self.write_space();
36112 }
36113 self.write_keyword("TEMPORARY");
36114 Ok(())
36115 }
36116
36117 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
36120 self.write_keyword("TIME");
36122 self.write("(");
36123 self.generate_expression(&e.this)?;
36124 self.write(")");
36125 Ok(())
36126 }
36127
36128 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
36129 self.write_keyword("TIME_ADD");
36131 self.write("(");
36132 self.generate_expression(&e.this)?;
36133 self.write(", ");
36134 self.generate_expression(&e.expression)?;
36135 if let Some(unit) = &e.unit {
36136 self.write(", ");
36137 self.write_keyword(unit);
36138 }
36139 self.write(")");
36140 Ok(())
36141 }
36142
36143 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
36144 self.write_keyword("TIME_DIFF");
36146 self.write("(");
36147 self.generate_expression(&e.this)?;
36148 self.write(", ");
36149 self.generate_expression(&e.expression)?;
36150 if let Some(unit) = &e.unit {
36151 self.write(", ");
36152 self.write_keyword(unit);
36153 }
36154 self.write(")");
36155 Ok(())
36156 }
36157
36158 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
36159 self.write_keyword("TIME_FROM_PARTS");
36161 self.write("(");
36162 let mut first = true;
36163 if let Some(hour) = &e.hour {
36164 self.generate_expression(hour)?;
36165 first = false;
36166 }
36167 if let Some(minute) = &e.min {
36168 if !first {
36169 self.write(", ");
36170 }
36171 self.generate_expression(minute)?;
36172 first = false;
36173 }
36174 if let Some(second) = &e.sec {
36175 if !first {
36176 self.write(", ");
36177 }
36178 self.generate_expression(second)?;
36179 first = false;
36180 }
36181 if let Some(ns) = &e.nano {
36182 if !first {
36183 self.write(", ");
36184 }
36185 self.generate_expression(ns)?;
36186 }
36187 self.write(")");
36188 Ok(())
36189 }
36190
36191 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
36192 self.write_keyword("TIME_SLICE");
36194 self.write("(");
36195 self.generate_expression(&e.this)?;
36196 self.write(", ");
36197 self.generate_expression(&e.expression)?;
36198 self.write(", ");
36199 self.write_keyword(&e.unit);
36200 self.write(")");
36201 Ok(())
36202 }
36203
36204 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
36205 self.write_keyword("TIME_STR_TO_TIME");
36207 self.write("(");
36208 self.generate_expression(&e.this)?;
36209 self.write(")");
36210 Ok(())
36211 }
36212
36213 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
36214 self.write_keyword("TIME_SUB");
36216 self.write("(");
36217 self.generate_expression(&e.this)?;
36218 self.write(", ");
36219 self.generate_expression(&e.expression)?;
36220 if let Some(unit) = &e.unit {
36221 self.write(", ");
36222 self.write_keyword(unit);
36223 }
36224 self.write(")");
36225 Ok(())
36226 }
36227
36228 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
36229 match self.config.dialect {
36230 Some(DialectType::Exasol) => {
36231 self.write_keyword("TO_CHAR");
36233 self.write("(");
36234 self.generate_expression(&e.this)?;
36235 self.write(", '");
36236 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
36237 self.write("'");
36238 self.write(")");
36239 }
36240 Some(DialectType::PostgreSQL)
36241 | Some(DialectType::Redshift)
36242 | Some(DialectType::Materialize) => {
36243 self.write_keyword("TO_CHAR");
36245 self.write("(");
36246 self.generate_expression(&e.this)?;
36247 self.write(", '");
36248 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36249 self.write("'");
36250 self.write(")");
36251 }
36252 Some(DialectType::Oracle) => {
36253 self.write_keyword("TO_CHAR");
36255 self.write("(");
36256 self.generate_expression(&e.this)?;
36257 self.write(", '");
36258 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
36259 self.write("'");
36260 self.write(")");
36261 }
36262 Some(DialectType::Drill) => {
36263 self.write_keyword("TO_CHAR");
36265 self.write("(");
36266 self.generate_expression(&e.this)?;
36267 self.write(", '");
36268 self.write(&Self::strftime_to_java_format(&e.format));
36269 self.write("'");
36270 self.write(")");
36271 }
36272 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
36273 self.write_keyword("FORMAT");
36275 self.write("(");
36276 self.generate_expression(&e.this)?;
36277 self.write(", '");
36278 self.write(&Self::strftime_to_tsql_format(&e.format));
36279 self.write("'");
36280 self.write(")");
36281 }
36282 Some(DialectType::DuckDB) => {
36283 self.write_keyword("STRFTIME");
36285 self.write("(");
36286 self.generate_expression(&e.this)?;
36287 self.write(", '");
36288 self.write(&e.format);
36289 self.write("'");
36290 self.write(")");
36291 }
36292 Some(DialectType::BigQuery) => {
36293 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
36296 self.write_keyword("FORMAT_DATE");
36297 self.write("('");
36298 self.write(&fmt);
36299 self.write("', ");
36300 self.generate_expression(&e.this)?;
36301 self.write(")");
36302 }
36303 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36304 self.write_keyword("DATE_FORMAT");
36306 self.write("(");
36307 self.generate_expression(&e.this)?;
36308 self.write(", '");
36309 self.write(&Self::strftime_to_java_format(&e.format));
36310 self.write("'");
36311 self.write(")");
36312 }
36313 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
36314 self.write_keyword("DATE_FORMAT");
36316 self.write("(");
36317 self.generate_expression(&e.this)?;
36318 self.write(", '");
36319 self.write(&e.format);
36320 self.write("'");
36321 self.write(")");
36322 }
36323 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36324 self.write_keyword("DATE_FORMAT");
36326 self.write("(");
36327 self.generate_expression(&e.this)?;
36328 self.write(", '");
36329 self.write(&e.format);
36330 self.write("'");
36331 self.write(")");
36332 }
36333 _ => {
36334 self.write_keyword("TIME_TO_STR");
36336 self.write("(");
36337 self.generate_expression(&e.this)?;
36338 self.write(", '");
36339 self.write(&e.format);
36340 self.write("'");
36341 self.write(")");
36342 }
36343 }
36344 Ok(())
36345 }
36346
36347 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36348 match self.config.dialect {
36349 Some(DialectType::DuckDB) => {
36350 self.write_keyword("EPOCH");
36352 self.write("(");
36353 self.generate_expression(&e.this)?;
36354 self.write(")");
36355 }
36356 Some(DialectType::Hive)
36357 | Some(DialectType::Spark)
36358 | Some(DialectType::Databricks)
36359 | Some(DialectType::Doris)
36360 | Some(DialectType::StarRocks)
36361 | Some(DialectType::Drill) => {
36362 self.write_keyword("UNIX_TIMESTAMP");
36364 self.write("(");
36365 self.generate_expression(&e.this)?;
36366 self.write(")");
36367 }
36368 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36369 self.write_keyword("TO_UNIXTIME");
36371 self.write("(");
36372 self.generate_expression(&e.this)?;
36373 self.write(")");
36374 }
36375 _ => {
36376 self.write_keyword("TIME_TO_UNIX");
36378 self.write("(");
36379 self.generate_expression(&e.this)?;
36380 self.write(")");
36381 }
36382 }
36383 Ok(())
36384 }
36385
36386 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
36387 match self.config.dialect {
36388 Some(DialectType::Hive) => {
36389 self.write_keyword("TO_DATE");
36391 self.write("(");
36392 self.generate_expression(&e.this)?;
36393 self.write(")");
36394 }
36395 _ => {
36396 self.write_keyword("TIME_STR_TO_DATE");
36398 self.write("(");
36399 self.generate_expression(&e.this)?;
36400 self.write(")");
36401 }
36402 }
36403 Ok(())
36404 }
36405
36406 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
36407 self.write_keyword("TIME_TRUNC");
36409 self.write("(");
36410 self.generate_expression(&e.this)?;
36411 self.write(", ");
36412 self.write_keyword(&e.unit);
36413 self.write(")");
36414 Ok(())
36415 }
36416
36417 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
36418 if let Some(unit) = &e.unit {
36420 self.write_keyword(unit);
36421 }
36422 Ok(())
36423 }
36424
36425 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
36429 use crate::dialects::DialectType;
36430 use crate::expressions::Literal;
36431
36432 match self.config.dialect {
36433 Some(DialectType::Exasol) => {
36435 self.write_keyword("TO_TIMESTAMP");
36436 self.write("(");
36437 if let Some(this) = &e.this {
36439 match this.as_ref() {
36440 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36441 let Literal::String(s) = lit.as_ref() else {
36442 unreachable!()
36443 };
36444 self.write("'");
36445 self.write(s);
36446 self.write("'");
36447 }
36448 _ => {
36449 self.generate_expression(this)?;
36450 }
36451 }
36452 }
36453 self.write(")");
36454 }
36455 _ => {
36457 self.write_keyword("TIMESTAMP");
36458 self.write("(");
36459 if let Some(this) = &e.this {
36460 self.generate_expression(this)?;
36461 }
36462 if let Some(zone) = &e.zone {
36463 self.write(", ");
36464 self.generate_expression(zone)?;
36465 }
36466 self.write(")");
36467 }
36468 }
36469 Ok(())
36470 }
36471
36472 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
36473 self.write_keyword("TIMESTAMP_ADD");
36475 self.write("(");
36476 self.generate_expression(&e.this)?;
36477 self.write(", ");
36478 self.generate_expression(&e.expression)?;
36479 if let Some(unit) = &e.unit {
36480 self.write(", ");
36481 self.write_keyword(unit);
36482 }
36483 self.write(")");
36484 Ok(())
36485 }
36486
36487 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
36488 self.write_keyword("TIMESTAMP_DIFF");
36490 self.write("(");
36491 self.generate_expression(&e.this)?;
36492 self.write(", ");
36493 self.generate_expression(&e.expression)?;
36494 if let Some(unit) = &e.unit {
36495 self.write(", ");
36496 self.write_keyword(unit);
36497 }
36498 self.write(")");
36499 Ok(())
36500 }
36501
36502 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
36503 self.write_keyword("TIMESTAMP_FROM_PARTS");
36505 self.write("(");
36506 if let Some(this) = &e.this {
36507 self.generate_expression(this)?;
36508 }
36509 if let Some(expression) = &e.expression {
36510 self.write(", ");
36511 self.generate_expression(expression)?;
36512 }
36513 if let Some(zone) = &e.zone {
36514 self.write(", ");
36515 self.generate_expression(zone)?;
36516 }
36517 if let Some(milli) = &e.milli {
36518 self.write(", ");
36519 self.generate_expression(milli)?;
36520 }
36521 self.write(")");
36522 Ok(())
36523 }
36524
36525 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
36526 self.write_keyword("TIMESTAMP_SUB");
36528 self.write("(");
36529 self.generate_expression(&e.this)?;
36530 self.write(", ");
36531 self.write_keyword("INTERVAL");
36532 self.write_space();
36533 self.generate_expression(&e.expression)?;
36534 if let Some(unit) = &e.unit {
36535 self.write_space();
36536 self.write_keyword(unit);
36537 }
36538 self.write(")");
36539 Ok(())
36540 }
36541
36542 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
36543 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
36545 self.write("(");
36546 if let Some(zone) = &e.zone {
36547 self.generate_expression(zone)?;
36548 }
36549 self.write(")");
36550 Ok(())
36551 }
36552
36553 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
36554 self.write_keyword("TO_BINARY");
36556 self.write("(");
36557 self.generate_expression(&e.this)?;
36558 if let Some(format) = &e.format {
36559 self.write(", '");
36560 self.write(format);
36561 self.write("'");
36562 }
36563 self.write(")");
36564 Ok(())
36565 }
36566
36567 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
36568 self.write_keyword("TO_BOOLEAN");
36570 self.write("(");
36571 self.generate_expression(&e.this)?;
36572 self.write(")");
36573 Ok(())
36574 }
36575
36576 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
36577 self.write_keyword("TO_CHAR");
36579 self.write("(");
36580 self.generate_expression(&e.this)?;
36581 if let Some(format) = &e.format {
36582 self.write(", '");
36583 self.write(format);
36584 self.write("'");
36585 }
36586 if let Some(nlsparam) = &e.nlsparam {
36587 self.write(", ");
36588 self.generate_expression(nlsparam)?;
36589 }
36590 self.write(")");
36591 Ok(())
36592 }
36593
36594 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
36595 self.write_keyword("TO_DECFLOAT");
36597 self.write("(");
36598 self.generate_expression(&e.this)?;
36599 if let Some(format) = &e.format {
36600 self.write(", '");
36601 self.write(format);
36602 self.write("'");
36603 }
36604 self.write(")");
36605 Ok(())
36606 }
36607
36608 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
36609 self.write_keyword("TO_DOUBLE");
36611 self.write("(");
36612 self.generate_expression(&e.this)?;
36613 if let Some(format) = &e.format {
36614 self.write(", '");
36615 self.write(format);
36616 self.write("'");
36617 }
36618 self.write(")");
36619 Ok(())
36620 }
36621
36622 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
36623 self.write_keyword("TO_FILE");
36625 self.write("(");
36626 self.generate_expression(&e.this)?;
36627 if let Some(path) = &e.path {
36628 self.write(", ");
36629 self.generate_expression(path)?;
36630 }
36631 self.write(")");
36632 Ok(())
36633 }
36634
36635 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
36636 let is_safe = e.safe.is_some();
36639 if is_safe {
36640 self.write_keyword("TRY_TO_NUMBER");
36641 } else {
36642 self.write_keyword("TO_NUMBER");
36643 }
36644 self.write("(");
36645 self.generate_expression(&e.this)?;
36646 let precision_is_snowflake_default = e.precision.is_none()
36647 || matches!(
36648 e.precision.as_deref(),
36649 Some(Expression::Literal(lit))
36650 if matches!(lit.as_ref(), Literal::Number(n) if n == "0")
36651 );
36652 let is_snowflake_default_precision =
36653 matches!(self.config.dialect, Some(DialectType::Snowflake))
36654 && e.nlsparam.is_none()
36655 && e.scale.is_none()
36656 && matches!(
36657 e.format.as_deref(),
36658 Some(Expression::Literal(lit))
36659 if matches!(lit.as_ref(), Literal::Number(n) if n == "38")
36660 )
36661 && precision_is_snowflake_default;
36662
36663 if !is_snowflake_default_precision {
36664 if let Some(format) = &e.format {
36665 self.write(", ");
36666 self.generate_expression(format)?;
36667 }
36668 if let Some(nlsparam) = &e.nlsparam {
36669 self.write(", ");
36670 self.generate_expression(nlsparam)?;
36671 }
36672 if let Some(precision) = &e.precision {
36673 self.write(", ");
36674 self.generate_expression(precision)?;
36675 }
36676 if let Some(scale) = &e.scale {
36677 self.write(", ");
36678 self.generate_expression(scale)?;
36679 }
36680 }
36681 self.write(")");
36682 Ok(())
36683 }
36684
36685 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
36686 self.write_keyword("TO_TABLE");
36688 self.write_space();
36689 self.generate_expression(&e.this)?;
36690 Ok(())
36691 }
36692
36693 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
36694 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
36696 Expression::Identifier(id) => id.name.clone(),
36697 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
36698 let Literal::String(s) = lit.as_ref() else {
36699 unreachable!()
36700 };
36701 s.clone()
36702 }
36703 _ => String::new(),
36704 });
36705
36706 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
36707 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
36708 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
36709 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
36710 });
36711
36712 let use_start_transaction = matches!(
36714 self.config.dialect,
36715 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
36716 );
36717 let strip_transaction = matches!(
36719 self.config.dialect,
36720 Some(DialectType::Snowflake)
36721 | Some(DialectType::PostgreSQL)
36722 | Some(DialectType::Redshift)
36723 | Some(DialectType::MySQL)
36724 | Some(DialectType::Hive)
36725 | Some(DialectType::Spark)
36726 | Some(DialectType::Databricks)
36727 | Some(DialectType::DuckDB)
36728 | Some(DialectType::Oracle)
36729 | Some(DialectType::Doris)
36730 | Some(DialectType::StarRocks)
36731 | Some(DialectType::Materialize)
36732 | Some(DialectType::ClickHouse)
36733 );
36734
36735 if is_start || use_start_transaction {
36736 self.write_keyword("START TRANSACTION");
36738 if let Some(modes) = &e.modes {
36739 self.write_space();
36740 self.generate_expression(modes)?;
36741 }
36742 } else {
36743 self.write_keyword("BEGIN");
36745
36746 let is_kind = e.this.as_ref().map_or(false, |t| {
36748 if let Expression::Identifier(id) = t.as_ref() {
36749 id.name.eq_ignore_ascii_case("DEFERRED")
36750 || id.name.eq_ignore_ascii_case("IMMEDIATE")
36751 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
36752 } else {
36753 false
36754 }
36755 });
36756
36757 if is_kind {
36759 if let Some(this) = &e.this {
36760 self.write_space();
36761 if let Expression::Identifier(id) = this.as_ref() {
36762 self.write_keyword(&id.name);
36763 }
36764 }
36765 }
36766
36767 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
36769 self.write_space();
36770 self.write_keyword("TRANSACTION");
36771 }
36772
36773 if !is_kind {
36775 if let Some(this) = &e.this {
36776 self.write_space();
36777 self.generate_expression(this)?;
36778 }
36779 }
36780
36781 if has_with_mark {
36783 self.write_space();
36784 self.write_keyword("WITH MARK");
36785 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
36786 if let Literal::String(desc) = lit.as_ref() {
36787 if !desc.is_empty() {
36788 self.write_space();
36789 self.write(&format!("'{}'", desc));
36790 }
36791 }
36792 }
36793 }
36794
36795 if let Some(modes) = &e.modes {
36797 self.write_space();
36798 self.generate_expression(modes)?;
36799 }
36800 }
36801 Ok(())
36802 }
36803
36804 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
36805 self.write_keyword("TRANSFORM");
36807 self.write("(");
36808 self.generate_expression(&e.this)?;
36809 self.write(", ");
36810 self.generate_expression(&e.expression)?;
36811 self.write(")");
36812 Ok(())
36813 }
36814
36815 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
36816 self.write_keyword("TRANSFORM");
36818 self.write("(");
36819 if self.config.pretty && !e.expressions.is_empty() {
36820 self.indent_level += 1;
36821 for (i, expr) in e.expressions.iter().enumerate() {
36822 if i > 0 {
36823 self.write(",");
36824 }
36825 self.write_newline();
36826 self.write_indent();
36827 self.generate_expression(expr)?;
36828 }
36829 self.indent_level -= 1;
36830 self.write_newline();
36831 self.write(")");
36832 } else {
36833 for (i, expr) in e.expressions.iter().enumerate() {
36834 if i > 0 {
36835 self.write(", ");
36836 }
36837 self.generate_expression(expr)?;
36838 }
36839 self.write(")");
36840 }
36841 Ok(())
36842 }
36843
36844 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
36845 use crate::dialects::DialectType;
36846 if let Some(this) = &e.this {
36848 self.generate_expression(this)?;
36849 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36850 self.write_space();
36851 }
36852 }
36853 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36854 self.write_keyword("TRANSIENT");
36855 }
36856 Ok(())
36857 }
36858
36859 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
36860 self.write_keyword("TRANSLATE");
36862 self.write("(");
36863 self.generate_expression(&e.this)?;
36864 if let Some(from) = &e.from_ {
36865 self.write(", ");
36866 self.generate_expression(from)?;
36867 }
36868 if let Some(to) = &e.to {
36869 self.write(", ");
36870 self.generate_expression(to)?;
36871 }
36872 self.write(")");
36873 Ok(())
36874 }
36875
36876 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
36877 self.write_keyword("TRANSLATE");
36879 self.write("(");
36880 self.generate_expression(&e.this)?;
36881 self.write_space();
36882 self.write_keyword("USING");
36883 self.write_space();
36884 self.generate_expression(&e.expression)?;
36885 if e.with_error.is_some() {
36886 self.write_space();
36887 self.write_keyword("WITH ERROR");
36888 }
36889 self.write(")");
36890 Ok(())
36891 }
36892
36893 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
36894 self.write_keyword("TRUNCATE TABLE");
36896 self.write_space();
36897 for (i, expr) in e.expressions.iter().enumerate() {
36898 if i > 0 {
36899 self.write(", ");
36900 }
36901 self.generate_expression(expr)?;
36902 }
36903 Ok(())
36904 }
36905
36906 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
36907 self.write_keyword("TRY_BASE64_DECODE_BINARY");
36909 self.write("(");
36910 self.generate_expression(&e.this)?;
36911 if let Some(alphabet) = &e.alphabet {
36912 self.write(", ");
36913 self.generate_expression(alphabet)?;
36914 }
36915 self.write(")");
36916 Ok(())
36917 }
36918
36919 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
36920 self.write_keyword("TRY_BASE64_DECODE_STRING");
36922 self.write("(");
36923 self.generate_expression(&e.this)?;
36924 if let Some(alphabet) = &e.alphabet {
36925 self.write(", ");
36926 self.generate_expression(alphabet)?;
36927 }
36928 self.write(")");
36929 Ok(())
36930 }
36931
36932 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
36933 self.write_keyword("TRY_TO_DECFLOAT");
36935 self.write("(");
36936 self.generate_expression(&e.this)?;
36937 if let Some(format) = &e.format {
36938 self.write(", '");
36939 self.write(format);
36940 self.write("'");
36941 }
36942 self.write(")");
36943 Ok(())
36944 }
36945
36946 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
36947 self.write_keyword("TS_OR_DS_ADD");
36949 self.write("(");
36950 self.generate_expression(&e.this)?;
36951 self.write(", ");
36952 self.generate_expression(&e.expression)?;
36953 if let Some(unit) = &e.unit {
36954 self.write(", ");
36955 self.write_keyword(unit);
36956 }
36957 if let Some(return_type) = &e.return_type {
36958 self.write(", ");
36959 self.generate_expression(return_type)?;
36960 }
36961 self.write(")");
36962 Ok(())
36963 }
36964
36965 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
36966 self.write_keyword("TS_OR_DS_DIFF");
36968 self.write("(");
36969 self.generate_expression(&e.this)?;
36970 self.write(", ");
36971 self.generate_expression(&e.expression)?;
36972 if let Some(unit) = &e.unit {
36973 self.write(", ");
36974 self.write_keyword(unit);
36975 }
36976 self.write(")");
36977 Ok(())
36978 }
36979
36980 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
36981 let default_time_format = "%Y-%m-%d %H:%M:%S";
36982 let default_date_format = "%Y-%m-%d";
36983 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
36984 f != default_time_format && f != default_date_format
36985 });
36986
36987 if has_non_default_format {
36988 let fmt = e.format.as_ref().unwrap();
36990 match self.config.dialect {
36991 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
36992 let str_to_time = crate::expressions::StrToTime {
36995 this: Box::new((*e.this).clone()),
36996 format: fmt.clone(),
36997 zone: None,
36998 safe: None,
36999 target_type: None,
37000 };
37001 self.generate_str_to_time(&str_to_time)?;
37002 }
37003 Some(DialectType::Hive)
37004 | Some(DialectType::Spark)
37005 | Some(DialectType::Databricks) => {
37006 self.write_keyword("TO_DATE");
37008 self.write("(");
37009 self.generate_expression(&e.this)?;
37010 self.write(", '");
37011 self.write(&Self::strftime_to_java_format(fmt));
37012 self.write("')");
37013 }
37014 Some(DialectType::Snowflake) => {
37015 self.write_keyword("TO_DATE");
37017 self.write("(");
37018 self.generate_expression(&e.this)?;
37019 self.write(", '");
37020 self.write(&Self::strftime_to_snowflake_format(fmt));
37021 self.write("')");
37022 }
37023 Some(DialectType::Doris) => {
37024 self.write_keyword("TO_DATE");
37026 self.write("(");
37027 self.generate_expression(&e.this)?;
37028 self.write(")");
37029 }
37030 _ => {
37031 self.write_keyword("CAST");
37033 self.write("(");
37034 let str_to_time = crate::expressions::StrToTime {
37035 this: Box::new((*e.this).clone()),
37036 format: fmt.clone(),
37037 zone: None,
37038 safe: None,
37039 target_type: None,
37040 };
37041 self.generate_str_to_time(&str_to_time)?;
37042 self.write_keyword(" AS ");
37043 self.write_keyword("DATE");
37044 self.write(")");
37045 }
37046 }
37047 } else {
37048 match self.config.dialect {
37050 Some(DialectType::MySQL)
37051 | Some(DialectType::SQLite)
37052 | Some(DialectType::StarRocks) => {
37053 self.write_keyword("DATE");
37055 self.write("(");
37056 self.generate_expression(&e.this)?;
37057 self.write(")");
37058 }
37059 Some(DialectType::Hive)
37060 | Some(DialectType::Spark)
37061 | Some(DialectType::Databricks)
37062 | Some(DialectType::Snowflake)
37063 | Some(DialectType::Doris) => {
37064 self.write_keyword("TO_DATE");
37066 self.write("(");
37067 self.generate_expression(&e.this)?;
37068 self.write(")");
37069 }
37070 Some(DialectType::Presto)
37071 | Some(DialectType::Trino)
37072 | Some(DialectType::Athena) => {
37073 self.write_keyword("CAST");
37075 self.write("(");
37076 self.write_keyword("CAST");
37077 self.write("(");
37078 self.generate_expression(&e.this)?;
37079 self.write_keyword(" AS ");
37080 self.write_keyword("TIMESTAMP");
37081 self.write(")");
37082 self.write_keyword(" AS ");
37083 self.write_keyword("DATE");
37084 self.write(")");
37085 }
37086 Some(DialectType::ClickHouse) => {
37087 self.write_keyword("CAST");
37089 self.write("(");
37090 self.generate_expression(&e.this)?;
37091 self.write_keyword(" AS ");
37092 self.write("Nullable(DATE)");
37093 self.write(")");
37094 }
37095 _ => {
37096 self.write_keyword("CAST");
37098 self.write("(");
37099 self.generate_expression(&e.this)?;
37100 self.write_keyword(" AS ");
37101 self.write_keyword("DATE");
37102 self.write(")");
37103 }
37104 }
37105 }
37106 Ok(())
37107 }
37108
37109 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
37110 self.write_keyword("TS_OR_DS_TO_TIME");
37112 self.write("(");
37113 self.generate_expression(&e.this)?;
37114 if let Some(format) = &e.format {
37115 self.write(", '");
37116 self.write(format);
37117 self.write("'");
37118 }
37119 self.write(")");
37120 Ok(())
37121 }
37122
37123 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
37124 self.write_keyword("UNHEX");
37126 self.write("(");
37127 self.generate_expression(&e.this)?;
37128 if let Some(expression) = &e.expression {
37129 self.write(", ");
37130 self.generate_expression(expression)?;
37131 }
37132 self.write(")");
37133 Ok(())
37134 }
37135
37136 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
37137 self.write("U&");
37139 self.generate_expression(&e.this)?;
37140 if let Some(escape) = &e.escape {
37141 self.write_space();
37142 self.write_keyword("UESCAPE");
37143 self.write_space();
37144 self.generate_expression(escape)?;
37145 }
37146 Ok(())
37147 }
37148
37149 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
37150 self.write_keyword("UNIFORM");
37152 self.write("(");
37153 self.generate_expression(&e.this)?;
37154 self.write(", ");
37155 self.generate_expression(&e.expression)?;
37156 if let Some(gen) = &e.gen {
37157 self.write(", ");
37158 self.generate_expression(gen)?;
37159 }
37160 if let Some(seed) = &e.seed {
37161 self.write(", ");
37162 self.generate_expression(seed)?;
37163 }
37164 self.write(")");
37165 Ok(())
37166 }
37167
37168 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
37169 self.write_keyword("UNIQUE");
37171 if e.nulls.is_some() {
37173 self.write(" NULLS NOT DISTINCT");
37174 }
37175 if let Some(this) = &e.this {
37176 self.write_space();
37177 self.generate_expression(this)?;
37178 }
37179 if let Some(index_type) = &e.index_type {
37180 self.write(" USING ");
37181 self.generate_expression(index_type)?;
37182 }
37183 if let Some(on_conflict) = &e.on_conflict {
37184 self.write_space();
37185 self.generate_expression(on_conflict)?;
37186 }
37187 for opt in &e.options {
37188 self.write_space();
37189 self.generate_expression(opt)?;
37190 }
37191 Ok(())
37192 }
37193
37194 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
37195 self.write_keyword("UNIQUE KEY");
37197 self.write(" (");
37198 for (i, expr) in e.expressions.iter().enumerate() {
37199 if i > 0 {
37200 self.write(", ");
37201 }
37202 self.generate_expression(expr)?;
37203 }
37204 self.write(")");
37205 Ok(())
37206 }
37207
37208 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
37209 self.write_keyword("ROLLUP");
37211 self.write(" (");
37212 for (i, index) in e.expressions.iter().enumerate() {
37213 if i > 0 {
37214 self.write(", ");
37215 }
37216 self.generate_identifier(&index.name)?;
37217 self.write("(");
37218 for (j, col) in index.expressions.iter().enumerate() {
37219 if j > 0 {
37220 self.write(", ");
37221 }
37222 self.generate_identifier(col)?;
37223 }
37224 self.write(")");
37225 }
37226 self.write(")");
37227 Ok(())
37228 }
37229
37230 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
37231 match self.config.dialect {
37232 Some(DialectType::DuckDB) => {
37233 self.write_keyword("STRFTIME");
37235 self.write("(");
37236 self.write_keyword("TO_TIMESTAMP");
37237 self.write("(");
37238 self.generate_expression(&e.this)?;
37239 self.write("), '");
37240 if let Some(format) = &e.format {
37241 self.write(format);
37242 }
37243 self.write("')");
37244 }
37245 Some(DialectType::Hive) => {
37246 self.write_keyword("FROM_UNIXTIME");
37248 self.write("(");
37249 self.generate_expression(&e.this)?;
37250 if let Some(format) = &e.format {
37251 if format != "yyyy-MM-dd HH:mm:ss" {
37252 self.write(", '");
37253 self.write(format);
37254 self.write("'");
37255 }
37256 }
37257 self.write(")");
37258 }
37259 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37260 self.write_keyword("DATE_FORMAT");
37262 self.write("(");
37263 self.write_keyword("FROM_UNIXTIME");
37264 self.write("(");
37265 self.generate_expression(&e.this)?;
37266 self.write("), '");
37267 if let Some(format) = &e.format {
37268 self.write(format);
37269 }
37270 self.write("')");
37271 }
37272 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
37273 self.write_keyword("FROM_UNIXTIME");
37275 self.write("(");
37276 self.generate_expression(&e.this)?;
37277 if let Some(format) = &e.format {
37278 self.write(", '");
37279 self.write(format);
37280 self.write("'");
37281 }
37282 self.write(")");
37283 }
37284 _ => {
37285 self.write_keyword("UNIX_TO_STR");
37287 self.write("(");
37288 self.generate_expression(&e.this)?;
37289 if let Some(format) = &e.format {
37290 self.write(", '");
37291 self.write(format);
37292 self.write("'");
37293 }
37294 self.write(")");
37295 }
37296 }
37297 Ok(())
37298 }
37299
37300 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
37301 use crate::dialects::DialectType;
37302 let scale = e.scale.unwrap_or(0); match self.config.dialect {
37305 Some(DialectType::Snowflake) => {
37306 self.write_keyword("TO_TIMESTAMP");
37308 self.write("(");
37309 self.generate_expression(&e.this)?;
37310 if let Some(s) = e.scale {
37311 if s > 0 {
37312 self.write(", ");
37313 self.write(&s.to_string());
37314 }
37315 }
37316 self.write(")");
37317 }
37318 Some(DialectType::BigQuery) => {
37319 match scale {
37322 0 => {
37323 self.write_keyword("TIMESTAMP_SECONDS");
37324 self.write("(");
37325 self.generate_expression(&e.this)?;
37326 self.write(")");
37327 }
37328 3 => {
37329 self.write_keyword("TIMESTAMP_MILLIS");
37330 self.write("(");
37331 self.generate_expression(&e.this)?;
37332 self.write(")");
37333 }
37334 6 => {
37335 self.write_keyword("TIMESTAMP_MICROS");
37336 self.write("(");
37337 self.generate_expression(&e.this)?;
37338 self.write(")");
37339 }
37340 _ => {
37341 self.write_keyword("TIMESTAMP_SECONDS");
37343 self.write("(CAST(");
37344 self.generate_expression(&e.this)?;
37345 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
37346 }
37347 }
37348 }
37349 Some(DialectType::Spark) => {
37350 match scale {
37355 0 => {
37356 self.write_keyword("CAST");
37357 self.write("(");
37358 self.write_keyword("FROM_UNIXTIME");
37359 self.write("(");
37360 self.generate_expression(&e.this)?;
37361 self.write(") ");
37362 self.write_keyword("AS TIMESTAMP");
37363 self.write(")");
37364 }
37365 3 => {
37366 self.write_keyword("TIMESTAMP_MILLIS");
37367 self.write("(");
37368 self.generate_expression(&e.this)?;
37369 self.write(")");
37370 }
37371 6 => {
37372 self.write_keyword("TIMESTAMP_MICROS");
37373 self.write("(");
37374 self.generate_expression(&e.this)?;
37375 self.write(")");
37376 }
37377 _ => {
37378 self.write_keyword("TIMESTAMP_SECONDS");
37379 self.write("(");
37380 self.generate_expression(&e.this)?;
37381 self.write(&format!(" / POWER(10, {}))", scale));
37382 }
37383 }
37384 }
37385 Some(DialectType::Databricks) => {
37386 match scale {
37390 0 => {
37391 self.write_keyword("CAST");
37392 self.write("(");
37393 self.write_keyword("FROM_UNIXTIME");
37394 self.write("(");
37395 self.generate_expression(&e.this)?;
37396 self.write(") ");
37397 self.write_keyword("AS TIMESTAMP");
37398 self.write(")");
37399 }
37400 3 => {
37401 self.write_keyword("TIMESTAMP_MILLIS");
37402 self.write("(");
37403 self.generate_expression(&e.this)?;
37404 self.write(")");
37405 }
37406 6 => {
37407 self.write_keyword("TIMESTAMP_MICROS");
37408 self.write("(");
37409 self.generate_expression(&e.this)?;
37410 self.write(")");
37411 }
37412 _ => {
37413 self.write_keyword("TIMESTAMP_SECONDS");
37414 self.write("(");
37415 self.generate_expression(&e.this)?;
37416 self.write(&format!(" / POWER(10, {}))", scale));
37417 }
37418 }
37419 }
37420 Some(DialectType::Hive) => {
37421 if scale == 0 {
37423 self.write_keyword("FROM_UNIXTIME");
37424 self.write("(");
37425 self.generate_expression(&e.this)?;
37426 self.write(")");
37427 } else {
37428 self.write_keyword("FROM_UNIXTIME");
37429 self.write("(");
37430 self.generate_expression(&e.this)?;
37431 self.write(&format!(" / POWER(10, {})", scale));
37432 self.write(")");
37433 }
37434 }
37435 Some(DialectType::Presto) | Some(DialectType::Trino) => {
37436 if scale == 0 {
37439 self.write_keyword("FROM_UNIXTIME");
37440 self.write("(");
37441 self.generate_expression(&e.this)?;
37442 self.write(")");
37443 } else {
37444 self.write_keyword("FROM_UNIXTIME");
37445 self.write("(CAST(");
37446 self.generate_expression(&e.this)?;
37447 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
37448 }
37449 }
37450 Some(DialectType::DuckDB) => {
37451 match scale {
37455 0 => {
37456 self.write_keyword("TO_TIMESTAMP");
37457 self.write("(");
37458 self.generate_expression(&e.this)?;
37459 self.write(")");
37460 }
37461 3 => {
37462 self.write_keyword("EPOCH_MS");
37463 self.write("(");
37464 self.generate_expression(&e.this)?;
37465 self.write(")");
37466 }
37467 6 => {
37468 self.write_keyword("MAKE_TIMESTAMP");
37469 self.write("(");
37470 self.generate_expression(&e.this)?;
37471 self.write(")");
37472 }
37473 _ => {
37474 self.write_keyword("TO_TIMESTAMP");
37475 self.write("(");
37476 self.generate_expression(&e.this)?;
37477 self.write(&format!(" / POWER(10, {}))", scale));
37478 self.write_keyword(" AT TIME ZONE");
37479 self.write(" 'UTC'");
37480 }
37481 }
37482 }
37483 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
37484 self.write_keyword("FROM_UNIXTIME");
37486 self.write("(");
37487 self.generate_expression(&e.this)?;
37488 self.write(")");
37489 }
37490 Some(DialectType::Oracle) => {
37491 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
37493 self.generate_expression(&e.this)?;
37494 self.write(" / 86400)");
37495 }
37496 Some(DialectType::Redshift) => {
37497 self.write("(TIMESTAMP 'epoch' + ");
37500 if scale == 0 {
37501 self.generate_expression(&e.this)?;
37502 } else {
37503 self.write("(");
37504 self.generate_expression(&e.this)?;
37505 self.write(&format!(" / POWER(10, {}))", scale));
37506 }
37507 self.write(" * INTERVAL '1 SECOND')");
37508 }
37509 Some(DialectType::Exasol) => {
37510 self.write_keyword("FROM_POSIX_TIME");
37512 self.write("(");
37513 self.generate_expression(&e.this)?;
37514 self.write(")");
37515 }
37516 _ => {
37517 self.write_keyword("TO_TIMESTAMP");
37519 self.write("(");
37520 self.generate_expression(&e.this)?;
37521 if let Some(s) = e.scale {
37522 self.write(", ");
37523 self.write(&s.to_string());
37524 }
37525 self.write(")");
37526 }
37527 }
37528 Ok(())
37529 }
37530
37531 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
37532 if !matches!(&*e.this, Expression::Null(_)) {
37534 self.write_keyword("NAME");
37535 self.write_space();
37536 self.generate_expression(&e.this)?;
37537 }
37538 if !e.expressions.is_empty() {
37539 self.write_space();
37540 self.write_keyword("VALUE");
37541 self.write_space();
37542 for (i, expr) in e.expressions.iter().enumerate() {
37543 if i > 0 {
37544 self.write(", ");
37545 }
37546 self.generate_expression(expr)?;
37547 }
37548 }
37549 Ok(())
37550 }
37551
37552 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
37553 if e.wrapped.is_some() {
37555 self.write("(");
37556 }
37557 self.generate_expression(&e.this)?;
37558 if e.wrapped.is_some() {
37559 self.write(")");
37560 }
37561 self.write("(");
37562 for (i, expr) in e.expressions.iter().enumerate() {
37563 if i > 0 {
37564 self.write(", ");
37565 }
37566 self.generate_expression(expr)?;
37567 }
37568 self.write(")");
37569 Ok(())
37570 }
37571
37572 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
37573 self.write_keyword("USING TEMPLATE");
37575 self.write_space();
37576 self.generate_expression(&e.this)?;
37577 Ok(())
37578 }
37579
37580 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
37581 self.write_keyword("UTC_TIME");
37583 Ok(())
37584 }
37585
37586 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
37587 if matches!(
37588 self.config.dialect,
37589 Some(crate::dialects::DialectType::ClickHouse)
37590 ) {
37591 self.write_keyword("CURRENT_TIMESTAMP");
37592 self.write("('UTC')");
37593 } else {
37594 self.write_keyword("UTC_TIMESTAMP");
37595 }
37596 Ok(())
37597 }
37598
37599 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
37600 use crate::dialects::DialectType;
37601 let func_name = match self.config.dialect {
37603 Some(DialectType::Snowflake) => "UUID_STRING",
37604 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
37605 Some(DialectType::BigQuery) => "GENERATE_UUID",
37606 _ => {
37607 if let Some(name) = &e.name {
37608 name.as_str()
37609 } else {
37610 "UUID"
37611 }
37612 }
37613 };
37614 self.write_keyword(func_name);
37615 self.write("(");
37616 if let Some(this) = &e.this {
37617 self.generate_expression(this)?;
37618 }
37619 self.write(")");
37620 Ok(())
37621 }
37622
37623 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
37624 self.write_keyword("MAP");
37626 self.write("(");
37627 let mut first = true;
37628 for (k, v) in e.keys.iter().zip(e.values.iter()) {
37629 if !first {
37630 self.write(", ");
37631 }
37632 self.generate_expression(k)?;
37633 self.write(", ");
37634 self.generate_expression(v)?;
37635 first = false;
37636 }
37637 self.write(")");
37638 Ok(())
37639 }
37640
37641 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
37642 self.write_keyword("VECTOR_SEARCH");
37644 self.write("(");
37645 self.generate_expression(&e.this)?;
37646 if let Some(col) = &e.column_to_search {
37647 self.write(", ");
37648 self.generate_expression(col)?;
37649 }
37650 if let Some(query_table) = &e.query_table {
37651 self.write(", ");
37652 self.generate_expression(query_table)?;
37653 }
37654 if let Some(query_col) = &e.query_column_to_search {
37655 self.write(", ");
37656 self.generate_expression(query_col)?;
37657 }
37658 if let Some(top_k) = &e.top_k {
37659 self.write(", ");
37660 self.generate_expression(top_k)?;
37661 }
37662 if let Some(dist_type) = &e.distance_type {
37663 self.write(", ");
37664 self.generate_expression(dist_type)?;
37665 }
37666 self.write(")");
37667 Ok(())
37668 }
37669
37670 fn generate_version(&mut self, e: &Version) -> Result<()> {
37671 use crate::dialects::DialectType;
37677 let skip_for = matches!(
37678 self.config.dialect,
37679 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
37680 );
37681 if !skip_for {
37682 self.write_keyword("FOR");
37683 self.write_space();
37684 }
37685 match e.this.as_ref() {
37687 Expression::Identifier(ident) => {
37688 self.write_keyword(&ident.name);
37689 }
37690 _ => {
37691 self.generate_expression(&e.this)?;
37692 }
37693 }
37694 self.write_space();
37695 self.write_keyword(&e.kind);
37696 if let Some(expression) = &e.expression {
37697 self.write_space();
37698 self.generate_expression(expression)?;
37699 }
37700 Ok(())
37701 }
37702
37703 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
37704 self.generate_expression(&e.this)?;
37706 Ok(())
37707 }
37708
37709 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
37710 if e.this.is_some() {
37712 self.write_keyword("NOT VOLATILE");
37713 } else {
37714 self.write_keyword("VOLATILE");
37715 }
37716 Ok(())
37717 }
37718
37719 fn generate_watermark_column_constraint(
37720 &mut self,
37721 e: &WatermarkColumnConstraint,
37722 ) -> Result<()> {
37723 self.write_keyword("WATERMARK FOR");
37725 self.write_space();
37726 self.generate_expression(&e.this)?;
37727 self.write_space();
37728 self.write_keyword("AS");
37729 self.write_space();
37730 self.generate_expression(&e.expression)?;
37731 Ok(())
37732 }
37733
37734 fn generate_week(&mut self, e: &Week) -> Result<()> {
37735 self.write_keyword("WEEK");
37737 self.write("(");
37738 self.generate_expression(&e.this)?;
37739 if let Some(mode) = &e.mode {
37740 self.write(", ");
37741 self.generate_expression(mode)?;
37742 }
37743 self.write(")");
37744 Ok(())
37745 }
37746
37747 fn generate_when(&mut self, e: &When) -> Result<()> {
37748 self.write_keyword("WHEN");
37752 self.write_space();
37753
37754 if let Some(matched) = &e.matched {
37756 match matched.as_ref() {
37758 Expression::Boolean(b) if b.value => {
37759 self.write_keyword("MATCHED");
37760 }
37761 _ => {
37762 self.write_keyword("NOT MATCHED");
37763 }
37764 }
37765 } else {
37766 self.write_keyword("NOT MATCHED");
37767 }
37768
37769 if self.config.matched_by_source {
37774 if let Some(source) = &e.source {
37775 if let Expression::Boolean(b) = source.as_ref() {
37776 if b.value {
37777 self.write_space();
37779 self.write_keyword("BY SOURCE");
37780 }
37781 } else {
37783 self.write_space();
37785 self.write_keyword("BY SOURCE");
37786 }
37787 }
37788 }
37789
37790 if let Some(condition) = &e.condition {
37792 self.write_space();
37793 self.write_keyword("AND");
37794 self.write_space();
37795 self.generate_expression(condition)?;
37796 }
37797
37798 self.write_space();
37799 self.write_keyword("THEN");
37800 self.write_space();
37801
37802 self.generate_merge_action(&e.then)?;
37805
37806 Ok(())
37807 }
37808
37809 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
37810 match action {
37811 Expression::Tuple(tuple) => {
37812 let elements = &tuple.expressions;
37813 if elements.is_empty() {
37814 return self.generate_expression(action);
37815 }
37816 match &elements[0] {
37818 Expression::Var(v) if v.this == "INSERT" => {
37819 self.write_keyword("INSERT");
37820 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37822 self.write(" *");
37823 if let Some(Expression::Where(w)) = elements.get(2) {
37824 self.write_space();
37825 self.generate_where(w)?;
37826 }
37827 } else {
37828 let mut values_idx = 1;
37829 if elements.len() > 1 {
37831 if let Expression::Tuple(cols) = &elements[1] {
37832 if elements.len() > 2 {
37834 self.write(" (");
37836 for (i, col) in cols.expressions.iter().enumerate() {
37837 if i > 0 {
37838 self.write(", ");
37839 }
37840 if !self.merge_strip_qualifiers.is_empty() {
37842 let stripped = self.strip_merge_qualifier(col);
37843 self.generate_expression(&stripped)?;
37844 } else {
37845 self.generate_expression(col)?;
37846 }
37847 }
37848 self.write(")");
37849 values_idx = 2;
37850 } else {
37851 values_idx = 1;
37853 }
37854 }
37855 }
37856 let mut next_idx = values_idx;
37857 if values_idx < elements.len()
37859 && !matches!(&elements[values_idx], Expression::Where(_))
37860 {
37861 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
37863 if !is_row {
37864 self.write_space();
37865 self.write_keyword("VALUES");
37866 }
37867 self.write(" ");
37868 if let Expression::Tuple(vals) = &elements[values_idx] {
37869 self.write("(");
37870 for (i, val) in vals.expressions.iter().enumerate() {
37871 if i > 0 {
37872 self.write(", ");
37873 }
37874 self.generate_expression(val)?;
37875 }
37876 self.write(")");
37877 } else {
37878 self.generate_expression(&elements[values_idx])?;
37879 }
37880 next_idx += 1;
37881 }
37882 if let Some(Expression::Where(w)) = elements.get(next_idx) {
37883 self.write_space();
37884 self.generate_where(w)?;
37885 }
37886 } }
37888 Expression::Var(v) if v.this == "UPDATE" => {
37889 self.write_keyword("UPDATE");
37890 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37892 self.write(" *");
37893 if let Some(Expression::Where(w)) = elements.get(2) {
37894 self.write_space();
37895 self.generate_where(w)?;
37896 }
37897 } else if elements.len() > 1 {
37898 self.write_space();
37899 self.write_keyword("SET");
37900 if self.config.pretty {
37902 self.write_newline();
37903 self.indent_level += 1;
37904 self.write_indent();
37905 } else {
37906 self.write_space();
37907 }
37908 if let Expression::Tuple(assignments) = &elements[1] {
37909 for (i, assignment) in assignments.expressions.iter().enumerate() {
37910 if i > 0 {
37911 if self.config.pretty {
37912 self.write(",");
37913 self.write_newline();
37914 self.write_indent();
37915 } else {
37916 self.write(", ");
37917 }
37918 }
37919 if !self.merge_strip_qualifiers.is_empty() {
37921 self.generate_merge_set_assignment(assignment)?;
37922 } else {
37923 self.generate_expression(assignment)?;
37924 }
37925 }
37926 } else {
37927 self.generate_expression(&elements[1])?;
37928 }
37929 if self.config.pretty {
37930 self.indent_level -= 1;
37931 }
37932 if let Some(Expression::Where(w)) = elements.get(2) {
37933 self.write_space();
37934 self.generate_where(w)?;
37935 }
37936 }
37937 }
37938 Expression::Var(v) if v.this == "DELETE" => {
37939 self.write_keyword("DELETE");
37940 if let Some(Expression::Where(w)) = elements.get(1) {
37941 self.write_space();
37942 self.generate_where(w)?;
37943 }
37944 }
37945 _ => {
37946 self.generate_expression(action)?;
37948 }
37949 }
37950 }
37951 Expression::Var(v)
37952 if v.this == "INSERT"
37953 || v.this == "UPDATE"
37954 || v.this == "DELETE"
37955 || v.this == "DO NOTHING" =>
37956 {
37957 self.write_keyword(&v.this);
37958 }
37959 _ => {
37960 self.generate_expression(action)?;
37961 }
37962 }
37963 Ok(())
37964 }
37965
37966 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
37968 match assignment {
37969 Expression::Eq(eq) => {
37970 let stripped_left = self.strip_merge_qualifier(&eq.left);
37972 self.generate_expression(&stripped_left)?;
37973 self.write(" = ");
37974 self.generate_expression(&eq.right)?;
37975 Ok(())
37976 }
37977 other => self.generate_expression(other),
37978 }
37979 }
37980
37981 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
37983 match expr {
37984 Expression::Column(col) => {
37985 if let Some(ref table_ident) = col.table {
37986 if self
37987 .merge_strip_qualifiers
37988 .iter()
37989 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
37990 {
37991 let mut col = col.clone();
37993 col.table = None;
37994 return Expression::Column(col);
37995 }
37996 }
37997 expr.clone()
37998 }
37999 Expression::Dot(dot) => {
38000 if let Expression::Identifier(id) = &dot.this {
38002 if self
38003 .merge_strip_qualifiers
38004 .iter()
38005 .any(|n| n.eq_ignore_ascii_case(&id.name))
38006 {
38007 return Expression::Identifier(dot.field.clone());
38008 }
38009 }
38010 expr.clone()
38011 }
38012 _ => expr.clone(),
38013 }
38014 }
38015
38016 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
38017 for (i, expr) in e.expressions.iter().enumerate() {
38019 if i > 0 {
38020 if self.config.pretty {
38022 self.write_newline();
38023 self.write_indent();
38024 } else {
38025 self.write_space();
38026 }
38027 }
38028 self.generate_expression(expr)?;
38029 }
38030 Ok(())
38031 }
38032
38033 fn generate_where(&mut self, e: &Where) -> Result<()> {
38034 self.write_keyword("WHERE");
38036 self.write_space();
38037 self.generate_expression(&e.this)?;
38038 Ok(())
38039 }
38040
38041 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
38042 self.write_keyword("WIDTH_BUCKET");
38044 self.write("(");
38045 self.generate_expression(&e.this)?;
38046 if let Some(min_value) = &e.min_value {
38047 self.write(", ");
38048 self.generate_expression(min_value)?;
38049 }
38050 if let Some(max_value) = &e.max_value {
38051 self.write(", ");
38052 self.generate_expression(max_value)?;
38053 }
38054 if let Some(num_buckets) = &e.num_buckets {
38055 self.write(", ");
38056 self.generate_expression(num_buckets)?;
38057 }
38058 self.write(")");
38059 Ok(())
38060 }
38061
38062 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
38063 self.generate_window_spec(e)
38065 }
38066
38067 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
38068 let mut has_content = false;
38070
38071 if !e.partition_by.is_empty() {
38073 self.write_keyword("PARTITION BY");
38074 self.write_space();
38075 for (i, expr) in e.partition_by.iter().enumerate() {
38076 if i > 0 {
38077 self.write(", ");
38078 }
38079 self.generate_expression(expr)?;
38080 }
38081 has_content = true;
38082 }
38083
38084 if !e.order_by.is_empty() {
38086 if has_content {
38087 self.write_space();
38088 }
38089 self.write_keyword("ORDER BY");
38090 self.write_space();
38091 for (i, ordered) in e.order_by.iter().enumerate() {
38092 if i > 0 {
38093 self.write(", ");
38094 }
38095 self.generate_expression(&ordered.this)?;
38096 if ordered.desc {
38097 self.write_space();
38098 self.write_keyword("DESC");
38099 } else if ordered.explicit_asc {
38100 self.write_space();
38101 self.write_keyword("ASC");
38102 }
38103 if let Some(nulls_first) = ordered.nulls_first {
38104 self.write_space();
38105 self.write_keyword("NULLS");
38106 self.write_space();
38107 if nulls_first {
38108 self.write_keyword("FIRST");
38109 } else {
38110 self.write_keyword("LAST");
38111 }
38112 }
38113 }
38114 has_content = true;
38115 }
38116
38117 if let Some(frame) = &e.frame {
38119 if has_content {
38120 self.write_space();
38121 }
38122 self.generate_window_frame(frame)?;
38123 }
38124
38125 Ok(())
38126 }
38127
38128 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
38129 self.write_keyword("WITH");
38131 self.write_space();
38132 if e.no.is_some() {
38133 self.write_keyword("NO");
38134 self.write_space();
38135 }
38136 self.write_keyword("DATA");
38137
38138 if let Some(statistics) = &e.statistics {
38140 self.write_space();
38141 self.write_keyword("AND");
38142 self.write_space();
38143 match statistics.as_ref() {
38145 Expression::Boolean(b) if !b.value => {
38146 self.write_keyword("NO");
38147 self.write_space();
38148 }
38149 _ => {}
38150 }
38151 self.write_keyword("STATISTICS");
38152 }
38153 Ok(())
38154 }
38155
38156 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
38157 self.write_keyword("WITH FILL");
38159
38160 if let Some(from_) = &e.from_ {
38161 self.write_space();
38162 self.write_keyword("FROM");
38163 self.write_space();
38164 self.generate_expression(from_)?;
38165 }
38166
38167 if let Some(to) = &e.to {
38168 self.write_space();
38169 self.write_keyword("TO");
38170 self.write_space();
38171 self.generate_expression(to)?;
38172 }
38173
38174 if let Some(step) = &e.step {
38175 self.write_space();
38176 self.write_keyword("STEP");
38177 self.write_space();
38178 self.generate_expression(step)?;
38179 }
38180
38181 if let Some(staleness) = &e.staleness {
38182 self.write_space();
38183 self.write_keyword("STALENESS");
38184 self.write_space();
38185 self.generate_expression(staleness)?;
38186 }
38187
38188 if let Some(interpolate) = &e.interpolate {
38189 self.write_space();
38190 self.write_keyword("INTERPOLATE");
38191 self.write(" (");
38192 self.generate_interpolate_item(interpolate)?;
38194 self.write(")");
38195 }
38196
38197 Ok(())
38198 }
38199
38200 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
38202 match expr {
38203 Expression::Alias(alias) => {
38204 self.generate_identifier(&alias.alias)?;
38206 self.write_space();
38207 self.write_keyword("AS");
38208 self.write_space();
38209 self.generate_expression(&alias.this)?;
38210 }
38211 Expression::Tuple(tuple) => {
38212 for (i, item) in tuple.expressions.iter().enumerate() {
38213 if i > 0 {
38214 self.write(", ");
38215 }
38216 self.generate_interpolate_item(item)?;
38217 }
38218 }
38219 other => {
38220 self.generate_expression(other)?;
38221 }
38222 }
38223 Ok(())
38224 }
38225
38226 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
38227 self.write_keyword("WITH JOURNAL TABLE");
38229 self.write("=");
38230 self.generate_expression(&e.this)?;
38231 Ok(())
38232 }
38233
38234 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
38235 self.generate_expression(&e.this)?;
38237 self.write_space();
38238 self.write_keyword("WITH");
38239 self.write_space();
38240 self.write_keyword(&e.op);
38241 Ok(())
38242 }
38243
38244 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
38245 self.write_keyword("WITH");
38247 self.write_space();
38248 for (i, expr) in e.expressions.iter().enumerate() {
38249 if i > 0 {
38250 self.write(", ");
38251 }
38252 self.generate_expression(expr)?;
38253 }
38254 Ok(())
38255 }
38256
38257 fn generate_with_schema_binding_property(
38258 &mut self,
38259 e: &WithSchemaBindingProperty,
38260 ) -> Result<()> {
38261 self.write_keyword("WITH");
38263 self.write_space();
38264 self.generate_expression(&e.this)?;
38265 Ok(())
38266 }
38267
38268 fn generate_with_system_versioning_property(
38269 &mut self,
38270 e: &WithSystemVersioningProperty,
38271 ) -> Result<()> {
38272 let mut parts = Vec::new();
38278
38279 if let Some(this) = &e.this {
38280 let mut s = String::from("HISTORY_TABLE=");
38282 let mut gen = Generator::new();
38283 gen.generate_expression(this)?;
38284 s.push_str(&gen.output);
38285 parts.push(s);
38286 }
38287
38288 if let Some(data_consistency) = &e.data_consistency {
38289 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
38290 let mut gen = Generator::new();
38291 gen.generate_expression(data_consistency)?;
38292 s.push_str(&gen.output);
38293 parts.push(s);
38294 }
38295
38296 if let Some(retention_period) = &e.retention_period {
38297 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
38298 let mut gen = Generator::new();
38299 gen.generate_expression(retention_period)?;
38300 s.push_str(&gen.output);
38301 parts.push(s);
38302 }
38303
38304 self.write_keyword("SYSTEM_VERSIONING");
38305 self.write("=");
38306
38307 if !parts.is_empty() {
38308 self.write_keyword("ON");
38309 self.write("(");
38310 self.write(&parts.join(", "));
38311 self.write(")");
38312 } else if e.on.is_some() {
38313 self.write_keyword("ON");
38314 } else {
38315 self.write_keyword("OFF");
38316 }
38317
38318 if e.with_.is_some() {
38320 let inner = self.output.clone();
38321 self.output.clear();
38322 self.write("WITH(");
38323 self.write(&inner);
38324 self.write(")");
38325 }
38326
38327 Ok(())
38328 }
38329
38330 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
38331 self.write_keyword("WITH");
38333 self.write(" (");
38334 for (i, expr) in e.expressions.iter().enumerate() {
38335 if i > 0 {
38336 self.write(", ");
38337 }
38338 self.generate_expression(expr)?;
38339 }
38340 self.write(")");
38341 Ok(())
38342 }
38343
38344 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
38345 self.write_keyword("XMLELEMENT");
38348 self.write("(");
38349
38350 if e.evalname.is_some() {
38351 self.write_keyword("EVALNAME");
38352 } else {
38353 self.write_keyword("NAME");
38354 }
38355 self.write_space();
38356 self.generate_expression(&e.this)?;
38357
38358 for expr in &e.expressions {
38359 self.write(", ");
38360 self.generate_expression(expr)?;
38361 }
38362 self.write(")");
38363 Ok(())
38364 }
38365
38366 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
38367 self.write_keyword("XMLGET");
38369 self.write("(");
38370 self.generate_expression(&e.this)?;
38371 self.write(", ");
38372 self.generate_expression(&e.expression)?;
38373 if let Some(instance) = &e.instance {
38374 self.write(", ");
38375 self.generate_expression(instance)?;
38376 }
38377 self.write(")");
38378 Ok(())
38379 }
38380
38381 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
38382 self.generate_expression(&e.this)?;
38384 if let Some(expression) = &e.expression {
38385 self.write("(");
38386 self.generate_expression(expression)?;
38387 self.write(")");
38388 }
38389 Ok(())
38390 }
38391
38392 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
38393 self.write_keyword("XMLTABLE");
38395 self.write("(");
38396
38397 if self.config.pretty {
38398 self.indent_level += 1;
38399 self.write_newline();
38400 self.write_indent();
38401 self.generate_expression(&e.this)?;
38402
38403 if let Some(passing) = &e.passing {
38404 self.write_newline();
38405 self.write_indent();
38406 self.write_keyword("PASSING");
38407 if let Expression::Tuple(tuple) = passing.as_ref() {
38408 for expr in &tuple.expressions {
38409 self.write_newline();
38410 self.indent_level += 1;
38411 self.write_indent();
38412 self.generate_expression(expr)?;
38413 self.indent_level -= 1;
38414 }
38415 } else {
38416 self.write_newline();
38417 self.indent_level += 1;
38418 self.write_indent();
38419 self.generate_expression(passing)?;
38420 self.indent_level -= 1;
38421 }
38422 }
38423
38424 if e.by_ref.is_some() {
38425 self.write_newline();
38426 self.write_indent();
38427 self.write_keyword("RETURNING SEQUENCE BY REF");
38428 }
38429
38430 if !e.columns.is_empty() {
38431 self.write_newline();
38432 self.write_indent();
38433 self.write_keyword("COLUMNS");
38434 for (i, col) in e.columns.iter().enumerate() {
38435 self.write_newline();
38436 self.indent_level += 1;
38437 self.write_indent();
38438 self.generate_expression(col)?;
38439 self.indent_level -= 1;
38440 if i < e.columns.len() - 1 {
38441 self.write(",");
38442 }
38443 }
38444 }
38445
38446 self.indent_level -= 1;
38447 self.write_newline();
38448 self.write_indent();
38449 self.write(")");
38450 return Ok(());
38451 }
38452
38453 if let Some(namespaces) = &e.namespaces {
38455 self.write_keyword("XMLNAMESPACES");
38456 self.write("(");
38457 if let Expression::Tuple(tuple) = namespaces.as_ref() {
38459 for (i, expr) in tuple.expressions.iter().enumerate() {
38460 if i > 0 {
38461 self.write(", ");
38462 }
38463 if !matches!(expr, Expression::Alias(_)) {
38466 self.write_keyword("DEFAULT");
38467 self.write_space();
38468 }
38469 self.generate_expression(expr)?;
38470 }
38471 } else {
38472 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
38474 self.write_keyword("DEFAULT");
38475 self.write_space();
38476 }
38477 self.generate_expression(namespaces)?;
38478 }
38479 self.write("), ");
38480 }
38481
38482 self.generate_expression(&e.this)?;
38484
38485 if let Some(passing) = &e.passing {
38487 self.write_space();
38488 self.write_keyword("PASSING");
38489 self.write_space();
38490 if let Expression::Tuple(tuple) = passing.as_ref() {
38492 for (i, expr) in tuple.expressions.iter().enumerate() {
38493 if i > 0 {
38494 self.write(", ");
38495 }
38496 self.generate_expression(expr)?;
38497 }
38498 } else {
38499 self.generate_expression(passing)?;
38500 }
38501 }
38502
38503 if e.by_ref.is_some() {
38505 self.write_space();
38506 self.write_keyword("RETURNING SEQUENCE BY REF");
38507 }
38508
38509 if !e.columns.is_empty() {
38511 self.write_space();
38512 self.write_keyword("COLUMNS");
38513 self.write_space();
38514 for (i, col) in e.columns.iter().enumerate() {
38515 if i > 0 {
38516 self.write(", ");
38517 }
38518 self.generate_expression(col)?;
38519 }
38520 }
38521
38522 self.write(")");
38523 Ok(())
38524 }
38525
38526 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
38527 if let Some(this) = &e.this {
38530 self.generate_expression(this)?;
38531 if let Some(expression) = &e.expression {
38532 self.write_space();
38533 self.write_keyword("XOR");
38534 self.write_space();
38535 self.generate_expression(expression)?;
38536 }
38537 }
38538
38539 for (i, expr) in e.expressions.iter().enumerate() {
38541 if i > 0 || e.this.is_some() {
38542 self.write_space();
38543 self.write_keyword("XOR");
38544 self.write_space();
38545 }
38546 self.generate_expression(expr)?;
38547 }
38548 Ok(())
38549 }
38550
38551 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
38552 self.write_keyword("ZIPF");
38554 self.write("(");
38555 self.generate_expression(&e.this)?;
38556 if let Some(elementcount) = &e.elementcount {
38557 self.write(", ");
38558 self.generate_expression(elementcount)?;
38559 }
38560 if let Some(gen) = &e.gen {
38561 self.write(", ");
38562 self.generate_expression(gen)?;
38563 }
38564 self.write(")");
38565 Ok(())
38566 }
38567}
38568
38569impl Default for Generator {
38570 fn default() -> Self {
38571 Self::new()
38572 }
38573}
38574
38575#[cfg(test)]
38576mod tests {
38577 use super::*;
38578 use crate::parser::Parser;
38579
38580 fn roundtrip(sql: &str) -> String {
38581 let ast = Parser::parse_sql(sql).unwrap();
38582 Generator::sql(&ast[0]).unwrap()
38583 }
38584
38585 #[test]
38586 fn test_simple_select() {
38587 let result = roundtrip("SELECT 1");
38588 assert_eq!(result, "SELECT 1");
38589 }
38590
38591 #[test]
38592 fn test_select_from() {
38593 let result = roundtrip("SELECT a, b FROM t");
38594 assert_eq!(result, "SELECT a, b FROM t");
38595 }
38596
38597 #[test]
38598 fn test_select_where() {
38599 let result = roundtrip("SELECT * FROM t WHERE x = 1");
38600 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
38601 }
38602
38603 #[test]
38604 fn test_select_join() {
38605 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
38606 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
38607 }
38608
38609 #[test]
38610 fn test_insert() {
38611 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
38612 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
38613 }
38614
38615 #[test]
38616 fn test_pretty_print() {
38617 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
38618 let result = Generator::pretty_sql(&ast[0]).unwrap();
38619 assert!(result.contains('\n'));
38620 }
38621
38622 #[test]
38623 fn test_window_function() {
38624 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
38625 assert_eq!(
38626 result,
38627 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
38628 );
38629 }
38630
38631 #[test]
38632 fn test_window_function_with_frame() {
38633 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
38634 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
38635 }
38636
38637 #[test]
38638 fn test_aggregate_with_filter() {
38639 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
38640 assert_eq!(
38641 result,
38642 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
38643 );
38644 }
38645
38646 #[test]
38647 fn test_subscript() {
38648 let result = roundtrip("SELECT arr[0]");
38649 assert_eq!(result, "SELECT arr[0]");
38650 }
38651
38652 #[test]
38654 fn test_create_table() {
38655 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
38656 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
38657 }
38658
38659 #[test]
38660 fn test_create_table_with_constraints() {
38661 let result = roundtrip(
38662 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
38663 );
38664 assert_eq!(
38665 result,
38666 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
38667 );
38668 }
38669
38670 #[test]
38671 fn test_create_table_if_not_exists() {
38672 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
38673 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
38674 }
38675
38676 #[test]
38677 fn test_drop_table() {
38678 let result = roundtrip("DROP TABLE users");
38679 assert_eq!(result, "DROP TABLE users");
38680 }
38681
38682 #[test]
38683 fn test_drop_table_if_exists_cascade() {
38684 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
38685 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
38686 }
38687
38688 #[test]
38689 fn test_alter_table_add_column() {
38690 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38691 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
38692 }
38693
38694 #[test]
38695 fn test_alter_table_drop_column() {
38696 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
38697 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
38698 }
38699
38700 #[test]
38701 fn test_create_index() {
38702 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
38703 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
38704 }
38705
38706 #[test]
38707 fn test_create_unique_index() {
38708 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
38709 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
38710 }
38711
38712 #[test]
38713 fn test_drop_index() {
38714 let result = roundtrip("DROP INDEX idx_name");
38715 assert_eq!(result, "DROP INDEX idx_name");
38716 }
38717
38718 #[test]
38719 fn test_create_view() {
38720 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
38721 assert_eq!(
38722 result,
38723 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
38724 );
38725 }
38726
38727 #[test]
38728 fn test_drop_view() {
38729 let result = roundtrip("DROP VIEW active_users");
38730 assert_eq!(result, "DROP VIEW active_users");
38731 }
38732
38733 #[test]
38734 fn test_truncate() {
38735 let result = roundtrip("TRUNCATE TABLE users");
38736 assert_eq!(result, "TRUNCATE TABLE users");
38737 }
38738
38739 #[test]
38740 fn test_string_literal_escaping_default() {
38741 let result = roundtrip("SELECT 'hello'");
38743 assert_eq!(result, "SELECT 'hello'");
38744
38745 let result = roundtrip("SELECT 'it''s a test'");
38747 assert_eq!(result, "SELECT 'it''s a test'");
38748 }
38749
38750 #[test]
38751 fn test_not_in_style_prefix_default_generic() {
38752 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
38753 assert_eq!(
38754 result,
38755 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
38756 );
38757 }
38758
38759 #[test]
38760 fn test_not_in_style_infix_generic_override() {
38761 let ast =
38762 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
38763 .unwrap();
38764 let config = GeneratorConfig {
38765 not_in_style: NotInStyle::Infix,
38766 ..Default::default()
38767 };
38768 let mut gen = Generator::with_config(config);
38769 let result = gen.generate(&ast[0]).unwrap();
38770 assert_eq!(
38771 result,
38772 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
38773 );
38774 }
38775
38776 #[test]
38777 fn test_string_literal_escaping_mysql() {
38778 use crate::dialects::DialectType;
38779
38780 let config = GeneratorConfig {
38781 dialect: Some(DialectType::MySQL),
38782 ..Default::default()
38783 };
38784
38785 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38786 let mut gen = Generator::with_config(config.clone());
38787 let result = gen.generate(&ast[0]).unwrap();
38788 assert_eq!(result, "SELECT 'hello'");
38789
38790 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38792 let mut gen = Generator::with_config(config.clone());
38793 let result = gen.generate(&ast[0]).unwrap();
38794 assert_eq!(result, "SELECT 'it''s'");
38795 }
38796
38797 #[test]
38798 fn test_string_literal_escaping_postgres() {
38799 use crate::dialects::DialectType;
38800
38801 let config = GeneratorConfig {
38802 dialect: Some(DialectType::PostgreSQL),
38803 ..Default::default()
38804 };
38805
38806 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38807 let mut gen = Generator::with_config(config.clone());
38808 let result = gen.generate(&ast[0]).unwrap();
38809 assert_eq!(result, "SELECT 'hello'");
38810
38811 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38813 let mut gen = Generator::with_config(config.clone());
38814 let result = gen.generate(&ast[0]).unwrap();
38815 assert_eq!(result, "SELECT 'it''s'");
38816 }
38817
38818 #[test]
38819 fn test_string_literal_escaping_bigquery() {
38820 use crate::dialects::DialectType;
38821
38822 let config = GeneratorConfig {
38823 dialect: Some(DialectType::BigQuery),
38824 ..Default::default()
38825 };
38826
38827 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38828 let mut gen = Generator::with_config(config.clone());
38829 let result = gen.generate(&ast[0]).unwrap();
38830 assert_eq!(result, "SELECT 'hello'");
38831
38832 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38834 let mut gen = Generator::with_config(config.clone());
38835 let result = gen.generate(&ast[0]).unwrap();
38836 assert_eq!(result, "SELECT 'it\\'s'");
38837 }
38838
38839 #[test]
38840 fn test_generate_deep_and_chain_without_stack_growth() {
38841 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38842 Expression::column("c0"),
38843 Expression::number(0),
38844 )));
38845
38846 for i in 1..2500 {
38847 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38848 Expression::column(format!("c{i}")),
38849 Expression::number(i as i64),
38850 )));
38851 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
38852 }
38853
38854 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
38855 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38856 }
38857
38858 #[test]
38859 fn test_generate_deep_or_chain_without_stack_growth() {
38860 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38861 Expression::column("c0"),
38862 Expression::number(0),
38863 )));
38864
38865 for i in 1..2500 {
38866 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38867 Expression::column(format!("c{i}")),
38868 Expression::number(i as i64),
38869 )));
38870 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
38871 }
38872
38873 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
38874 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38875 }
38876}