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("values");
873 set.remove("table");
874 set
875 });
876
877 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
879 let mut set = SQL_RESERVED.clone();
880 set.extend([
881 "accessible",
882 "add",
883 "analyze",
884 "asensitive",
885 "before",
886 "bigint",
887 "binary",
888 "blob",
889 "call",
890 "cascade",
891 "change",
892 "char",
893 "character",
894 "condition",
895 "continue",
896 "convert",
897 "current_date",
898 "current_time",
899 "current_timestamp",
900 "current_user",
901 "cursor",
902 "database",
903 "databases",
904 "day_hour",
905 "day_microsecond",
906 "day_minute",
907 "day_second",
908 "dec",
909 "decimal",
910 "declare",
911 "delayed",
912 "describe",
913 "deterministic",
914 "distinctrow",
915 "div",
916 "double",
917 "dual",
918 "each",
919 "elseif",
920 "enclosed",
921 "escaped",
922 "exit",
923 "explain",
924 "float",
925 "float4",
926 "float8",
927 "force",
928 "get",
929 "high_priority",
930 "hour_microsecond",
931 "hour_minute",
932 "hour_second",
933 "ignore",
934 "infile",
935 "inout",
936 "insensitive",
937 "int",
938 "int1",
939 "int2",
940 "int3",
941 "int4",
942 "int8",
943 "integer",
944 "iterate",
945 "keys",
946 "kill",
947 "leave",
948 "linear",
949 "lines",
950 "load",
951 "lock",
952 "long",
953 "longblob",
954 "longtext",
955 "loop",
956 "low_priority",
957 "master_ssl_verify_server_cert",
958 "maxvalue",
959 "mediumblob",
960 "mediumint",
961 "mediumtext",
962 "middleint",
963 "minute_microsecond",
964 "minute_second",
965 "mod",
966 "modifies",
967 "no_write_to_binlog",
968 "numeric",
969 "optimize",
970 "option",
971 "optionally",
972 "out",
973 "outfile",
974 "precision",
975 "purge",
976 "read",
977 "reads",
978 "real",
979 "regexp",
980 "release",
981 "rename",
982 "repeat",
983 "replace",
984 "require",
985 "resignal",
986 "restrict",
987 "return",
988 "revoke",
989 "rlike",
990 "schema",
991 "schemas",
992 "second_microsecond",
993 "sensitive",
994 "separator",
995 "show",
996 "signal",
997 "smallint",
998 "spatial",
999 "specific",
1000 "sql",
1001 "sql_big_result",
1002 "sql_calc_found_rows",
1003 "sql_small_result",
1004 "sqlexception",
1005 "sqlstate",
1006 "sqlwarning",
1007 "ssl",
1008 "starting",
1009 "straight_join",
1010 "terminated",
1011 "text",
1012 "tinyblob",
1013 "tinyint",
1014 "tinytext",
1015 "trigger",
1016 "undo",
1017 "unlock",
1018 "unsigned",
1019 "usage",
1020 "utc_date",
1021 "utc_time",
1022 "utc_timestamp",
1023 "varbinary",
1024 "varchar",
1025 "varcharacter",
1026 "varying",
1027 "while",
1028 "write",
1029 "xor",
1030 "year_month",
1031 "zerofill",
1032 ]);
1033 set.remove("table");
1034 set
1035 });
1036
1037 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1040 let mut set = MYSQL_RESERVED.clone();
1041 set.extend([
1042 "aggregate",
1043 "anti",
1044 "array",
1045 "backend",
1046 "backup",
1047 "begin",
1048 "bitmap",
1049 "boolean",
1050 "broker",
1051 "buckets",
1052 "cached",
1053 "cancel",
1054 "cast",
1055 "catalog",
1056 "charset",
1057 "cluster",
1058 "collation",
1059 "columns",
1060 "comment",
1061 "commit",
1062 "config",
1063 "connection",
1064 "count",
1065 "current",
1066 "data",
1067 "date",
1068 "datetime",
1069 "day",
1070 "deferred",
1071 "distributed",
1072 "dynamic",
1073 "enable",
1074 "end",
1075 "events",
1076 "export",
1077 "external",
1078 "fields",
1079 "first",
1080 "follower",
1081 "format",
1082 "free",
1083 "frontend",
1084 "full",
1085 "functions",
1086 "global",
1087 "grants",
1088 "hash",
1089 "help",
1090 "hour",
1091 "install",
1092 "intermediate",
1093 "json",
1094 "label",
1095 "last",
1096 "less",
1097 "level",
1098 "link",
1099 "local",
1100 "location",
1101 "max",
1102 "merge",
1103 "min",
1104 "minute",
1105 "modify",
1106 "month",
1107 "name",
1108 "names",
1109 "negative",
1110 "nulls",
1111 "observer",
1112 "offset",
1113 "only",
1114 "open",
1115 "overwrite",
1116 "password",
1117 "path",
1118 "plan",
1119 "plugin",
1120 "plugins",
1121 "policy",
1122 "process",
1123 "properties",
1124 "property",
1125 "query",
1126 "quota",
1127 "recover",
1128 "refresh",
1129 "repair",
1130 "replica",
1131 "repository",
1132 "resource",
1133 "restore",
1134 "resume",
1135 "role",
1136 "roles",
1137 "rollback",
1138 "rollup",
1139 "routine",
1140 "sample",
1141 "second",
1142 "semi",
1143 "session",
1144 "signed",
1145 "snapshot",
1146 "start",
1147 "stats",
1148 "status",
1149 "stop",
1150 "stream",
1151 "string",
1152 "sum",
1153 "tables",
1154 "tablet",
1155 "temporary",
1156 "text",
1157 "timestamp",
1158 "transaction",
1159 "trash",
1160 "trim",
1161 "truncate",
1162 "type",
1163 "user",
1164 "value",
1165 "variables",
1166 "verbose",
1167 "version",
1168 "view",
1169 "warnings",
1170 "week",
1171 "work",
1172 "year",
1173 ]);
1174 set
1175 });
1176
1177 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1179 let mut set = SQL_RESERVED.clone();
1180 set.extend([
1181 "analyse",
1182 "analyze",
1183 "asymmetric",
1184 "binary",
1185 "collation",
1186 "concurrently",
1187 "current_catalog",
1188 "current_role",
1189 "current_schema",
1190 "deferrable",
1191 "do",
1192 "freeze",
1193 "ilike",
1194 "initially",
1195 "isnull",
1196 "lateral",
1197 "notnull",
1198 "placing",
1199 "returning",
1200 "similar",
1201 "symmetric",
1202 "variadic",
1203 "verbose",
1204 ]);
1205 set.remove("default");
1207 set.remove("interval");
1208 set.remove("match");
1209 set.remove("offset");
1210 set.remove("table");
1211 set
1212 });
1213
1214 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1218 [
1219 "aes128",
1220 "aes256",
1221 "all",
1222 "allowoverwrite",
1223 "analyse",
1224 "analyze",
1225 "and",
1226 "any",
1227 "array",
1228 "as",
1229 "asc",
1230 "authorization",
1231 "az64",
1232 "backup",
1233 "between",
1234 "binary",
1235 "blanksasnull",
1236 "both",
1237 "bytedict",
1238 "bzip2",
1239 "case",
1240 "cast",
1241 "check",
1242 "collate",
1243 "column",
1244 "constraint",
1245 "create",
1246 "credentials",
1247 "cross",
1248 "current_date",
1249 "current_time",
1250 "current_timestamp",
1251 "current_user",
1252 "current_user_id",
1253 "default",
1254 "deferrable",
1255 "deflate",
1256 "defrag",
1257 "delta",
1258 "delta32k",
1259 "desc",
1260 "disable",
1261 "distinct",
1262 "do",
1263 "else",
1264 "emptyasnull",
1265 "enable",
1266 "encode",
1267 "encrypt",
1268 "encryption",
1269 "end",
1270 "except",
1271 "explicit",
1272 "false",
1273 "for",
1274 "foreign",
1275 "freeze",
1276 "from",
1277 "full",
1278 "globaldict256",
1279 "globaldict64k",
1280 "grant",
1281 "group",
1282 "gzip",
1283 "having",
1284 "identity",
1285 "ignore",
1286 "ilike",
1287 "in",
1288 "initially",
1289 "inner",
1290 "intersect",
1291 "interval",
1292 "into",
1293 "is",
1294 "isnull",
1295 "join",
1296 "leading",
1297 "left",
1298 "like",
1299 "limit",
1300 "localtime",
1301 "localtimestamp",
1302 "lun",
1303 "luns",
1304 "lzo",
1305 "lzop",
1306 "minus",
1307 "mostly16",
1308 "mostly32",
1309 "mostly8",
1310 "natural",
1311 "new",
1312 "not",
1313 "notnull",
1314 "null",
1315 "nulls",
1316 "off",
1317 "offline",
1318 "offset",
1319 "oid",
1320 "old",
1321 "on",
1322 "only",
1323 "open",
1324 "or",
1325 "order",
1326 "outer",
1327 "overlaps",
1328 "parallel",
1329 "partition",
1330 "percent",
1331 "permissions",
1332 "pivot",
1333 "placing",
1334 "primary",
1335 "raw",
1336 "readratio",
1337 "recover",
1338 "references",
1339 "rejectlog",
1340 "resort",
1341 "respect",
1342 "restore",
1343 "right",
1344 "select",
1345 "session_user",
1346 "similar",
1347 "snapshot",
1348 "some",
1349 "sysdate",
1350 "system",
1351 "table",
1352 "tag",
1353 "tdes",
1354 "text255",
1355 "text32k",
1356 "then",
1357 "timestamp",
1358 "to",
1359 "top",
1360 "trailing",
1361 "true",
1362 "truncatecolumns",
1363 "type",
1364 "union",
1365 "unique",
1366 "unnest",
1367 "unpivot",
1368 "user",
1369 "using",
1370 "verbose",
1371 "wallet",
1372 "when",
1373 "where",
1374 "with",
1375 "without",
1376 ]
1377 .into_iter()
1378 .collect()
1379 });
1380
1381 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1383 let mut set = POSTGRES_RESERVED.clone();
1384 set.extend([
1385 "anti",
1386 "asof",
1387 "columns",
1388 "describe",
1389 "groups",
1390 "macro",
1391 "pivot",
1392 "pivot_longer",
1393 "pivot_wider",
1394 "qualify",
1395 "replace",
1396 "respect",
1397 "semi",
1398 "show",
1399 "table",
1400 "unpivot",
1401 ]);
1402 set.remove("at");
1403 set.remove("key");
1404 set.remove("range");
1405 set.remove("row");
1406 set.remove("values");
1407 set
1408 });
1409
1410 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1412 let mut set = SQL_RESERVED.clone();
1413 set.extend([
1414 "alter",
1415 "and",
1416 "as",
1417 "between",
1418 "by",
1419 "case",
1420 "cast",
1421 "constraint",
1422 "create",
1423 "cross",
1424 "cube",
1425 "current_catalog",
1426 "current_date",
1427 "current_path",
1428 "current_role",
1429 "current_schema",
1430 "current_time",
1431 "current_timestamp",
1432 "current_user",
1433 "deallocate",
1434 "delete",
1435 "describe",
1436 "distinct",
1437 "drop",
1438 "else",
1439 "end",
1440 "escape",
1441 "except",
1442 "execute",
1443 "exists",
1444 "extract",
1445 "false",
1446 "for",
1447 "from",
1448 "full",
1449 "group",
1450 "grouping",
1451 "having",
1452 "in",
1453 "inner",
1454 "insert",
1455 "intersect",
1456 "into",
1457 "is",
1458 "join",
1459 "json_array",
1460 "json_exists",
1461 "json_object",
1462 "json_query",
1463 "json_table",
1464 "json_value",
1465 "left",
1466 "like",
1467 "listagg",
1468 "localtime",
1469 "localtimestamp",
1470 "natural",
1471 "normalize",
1472 "not",
1473 "null",
1474 "on",
1475 "or",
1476 "order",
1477 "outer",
1478 "prepare",
1479 "recursive",
1480 "right",
1481 "rollup",
1482 "select",
1483 "skip",
1484 "table",
1485 "then",
1486 "trim",
1487 "true",
1488 "uescape",
1489 "union",
1490 "unnest",
1491 "using",
1492 "values",
1493 "when",
1494 "where",
1495 "with",
1496 ]);
1497 set.remove("key");
1499 set
1500 });
1501
1502 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1505 [
1506 "add",
1507 "all",
1508 "alter",
1509 "analyze",
1510 "and",
1511 "array",
1512 "as",
1513 "asc",
1514 "between",
1515 "bigint",
1516 "bitmap",
1517 "both",
1518 "by",
1519 "case",
1520 "char",
1521 "character",
1522 "check",
1523 "collate",
1524 "column",
1525 "compaction",
1526 "convert",
1527 "create",
1528 "cross",
1529 "cube",
1530 "current_date",
1531 "current_role",
1532 "current_time",
1533 "current_timestamp",
1534 "current_user",
1535 "database",
1536 "databases",
1537 "decimal",
1538 "decimalv2",
1539 "decimal32",
1540 "decimal64",
1541 "decimal128",
1542 "default",
1543 "deferred",
1544 "delete",
1545 "dense_rank",
1546 "desc",
1547 "describe",
1548 "distinct",
1549 "double",
1550 "drop",
1551 "dual",
1552 "else",
1553 "except",
1554 "exists",
1555 "explain",
1556 "false",
1557 "first_value",
1558 "float",
1559 "for",
1560 "force",
1561 "from",
1562 "full",
1563 "function",
1564 "grant",
1565 "group",
1566 "grouping",
1567 "grouping_id",
1568 "groups",
1569 "having",
1570 "hll",
1571 "host",
1572 "if",
1573 "ignore",
1574 "immediate",
1575 "in",
1576 "index",
1577 "infile",
1578 "inner",
1579 "insert",
1580 "int",
1581 "integer",
1582 "intersect",
1583 "into",
1584 "is",
1585 "join",
1586 "json",
1587 "key",
1588 "keys",
1589 "kill",
1590 "lag",
1591 "largeint",
1592 "last_value",
1593 "lateral",
1594 "lead",
1595 "left",
1596 "like",
1597 "limit",
1598 "load",
1599 "localtime",
1600 "localtimestamp",
1601 "maxvalue",
1602 "minus",
1603 "mod",
1604 "not",
1605 "ntile",
1606 "null",
1607 "on",
1608 "or",
1609 "order",
1610 "outer",
1611 "outfile",
1612 "over",
1613 "partition",
1614 "percentile",
1615 "primary",
1616 "procedure",
1617 "qualify",
1618 "range",
1619 "rank",
1620 "read",
1621 "regexp",
1622 "release",
1623 "rename",
1624 "replace",
1625 "revoke",
1626 "right",
1627 "rlike",
1628 "row",
1629 "row_number",
1630 "rows",
1631 "schema",
1632 "schemas",
1633 "select",
1634 "set",
1635 "set_var",
1636 "show",
1637 "smallint",
1638 "system",
1639 "table",
1640 "terminated",
1641 "text",
1642 "then",
1643 "tinyint",
1644 "to",
1645 "true",
1646 "union",
1647 "unique",
1648 "unsigned",
1649 "update",
1650 "use",
1651 "using",
1652 "values",
1653 "varchar",
1654 "when",
1655 "where",
1656 "with",
1657 ]
1658 .into_iter()
1659 .collect()
1660 });
1661
1662 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1665 let mut set = MYSQL_RESERVED.clone();
1666 set.extend([
1667 "abs",
1670 "account",
1671 "acos",
1672 "adddate",
1673 "addtime",
1674 "admin",
1675 "aes_decrypt",
1676 "aes_encrypt",
1677 "aggregate",
1678 "aggregates",
1679 "aggregator",
1680 "anti_join",
1681 "any_value",
1682 "approx_count_distinct",
1683 "approx_percentile",
1684 "arrange",
1685 "arrangement",
1686 "asin",
1687 "atan",
1688 "atan2",
1689 "attach",
1690 "autostats",
1691 "avro",
1692 "background",
1693 "backup",
1694 "batch",
1695 "batches",
1696 "boot_strapping",
1697 "ceil",
1698 "ceiling",
1699 "coercibility",
1700 "columnar",
1701 "columnstore",
1702 "compile",
1703 "concurrent",
1704 "connection_id",
1705 "cos",
1706 "cot",
1707 "current_security_groups",
1708 "current_security_roles",
1709 "dayname",
1710 "dayofmonth",
1711 "dayofweek",
1712 "dayofyear",
1713 "degrees",
1714 "dot_product",
1715 "dump",
1716 "durability",
1717 "earliest",
1718 "echo",
1719 "election",
1720 "euclidean_distance",
1721 "exp",
1722 "extractor",
1723 "extractors",
1724 "floor",
1725 "foreground",
1726 "found_rows",
1727 "from_base64",
1728 "from_days",
1729 "from_unixtime",
1730 "fs",
1731 "fulltext",
1732 "gc",
1733 "gcs",
1734 "geography",
1735 "geography_area",
1736 "geography_contains",
1737 "geography_distance",
1738 "geography_intersects",
1739 "geography_latitude",
1740 "geography_length",
1741 "geography_longitude",
1742 "geographypoint",
1743 "geography_point",
1744 "geography_within_distance",
1745 "geometry",
1746 "geometry_area",
1747 "geometry_contains",
1748 "geometry_distance",
1749 "geometry_filter",
1750 "geometry_intersects",
1751 "geometry_length",
1752 "geometrypoint",
1753 "geometry_point",
1754 "geometry_within_distance",
1755 "geometry_x",
1756 "geometry_y",
1757 "greatest",
1758 "groups",
1759 "group_concat",
1760 "gzip",
1761 "hdfs",
1762 "hex",
1763 "highlight",
1764 "ifnull",
1765 "ilike",
1766 "inet_aton",
1767 "inet_ntoa",
1768 "inet6_aton",
1769 "inet6_ntoa",
1770 "initcap",
1771 "instr",
1772 "interpreter_mode",
1773 "isnull",
1774 "json",
1775 "json_agg",
1776 "json_array_contains_double",
1777 "json_array_contains_json",
1778 "json_array_contains_string",
1779 "json_delete_key",
1780 "json_extract_double",
1781 "json_extract_json",
1782 "json_extract_string",
1783 "json_extract_bigint",
1784 "json_get_type",
1785 "json_length",
1786 "json_set_double",
1787 "json_set_json",
1788 "json_set_string",
1789 "kafka",
1790 "lag",
1791 "last_day",
1792 "last_insert_id",
1793 "latest",
1794 "lcase",
1795 "lead",
1796 "leaf",
1797 "least",
1798 "leaves",
1799 "length",
1800 "license",
1801 "links",
1802 "llvm",
1803 "ln",
1804 "load",
1805 "locate",
1806 "log",
1807 "log10",
1808 "log2",
1809 "lpad",
1810 "lz4",
1811 "management",
1812 "match",
1813 "mbc",
1814 "md5",
1815 "median",
1816 "memsql",
1817 "memsql_deserialize",
1818 "memsql_serialize",
1819 "metadata",
1820 "microsecond",
1821 "minute",
1822 "model",
1823 "monthname",
1824 "months_between",
1825 "mpl",
1826 "namespace",
1827 "node",
1828 "noparam",
1829 "now",
1830 "nth_value",
1831 "ntile",
1832 "nullcols",
1833 "nullif",
1834 "object",
1835 "octet_length",
1836 "offsets",
1837 "online",
1838 "optimizer",
1839 "orphan",
1840 "parquet",
1841 "partitions",
1842 "pause",
1843 "percentile_cont",
1844 "percentile_disc",
1845 "periodic",
1846 "persisted",
1847 "pi",
1848 "pipeline",
1849 "pipelines",
1850 "plancache",
1851 "plugins",
1852 "pool",
1853 "pools",
1854 "pow",
1855 "power",
1856 "process",
1857 "processlist",
1858 "profile",
1859 "profiles",
1860 "quarter",
1861 "queries",
1862 "query",
1863 "radians",
1864 "rand",
1865 "record",
1866 "reduce",
1867 "redundancy",
1868 "regexp_match",
1869 "regexp_substr",
1870 "remote",
1871 "replication",
1872 "resource",
1873 "resource_pool",
1874 "restore",
1875 "retry",
1876 "role",
1877 "roles",
1878 "round",
1879 "rpad",
1880 "rtrim",
1881 "running",
1882 "s3",
1883 "scalar",
1884 "sec_to_time",
1885 "second",
1886 "security_lists_intersect",
1887 "semi_join",
1888 "sha",
1889 "sha1",
1890 "sha2",
1891 "shard",
1892 "sharded",
1893 "sharded_id",
1894 "sigmoid",
1895 "sign",
1896 "sin",
1897 "skip",
1898 "sleep",
1899 "snapshot",
1900 "soname",
1901 "sparse",
1902 "spatial_check_index",
1903 "split",
1904 "sqrt",
1905 "standalone",
1906 "std",
1907 "stddev",
1908 "stddev_pop",
1909 "stddev_samp",
1910 "stop",
1911 "str_to_date",
1912 "subdate",
1913 "substr",
1914 "substring_index",
1915 "success",
1916 "synchronize",
1917 "table_checksum",
1918 "tan",
1919 "task",
1920 "timediff",
1921 "time_bucket",
1922 "time_format",
1923 "time_to_sec",
1924 "timestampadd",
1925 "timestampdiff",
1926 "to_base64",
1927 "to_char",
1928 "to_date",
1929 "to_days",
1930 "to_json",
1931 "to_number",
1932 "to_seconds",
1933 "to_timestamp",
1934 "tracelogs",
1935 "transform",
1936 "trim",
1937 "trunc",
1938 "truncate",
1939 "ucase",
1940 "unhex",
1941 "unix_timestamp",
1942 "utc_date",
1943 "utc_time",
1944 "utc_timestamp",
1945 "vacuum",
1946 "variance",
1947 "var_pop",
1948 "var_samp",
1949 "vector_sub",
1950 "voting",
1951 "week",
1952 "weekday",
1953 "weekofyear",
1954 "workload",
1955 "year",
1956 ]);
1957 set.remove("all");
1959 set
1960 });
1961
1962 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
1966 [
1968 "abort",
1969 "action",
1970 "add",
1971 "after",
1972 "all",
1973 "alter",
1974 "always",
1975 "analyze",
1976 "and",
1977 "as",
1978 "asc",
1979 "attach",
1980 "autoincrement",
1981 "before",
1982 "begin",
1983 "between",
1984 "by",
1985 "cascade",
1986 "case",
1987 "cast",
1988 "check",
1989 "collate",
1990 "column",
1991 "commit",
1992 "conflict",
1993 "constraint",
1994 "create",
1995 "cross",
1996 "current",
1997 "current_date",
1998 "current_time",
1999 "current_timestamp",
2000 "database",
2001 "default",
2002 "deferrable",
2003 "deferred",
2004 "delete",
2005 "desc",
2006 "detach",
2007 "distinct",
2008 "do",
2009 "drop",
2010 "each",
2011 "else",
2012 "end",
2013 "escape",
2014 "except",
2015 "exclude",
2016 "exclusive",
2017 "exists",
2018 "explain",
2019 "fail",
2020 "filter",
2021 "first",
2022 "following",
2023 "for",
2024 "foreign",
2025 "from",
2026 "full",
2027 "generated",
2028 "glob",
2029 "group",
2030 "groups",
2031 "having",
2032 "if",
2033 "ignore",
2034 "immediate",
2035 "in",
2036 "index",
2037 "indexed",
2038 "initially",
2039 "inner",
2040 "insert",
2041 "instead",
2042 "intersect",
2043 "into",
2044 "is",
2045 "isnull",
2046 "join",
2047 "key",
2048 "last",
2049 "left",
2050 "like",
2051 "limit",
2052 "natural",
2053 "no",
2054 "not",
2055 "nothing",
2056 "notnull",
2057 "null",
2058 "nulls",
2059 "of",
2060 "offset",
2061 "on",
2062 "or",
2063 "order",
2064 "others",
2065 "outer",
2066 "partition",
2067 "plan",
2068 "pragma",
2069 "preceding",
2070 "primary",
2071 "query",
2072 "raise",
2073 "range",
2074 "recursive",
2075 "references",
2076 "regexp",
2077 "reindex",
2078 "release",
2079 "rename",
2080 "replace",
2081 "restrict",
2082 "returning",
2083 "right",
2084 "rollback",
2085 "row",
2086 "rows",
2087 "savepoint",
2088 "select",
2089 "set",
2090 "table",
2091 "temp",
2092 "temporary",
2093 "then",
2094 "ties",
2095 "to",
2096 "transaction",
2097 "trigger",
2098 "unbounded",
2099 "union",
2100 "unique",
2101 "update",
2102 "using",
2103 "vacuum",
2104 "values",
2105 "view",
2106 "virtual",
2107 "when",
2108 "where",
2109 "window",
2110 "with",
2111 "without",
2112 ]
2113 .into_iter()
2114 .collect()
2115 });
2116}
2117
2118impl Generator {
2119 pub fn new() -> Self {
2125 Self::with_config(GeneratorConfig::default())
2126 }
2127
2128 pub fn with_config(config: GeneratorConfig) -> Self {
2133 Self::with_arc_config(Arc::new(config))
2134 }
2135
2136 pub(crate) fn with_arc_config(config: Arc<GeneratorConfig>) -> Self {
2141 Self {
2142 config,
2143 output: String::new(),
2144 unsupported_messages: Vec::new(),
2145 indent_level: 0,
2146 athena_hive_context: false,
2147 sqlite_inline_pk_columns: std::collections::HashSet::new(),
2148 merge_strip_qualifiers: Vec::new(),
2149 clickhouse_nullable_depth: 0,
2150 }
2151 }
2152
2153 fn add_column_aliases_to_query(expr: Expression) -> Expression {
2157 match expr {
2158 Expression::Select(mut select) => {
2159 select.expressions = select
2161 .expressions
2162 .into_iter()
2163 .map(|e| Self::add_alias_to_expression(e))
2164 .collect();
2165
2166 if let Some(ref mut from) = select.from {
2168 from.expressions = from
2169 .expressions
2170 .iter()
2171 .cloned()
2172 .map(|e| Self::add_column_aliases_to_query(e))
2173 .collect();
2174 }
2175
2176 Expression::Select(select)
2177 }
2178 Expression::Subquery(mut sq) => {
2179 sq.this = Self::add_column_aliases_to_query(sq.this);
2180 Expression::Subquery(sq)
2181 }
2182 Expression::Paren(mut p) => {
2183 p.this = Self::add_column_aliases_to_query(p.this);
2184 Expression::Paren(p)
2185 }
2186 other => other,
2188 }
2189 }
2190
2191 fn add_alias_to_expression(expr: Expression) -> Expression {
2194 use crate::expressions::Alias;
2195
2196 match &expr {
2197 Expression::Alias(_) => expr,
2199
2200 Expression::Column(col) => Expression::Alias(Box::new(Alias {
2202 this: expr.clone(),
2203 alias: col.name.clone(),
2204 column_aliases: Vec::new(),
2205 pre_alias_comments: Vec::new(),
2206 trailing_comments: Vec::new(),
2207 inferred_type: None,
2208 })),
2209
2210 Expression::Identifier(ident) => Expression::Alias(Box::new(Alias {
2212 this: expr.clone(),
2213 alias: ident.clone(),
2214 column_aliases: Vec::new(),
2215 pre_alias_comments: Vec::new(),
2216 trailing_comments: Vec::new(),
2217 inferred_type: None,
2218 })),
2219
2220 Expression::Subquery(sq) => {
2222 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
2223 if sq.alias.is_some() {
2225 processed
2226 } else {
2227 processed
2229 }
2230 }
2231
2232 Expression::Star(_) => expr,
2234
2235 _ => expr,
2238 }
2239 }
2240
2241 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
2245 match expr {
2246 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
2247 let Literal::Number(n) = lit.as_ref() else {
2248 unreachable!()
2249 };
2250 n.parse::<i64>().ok()
2251 }
2252 Expression::Add(op) => {
2253 let left = Self::try_evaluate_constant(&op.left)?;
2254 let right = Self::try_evaluate_constant(&op.right)?;
2255 Some(left + right)
2256 }
2257 Expression::Sub(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::Mul(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::Div(op) => {
2268 let left = Self::try_evaluate_constant(&op.left)?;
2269 let right = Self::try_evaluate_constant(&op.right)?;
2270 if right != 0 {
2271 Some(left / right)
2272 } else {
2273 None
2274 }
2275 }
2276 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
2277 _ => None,
2278 }
2279 }
2280
2281 fn is_reserved_keyword(&self, name: &str) -> bool {
2283 use crate::dialects::DialectType;
2284 let mut buf = [0u8; 128];
2285 let lower_ref: &str = if name.len() <= 128 {
2286 for (i, b) in name.bytes().enumerate() {
2287 buf[i] = b.to_ascii_lowercase();
2288 }
2289 std::str::from_utf8(&buf[..name.len()]).unwrap_or(name)
2291 } else {
2292 return false;
2293 };
2294
2295 match self.config.dialect {
2296 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
2297 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
2298 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
2299 }
2300 Some(DialectType::Doris) => reserved_keywords::DORIS_RESERVED.contains(lower_ref),
2301 Some(DialectType::SingleStore) => {
2302 reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref)
2303 }
2304 Some(DialectType::StarRocks) => {
2305 reserved_keywords::STARROCKS_RESERVED.contains(lower_ref)
2306 }
2307 Some(DialectType::PostgreSQL)
2308 | Some(DialectType::CockroachDB)
2309 | Some(DialectType::Materialize)
2310 | Some(DialectType::RisingWave) => {
2311 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
2312 }
2313 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
2314 Some(DialectType::Snowflake) => false,
2317 Some(DialectType::ClickHouse) => false,
2319 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
2320 Some(DialectType::Teradata) => false,
2322 Some(DialectType::TSQL)
2324 | Some(DialectType::Fabric)
2325 | Some(DialectType::Oracle)
2326 | Some(DialectType::Spark)
2327 | Some(DialectType::Databricks)
2328 | Some(DialectType::Hive)
2329 | Some(DialectType::Solr) => false,
2330 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
2331 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
2332 }
2333 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
2334 Some(DialectType::Generic) | None => false,
2336 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
2338 }
2339 }
2340
2341 fn normalize_func_name<'a>(&self, name: &'a str) -> Cow<'a, str> {
2343 match self.config.normalize_functions {
2344 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
2345 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
2346 NormalizeFunctions::None => Cow::Borrowed(name),
2347 }
2348 }
2349
2350 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
2359 self.output.clear();
2360 self.unsupported_messages.clear();
2361 self.generate_expression(expr)?;
2362 if self.config.unsupported_level == UnsupportedLevel::Raise
2363 && !self.unsupported_messages.is_empty()
2364 {
2365 return Err(crate::error::Error::generate(
2366 self.format_unsupported_messages(),
2367 ));
2368 }
2369 Ok(std::mem::take(&mut self.output))
2370 }
2371
2372 pub fn unsupported_messages(&self) -> &[String] {
2374 &self.unsupported_messages
2375 }
2376
2377 fn unsupported(&mut self, message: impl Into<String>) -> Result<()> {
2378 let message = message.into();
2379 if self.config.unsupported_level == UnsupportedLevel::Immediate {
2380 return Err(crate::error::Error::generate(message));
2381 }
2382 self.unsupported_messages.push(message);
2383 Ok(())
2384 }
2385
2386 fn write_unsupported_comment(&mut self, message: &str) -> Result<()> {
2387 self.unsupported(message.to_string())?;
2388 self.write("/* ");
2389 self.write(message);
2390 self.write(" */");
2391 Ok(())
2392 }
2393
2394 fn format_unsupported_messages(&self) -> String {
2395 let limit = self.config.max_unsupported.max(1);
2396 if self.unsupported_messages.len() <= limit {
2397 return self.unsupported_messages.join("; ");
2398 }
2399
2400 let mut messages = self
2401 .unsupported_messages
2402 .iter()
2403 .take(limit)
2404 .cloned()
2405 .collect::<Vec<_>>();
2406 messages.push(format!(
2407 "... and {} more",
2408 self.unsupported_messages.len() - limit
2409 ));
2410 messages.join("; ")
2411 }
2412
2413 pub fn sql(expr: &Expression) -> Result<String> {
2419 let mut gen = Generator::new();
2420 gen.generate(expr)
2421 }
2422
2423 pub fn pretty_sql(expr: &Expression) -> Result<String> {
2428 let config = GeneratorConfig {
2429 pretty: true,
2430 ..Default::default()
2431 };
2432 let mut gen = Generator::with_config(config);
2433 let mut sql = gen.generate(expr)?;
2434 if !sql.ends_with(';') {
2436 sql.push(';');
2437 }
2438 Ok(sql)
2439 }
2440
2441 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
2442 match expr {
2443 Expression::Select(select) => self.generate_select(select),
2444 Expression::Union(union) => self.generate_union(union),
2445 Expression::Intersect(intersect) => self.generate_intersect(intersect),
2446 Expression::Except(except) => self.generate_except(except),
2447 Expression::Insert(insert) => self.generate_insert(insert),
2448 Expression::Update(update) => self.generate_update(update),
2449 Expression::Delete(delete) => self.generate_delete(delete),
2450 Expression::Literal(lit) => self.generate_literal(lit),
2451 Expression::Boolean(b) => self.generate_boolean(b),
2452 Expression::Null(_) => {
2453 self.write_keyword("NULL");
2454 Ok(())
2455 }
2456 Expression::Identifier(id) => self.generate_identifier(id),
2457 Expression::Column(col) => self.generate_column(col),
2458 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
2459 Expression::Connect(c) => self.generate_connect_expr(c),
2460 Expression::Prior(p) => self.generate_prior(p),
2461 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
2462 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
2463 Expression::Table(table) => self.generate_table(table),
2464 Expression::StageReference(sr) => self.generate_stage_reference(sr),
2465 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
2466 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
2467 Expression::Star(star) => self.generate_star(star),
2468 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
2469 Expression::Alias(alias) => self.generate_alias(alias),
2470 Expression::Cast(cast) => self.generate_cast(cast),
2471 Expression::Collation(coll) => self.generate_collation(coll),
2472 Expression::Case(case) => self.generate_case(case),
2473 Expression::Function(func) => self.generate_function(func),
2474 Expression::FunctionEmits(fe) => self.generate_function_emits(fe),
2475 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
2476 Expression::WindowFunction(wf) => self.generate_window_function(wf),
2477 Expression::WithinGroup(wg) => self.generate_within_group(wg),
2478 Expression::Interval(interval) => self.generate_interval(interval),
2479
2480 Expression::ConcatWs(f) => self.generate_concat_ws(f),
2482 Expression::Substring(f) => self.generate_substring(f),
2483 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
2484 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
2485 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
2486 Expression::Trim(f) => self.generate_trim(f),
2487 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
2488 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
2489 Expression::Replace(f) => self.generate_replace(f),
2490 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
2491 Expression::Left(f) => self.generate_left_right("LEFT", f),
2492 Expression::Right(f) => self.generate_left_right("RIGHT", f),
2493 Expression::Repeat(f) => self.generate_repeat(f),
2494 Expression::Lpad(f) => self.generate_pad("LPAD", f),
2495 Expression::Rpad(f) => self.generate_pad("RPAD", f),
2496 Expression::Split(f) => self.generate_split(f),
2497 Expression::RegexpLike(f) => self.generate_regexp_like(f),
2498 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
2499 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
2500 Expression::Overlay(f) => self.generate_overlay(f),
2501
2502 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
2504 Expression::Round(f) => self.generate_round(f),
2505 Expression::Floor(f) => self.generate_floor(f),
2506 Expression::Ceil(f) => self.generate_ceil(f),
2507 Expression::Power(f) => self.generate_power(f),
2508 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
2509 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
2510 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
2511 Expression::Log(f) => self.generate_log(f),
2512 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
2513 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
2514 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
2515 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
2516
2517 Expression::CurrentDate(_) => {
2519 self.write_keyword("CURRENT_DATE");
2520 Ok(())
2521 }
2522 Expression::CurrentTime(f) => self.generate_current_time(f),
2523 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
2524 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
2525 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
2526 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
2527 Expression::DateDiff(f) => self.generate_datediff(f),
2528 Expression::DateTrunc(f) => self.generate_date_trunc(f),
2529 Expression::Extract(f) => self.generate_extract(f),
2530 Expression::ToDate(f) => self.generate_to_date(f),
2531 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
2532
2533 Expression::Coalesce(f) => {
2535 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
2537 self.generate_vararg_func(func_name, &f.expressions)
2538 }
2539 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
2540 Expression::IfFunc(f) => self.generate_if_func(f),
2541 Expression::IfNull(f) => self.generate_ifnull(f),
2542 Expression::Nvl(f) => self.generate_nvl(f),
2543 Expression::Nvl2(f) => self.generate_nvl2(f),
2544
2545 Expression::TryCast(cast) => self.generate_try_cast(cast),
2547 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
2548
2549 Expression::Count(f) => self.generate_count(f),
2551 Expression::Sum(f) => self.generate_agg_func("SUM", f),
2552 Expression::Avg(f) => self.generate_agg_func("AVG", f),
2553 Expression::Min(f) => self.generate_agg_func("MIN", f),
2554 Expression::Max(f) => self.generate_agg_func("MAX", f),
2555 Expression::GroupConcat(f) => self.generate_group_concat(f),
2556 Expression::StringAgg(f) => self.generate_string_agg(f),
2557 Expression::ListAgg(f) => self.generate_listagg(f),
2558 Expression::ArrayAgg(f) => {
2559 let override_name = f
2562 .name
2563 .as_ref()
2564 .filter(|n| !n.eq_ignore_ascii_case("ARRAY_AGG"))
2565 .map(|n| n.to_ascii_uppercase());
2566 match override_name {
2567 Some(name) => self.generate_agg_func(&name, f),
2568 None => self.generate_agg_func("ARRAY_AGG", f),
2569 }
2570 }
2571 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
2572 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
2573 Expression::SumIf(f) => self.generate_sum_if(f),
2574 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
2575 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
2576 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
2577 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
2578 Expression::VarPop(f) => {
2579 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
2580 "VARIANCE_POP"
2581 } else {
2582 "VAR_POP"
2583 };
2584 self.generate_agg_func(name, f)
2585 }
2586 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
2587 Expression::Skewness(f) => {
2588 let name = match self.config.dialect {
2589 Some(DialectType::Snowflake) => "SKEW",
2590 _ => "SKEWNESS",
2591 };
2592 self.generate_agg_func(name, f)
2593 }
2594 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
2595 Expression::Mode(f) => self.generate_agg_func("MODE", f),
2596 Expression::First(f) => self.generate_agg_func_with_ignore_nulls_bool("FIRST", f),
2597 Expression::Last(f) => self.generate_agg_func_with_ignore_nulls_bool("LAST", f),
2598 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
2599 Expression::ApproxDistinct(f) => {
2600 match self.config.dialect {
2601 Some(DialectType::Hive)
2602 | Some(DialectType::Spark)
2603 | Some(DialectType::Databricks)
2604 | Some(DialectType::BigQuery) => {
2605 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2607 }
2608 Some(DialectType::Redshift) => {
2609 self.write_keyword("APPROXIMATE COUNT");
2611 self.write("(");
2612 self.write_keyword("DISTINCT");
2613 self.write(" ");
2614 self.generate_expression(&f.this)?;
2615 self.write(")");
2616 Ok(())
2617 }
2618 _ => self.generate_agg_func("APPROX_DISTINCT", f),
2619 }
2620 }
2621 Expression::ApproxCountDistinct(f) => {
2622 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
2623 }
2624 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
2625 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
2626 Expression::LogicalAnd(f) => {
2627 let name = match self.config.dialect {
2628 Some(DialectType::Snowflake) => "BOOLAND_AGG",
2629 Some(DialectType::Spark)
2630 | Some(DialectType::Databricks)
2631 | Some(DialectType::PostgreSQL)
2632 | Some(DialectType::DuckDB)
2633 | Some(DialectType::Redshift) => "BOOL_AND",
2634 Some(DialectType::Oracle)
2635 | Some(DialectType::SQLite)
2636 | Some(DialectType::MySQL) => "MIN",
2637 _ => "BOOL_AND",
2638 };
2639 self.generate_agg_func(name, f)
2640 }
2641 Expression::LogicalOr(f) => {
2642 let name = match self.config.dialect {
2643 Some(DialectType::Snowflake) => "BOOLOR_AGG",
2644 Some(DialectType::Spark)
2645 | Some(DialectType::Databricks)
2646 | Some(DialectType::PostgreSQL)
2647 | Some(DialectType::DuckDB)
2648 | Some(DialectType::Redshift) => "BOOL_OR",
2649 Some(DialectType::Oracle)
2650 | Some(DialectType::SQLite)
2651 | Some(DialectType::MySQL) => "MAX",
2652 _ => "BOOL_OR",
2653 };
2654 self.generate_agg_func(name, f)
2655 }
2656
2657 Expression::RowNumber(_) => {
2659 if self.config.dialect == Some(DialectType::ClickHouse) {
2660 self.write("row_number");
2661 } else {
2662 self.write_keyword("ROW_NUMBER");
2663 }
2664 self.write("()");
2665 Ok(())
2666 }
2667 Expression::Rank(r) => {
2668 self.write_keyword("RANK");
2669 self.write("(");
2670 if !r.args.is_empty() {
2672 for (i, arg) in r.args.iter().enumerate() {
2673 if i > 0 {
2674 self.write(", ");
2675 }
2676 self.generate_expression(arg)?;
2677 }
2678 } else if let Some(order_by) = &r.order_by {
2679 self.write_keyword(" ORDER BY ");
2681 for (i, ob) in order_by.iter().enumerate() {
2682 if i > 0 {
2683 self.write(", ");
2684 }
2685 self.generate_ordered(ob)?;
2686 }
2687 }
2688 self.write(")");
2689 Ok(())
2690 }
2691 Expression::DenseRank(dr) => {
2692 self.write_keyword("DENSE_RANK");
2693 self.write("(");
2694 for (i, arg) in dr.args.iter().enumerate() {
2696 if i > 0 {
2697 self.write(", ");
2698 }
2699 self.generate_expression(arg)?;
2700 }
2701 self.write(")");
2702 Ok(())
2703 }
2704 Expression::NTile(f) => self.generate_ntile(f),
2705 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
2706 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
2707 Expression::FirstValue(f) => {
2708 self.generate_value_func_with_ignore_nulls_bool("FIRST_VALUE", f)
2709 }
2710 Expression::LastValue(f) => {
2711 self.generate_value_func_with_ignore_nulls_bool("LAST_VALUE", f)
2712 }
2713 Expression::NthValue(f) => self.generate_nth_value(f),
2714 Expression::PercentRank(pr) => {
2715 self.write_keyword("PERCENT_RANK");
2716 self.write("(");
2717 if !pr.args.is_empty() {
2719 for (i, arg) in pr.args.iter().enumerate() {
2720 if i > 0 {
2721 self.write(", ");
2722 }
2723 self.generate_expression(arg)?;
2724 }
2725 } else if let Some(order_by) = &pr.order_by {
2726 self.write_keyword(" ORDER BY ");
2728 for (i, ob) in order_by.iter().enumerate() {
2729 if i > 0 {
2730 self.write(", ");
2731 }
2732 self.generate_ordered(ob)?;
2733 }
2734 }
2735 self.write(")");
2736 Ok(())
2737 }
2738 Expression::CumeDist(cd) => {
2739 self.write_keyword("CUME_DIST");
2740 self.write("(");
2741 if !cd.args.is_empty() {
2743 for (i, arg) in cd.args.iter().enumerate() {
2744 if i > 0 {
2745 self.write(", ");
2746 }
2747 self.generate_expression(arg)?;
2748 }
2749 } else if let Some(order_by) = &cd.order_by {
2750 self.write_keyword(" ORDER BY ");
2752 for (i, ob) in order_by.iter().enumerate() {
2753 if i > 0 {
2754 self.write(", ");
2755 }
2756 self.generate_ordered(ob)?;
2757 }
2758 }
2759 self.write(")");
2760 Ok(())
2761 }
2762 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
2763 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
2764
2765 Expression::Contains(f) => {
2767 self.generate_binary_func("CONTAINS", &f.this, &f.expression)
2768 }
2769 Expression::StartsWith(f) => {
2770 let name = match self.config.dialect {
2771 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
2772 _ => "STARTS_WITH",
2773 };
2774 self.generate_binary_func(name, &f.this, &f.expression)
2775 }
2776 Expression::EndsWith(f) => {
2777 let name = match self.config.dialect {
2778 Some(DialectType::Snowflake) => "ENDSWITH",
2779 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
2780 Some(DialectType::ClickHouse) => "endsWith",
2781 _ => "ENDS_WITH",
2782 };
2783 self.generate_binary_func(name, &f.this, &f.expression)
2784 }
2785 Expression::Position(f) => self.generate_position(f),
2786 Expression::Initcap(f) => match self.config.dialect {
2787 Some(DialectType::Presto)
2788 | Some(DialectType::Trino)
2789 | Some(DialectType::Athena) => {
2790 self.write_keyword("REGEXP_REPLACE");
2791 self.write("(");
2792 self.generate_expression(&f.this)?;
2793 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
2794 Ok(())
2795 }
2796 _ => self.generate_simple_func("INITCAP", &f.this),
2797 },
2798 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
2799 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
2800 Expression::CharFunc(f) => self.generate_char_func(f),
2801 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
2802 Expression::Levenshtein(f) => {
2803 self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression)
2804 }
2805
2806 Expression::ModFunc(f) => self.generate_mod_func(f),
2808 Expression::Random(_) => {
2809 self.write_keyword("RANDOM");
2810 self.write("()");
2811 Ok(())
2812 }
2813 Expression::Rand(f) => self.generate_rand(f),
2814 Expression::TruncFunc(f) => self.generate_truncate_func(f),
2815 Expression::Pi(_) => {
2816 self.write_keyword("PI");
2817 self.write("()");
2818 Ok(())
2819 }
2820 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
2821 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
2822 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
2823 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
2824 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
2825 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
2826 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
2827 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
2828 Expression::Atan2(f) => {
2829 let name = f.original_name.as_deref().unwrap_or("ATAN2");
2830 self.generate_binary_func(name, &f.this, &f.expression)
2831 }
2832
2833 Expression::Decode(f) => self.generate_decode(f),
2835
2836 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
2838 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
2839 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
2840 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
2841 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
2842 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
2843 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
2844 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
2845 Expression::DayOfWeek(f) => {
2846 let name = match self.config.dialect {
2847 Some(DialectType::Presto)
2848 | Some(DialectType::Trino)
2849 | Some(DialectType::Athena) => "DAY_OF_WEEK",
2850 Some(DialectType::DuckDB) => "ISODOW",
2851 _ => "DAYOFWEEK",
2852 };
2853 self.generate_simple_func(name, &f.this)
2854 }
2855 Expression::DayOfMonth(f) => {
2856 let name = match self.config.dialect {
2857 Some(DialectType::Presto)
2858 | Some(DialectType::Trino)
2859 | Some(DialectType::Athena) => "DAY_OF_MONTH",
2860 _ => "DAYOFMONTH",
2861 };
2862 self.generate_simple_func(name, &f.this)
2863 }
2864 Expression::DayOfYear(f) => {
2865 let name = match self.config.dialect {
2866 Some(DialectType::Presto)
2867 | Some(DialectType::Trino)
2868 | Some(DialectType::Athena) => "DAY_OF_YEAR",
2869 _ => "DAYOFYEAR",
2870 };
2871 self.generate_simple_func(name, &f.this)
2872 }
2873 Expression::WeekOfYear(f) => {
2874 let name = match self.config.dialect {
2876 Some(DialectType::Hive)
2877 | Some(DialectType::DuckDB)
2878 | Some(DialectType::Spark)
2879 | Some(DialectType::Databricks)
2880 | Some(DialectType::MySQL) => "WEEKOFYEAR",
2881 _ => "WEEK_OF_YEAR",
2882 };
2883 self.generate_simple_func(name, &f.this)
2884 }
2885 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
2886 Expression::AddMonths(f) => {
2887 self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression)
2888 }
2889 Expression::MonthsBetween(f) => {
2890 self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression)
2891 }
2892 Expression::LastDay(f) => self.generate_last_day(f),
2893 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
2894 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
2895 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
2896 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
2897 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
2898 Expression::MakeDate(f) => self.generate_make_date(f),
2899 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
2900 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
2901
2902 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
2904 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
2905 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
2906 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
2907 Expression::ArrayContains(f) => {
2908 self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression)
2909 }
2910 Expression::ArrayPosition(f) => {
2911 self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression)
2912 }
2913 Expression::ArrayAppend(f) => {
2914 self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression)
2915 }
2916 Expression::ArrayPrepend(f) => {
2917 self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression)
2918 }
2919 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
2920 Expression::ArraySort(f) => self.generate_array_sort(f),
2921 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
2922 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
2923 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
2924 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
2925 Expression::Unnest(f) => self.generate_unnest(f),
2926 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
2927 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
2928 Expression::ArrayFilter(f) => self.generate_array_filter(f),
2929 Expression::ArrayTransform(f) => self.generate_array_transform(f),
2930 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
2931 Expression::ArrayCompact(f) => {
2932 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
2933 self.write("LIST_FILTER(");
2935 self.generate_expression(&f.this)?;
2936 self.write(", _u -> NOT _u IS NULL)");
2937 Ok(())
2938 } else {
2939 self.generate_simple_func("ARRAY_COMPACT", &f.this)
2940 }
2941 }
2942 Expression::ArrayIntersect(f) => {
2943 let func_name = f.original_name.as_deref().unwrap_or("ARRAY_INTERSECT");
2944 self.generate_vararg_func(func_name, &f.expressions)
2945 }
2946 Expression::ArrayUnion(f) => {
2947 self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression)
2948 }
2949 Expression::ArrayExcept(f) => {
2950 self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression)
2951 }
2952 Expression::ArrayRemove(f) => {
2953 self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression)
2954 }
2955 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
2956 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
2957 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
2958
2959 Expression::StructFunc(f) => self.generate_struct_constructor(f),
2961 Expression::StructExtract(f) => self.generate_struct_extract(f),
2962 Expression::NamedStruct(f) => self.generate_named_struct(f),
2963
2964 Expression::MapFunc(f) => self.generate_map_constructor(f),
2966 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
2967 Expression::MapFromArrays(f) => {
2968 self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression)
2969 }
2970 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
2971 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
2972 Expression::MapContainsKey(f) => {
2973 self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression)
2974 }
2975 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
2976 Expression::ElementAt(f) => {
2977 self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression)
2978 }
2979 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
2980 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
2981
2982 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
2984 Expression::JsonExtractScalar(f) => {
2985 self.generate_json_extract("JSON_EXTRACT_SCALAR", f)
2986 }
2987 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
2988 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
2989 Expression::JsonObject(f) => self.generate_json_object(f),
2990 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
2991 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
2992 Expression::JsonArrayLength(f) => {
2993 self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this)
2994 }
2995 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
2996 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
2997 Expression::ParseJson(f) => {
2998 let name = match self.config.dialect {
2999 Some(DialectType::Presto)
3000 | Some(DialectType::Trino)
3001 | Some(DialectType::Athena) => "JSON_PARSE",
3002 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
3003 self.write_keyword("CAST");
3005 self.write("(");
3006 self.generate_expression(&f.this)?;
3007 self.write_keyword(" AS ");
3008 self.write_keyword("JSON");
3009 self.write(")");
3010 return Ok(());
3011 }
3012 Some(DialectType::Hive)
3013 | Some(DialectType::Spark)
3014 | Some(DialectType::MySQL)
3015 | Some(DialectType::SingleStore)
3016 | Some(DialectType::TiDB)
3017 | Some(DialectType::TSQL) => {
3018 self.generate_expression(&f.this)?;
3020 return Ok(());
3021 }
3022 Some(DialectType::DuckDB) => "JSON",
3023 _ => "PARSE_JSON",
3024 };
3025 self.generate_simple_func(name, &f.this)
3026 }
3027 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
3028 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
3029 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
3030 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
3031 Expression::JsonMergePatch(f) => {
3032 self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression)
3033 }
3034 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
3035 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
3036
3037 Expression::Convert(f) => self.generate_convert(f),
3039 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
3040
3041 Expression::Lambda(f) => self.generate_lambda(f),
3043 Expression::Parameter(f) => self.generate_parameter(f),
3044 Expression::Placeholder(f) => self.generate_placeholder(f),
3045 Expression::NamedArgument(f) => self.generate_named_argument(f),
3046 Expression::TableArgument(f) => self.generate_table_argument(f),
3047 Expression::SqlComment(f) => self.generate_sql_comment(f),
3048
3049 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
3051 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
3052 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
3053 Expression::SimilarTo(f) => self.generate_similar_to(f),
3054 Expression::Any(f) => self.generate_quantified("ANY", f),
3055 Expression::All(f) => self.generate_quantified("ALL", f),
3056 Expression::Overlaps(f) => self.generate_overlaps(f),
3057
3058 Expression::BitwiseLeftShift(op) => {
3060 if matches!(
3061 self.config.dialect,
3062 Some(DialectType::Presto) | Some(DialectType::Trino)
3063 ) {
3064 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
3065 self.write("(");
3066 self.generate_expression(&op.left)?;
3067 self.write(", ");
3068 self.generate_expression(&op.right)?;
3069 self.write(")");
3070 Ok(())
3071 } else if matches!(
3072 self.config.dialect,
3073 Some(DialectType::Spark) | Some(DialectType::Databricks)
3074 ) {
3075 self.write_keyword("SHIFTLEFT");
3076 self.write("(");
3077 self.generate_expression(&op.left)?;
3078 self.write(", ");
3079 self.generate_expression(&op.right)?;
3080 self.write(")");
3081 Ok(())
3082 } else {
3083 self.generate_binary_op(op, "<<")
3084 }
3085 }
3086 Expression::BitwiseRightShift(op) => {
3087 if matches!(
3088 self.config.dialect,
3089 Some(DialectType::Presto) | Some(DialectType::Trino)
3090 ) {
3091 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
3092 self.write("(");
3093 self.generate_expression(&op.left)?;
3094 self.write(", ");
3095 self.generate_expression(&op.right)?;
3096 self.write(")");
3097 Ok(())
3098 } else if matches!(
3099 self.config.dialect,
3100 Some(DialectType::Spark) | Some(DialectType::Databricks)
3101 ) {
3102 self.write_keyword("SHIFTRIGHT");
3103 self.write("(");
3104 self.generate_expression(&op.left)?;
3105 self.write(", ");
3106 self.generate_expression(&op.right)?;
3107 self.write(")");
3108 Ok(())
3109 } else {
3110 self.generate_binary_op(op, ">>")
3111 }
3112 }
3113 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
3114 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
3115 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
3116
3117 Expression::Subscript(s) => self.generate_subscript(s),
3119 Expression::Dot(d) => self.generate_dot_access(d),
3120 Expression::MethodCall(m) => self.generate_method_call(m),
3121 Expression::ArraySlice(s) => self.generate_array_slice(s),
3122
3123 Expression::And(op) => self.generate_connector_op(op, ConnectorOperator::And),
3124 Expression::Or(op) => self.generate_connector_op(op, ConnectorOperator::Or),
3125 Expression::Add(op) => self.generate_binary_op(op, "+"),
3126 Expression::Sub(op) => self.generate_binary_op(op, "-"),
3127 Expression::Mul(op) => self.generate_binary_op(op, "*"),
3128 Expression::Div(op) => self.generate_binary_op(op, "/"),
3129 Expression::IntDiv(f) => {
3130 use crate::dialects::DialectType;
3131 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
3132 self.generate_expression(&f.this)?;
3134 self.write(" // ");
3135 self.generate_expression(&f.expression)?;
3136 Ok(())
3137 } else if matches!(
3138 self.config.dialect,
3139 Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)
3140 ) {
3141 self.generate_expression(&f.this)?;
3143 self.write(" ");
3144 self.write_keyword("DIV");
3145 self.write(" ");
3146 self.generate_expression(&f.expression)?;
3147 Ok(())
3148 } else {
3149 self.write_keyword("DIV");
3151 self.write("(");
3152 self.generate_expression(&f.this)?;
3153 self.write(", ");
3154 self.generate_expression(&f.expression)?;
3155 self.write(")");
3156 Ok(())
3157 }
3158 }
3159 Expression::Mod(op) => {
3160 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
3161 self.generate_binary_op(op, "MOD")
3162 } else {
3163 self.generate_binary_op(op, "%")
3164 }
3165 }
3166 Expression::Eq(op) => self.generate_binary_op(op, "="),
3167 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
3168 Expression::Lt(op) => self.generate_binary_op(op, "<"),
3169 Expression::Lte(op) => self.generate_binary_op(op, "<="),
3170 Expression::Gt(op) => self.generate_binary_op(op, ">"),
3171 Expression::Gte(op) => self.generate_binary_op(op, ">="),
3172 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
3173 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
3174 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
3175 Expression::Concat(op) => {
3176 if self.config.dialect == Some(DialectType::Solr) {
3178 self.generate_binary_op(op, "OR")
3179 } else if self.config.dialect == Some(DialectType::MySQL) {
3180 self.generate_mysql_concat_from_concat(op)
3181 } else {
3182 self.generate_binary_op(op, "||")
3183 }
3184 }
3185 Expression::BitwiseAnd(op) => {
3186 if matches!(
3188 self.config.dialect,
3189 Some(DialectType::Presto) | Some(DialectType::Trino)
3190 ) {
3191 self.write_keyword("BITWISE_AND");
3192 self.write("(");
3193 self.generate_expression(&op.left)?;
3194 self.write(", ");
3195 self.generate_expression(&op.right)?;
3196 self.write(")");
3197 Ok(())
3198 } else {
3199 self.generate_binary_op(op, "&")
3200 }
3201 }
3202 Expression::BitwiseOr(op) => {
3203 if matches!(
3205 self.config.dialect,
3206 Some(DialectType::Presto) | Some(DialectType::Trino)
3207 ) {
3208 self.write_keyword("BITWISE_OR");
3209 self.write("(");
3210 self.generate_expression(&op.left)?;
3211 self.write(", ");
3212 self.generate_expression(&op.right)?;
3213 self.write(")");
3214 Ok(())
3215 } else {
3216 self.generate_binary_op(op, "|")
3217 }
3218 }
3219 Expression::BitwiseXor(op) => {
3220 if matches!(
3222 self.config.dialect,
3223 Some(DialectType::Presto) | Some(DialectType::Trino)
3224 ) {
3225 self.write_keyword("BITWISE_XOR");
3226 self.write("(");
3227 self.generate_expression(&op.left)?;
3228 self.write(", ");
3229 self.generate_expression(&op.right)?;
3230 self.write(")");
3231 Ok(())
3232 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
3233 self.generate_binary_op(op, "#")
3234 } else {
3235 self.generate_binary_op(op, "^")
3236 }
3237 }
3238 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
3239 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
3240 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
3241 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
3242 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
3243 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
3244 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
3245 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
3246 Expression::JSONBContains(f) => {
3247 self.generate_expression(&f.this)?;
3249 self.write_space();
3250 self.write("?");
3251 self.write_space();
3252 self.generate_expression(&f.expression)
3253 }
3254 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
3255 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
3256 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
3257 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
3258 Expression::Neg(op) => self.generate_unary_op(op, "-"),
3259 Expression::BitwiseNot(op) => {
3260 if matches!(
3262 self.config.dialect,
3263 Some(DialectType::Presto) | Some(DialectType::Trino)
3264 ) {
3265 self.write_keyword("BITWISE_NOT");
3266 self.write("(");
3267 self.generate_expression(&op.this)?;
3268 self.write(")");
3269 Ok(())
3270 } else {
3271 self.generate_unary_op(op, "~")
3272 }
3273 }
3274 Expression::In(in_expr) => self.generate_in(in_expr),
3275 Expression::Between(between) => self.generate_between(between),
3276 Expression::IsNull(is_null) => self.generate_is_null(is_null),
3277 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
3278 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
3279 Expression::IsJson(is_json) => self.generate_is_json(is_json),
3280 Expression::Is(is_expr) => self.generate_is(is_expr),
3281 Expression::Exists(exists) => self.generate_exists(exists),
3282 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
3283 Expression::Subquery(subquery) => self.generate_subquery(subquery),
3284 Expression::Paren(paren) => {
3285 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
3287
3288 if !skip_parens {
3289 self.write("(");
3290 if self.config.pretty {
3291 self.write_newline();
3292 self.indent_level += 1;
3293 self.write_indent();
3294 }
3295 }
3296 self.generate_expression(&paren.this)?;
3297 if !skip_parens {
3298 if self.config.pretty {
3299 self.write_newline();
3300 self.indent_level -= 1;
3301 self.write_indent();
3302 }
3303 self.write(")");
3304 }
3305 for comment in &paren.trailing_comments {
3307 self.write(" ");
3308 self.write_formatted_comment(comment);
3309 }
3310 Ok(())
3311 }
3312 Expression::Array(arr) => self.generate_array(arr),
3313 Expression::Tuple(tuple) => self.generate_tuple(tuple),
3314 Expression::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
3315 Expression::Ordered(ordered) => self.generate_ordered(ordered),
3316 Expression::DataType(dt) => self.generate_data_type(dt),
3317 Expression::Raw(raw) => {
3318 self.write(&raw.sql);
3319 Ok(())
3320 }
3321 Expression::CreateTask(task) => self.generate_create_task(task),
3322 Expression::Command(cmd) => {
3323 self.write(&cmd.this);
3324 Ok(())
3325 }
3326 Expression::Kill(kill) => {
3327 self.write_keyword("KILL");
3328 if let Some(kind) = &kill.kind {
3329 self.write_space();
3330 self.write_keyword(kind);
3331 }
3332 self.write_space();
3333 self.generate_expression(&kill.this)?;
3334 Ok(())
3335 }
3336 Expression::Execute(exec) => {
3337 self.write_keyword("EXECUTE");
3338 self.write_space();
3339 self.generate_expression(&exec.this)?;
3340 for (i, param) in exec.parameters.iter().enumerate() {
3341 if i == 0 {
3342 self.write_space();
3343 } else {
3344 self.write(", ");
3345 }
3346 self.write(¶m.name);
3347 if !param.positional {
3349 self.write(" = ");
3350 self.generate_expression(¶m.value)?;
3351 }
3352 if param.output {
3353 self.write_space();
3354 self.write_keyword("OUTPUT");
3355 }
3356 }
3357 if let Some(ref suffix) = exec.suffix {
3358 self.write_space();
3359 self.write(suffix);
3360 }
3361 Ok(())
3362 }
3363 Expression::Annotated(annotated) => {
3364 self.generate_expression(&annotated.this)?;
3365 for comment in &annotated.trailing_comments {
3366 self.write(" ");
3367 self.write_formatted_comment(comment);
3368 }
3369 Ok(())
3370 }
3371
3372 Expression::CreateTable(ct) => self.generate_create_table(ct),
3374 Expression::DropTable(dt) => self.generate_drop_table(dt),
3375 Expression::AlterTable(at) => self.generate_alter_table(at),
3376 Expression::CreateIndex(ci) => self.generate_create_index(ci),
3377 Expression::DropIndex(di) => self.generate_drop_index(di),
3378 Expression::CreateView(cv) => self.generate_create_view(cv),
3379 Expression::DropView(dv) => self.generate_drop_view(dv),
3380 Expression::AlterView(av) => self.generate_alter_view(av),
3381 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
3382 Expression::Truncate(tr) => self.generate_truncate(tr),
3383 Expression::Use(u) => self.generate_use(u),
3384 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
3386 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
3387 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
3388 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
3389 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
3390 Expression::CreateFunction(cf) => self.generate_create_function(cf),
3391 Expression::DropFunction(df) => self.generate_drop_function(df),
3392 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
3393 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
3394 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
3395 Expression::CreateSynonym(cs) => {
3396 self.write_keyword("CREATE SYNONYM");
3397 self.write_space();
3398 self.generate_table(&cs.name)?;
3399 self.write_space();
3400 self.write_keyword("FOR");
3401 self.write_space();
3402 self.generate_table(&cs.target)?;
3403 Ok(())
3404 }
3405 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
3406 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
3407 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
3408 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
3409 Expression::CreateType(ct) => self.generate_create_type(ct),
3410 Expression::DropType(dt) => self.generate_drop_type(dt),
3411 Expression::Describe(d) => self.generate_describe(d),
3412 Expression::Show(s) => self.generate_show(s),
3413
3414 Expression::Cache(c) => self.generate_cache(c),
3416 Expression::Uncache(u) => self.generate_uncache(u),
3417 Expression::LoadData(l) => self.generate_load_data(l),
3418 Expression::Pragma(p) => self.generate_pragma(p),
3419 Expression::Grant(g) => self.generate_grant(g),
3420 Expression::Revoke(r) => self.generate_revoke(r),
3421 Expression::Comment(c) => self.generate_comment(c),
3422 Expression::SetStatement(s) => self.generate_set_statement(s),
3423
3424 Expression::Pivot(pivot) => self.generate_pivot(pivot),
3426 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
3427
3428 Expression::Values(values) => self.generate_values(values),
3430
3431 Expression::AIAgg(e) => self.generate_ai_agg(e),
3433 Expression::AIClassify(e) => self.generate_ai_classify(e),
3434 Expression::AddPartition(e) => self.generate_add_partition(e),
3435 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
3436 Expression::Aliases(e) => self.generate_aliases(e),
3437 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
3438 Expression::AlterColumn(e) => self.generate_alter_column(e),
3439 Expression::AlterSession(e) => self.generate_alter_session(e),
3440 Expression::AlterSet(e) => self.generate_alter_set(e),
3441 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
3442 Expression::Analyze(e) => self.generate_analyze(e),
3443 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
3444 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
3445 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
3446 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
3447 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
3448 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
3449 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
3450 Expression::Anonymous(e) => self.generate_anonymous(e),
3451 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
3452 Expression::Apply(e) => self.generate_apply(e),
3453 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
3454 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
3455 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
3456 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
3457 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
3458 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
3459 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
3460 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
3461 Expression::ArgMax(e) => self.generate_arg_max(e),
3462 Expression::ArgMin(e) => self.generate_arg_min(e),
3463 Expression::ArrayAll(e) => self.generate_array_all(e),
3464 Expression::ArrayAny(e) => self.generate_array_any(e),
3465 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
3466 Expression::ArraySum(e) => self.generate_array_sum(e),
3467 Expression::AtIndex(e) => self.generate_at_index(e),
3468 Expression::Attach(e) => self.generate_attach(e),
3469 Expression::AttachOption(e) => self.generate_attach_option(e),
3470 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
3471 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
3472 Expression::BackupProperty(e) => self.generate_backup_property(e),
3473 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
3474 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
3475 Expression::Base64Encode(e) => self.generate_base64_encode(e),
3476 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
3477 Expression::Booland(e) => self.generate_booland(e),
3478 Expression::Boolor(e) => self.generate_boolor(e),
3479 Expression::BuildProperty(e) => self.generate_build_property(e),
3480 Expression::ByteString(e) => self.generate_byte_string(e),
3481 Expression::CaseSpecificColumnConstraint(e) => {
3482 self.generate_case_specific_column_constraint(e)
3483 }
3484 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
3485 Expression::Changes(e) => self.generate_changes(e),
3486 Expression::CharacterSetColumnConstraint(e) => {
3487 self.generate_character_set_column_constraint(e)
3488 }
3489 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
3490 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
3491 Expression::AssumeColumnConstraint(e) => self.generate_assume_column_constraint(e),
3492 Expression::CheckJson(e) => self.generate_check_json(e),
3493 Expression::CheckXml(e) => self.generate_check_xml(e),
3494 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
3495 Expression::Clone(e) => self.generate_clone(e),
3496 Expression::ClusterBy(e) => self.generate_cluster_by(e),
3497 Expression::ClusterByColumnsProperty(e) => self.generate_cluster_by_columns_property(e),
3498 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
3499 Expression::CollateProperty(e) => self.generate_collate_property(e),
3500 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
3501 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
3502 Expression::ColumnPosition(e) => self.generate_column_position(e),
3503 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
3504 Expression::Columns(e) => self.generate_columns(e),
3505 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
3506 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
3507 Expression::Commit(e) => self.generate_commit(e),
3508 Expression::Comprehension(e) => self.generate_comprehension(e),
3509 Expression::Compress(e) => self.generate_compress(e),
3510 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
3511 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
3512 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
3513 Expression::Constraint(e) => self.generate_constraint(e),
3514 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
3515 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
3516 Expression::Copy(e) => self.generate_copy(e),
3517 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
3518 Expression::Corr(e) => self.generate_corr(e),
3519 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
3520 Expression::CovarPop(e) => self.generate_covar_pop(e),
3521 Expression::CovarSamp(e) => self.generate_covar_samp(e),
3522 Expression::Credentials(e) => self.generate_credentials(e),
3523 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
3524 Expression::Cte(e) => self.generate_cte(e),
3525 Expression::Cube(e) => self.generate_cube(e),
3526 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
3527 Expression::CurrentSchema(e) => self.generate_current_schema(e),
3528 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
3529 Expression::CurrentUser(e) => self.generate_current_user(e),
3530 Expression::DPipe(e) => self.generate_d_pipe(e),
3531 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
3532 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
3533 Expression::Date(e) => self.generate_date_func(e),
3534 Expression::DateBin(e) => self.generate_date_bin(e),
3535 Expression::DateFormatColumnConstraint(e) => {
3536 self.generate_date_format_column_constraint(e)
3537 }
3538 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
3539 Expression::Datetime(e) => self.generate_datetime(e),
3540 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
3541 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
3542 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
3543 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
3544 Expression::Dayname(e) => self.generate_dayname(e),
3545 Expression::Declare(e) => self.generate_declare(e),
3546 Expression::DeclareItem(e) => self.generate_declare_item(e),
3547 Expression::DecodeCase(e) => self.generate_decode_case(e),
3548 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
3549 Expression::DecompressString(e) => self.generate_decompress_string(e),
3550 Expression::Decrypt(e) => self.generate_decrypt(e),
3551 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
3552 Expression::DefaultColumnConstraint(e) => {
3553 self.write_keyword("DEFAULT");
3554 self.write_space();
3555 self.generate_expression(&e.this)?;
3556 if let Some(ref col) = e.for_column {
3557 self.write_space();
3558 self.write_keyword("FOR");
3559 self.write_space();
3560 self.generate_identifier(col)?;
3561 }
3562 Ok(())
3563 }
3564 Expression::DefinerProperty(e) => self.generate_definer_property(e),
3565 Expression::Detach(e) => self.generate_detach(e),
3566 Expression::DictProperty(e) => self.generate_dict_property(e),
3567 Expression::DictRange(e) => self.generate_dict_range(e),
3568 Expression::Directory(e) => self.generate_directory(e),
3569 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
3570 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
3571 Expression::DistributeBy(e) => self.generate_distribute_by(e),
3572 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
3573 Expression::DotProduct(e) => self.generate_dot_product(e),
3574 Expression::DropPartition(e) => self.generate_drop_partition(e),
3575 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
3576 Expression::Elt(e) => self.generate_elt(e),
3577 Expression::Encode(e) => self.generate_encode(e),
3578 Expression::EncodeProperty(e) => self.generate_encode_property(e),
3579 Expression::Encrypt(e) => self.generate_encrypt(e),
3580 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
3581 Expression::EngineProperty(e) => self.generate_engine_property(e),
3582 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
3583 Expression::EphemeralColumnConstraint(e) => {
3584 self.generate_ephemeral_column_constraint(e)
3585 }
3586 Expression::EqualNull(e) => self.generate_equal_null(e),
3587 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
3588 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
3589 Expression::Export(e) => self.generate_export(e),
3590 Expression::ExternalProperty(e) => self.generate_external_property(e),
3591 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
3592 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
3593 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
3594 Expression::Fetch(e) => self.generate_fetch(e),
3595 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
3596 Expression::Filter(e) => self.generate_filter(e),
3597 Expression::Float64(e) => self.generate_float64(e),
3598 Expression::ForIn(e) => self.generate_for_in(e),
3599 Expression::ForeignKey(e) => self.generate_foreign_key(e),
3600 Expression::Format(e) => self.generate_format(e),
3601 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
3602 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
3603 Expression::From(e) => self.generate_from(e),
3604 Expression::FromBase(e) => self.generate_from_base(e),
3605 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
3606 Expression::GapFill(e) => self.generate_gap_fill(e),
3607 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
3608 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
3609 Expression::GenerateSeries(e) => self.generate_generate_series(e),
3610 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
3611 Expression::GeneratedAsIdentityColumnConstraint(e) => {
3612 self.generate_generated_as_identity_column_constraint(e)
3613 }
3614 Expression::GeneratedAsRowColumnConstraint(e) => {
3615 self.generate_generated_as_row_column_constraint(e)
3616 }
3617 Expression::Get(e) => self.generate_get(e),
3618 Expression::GetExtract(e) => self.generate_get_extract(e),
3619 Expression::Getbit(e) => self.generate_getbit(e),
3620 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
3621 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
3622 Expression::Group(e) => self.generate_group(e),
3623 Expression::GroupBy(e) => self.generate_group_by(e),
3624 Expression::Grouping(e) => self.generate_grouping(e),
3625 Expression::GroupingId(e) => self.generate_grouping_id(e),
3626 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
3627 Expression::HashAgg(e) => self.generate_hash_agg(e),
3628 Expression::Having(e) => self.generate_having(e),
3629 Expression::HavingMax(e) => self.generate_having_max(e),
3630 Expression::Heredoc(e) => self.generate_heredoc(e),
3631 Expression::HexEncode(e) => self.generate_hex_encode(e),
3632 Expression::Hll(e) => self.generate_hll(e),
3633 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
3634 Expression::IncludeProperty(e) => self.generate_include_property(e),
3635 Expression::Index(e) => self.generate_index(e),
3636 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
3637 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
3638 Expression::IndexParameters(e) => self.generate_index_parameters(e),
3639 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
3640 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
3641 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
3642 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
3643 Expression::Install(e) => self.generate_install(e),
3644 Expression::IntervalOp(e) => self.generate_interval_op(e),
3645 Expression::IntervalSpan(e) => self.generate_interval_span(e),
3646 Expression::IntoClause(e) => self.generate_into_clause(e),
3647 Expression::Introducer(e) => self.generate_introducer(e),
3648 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
3649 Expression::JSON(e) => self.generate_json(e),
3650 Expression::JSONArray(e) => self.generate_json_array(e),
3651 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
3652 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
3653 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
3654 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
3655 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
3656 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
3657 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
3658 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
3659 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
3660 Expression::JSONExists(e) => self.generate_json_exists(e),
3661 Expression::JSONCast(e) => self.generate_json_cast(e),
3662 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
3663 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
3664 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
3665 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
3666 Expression::JSONFormat(e) => self.generate_json_format(e),
3667 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
3668 Expression::JSONKeys(e) => self.generate_json_keys(e),
3669 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
3670 Expression::JSONPath(e) => self.generate_json_path_expr(e),
3671 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
3672 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
3673 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
3674 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
3675 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
3676 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
3677 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
3678 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
3679 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
3680 Expression::JSONRemove(e) => self.generate_json_remove(e),
3681 Expression::JSONSchema(e) => self.generate_json_schema(e),
3682 Expression::JSONSet(e) => self.generate_json_set(e),
3683 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
3684 Expression::JSONTable(e) => self.generate_json_table(e),
3685 Expression::JSONType(e) => self.generate_json_type(e),
3686 Expression::JSONValue(e) => self.generate_json_value(e),
3687 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
3688 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
3689 Expression::JoinHint(e) => self.generate_join_hint(e),
3690 Expression::JournalProperty(e) => self.generate_journal_property(e),
3691 Expression::LanguageProperty(e) => self.generate_language_property(e),
3692 Expression::Lateral(e) => self.generate_lateral(e),
3693 Expression::LikeProperty(e) => self.generate_like_property(e),
3694 Expression::Limit(e) => self.generate_limit(e),
3695 Expression::LimitOptions(e) => self.generate_limit_options(e),
3696 Expression::List(e) => self.generate_list(e),
3697 Expression::ToMap(e) => self.generate_tomap(e),
3698 Expression::Localtime(e) => self.generate_localtime(e),
3699 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
3700 Expression::LocationProperty(e) => self.generate_location_property(e),
3701 Expression::Lock(e) => self.generate_lock(e),
3702 Expression::LockProperty(e) => self.generate_lock_property(e),
3703 Expression::LockingProperty(e) => self.generate_locking_property(e),
3704 Expression::LockingStatement(e) => self.generate_locking_statement(e),
3705 Expression::LogProperty(e) => self.generate_log_property(e),
3706 Expression::MD5Digest(e) => self.generate_md5_digest(e),
3707 Expression::MLForecast(e) => self.generate_ml_forecast(e),
3708 Expression::MLTranslate(e) => self.generate_ml_translate(e),
3709 Expression::MakeInterval(e) => self.generate_make_interval(e),
3710 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
3711 Expression::Map(e) => self.generate_map(e),
3712 Expression::MapCat(e) => self.generate_map_cat(e),
3713 Expression::MapDelete(e) => self.generate_map_delete(e),
3714 Expression::MapInsert(e) => self.generate_map_insert(e),
3715 Expression::MapPick(e) => self.generate_map_pick(e),
3716 Expression::MaskingPolicyColumnConstraint(e) => {
3717 self.generate_masking_policy_column_constraint(e)
3718 }
3719 Expression::MatchAgainst(e) => self.generate_match_against(e),
3720 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
3721 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
3722 Expression::Merge(e) => self.generate_merge(e),
3723 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
3724 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
3725 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
3726 Expression::Minhash(e) => self.generate_minhash(e),
3727 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
3728 Expression::Monthname(e) => self.generate_monthname(e),
3729 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
3730 Expression::NextValueFor(e) => self.generate_next_value_for(e),
3731 Expression::Normal(e) => self.generate_normal(e),
3732 Expression::Normalize(e) => self.generate_normalize(e),
3733 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
3734 Expression::Nullif(e) => self.generate_nullif(e),
3735 Expression::NumberToStr(e) => self.generate_number_to_str(e),
3736 Expression::ObjectAgg(e) => self.generate_object_agg(e),
3737 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
3738 Expression::ObjectInsert(e) => self.generate_object_insert(e),
3739 Expression::Offset(e) => self.generate_offset(e),
3740 Expression::Qualify(e) => self.generate_qualify(e),
3741 Expression::OnCluster(e) => self.generate_on_cluster(e),
3742 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
3743 Expression::OnCondition(e) => self.generate_on_condition(e),
3744 Expression::OnConflict(e) => self.generate_on_conflict(e),
3745 Expression::OnProperty(e) => self.generate_on_property(e),
3746 Expression::Opclass(e) => self.generate_opclass(e),
3747 Expression::OpenJSON(e) => self.generate_open_json(e),
3748 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
3749 Expression::Operator(e) => self.generate_operator(e),
3750 Expression::OrderBy(e) => self.generate_order_by(e),
3751 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
3752 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
3753 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
3754 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
3755 Expression::ParseIp(e) => self.generate_parse_ip(e),
3756 Expression::ParseJSON(e) => self.generate_parse_json(e),
3757 Expression::ParseTime(e) => self.generate_parse_time(e),
3758 Expression::ParseUrl(e) => self.generate_parse_url(e),
3759 Expression::Partition(e) => self.generate_partition_expr(e),
3760 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
3761 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
3762 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
3763 Expression::PartitionByRangePropertyDynamic(e) => {
3764 self.generate_partition_by_range_property_dynamic(e)
3765 }
3766 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
3767 Expression::PartitionList(e) => self.generate_partition_list(e),
3768 Expression::PartitionRange(e) => self.generate_partition_range(e),
3769 Expression::PartitionByProperty(e) => self.generate_partition_by_property(e),
3770 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
3771 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
3772 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
3773 Expression::PeriodForSystemTimeConstraint(e) => {
3774 self.generate_period_for_system_time_constraint(e)
3775 }
3776 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
3777 Expression::PivotAny(e) => self.generate_pivot_any(e),
3778 Expression::Predict(e) => self.generate_predict(e),
3779 Expression::PreviousDay(e) => self.generate_previous_day(e),
3780 Expression::PrimaryKey(e) => self.generate_primary_key(e),
3781 Expression::PrimaryKeyColumnConstraint(e) => {
3782 self.generate_primary_key_column_constraint(e)
3783 }
3784 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
3785 Expression::ProjectionDef(e) => self.generate_projection_def(e),
3786 Expression::OptionsProperty(e) => self.generate_options_property(e),
3787 Expression::Properties(e) => self.generate_properties(e),
3788 Expression::Property(e) => self.generate_property(e),
3789 Expression::PseudoType(e) => self.generate_pseudo_type(e),
3790 Expression::Put(e) => self.generate_put(e),
3791 Expression::Quantile(e) => self.generate_quantile(e),
3792 Expression::QueryBand(e) => self.generate_query_band(e),
3793 Expression::QueryOption(e) => self.generate_query_option(e),
3794 Expression::QueryTransform(e) => self.generate_query_transform(e),
3795 Expression::Randn(e) => self.generate_randn(e),
3796 Expression::Randstr(e) => self.generate_randstr(e),
3797 Expression::RangeBucket(e) => self.generate_range_bucket(e),
3798 Expression::RangeN(e) => self.generate_range_n(e),
3799 Expression::ReadCSV(e) => self.generate_read_csv(e),
3800 Expression::ReadParquet(e) => self.generate_read_parquet(e),
3801 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
3802 Expression::Reduce(e) => self.generate_reduce(e),
3803 Expression::Reference(e) => self.generate_reference(e),
3804 Expression::Refresh(e) => self.generate_refresh(e),
3805 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
3806 Expression::RegexpCount(e) => self.generate_regexp_count(e),
3807 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
3808 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
3809 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
3810 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
3811 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
3812 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
3813 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
3814 Expression::RegrCount(e) => self.generate_regr_count(e),
3815 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
3816 Expression::RegrR2(e) => self.generate_regr_r2(e),
3817 Expression::RegrSlope(e) => self.generate_regr_slope(e),
3818 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
3819 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
3820 Expression::RegrSyy(e) => self.generate_regr_syy(e),
3821 Expression::RegrValx(e) => self.generate_regr_valx(e),
3822 Expression::RegrValy(e) => self.generate_regr_valy(e),
3823 Expression::RemoteWithConnectionModelProperty(e) => {
3824 self.generate_remote_with_connection_model_property(e)
3825 }
3826 Expression::RenameColumn(e) => self.generate_rename_column(e),
3827 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
3828 Expression::Returning(e) => self.generate_returning(e),
3829 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
3830 Expression::Rollback(e) => self.generate_rollback(e),
3831 Expression::Rollup(e) => self.generate_rollup(e),
3832 Expression::RowFormatDelimitedProperty(e) => {
3833 self.generate_row_format_delimited_property(e)
3834 }
3835 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
3836 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
3837 Expression::SHA2(e) => self.generate_sha2(e),
3838 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
3839 Expression::SafeAdd(e) => self.generate_safe_add(e),
3840 Expression::SafeDivide(e) => self.generate_safe_divide(e),
3841 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
3842 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
3843 Expression::SampleProperty(e) => self.generate_sample_property(e),
3844 Expression::Schema(e) => self.generate_schema(e),
3845 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
3846 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
3847 Expression::Search(e) => self.generate_search(e),
3848 Expression::SearchIp(e) => self.generate_search_ip(e),
3849 Expression::SecurityProperty(e) => self.generate_security_property(e),
3850 Expression::SemanticView(e) => self.generate_semantic_view(e),
3851 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
3852 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
3853 Expression::SessionParameter(e) => self.generate_session_parameter(e),
3854 Expression::Set(e) => self.generate_set(e),
3855 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
3856 Expression::SetItem(e) => self.generate_set_item(e),
3857 Expression::SetOperation(e) => self.generate_set_operation(e),
3858 Expression::SetProperty(e) => self.generate_set_property(e),
3859 Expression::SettingsProperty(e) => self.generate_settings_property(e),
3860 Expression::SharingProperty(e) => self.generate_sharing_property(e),
3861 Expression::Slice(e) => self.generate_slice(e),
3862 Expression::SortArray(e) => self.generate_sort_array(e),
3863 Expression::SortBy(e) => self.generate_sort_by(e),
3864 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
3865 Expression::SplitPart(e) => self.generate_split_part(e),
3866 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
3867 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
3868 Expression::StDistance(e) => self.generate_st_distance(e),
3869 Expression::StPoint(e) => self.generate_st_point(e),
3870 Expression::StabilityProperty(e) => self.generate_stability_property(e),
3871 Expression::StandardHash(e) => self.generate_standard_hash(e),
3872 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
3873 Expression::StrPosition(e) => self.generate_str_position(e),
3874 Expression::StrToDate(e) => self.generate_str_to_date(e),
3875 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
3876 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
3877 Expression::StrToMap(e) => self.generate_str_to_map(e),
3878 Expression::StrToTime(e) => self.generate_str_to_time(e),
3879 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
3880 Expression::StringToArray(e) => self.generate_string_to_array(e),
3881 Expression::Struct(e) => self.generate_struct(e),
3882 Expression::Stuff(e) => self.generate_stuff(e),
3883 Expression::SubstringIndex(e) => self.generate_substring_index(e),
3884 Expression::Summarize(e) => self.generate_summarize(e),
3885 Expression::Systimestamp(e) => self.generate_systimestamp(e),
3886 Expression::TableAlias(e) => self.generate_table_alias(e),
3887 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
3888 Expression::RowsFrom(e) => self.generate_rows_from(e),
3889 Expression::TableSample(e) => self.generate_table_sample(e),
3890 Expression::Tag(e) => self.generate_tag(e),
3891 Expression::Tags(e) => self.generate_tags(e),
3892 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
3893 Expression::Time(e) => self.generate_time_func(e),
3894 Expression::TimeAdd(e) => self.generate_time_add(e),
3895 Expression::TimeDiff(e) => self.generate_time_diff(e),
3896 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
3897 Expression::TimeSlice(e) => self.generate_time_slice(e),
3898 Expression::TimeStrToDate(e) => self.generate_time_str_to_date(e),
3899 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
3900 Expression::TimeSub(e) => self.generate_time_sub(e),
3901 Expression::TimeToStr(e) => self.generate_time_to_str(e),
3902 Expression::TimeToUnix(e) => self.generate_time_to_unix(e),
3903 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
3904 Expression::TimeUnit(e) => self.generate_time_unit(e),
3905 Expression::Timestamp(e) => self.generate_timestamp_func(e),
3906 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
3907 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
3908 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
3909 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
3910 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
3911 Expression::ToBinary(e) => self.generate_to_binary(e),
3912 Expression::ToBoolean(e) => self.generate_to_boolean(e),
3913 Expression::ToChar(e) => self.generate_to_char(e),
3914 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
3915 Expression::ToDouble(e) => self.generate_to_double(e),
3916 Expression::ToFile(e) => self.generate_to_file(e),
3917 Expression::ToNumber(e) => self.generate_to_number(e),
3918 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
3919 Expression::Transaction(e) => self.generate_transaction(e),
3920 Expression::Transform(e) => self.generate_transform(e),
3921 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
3922 Expression::TransientProperty(e) => self.generate_transient_property(e),
3923 Expression::Translate(e) => self.generate_translate(e),
3924 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
3925 Expression::TruncateTable(e) => self.generate_truncate_table(e),
3926 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
3927 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
3928 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
3929 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
3930 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
3931 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
3932 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
3933 Expression::Unhex(e) => self.generate_unhex(e),
3934 Expression::UnicodeString(e) => self.generate_unicode_string(e),
3935 Expression::Uniform(e) => self.generate_uniform(e),
3936 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
3937 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
3938 Expression::RollupProperty(e) => self.generate_rollup_property(e),
3939 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
3940 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
3941 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
3942 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
3943 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
3944 Expression::UtcTime(e) => self.generate_utc_time(e),
3945 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
3946 Expression::Uuid(e) => self.generate_uuid(e),
3947 Expression::Var(v) => {
3948 if matches!(self.config.dialect, Some(DialectType::MySQL))
3949 && v.this.len() > 2
3950 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
3951 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
3952 {
3953 return self.generate_identifier(&Identifier {
3954 name: v.this.clone(),
3955 quoted: true,
3956 trailing_comments: Vec::new(),
3957 span: None,
3958 });
3959 }
3960 self.write(&v.this);
3961 Ok(())
3962 }
3963 Expression::Variadic(e) => {
3964 self.write_keyword("VARIADIC");
3965 self.write_space();
3966 self.generate_expression(&e.this)?;
3967 Ok(())
3968 }
3969 Expression::VarMap(e) => self.generate_var_map(e),
3970 Expression::VectorSearch(e) => self.generate_vector_search(e),
3971 Expression::Version(e) => self.generate_version(e),
3972 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
3973 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
3974 Expression::WatermarkColumnConstraint(e) => {
3975 self.generate_watermark_column_constraint(e)
3976 }
3977 Expression::Week(e) => self.generate_week(e),
3978 Expression::When(e) => self.generate_when(e),
3979 Expression::Whens(e) => self.generate_whens(e),
3980 Expression::Where(e) => self.generate_where(e),
3981 Expression::WidthBucket(e) => self.generate_width_bucket(e),
3982 Expression::Window(e) => self.generate_window(e),
3983 Expression::WindowSpec(e) => self.generate_window_spec(e),
3984 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
3985 Expression::WithFill(e) => self.generate_with_fill(e),
3986 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
3987 Expression::WithOperator(e) => self.generate_with_operator(e),
3988 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
3989 Expression::WithSchemaBindingProperty(e) => {
3990 self.generate_with_schema_binding_property(e)
3991 }
3992 Expression::WithSystemVersioningProperty(e) => {
3993 self.generate_with_system_versioning_property(e)
3994 }
3995 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
3996 Expression::XMLElement(e) => self.generate_xml_element(e),
3997 Expression::XMLGet(e) => self.generate_xml_get(e),
3998 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
3999 Expression::XMLTable(e) => self.generate_xml_table(e),
4000 Expression::Xor(e) => self.generate_xor(e),
4001 Expression::Zipf(e) => self.generate_zipf(e),
4002 _ => self.write_unsupported_comment("unsupported expression"),
4003 }
4004 }
4005
4006 fn generate_select(&mut self, select: &Select) -> Result<()> {
4007 use crate::dialects::DialectType;
4008
4009 if let Some(exclude) = &select.exclude {
4013 if !exclude.is_empty() && !matches!(self.config.dialect, Some(DialectType::Redshift)) {
4014 let mut inner_select = select.clone();
4016 inner_select.exclude = None;
4017 let inner_expr = Expression::Select(Box::new(inner_select));
4018
4019 let subquery = crate::expressions::Subquery {
4021 this: inner_expr,
4022 alias: None,
4023 column_aliases: Vec::new(),
4024 order_by: None,
4025 limit: None,
4026 offset: None,
4027 distribute_by: None,
4028 sort_by: None,
4029 cluster_by: None,
4030 lateral: false,
4031 modifiers_inside: false,
4032 trailing_comments: Vec::new(),
4033 inferred_type: None,
4034 };
4035
4036 let star = Expression::Star(crate::expressions::Star {
4038 table: None,
4039 except: Some(
4040 exclude
4041 .iter()
4042 .map(|e| match e {
4043 Expression::Column(col) => col.name.clone(),
4044 Expression::Identifier(id) => id.clone(),
4045 _ => crate::expressions::Identifier::new("unknown".to_string()),
4046 })
4047 .collect(),
4048 ),
4049 replace: None,
4050 rename: None,
4051 trailing_comments: Vec::new(),
4052 span: None,
4053 });
4054
4055 let outer_select = Select {
4056 expressions: vec![star],
4057 from: Some(crate::expressions::From {
4058 expressions: vec![Expression::Subquery(Box::new(subquery))],
4059 }),
4060 ..Select::new()
4061 };
4062
4063 return self.generate_select(&outer_select);
4064 }
4065 }
4066
4067 for comment in &select.leading_comments {
4069 self.write_formatted_comment(comment);
4070 self.write(" ");
4071 }
4072
4073 if let Some(with) = &select.with {
4075 self.generate_with(with)?;
4076 if self.config.pretty {
4077 self.write_newline();
4078 self.write_indent();
4079 } else {
4080 self.write_space();
4081 }
4082 }
4083
4084 for comment in &select.post_select_comments {
4087 self.write_formatted_comment(comment);
4088 self.write(" ");
4089 }
4090
4091 self.write_keyword("SELECT");
4092
4093 if let Some(hint) = &select.hint {
4095 self.generate_hint(hint)?;
4096 }
4097
4098 let use_top_from_limit = matches!(self.config.dialect, Some(DialectType::TSQL))
4102 && select.top.is_none()
4103 && select.limit.is_some()
4104 && select.offset.is_none(); let is_top_dialect = matches!(
4109 self.config.dialect,
4110 Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric)
4111 );
4112 let keep_top_verbatim = !is_top_dialect
4113 && select.limit.is_none()
4114 && select
4115 .top
4116 .as_ref()
4117 .map_or(false, |top| top.percent || top.with_ties);
4118
4119 if select.distinct && (is_top_dialect || select.top.is_some()) {
4120 self.write_space();
4121 self.write_keyword("DISTINCT");
4122 }
4123
4124 if is_top_dialect || keep_top_verbatim {
4125 if let Some(top) = &select.top {
4126 self.write_space();
4127 self.write_keyword("TOP");
4128 if top.parenthesized {
4129 self.write(" (");
4130 self.generate_expression(&top.this)?;
4131 self.write(")");
4132 } else {
4133 self.write_space();
4134 self.generate_expression(&top.this)?;
4135 }
4136 if top.percent {
4137 self.write_space();
4138 self.write_keyword("PERCENT");
4139 }
4140 if top.with_ties {
4141 self.write_space();
4142 self.write_keyword("WITH TIES");
4143 }
4144 } else if use_top_from_limit {
4145 if let Some(limit) = &select.limit {
4147 self.write_space();
4148 self.write_keyword("TOP");
4149 let is_simple_literal = matches!(&limit.this, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)));
4151 if is_simple_literal {
4152 self.write_space();
4153 self.generate_expression(&limit.this)?;
4154 } else {
4155 self.write(" (");
4156 self.generate_expression(&limit.this)?;
4157 self.write(")");
4158 }
4159 }
4160 }
4161 }
4162
4163 if select.distinct && !is_top_dialect && select.top.is_none() {
4164 self.write_space();
4165 self.write_keyword("DISTINCT");
4166 }
4167
4168 if let Some(distinct_on) = &select.distinct_on {
4170 self.write_space();
4171 self.write_keyword("ON");
4172 self.write(" (");
4173 for (i, expr) in distinct_on.iter().enumerate() {
4174 if i > 0 {
4175 self.write(", ");
4176 }
4177 self.generate_expression(expr)?;
4178 }
4179 self.write(")");
4180 }
4181
4182 for modifier in &select.operation_modifiers {
4184 self.write_space();
4185 self.write_keyword(modifier);
4186 }
4187
4188 if let Some(kind) = &select.kind {
4190 self.write_space();
4191 self.write_keyword("AS");
4192 self.write_space();
4193 self.write_keyword(kind);
4194 }
4195
4196 if !select.expressions.is_empty() {
4198 if self.config.pretty {
4199 self.write_newline();
4200 self.indent_level += 1;
4201 } else {
4202 self.write_space();
4203 }
4204 }
4205
4206 for (i, expr) in select.expressions.iter().enumerate() {
4207 if i > 0 {
4208 self.write(",");
4209 if self.config.pretty {
4210 self.write_newline();
4211 } else {
4212 self.write_space();
4213 }
4214 }
4215 if self.config.pretty {
4216 self.write_indent();
4217 }
4218 self.generate_expression(expr)?;
4219 }
4220
4221 if self.config.pretty && !select.expressions.is_empty() {
4222 self.indent_level -= 1;
4223 }
4224
4225 if let Some(exclude) = &select.exclude {
4230 if !exclude.is_empty() && matches!(self.config.dialect, Some(DialectType::Redshift)) {
4231 self.write_space();
4232 self.write_keyword("EXCLUDE");
4233 self.write(" (");
4234 for (i, col) in exclude.iter().enumerate() {
4235 if i > 0 {
4236 self.write(", ");
4237 }
4238 self.generate_expression(col)?;
4239 }
4240 self.write(")");
4241 }
4242 }
4243
4244 if let Some(into) = &select.into {
4247 if self.config.pretty {
4248 self.write_newline();
4249 self.write_indent();
4250 } else {
4251 self.write_space();
4252 }
4253 if into.bulk_collect {
4254 self.write_keyword("BULK COLLECT INTO");
4255 } else {
4256 self.write_keyword("INTO");
4257 }
4258 if into.temporary {
4259 self.write_space();
4260 self.write_keyword("TEMPORARY");
4261 }
4262 if into.unlogged {
4263 self.write_space();
4264 self.write_keyword("UNLOGGED");
4265 }
4266 self.write_space();
4267 if !into.expressions.is_empty() {
4269 for (i, expr) in into.expressions.iter().enumerate() {
4270 if i > 0 {
4271 self.write(", ");
4272 }
4273 self.generate_expression(expr)?;
4274 }
4275 } else {
4276 self.generate_expression(&into.this)?;
4277 }
4278 }
4279
4280 if let Some(from) = &select.from {
4282 if self.config.pretty {
4283 self.write_newline();
4284 self.write_indent();
4285 } else {
4286 self.write_space();
4287 }
4288 self.write_keyword("FROM");
4289 self.write_space();
4290
4291 let has_tablesample = from
4296 .expressions
4297 .iter()
4298 .any(|e| matches!(e, Expression::TableSample(_)));
4299 let is_cross_join_dialect = matches!(
4300 self.config.dialect,
4301 Some(DialectType::BigQuery)
4302 | Some(DialectType::Hive)
4303 | Some(DialectType::Spark)
4304 | Some(DialectType::Databricks)
4305 | Some(DialectType::SQLite)
4306 | Some(DialectType::ClickHouse)
4307 );
4308 let source_is_same_as_target = self.config.source_dialect.is_some()
4311 && self.config.source_dialect == self.config.dialect;
4312 let source_is_cross_join_dialect = matches!(
4313 self.config.source_dialect,
4314 Some(DialectType::BigQuery)
4315 | Some(DialectType::Hive)
4316 | Some(DialectType::Spark)
4317 | Some(DialectType::Databricks)
4318 | Some(DialectType::SQLite)
4319 | Some(DialectType::ClickHouse)
4320 );
4321 let use_cross_join = !has_tablesample
4322 && is_cross_join_dialect
4323 && (source_is_same_as_target
4324 || source_is_cross_join_dialect
4325 || self.config.source_dialect.is_none());
4326
4327 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
4329
4330 for (i, expr) in from.expressions.iter().enumerate() {
4331 if i > 0 {
4332 if use_cross_join {
4333 self.write(" CROSS JOIN ");
4334 } else {
4335 self.write(", ");
4336 }
4337 }
4338 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
4339 self.write("(");
4340 self.generate_expression(expr)?;
4341 self.write(")");
4342 } else {
4343 self.generate_expression(expr)?;
4344 }
4345 let leading = Self::extract_table_leading_comments(expr);
4348 for comment in &leading {
4349 self.write_space();
4350 self.write_formatted_comment(comment);
4351 }
4352 }
4353 }
4354
4355 if self.config.pretty {
4359 self.generate_joins_with_nesting(&select.joins)?;
4360 } else {
4361 for join in &select.joins {
4362 self.generate_join(join)?;
4363 }
4364 for join in select.joins.iter().rev() {
4366 if join.deferred_condition {
4367 self.generate_join_condition(join)?;
4368 }
4369 }
4370 }
4371
4372 for (lv_idx, lateral_view) in select.lateral_views.iter().enumerate() {
4374 self.generate_lateral_view(lateral_view, lv_idx)?;
4375 }
4376
4377 if let Some(prewhere) = &select.prewhere {
4379 self.write_clause_condition("PREWHERE", prewhere)?;
4380 }
4381
4382 if let Some(where_clause) = &select.where_clause {
4384 self.write_clause_condition("WHERE", &where_clause.this)?;
4385 }
4386
4387 if let Some(connect) = &select.connect {
4389 self.generate_connect(connect)?;
4390 }
4391
4392 if let Some(group_by) = &select.group_by {
4394 if self.config.pretty {
4395 for comment in &group_by.comments {
4397 self.write_newline();
4398 self.write_indent();
4399 self.write_formatted_comment(comment);
4400 }
4401 self.write_newline();
4402 self.write_indent();
4403 } else {
4404 self.write_space();
4405 for comment in &group_by.comments {
4407 self.write_formatted_comment(comment);
4408 self.write_space();
4409 }
4410 }
4411 self.write_keyword("GROUP BY");
4412 match group_by.all {
4414 Some(true) => {
4415 self.write_space();
4416 self.write_keyword("ALL");
4417 }
4418 Some(false) => {
4419 self.write_space();
4420 self.write_keyword("DISTINCT");
4421 }
4422 None => {}
4423 }
4424 if !group_by.expressions.is_empty() {
4425 let mut trailing_cube = false;
4428 let mut trailing_rollup = false;
4429 let mut plain_expressions: Vec<&Expression> = Vec::new();
4430 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
4431 let mut cube_expressions: Vec<&Expression> = Vec::new();
4432 let mut rollup_expressions: Vec<&Expression> = Vec::new();
4433
4434 for expr in &group_by.expressions {
4435 match expr {
4436 Expression::Cube(c) if c.expressions.is_empty() => {
4437 trailing_cube = true;
4438 }
4439 Expression::Rollup(r) if r.expressions.is_empty() => {
4440 trailing_rollup = true;
4441 }
4442 Expression::Function(f) if f.name == "CUBE" => {
4443 cube_expressions.push(expr);
4444 }
4445 Expression::Function(f) if f.name == "ROLLUP" => {
4446 rollup_expressions.push(expr);
4447 }
4448 Expression::Function(f) if f.name == "GROUPING SETS" => {
4449 grouping_sets_expressions.push(expr);
4450 }
4451 _ => {
4452 plain_expressions.push(expr);
4453 }
4454 }
4455 }
4456
4457 let mut regular_expressions: Vec<&Expression> = Vec::new();
4459 regular_expressions.extend(plain_expressions);
4460 regular_expressions.extend(grouping_sets_expressions);
4461 regular_expressions.extend(cube_expressions);
4462 regular_expressions.extend(rollup_expressions);
4463
4464 if self.config.pretty {
4465 self.write_newline();
4466 self.indent_level += 1;
4467 self.write_indent();
4468 } else {
4469 self.write_space();
4470 }
4471
4472 for (i, expr) in regular_expressions.iter().enumerate() {
4473 if i > 0 {
4474 if self.config.pretty {
4475 self.write(",");
4476 self.write_newline();
4477 self.write_indent();
4478 } else {
4479 self.write(", ");
4480 }
4481 }
4482 self.generate_expression(expr)?;
4483 }
4484
4485 if self.config.pretty {
4486 self.indent_level -= 1;
4487 }
4488
4489 if trailing_cube {
4491 self.write_space();
4492 self.write_keyword("WITH CUBE");
4493 } else if trailing_rollup {
4494 self.write_space();
4495 self.write_keyword("WITH ROLLUP");
4496 }
4497 }
4498
4499 if group_by.totals {
4501 self.write_space();
4502 self.write_keyword("WITH TOTALS");
4503 }
4504 }
4505
4506 if let Some(having) = &select.having {
4508 if self.config.pretty {
4509 for comment in &having.comments {
4511 self.write_newline();
4512 self.write_indent();
4513 self.write_formatted_comment(comment);
4514 }
4515 } else {
4516 for comment in &having.comments {
4517 self.write_space();
4518 self.write_formatted_comment(comment);
4519 }
4520 }
4521 self.write_clause_condition("HAVING", &having.this)?;
4522 }
4523
4524 if select.qualify_after_window {
4526 if let Some(windows) = &select.windows {
4528 self.write_window_clause(windows)?;
4529 }
4530 if let Some(qualify) = &select.qualify {
4531 self.write_clause_condition("QUALIFY", &qualify.this)?;
4532 }
4533 } else {
4534 if let Some(qualify) = &select.qualify {
4536 self.write_clause_condition("QUALIFY", &qualify.this)?;
4537 }
4538 if let Some(windows) = &select.windows {
4539 self.write_window_clause(windows)?;
4540 }
4541 }
4542
4543 if let Some(distribute_by) = &select.distribute_by {
4545 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
4546 }
4547
4548 if let Some(cluster_by) = &select.cluster_by {
4550 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
4551 }
4552
4553 if let Some(sort_by) = &select.sort_by {
4555 self.write_order_clause("SORT BY", &sort_by.expressions)?;
4556 }
4557
4558 if let Some(order_by) = &select.order_by {
4560 if self.config.pretty {
4561 for comment in &order_by.comments {
4563 self.write_newline();
4564 self.write_indent();
4565 self.write_formatted_comment(comment);
4566 }
4567 } else {
4568 for comment in &order_by.comments {
4569 self.write_space();
4570 self.write_formatted_comment(comment);
4571 }
4572 }
4573 let keyword = if order_by.siblings {
4574 "ORDER SIBLINGS BY"
4575 } else {
4576 "ORDER BY"
4577 };
4578 self.write_order_clause(keyword, &order_by.expressions)?;
4579 }
4580
4581 if select.order_by.is_none()
4583 && select.fetch.is_some()
4584 && matches!(
4585 self.config.dialect,
4586 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4587 )
4588 {
4589 if self.config.pretty {
4590 self.write_newline();
4591 self.write_indent();
4592 } else {
4593 self.write_space();
4594 }
4595 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
4596 }
4597
4598 let is_presto_like = matches!(
4603 self.config.dialect,
4604 Some(DialectType::Presto) | Some(DialectType::Trino)
4605 );
4606
4607 if is_presto_like && select.offset.is_some() {
4608 if let Some(offset) = &select.offset {
4610 if self.config.pretty {
4611 self.write_newline();
4612 self.write_indent();
4613 } else {
4614 self.write_space();
4615 }
4616 self.write_keyword("OFFSET");
4617 self.write_space();
4618 self.write_limit_expr(&offset.this)?;
4619 if offset.rows == Some(true) {
4620 self.write_space();
4621 self.write_keyword("ROWS");
4622 }
4623 }
4624 if let Some(limit) = &select.limit {
4625 if self.config.pretty {
4626 self.write_newline();
4627 self.write_indent();
4628 } else {
4629 self.write_space();
4630 }
4631 self.write_keyword("LIMIT");
4632 self.write_space();
4633 self.write_limit_expr(&limit.this)?;
4634 if limit.percent {
4635 self.write_space();
4636 self.write_keyword("PERCENT");
4637 }
4638 for comment in &limit.comments {
4640 self.write(" ");
4641 self.write_formatted_comment(comment);
4642 }
4643 }
4644 } else {
4645 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
4647 !fetch.percent
4648 && !fetch.with_ties
4649 && fetch.count.is_some()
4650 && matches!(
4651 self.config.dialect,
4652 Some(DialectType::Spark)
4653 | Some(DialectType::Hive)
4654 | Some(DialectType::DuckDB)
4655 | Some(DialectType::SQLite)
4656 | Some(DialectType::MySQL)
4657 | Some(DialectType::BigQuery)
4658 | Some(DialectType::Databricks)
4659 | Some(DialectType::StarRocks)
4660 | Some(DialectType::Doris)
4661 | Some(DialectType::Athena)
4662 | Some(DialectType::ClickHouse)
4663 | Some(DialectType::Redshift)
4664 )
4665 });
4666
4667 if let Some(limit) = &select.limit {
4669 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
4671 if self.config.pretty {
4672 self.write_newline();
4673 self.write_indent();
4674 } else {
4675 self.write_space();
4676 }
4677 self.write_keyword("LIMIT");
4678 self.write_space();
4679 self.write_limit_expr(&limit.this)?;
4680 if limit.percent {
4681 self.write_space();
4682 self.write_keyword("PERCENT");
4683 }
4684 for comment in &limit.comments {
4686 self.write(" ");
4687 self.write_formatted_comment(comment);
4688 }
4689 }
4690 }
4691
4692 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
4694 if let Some(top) = &select.top {
4695 if !top.percent && !top.with_ties {
4696 if self.config.pretty {
4697 self.write_newline();
4698 self.write_indent();
4699 } else {
4700 self.write_space();
4701 }
4702 self.write_keyword("LIMIT");
4703 self.write_space();
4704 self.generate_expression(&top.this)?;
4705 }
4706 }
4707 }
4708
4709 if fetch_as_limit && select.offset.is_some() {
4712 if let Some(fetch) = &select.fetch {
4713 if self.config.pretty {
4714 self.write_newline();
4715 self.write_indent();
4716 } else {
4717 self.write_space();
4718 }
4719 self.write_keyword("LIMIT");
4720 self.write_space();
4721 self.generate_expression(fetch.count.as_ref().unwrap())?;
4722 }
4723 }
4724
4725 if let Some(offset) = &select.offset {
4729 if self.config.pretty {
4730 self.write_newline();
4731 self.write_indent();
4732 } else {
4733 self.write_space();
4734 }
4735 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4736 self.write_keyword("OFFSET");
4738 self.write_space();
4739 self.write_limit_expr(&offset.this)?;
4740 self.write_space();
4741 self.write_keyword("ROWS");
4742 if let Some(limit) = &select.limit {
4744 self.write_space();
4745 self.write_keyword("FETCH NEXT");
4746 self.write_space();
4747 self.write_limit_expr(&limit.this)?;
4748 self.write_space();
4749 self.write_keyword("ROWS ONLY");
4750 }
4751 } else {
4752 self.write_keyword("OFFSET");
4753 self.write_space();
4754 self.write_limit_expr(&offset.this)?;
4755 if offset.rows == Some(true) {
4757 self.write_space();
4758 self.write_keyword("ROWS");
4759 }
4760 }
4761 }
4762 }
4763
4764 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4766 if let Some(limit_by) = &select.limit_by {
4767 if !limit_by.is_empty() {
4768 self.write_space();
4769 self.write_keyword("BY");
4770 self.write_space();
4771 for (i, expr) in limit_by.iter().enumerate() {
4772 if i > 0 {
4773 self.write(", ");
4774 }
4775 self.generate_expression(expr)?;
4776 }
4777 }
4778 }
4779 }
4780
4781 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
4783 if let Some(settings) = &select.settings {
4784 if self.config.pretty {
4785 self.write_newline();
4786 self.write_indent();
4787 } else {
4788 self.write_space();
4789 }
4790 self.write_keyword("SETTINGS");
4791 self.write_space();
4792 for (i, expr) in settings.iter().enumerate() {
4793 if i > 0 {
4794 self.write(", ");
4795 }
4796 self.generate_expression(expr)?;
4797 }
4798 }
4799
4800 if let Some(format_expr) = &select.format {
4801 if self.config.pretty {
4802 self.write_newline();
4803 self.write_indent();
4804 } else {
4805 self.write_space();
4806 }
4807 self.write_keyword("FORMAT");
4808 self.write_space();
4809 self.generate_expression(format_expr)?;
4810 }
4811 }
4812
4813 if let Some(fetch) = &select.fetch {
4815 let fetch_already_as_limit = select.offset.is_some()
4817 && !fetch.percent
4818 && !fetch.with_ties
4819 && fetch.count.is_some()
4820 && matches!(
4821 self.config.dialect,
4822 Some(DialectType::Spark)
4823 | Some(DialectType::Hive)
4824 | Some(DialectType::DuckDB)
4825 | Some(DialectType::SQLite)
4826 | Some(DialectType::MySQL)
4827 | Some(DialectType::BigQuery)
4828 | Some(DialectType::Databricks)
4829 | Some(DialectType::StarRocks)
4830 | Some(DialectType::Doris)
4831 | Some(DialectType::Athena)
4832 | Some(DialectType::ClickHouse)
4833 | Some(DialectType::Redshift)
4834 );
4835
4836 if fetch_already_as_limit {
4837 } else {
4839 if self.config.pretty {
4840 self.write_newline();
4841 self.write_indent();
4842 } else {
4843 self.write_space();
4844 }
4845
4846 let use_limit = !fetch.percent
4848 && !fetch.with_ties
4849 && fetch.count.is_some()
4850 && matches!(
4851 self.config.dialect,
4852 Some(DialectType::Spark)
4853 | Some(DialectType::Hive)
4854 | Some(DialectType::DuckDB)
4855 | Some(DialectType::SQLite)
4856 | Some(DialectType::MySQL)
4857 | Some(DialectType::BigQuery)
4858 | Some(DialectType::Databricks)
4859 | Some(DialectType::StarRocks)
4860 | Some(DialectType::Doris)
4861 | Some(DialectType::Athena)
4862 | Some(DialectType::ClickHouse)
4863 | Some(DialectType::Redshift)
4864 );
4865
4866 if use_limit {
4867 self.write_keyword("LIMIT");
4868 self.write_space();
4869 self.generate_expression(fetch.count.as_ref().unwrap())?;
4870 } else {
4871 self.write_keyword("FETCH");
4872 self.write_space();
4873 self.write_keyword(&fetch.direction);
4874 if let Some(ref count) = fetch.count {
4875 self.write_space();
4876 self.generate_expression(count)?;
4877 }
4878 if fetch.percent {
4879 self.write_space();
4880 self.write_keyword("PERCENT");
4881 }
4882 if fetch.rows {
4883 self.write_space();
4884 self.write_keyword("ROWS");
4885 }
4886 if fetch.with_ties {
4887 self.write_space();
4888 self.write_keyword("WITH TIES");
4889 } else {
4890 self.write_space();
4891 self.write_keyword("ONLY");
4892 }
4893 }
4894 } }
4896
4897 if let Some(sample) = &select.sample {
4899 use crate::dialects::DialectType;
4900 if self.config.pretty {
4901 self.write_newline();
4902 } else {
4903 self.write_space();
4904 }
4905
4906 if sample.is_using_sample {
4907 self.write_keyword("USING SAMPLE");
4909 self.generate_sample_body(sample)?;
4910 } else {
4911 self.write_keyword("TABLESAMPLE");
4912
4913 let snowflake_bernoulli =
4915 matches!(self.config.dialect, Some(DialectType::Snowflake))
4916 && !sample.explicit_method;
4917 if snowflake_bernoulli {
4918 self.write_space();
4919 self.write_keyword("BERNOULLI");
4920 }
4921
4922 if matches!(sample.method, SampleMethod::Bucket) {
4924 self.write_space();
4925 self.write("(");
4926 self.write_keyword("BUCKET");
4927 self.write_space();
4928 if let Some(ref num) = sample.bucket_numerator {
4929 self.generate_expression(num)?;
4930 }
4931 self.write_space();
4932 self.write_keyword("OUT OF");
4933 self.write_space();
4934 if let Some(ref denom) = sample.bucket_denominator {
4935 self.generate_expression(denom)?;
4936 }
4937 if let Some(ref field) = sample.bucket_field {
4938 self.write_space();
4939 self.write_keyword("ON");
4940 self.write_space();
4941 self.generate_expression(field)?;
4942 }
4943 self.write(")");
4944 } else if sample.unit_after_size {
4945 if sample.explicit_method && sample.method_before_size {
4947 self.write_space();
4948 match sample.method {
4949 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4950 SampleMethod::System => self.write_keyword("SYSTEM"),
4951 SampleMethod::Block => self.write_keyword("BLOCK"),
4952 SampleMethod::Row => self.write_keyword("ROW"),
4953 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4954 _ => {}
4955 }
4956 }
4957 self.write(" (");
4958 self.generate_expression(&sample.size)?;
4959 self.write_space();
4960 match sample.method {
4961 SampleMethod::Percent => self.write_keyword("PERCENT"),
4962 SampleMethod::Row => self.write_keyword("ROWS"),
4963 SampleMethod::Reservoir => self.write_keyword("ROWS"),
4964 _ => {
4965 self.write_keyword("PERCENT");
4966 }
4967 }
4968 self.write(")");
4969 } else {
4970 self.write_space();
4972 match sample.method {
4973 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
4974 SampleMethod::System => self.write_keyword("SYSTEM"),
4975 SampleMethod::Block => self.write_keyword("BLOCK"),
4976 SampleMethod::Row => self.write_keyword("ROW"),
4977 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
4978 SampleMethod::Bucket => {}
4979 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
4980 }
4981 self.write(" (");
4982 self.generate_expression(&sample.size)?;
4983 if matches!(sample.method, SampleMethod::Percent) {
4984 self.write_space();
4985 self.write_keyword("PERCENT");
4986 }
4987 self.write(")");
4988 }
4989 }
4990
4991 if let Some(seed) = &sample.seed {
4992 self.write_space();
4993 let use_seed = sample.use_seed_keyword
4995 && !matches!(
4996 self.config.dialect,
4997 Some(crate::dialects::DialectType::Databricks)
4998 | Some(crate::dialects::DialectType::Spark)
4999 );
5000 if use_seed {
5001 self.write_keyword("SEED");
5002 } else {
5003 self.write_keyword("REPEATABLE");
5004 }
5005 self.write(" (");
5006 self.generate_expression(seed)?;
5007 self.write(")");
5008 }
5009 }
5010
5011 if self.config.locking_reads_supported {
5014 for lock in &select.locks {
5015 if self.config.pretty {
5016 self.write_newline();
5017 self.write_indent();
5018 } else {
5019 self.write_space();
5020 }
5021 self.generate_lock(lock)?;
5022 }
5023 }
5024
5025 if !select.for_xml.is_empty() {
5027 if self.config.pretty {
5028 self.write_newline();
5029 self.write_indent();
5030 } else {
5031 self.write_space();
5032 }
5033 self.write_keyword("FOR XML");
5034 for (i, opt) in select.for_xml.iter().enumerate() {
5035 if self.config.pretty {
5036 if i > 0 {
5037 self.write(",");
5038 }
5039 self.write_newline();
5040 self.write_indent();
5041 self.write(" "); } else {
5043 if i > 0 {
5044 self.write(",");
5045 }
5046 self.write_space();
5047 }
5048 self.generate_for_xml_option(opt)?;
5049 }
5050 }
5051
5052 if let Some(ref option) = select.option {
5054 if matches!(
5055 self.config.dialect,
5056 Some(crate::dialects::DialectType::TSQL)
5057 | Some(crate::dialects::DialectType::Fabric)
5058 ) {
5059 self.write_space();
5060 self.write(option);
5061 }
5062 }
5063
5064 Ok(())
5065 }
5066
5067 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
5069 match opt {
5070 Expression::QueryOption(qo) => {
5071 if let Expression::Var(var) = &*qo.this {
5073 self.write(&var.this);
5074 } else {
5075 self.generate_expression(&qo.this)?;
5076 }
5077 if let Some(expr) = &qo.expression {
5079 self.write("(");
5080 self.generate_expression(expr)?;
5081 self.write(")");
5082 }
5083 }
5084 _ => {
5085 self.generate_expression(opt)?;
5086 }
5087 }
5088 Ok(())
5089 }
5090
5091 fn generate_with(&mut self, with: &With) -> Result<()> {
5092 use crate::dialects::DialectType;
5093
5094 for comment in &with.leading_comments {
5096 self.write_formatted_comment(comment);
5097 self.write(" ");
5098 }
5099 self.write_keyword("WITH");
5100 if with.recursive && self.config.cte_recursive_keyword_required {
5101 self.write_space();
5102 self.write_keyword("RECURSIVE");
5103 }
5104 self.write_space();
5105
5106 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
5108
5109 for (i, cte) in with.ctes.iter().enumerate() {
5110 if i > 0 {
5111 self.write(",");
5112 if self.config.pretty {
5113 self.write_space();
5114 } else {
5115 self.write(" ");
5116 }
5117 }
5118 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
5119 self.generate_expression(&cte.this)?;
5120 self.write_space();
5121 self.write_keyword("AS");
5122 self.write_space();
5123 self.generate_identifier(&cte.alias)?;
5124 continue;
5125 }
5126 self.generate_identifier(&cte.alias)?;
5127 for comment in &cte.comments {
5129 self.write_space();
5130 self.write_formatted_comment(comment);
5131 }
5132 if !cte.columns.is_empty() && !skip_cte_columns {
5133 self.write("(");
5134 for (j, col) in cte.columns.iter().enumerate() {
5135 if j > 0 {
5136 self.write(", ");
5137 }
5138 self.generate_identifier(col)?;
5139 }
5140 self.write(")");
5141 }
5142 if !cte.key_expressions.is_empty() {
5144 self.write_space();
5145 self.write_keyword("USING KEY");
5146 self.write(" (");
5147 for (i, key) in cte.key_expressions.iter().enumerate() {
5148 if i > 0 {
5149 self.write(", ");
5150 }
5151 self.generate_identifier(key)?;
5152 }
5153 self.write(")");
5154 }
5155 self.write_space();
5156 self.write_keyword("AS");
5157 if let Some(materialized) = cte.materialized {
5159 self.write_space();
5160 if materialized {
5161 self.write_keyword("MATERIALIZED");
5162 } else {
5163 self.write_keyword("NOT MATERIALIZED");
5164 }
5165 }
5166 self.write(" (");
5167 if self.config.pretty {
5168 self.write_newline();
5169 self.indent_level += 1;
5170 self.write_indent();
5171 }
5172 let wrap_values_in_select = matches!(
5175 self.config.dialect,
5176 Some(DialectType::Spark) | Some(DialectType::Databricks)
5177 ) && matches!(&cte.this, Expression::Values(_));
5178
5179 if wrap_values_in_select {
5180 self.write_keyword("SELECT");
5181 self.write(" * ");
5182 self.write_keyword("FROM");
5183 self.write_space();
5184 }
5185 self.generate_expression(&cte.this)?;
5186 if self.config.pretty {
5187 self.write_newline();
5188 self.indent_level -= 1;
5189 self.write_indent();
5190 }
5191 self.write(")");
5192 }
5193
5194 if let Some(search) = &with.search {
5196 self.write_space();
5197 self.generate_expression(search)?;
5198 }
5199
5200 Ok(())
5201 }
5202
5203 fn generate_joins_with_nesting(&mut self, joins: &[Join]) -> Result<()> {
5207 let mut i = 0;
5208 while i < joins.len() {
5209 if joins[i].deferred_condition {
5210 let parent_group = joins[i].nesting_group;
5211
5212 self.generate_join_without_condition(&joins[i])?;
5215
5216 let child_start = i + 1;
5218 let mut child_end = child_start;
5219 while child_end < joins.len()
5220 && !joins[child_end].deferred_condition
5221 && joins[child_end].nesting_group == parent_group
5222 {
5223 child_end += 1;
5224 }
5225
5226 if child_start < child_end {
5228 self.indent_level += 1;
5229 for j in child_start..child_end {
5230 self.generate_join(&joins[j])?;
5231 }
5232 self.indent_level -= 1;
5233 }
5234
5235 self.generate_join_condition(&joins[i])?;
5237
5238 i = child_end;
5239 } else {
5240 self.generate_join(&joins[i])?;
5242 i += 1;
5243 }
5244 }
5245 Ok(())
5246 }
5247
5248 fn generate_join_without_condition(&mut self, join: &Join) -> Result<()> {
5251 let mut join_copy = join.clone();
5254 join_copy.on = None;
5255 join_copy.using = Vec::new();
5256 join_copy.deferred_condition = false;
5257 self.generate_join(&join_copy)
5258 }
5259
5260 fn generate_join(&mut self, join: &Join) -> Result<()> {
5261 if join.kind == JoinKind::Implicit {
5263 self.write(",");
5264 if self.config.pretty {
5265 self.write_newline();
5266 self.write_indent();
5267 } else {
5268 self.write_space();
5269 }
5270 self.generate_expression(&join.this)?;
5271 return Ok(());
5272 }
5273
5274 if self.config.pretty {
5275 self.write_newline();
5276 self.write_indent();
5277 } else {
5278 self.write_space();
5279 }
5280
5281 let hint_str = if self.config.join_hints {
5284 join.join_hint
5285 .as_ref()
5286 .map(|h| format!(" {}", h))
5287 .unwrap_or_default()
5288 } else {
5289 String::new()
5290 };
5291
5292 let clickhouse_join_keyword =
5293 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
5294 if let Some(hint) = &join.join_hint {
5295 let mut global = false;
5296 let mut strictness: Option<&'static str> = None;
5297 for part in hint.split_whitespace() {
5298 if part.eq_ignore_ascii_case("GLOBAL") {
5299 global = true;
5300 } else if part.eq_ignore_ascii_case("ANY") {
5301 strictness = Some("ANY");
5302 } else if part.eq_ignore_ascii_case("ASOF") {
5303 strictness = Some("ASOF");
5304 } else if part.eq_ignore_ascii_case("SEMI") {
5305 strictness = Some("SEMI");
5306 } else if part.eq_ignore_ascii_case("ANTI") {
5307 strictness = Some("ANTI");
5308 }
5309 }
5310
5311 if global || strictness.is_some() {
5312 let join_type = match join.kind {
5313 JoinKind::Left => {
5314 if join.use_outer_keyword {
5315 "LEFT OUTER"
5316 } else if join.use_inner_keyword {
5317 "LEFT INNER"
5318 } else {
5319 "LEFT"
5320 }
5321 }
5322 JoinKind::Right => {
5323 if join.use_outer_keyword {
5324 "RIGHT OUTER"
5325 } else if join.use_inner_keyword {
5326 "RIGHT INNER"
5327 } else {
5328 "RIGHT"
5329 }
5330 }
5331 JoinKind::Full => {
5332 if join.use_outer_keyword {
5333 "FULL OUTER"
5334 } else {
5335 "FULL"
5336 }
5337 }
5338 JoinKind::Inner => {
5339 if join.use_inner_keyword {
5340 "INNER"
5341 } else {
5342 ""
5343 }
5344 }
5345 _ => "",
5346 };
5347
5348 let mut parts = Vec::new();
5349 if global {
5350 parts.push("GLOBAL");
5351 }
5352 if !join_type.is_empty() {
5353 parts.push(join_type);
5354 }
5355 if let Some(strict) = strictness {
5356 parts.push(strict);
5357 }
5358 parts.push("JOIN");
5359 Some(parts.join(" "))
5360 } else {
5361 None
5362 }
5363 } else {
5364 None
5365 }
5366 } else {
5367 None
5368 };
5369
5370 if !join.comments.is_empty() {
5374 if self.config.pretty {
5375 let trimmed = self.output.trim_end().len();
5380 self.output.truncate(trimmed);
5381 for comment in &join.comments {
5382 self.write_newline();
5383 self.write_indent();
5384 self.write_formatted_comment(comment);
5385 }
5386 self.write_newline();
5387 self.write_indent();
5388 } else {
5389 for comment in &join.comments {
5390 self.write_formatted_comment(comment);
5391 self.write_space();
5392 }
5393 }
5394 }
5395
5396 let directed_str = if join.directed { " DIRECTED" } else { "" };
5397
5398 if let Some(keyword) = clickhouse_join_keyword {
5399 self.write_keyword(&keyword);
5400 } else {
5401 match join.kind {
5402 JoinKind::Inner => {
5403 if join.use_inner_keyword {
5404 if hint_str.is_empty() && directed_str.is_empty() {
5405 self.write_keyword("INNER JOIN");
5406 } else {
5407 self.write_keyword("INNER");
5408 if !hint_str.is_empty() {
5409 self.write_keyword(&hint_str);
5410 }
5411 if !directed_str.is_empty() {
5412 self.write_keyword(directed_str);
5413 }
5414 self.write_keyword(" JOIN");
5415 }
5416 } else {
5417 if !hint_str.is_empty() {
5418 self.write_keyword(hint_str.trim());
5419 self.write_keyword(" ");
5420 }
5421 if !directed_str.is_empty() {
5422 self.write_keyword("DIRECTED ");
5423 }
5424 self.write_keyword("JOIN");
5425 }
5426 }
5427 JoinKind::Left => {
5428 if join.use_outer_keyword {
5429 if hint_str.is_empty() && directed_str.is_empty() {
5430 self.write_keyword("LEFT OUTER JOIN");
5431 } else {
5432 self.write_keyword("LEFT OUTER");
5433 if !hint_str.is_empty() {
5434 self.write_keyword(&hint_str);
5435 }
5436 if !directed_str.is_empty() {
5437 self.write_keyword(directed_str);
5438 }
5439 self.write_keyword(" JOIN");
5440 }
5441 } else if join.use_inner_keyword {
5442 if hint_str.is_empty() && directed_str.is_empty() {
5443 self.write_keyword("LEFT INNER JOIN");
5444 } else {
5445 self.write_keyword("LEFT INNER");
5446 if !hint_str.is_empty() {
5447 self.write_keyword(&hint_str);
5448 }
5449 if !directed_str.is_empty() {
5450 self.write_keyword(directed_str);
5451 }
5452 self.write_keyword(" JOIN");
5453 }
5454 } else {
5455 if hint_str.is_empty() && directed_str.is_empty() {
5456 self.write_keyword("LEFT JOIN");
5457 } else {
5458 self.write_keyword("LEFT");
5459 if !hint_str.is_empty() {
5460 self.write_keyword(&hint_str);
5461 }
5462 if !directed_str.is_empty() {
5463 self.write_keyword(directed_str);
5464 }
5465 self.write_keyword(" JOIN");
5466 }
5467 }
5468 }
5469 JoinKind::Right => {
5470 if join.use_outer_keyword {
5471 if hint_str.is_empty() && directed_str.is_empty() {
5472 self.write_keyword("RIGHT OUTER JOIN");
5473 } else {
5474 self.write_keyword("RIGHT OUTER");
5475 if !hint_str.is_empty() {
5476 self.write_keyword(&hint_str);
5477 }
5478 if !directed_str.is_empty() {
5479 self.write_keyword(directed_str);
5480 }
5481 self.write_keyword(" JOIN");
5482 }
5483 } else if join.use_inner_keyword {
5484 if hint_str.is_empty() && directed_str.is_empty() {
5485 self.write_keyword("RIGHT INNER JOIN");
5486 } else {
5487 self.write_keyword("RIGHT INNER");
5488 if !hint_str.is_empty() {
5489 self.write_keyword(&hint_str);
5490 }
5491 if !directed_str.is_empty() {
5492 self.write_keyword(directed_str);
5493 }
5494 self.write_keyword(" JOIN");
5495 }
5496 } else {
5497 if hint_str.is_empty() && directed_str.is_empty() {
5498 self.write_keyword("RIGHT JOIN");
5499 } else {
5500 self.write_keyword("RIGHT");
5501 if !hint_str.is_empty() {
5502 self.write_keyword(&hint_str);
5503 }
5504 if !directed_str.is_empty() {
5505 self.write_keyword(directed_str);
5506 }
5507 self.write_keyword(" JOIN");
5508 }
5509 }
5510 }
5511 JoinKind::Full => {
5512 if join.use_outer_keyword {
5513 if hint_str.is_empty() && directed_str.is_empty() {
5514 self.write_keyword("FULL OUTER JOIN");
5515 } else {
5516 self.write_keyword("FULL OUTER");
5517 if !hint_str.is_empty() {
5518 self.write_keyword(&hint_str);
5519 }
5520 if !directed_str.is_empty() {
5521 self.write_keyword(directed_str);
5522 }
5523 self.write_keyword(" JOIN");
5524 }
5525 } else {
5526 if hint_str.is_empty() && directed_str.is_empty() {
5527 self.write_keyword("FULL JOIN");
5528 } else {
5529 self.write_keyword("FULL");
5530 if !hint_str.is_empty() {
5531 self.write_keyword(&hint_str);
5532 }
5533 if !directed_str.is_empty() {
5534 self.write_keyword(directed_str);
5535 }
5536 self.write_keyword(" JOIN");
5537 }
5538 }
5539 }
5540 JoinKind::Outer => {
5541 if directed_str.is_empty() {
5542 self.write_keyword("OUTER JOIN");
5543 } else {
5544 self.write_keyword("OUTER");
5545 self.write_keyword(directed_str);
5546 self.write_keyword(" JOIN");
5547 }
5548 }
5549 JoinKind::Cross => {
5550 if directed_str.is_empty() {
5551 self.write_keyword("CROSS JOIN");
5552 } else {
5553 self.write_keyword("CROSS");
5554 self.write_keyword(directed_str);
5555 self.write_keyword(" JOIN");
5556 }
5557 }
5558 JoinKind::Natural => {
5559 if join.use_inner_keyword {
5560 if directed_str.is_empty() {
5561 self.write_keyword("NATURAL INNER JOIN");
5562 } else {
5563 self.write_keyword("NATURAL INNER");
5564 self.write_keyword(directed_str);
5565 self.write_keyword(" JOIN");
5566 }
5567 } else {
5568 if directed_str.is_empty() {
5569 self.write_keyword("NATURAL JOIN");
5570 } else {
5571 self.write_keyword("NATURAL");
5572 self.write_keyword(directed_str);
5573 self.write_keyword(" JOIN");
5574 }
5575 }
5576 }
5577 JoinKind::NaturalLeft => {
5578 if join.use_outer_keyword {
5579 if directed_str.is_empty() {
5580 self.write_keyword("NATURAL LEFT OUTER JOIN");
5581 } else {
5582 self.write_keyword("NATURAL LEFT OUTER");
5583 self.write_keyword(directed_str);
5584 self.write_keyword(" JOIN");
5585 }
5586 } else {
5587 if directed_str.is_empty() {
5588 self.write_keyword("NATURAL LEFT JOIN");
5589 } else {
5590 self.write_keyword("NATURAL LEFT");
5591 self.write_keyword(directed_str);
5592 self.write_keyword(" JOIN");
5593 }
5594 }
5595 }
5596 JoinKind::NaturalRight => {
5597 if join.use_outer_keyword {
5598 if directed_str.is_empty() {
5599 self.write_keyword("NATURAL RIGHT OUTER JOIN");
5600 } else {
5601 self.write_keyword("NATURAL RIGHT OUTER");
5602 self.write_keyword(directed_str);
5603 self.write_keyword(" JOIN");
5604 }
5605 } else {
5606 if directed_str.is_empty() {
5607 self.write_keyword("NATURAL RIGHT JOIN");
5608 } else {
5609 self.write_keyword("NATURAL RIGHT");
5610 self.write_keyword(directed_str);
5611 self.write_keyword(" JOIN");
5612 }
5613 }
5614 }
5615 JoinKind::NaturalFull => {
5616 if join.use_outer_keyword {
5617 if directed_str.is_empty() {
5618 self.write_keyword("NATURAL FULL OUTER JOIN");
5619 } else {
5620 self.write_keyword("NATURAL FULL OUTER");
5621 self.write_keyword(directed_str);
5622 self.write_keyword(" JOIN");
5623 }
5624 } else {
5625 if directed_str.is_empty() {
5626 self.write_keyword("NATURAL FULL JOIN");
5627 } else {
5628 self.write_keyword("NATURAL FULL");
5629 self.write_keyword(directed_str);
5630 self.write_keyword(" JOIN");
5631 }
5632 }
5633 }
5634 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
5635 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
5636 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
5637 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
5638 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
5639 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
5640 JoinKind::CrossApply => {
5641 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5643 self.write_keyword("CROSS APPLY");
5644 } else {
5645 self.write_keyword("INNER JOIN LATERAL");
5646 }
5647 }
5648 JoinKind::OuterApply => {
5649 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
5651 self.write_keyword("OUTER APPLY");
5652 } else {
5653 self.write_keyword("LEFT JOIN LATERAL");
5654 }
5655 }
5656 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
5657 JoinKind::AsOfLeft => {
5658 if join.use_outer_keyword {
5659 self.write_keyword("ASOF LEFT OUTER JOIN");
5660 } else {
5661 self.write_keyword("ASOF LEFT JOIN");
5662 }
5663 }
5664 JoinKind::AsOfRight => {
5665 if join.use_outer_keyword {
5666 self.write_keyword("ASOF RIGHT OUTER JOIN");
5667 } else {
5668 self.write_keyword("ASOF RIGHT JOIN");
5669 }
5670 }
5671 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
5672 JoinKind::LeftLateral => {
5673 if join.use_outer_keyword {
5674 self.write_keyword("LEFT OUTER LATERAL JOIN");
5675 } else {
5676 self.write_keyword("LEFT LATERAL JOIN");
5677 }
5678 }
5679 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
5680 JoinKind::Implicit => {
5681 use crate::dialects::DialectType;
5685 let is_cj_dialect = matches!(
5686 self.config.dialect,
5687 Some(DialectType::BigQuery)
5688 | Some(DialectType::Hive)
5689 | Some(DialectType::Spark)
5690 | Some(DialectType::Databricks)
5691 );
5692 let source_is_same = self.config.source_dialect.is_some()
5693 && self.config.source_dialect == self.config.dialect;
5694 let source_is_cj = matches!(
5695 self.config.source_dialect,
5696 Some(DialectType::BigQuery)
5697 | Some(DialectType::Hive)
5698 | Some(DialectType::Spark)
5699 | Some(DialectType::Databricks)
5700 );
5701 if is_cj_dialect
5702 && (source_is_same || source_is_cj || self.config.source_dialect.is_none())
5703 {
5704 self.write_keyword("CROSS JOIN");
5705 } else {
5706 self.output.truncate(self.output.trim_end().len());
5710 self.write(",");
5711 }
5712 }
5713 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
5714 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
5715 JoinKind::Paste => self.write_keyword("PASTE JOIN"),
5716 JoinKind::Positional => self.write_keyword("POSITIONAL JOIN"),
5717 }
5718 }
5719
5720 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
5722 self.write_space();
5723 match &join.this {
5724 Expression::Tuple(t) => {
5725 for (i, item) in t.expressions.iter().enumerate() {
5726 if i > 0 {
5727 self.write(", ");
5728 }
5729 self.generate_expression(item)?;
5730 }
5731 }
5732 other => {
5733 self.generate_expression(other)?;
5734 }
5735 }
5736 } else {
5737 self.write_space();
5738 self.generate_expression(&join.this)?;
5739 }
5740
5741 if !join.deferred_condition {
5743 if let Some(match_cond) = &join.match_condition {
5745 self.write_space();
5746 self.write_keyword("MATCH_CONDITION");
5747 self.write(" (");
5748 self.generate_expression(match_cond)?;
5749 self.write(")");
5750 }
5751
5752 if let Some(on) = &join.on {
5753 if self.config.pretty {
5754 self.write_newline();
5755 self.indent_level += 1;
5756 self.write_indent();
5757 self.write_keyword("ON");
5758 self.write_space();
5759 self.generate_join_on_condition(on)?;
5760 self.indent_level -= 1;
5761 } else {
5762 self.write_space();
5763 self.write_keyword("ON");
5764 self.write_space();
5765 self.generate_expression(on)?;
5766 }
5767 }
5768
5769 if !join.using.is_empty() {
5770 if self.config.pretty {
5771 self.write_newline();
5772 self.indent_level += 1;
5773 self.write_indent();
5774 self.write_keyword("USING");
5775 self.write(" (");
5776 for (i, col) in join.using.iter().enumerate() {
5777 if i > 0 {
5778 self.write(", ");
5779 }
5780 self.generate_identifier(col)?;
5781 }
5782 self.write(")");
5783 self.indent_level -= 1;
5784 } else {
5785 self.write_space();
5786 self.write_keyword("USING");
5787 self.write(" (");
5788 for (i, col) in join.using.iter().enumerate() {
5789 if i > 0 {
5790 self.write(", ");
5791 }
5792 self.generate_identifier(col)?;
5793 }
5794 self.write(")");
5795 }
5796 }
5797 }
5798
5799 for pivot in &join.pivots {
5801 self.write_space();
5802 self.generate_expression(pivot)?;
5803 }
5804
5805 Ok(())
5806 }
5807
5808 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
5810 if let Some(match_cond) = &join.match_condition {
5812 self.write_space();
5813 self.write_keyword("MATCH_CONDITION");
5814 self.write(" (");
5815 self.generate_expression(match_cond)?;
5816 self.write(")");
5817 }
5818
5819 if let Some(on) = &join.on {
5820 if self.config.pretty {
5821 self.write_newline();
5822 self.indent_level += 1;
5823 self.write_indent();
5824 self.write_keyword("ON");
5825 self.write_space();
5826 self.generate_join_on_condition(on)?;
5828 self.indent_level -= 1;
5829 } else {
5830 self.write_space();
5831 self.write_keyword("ON");
5832 self.write_space();
5833 self.generate_expression(on)?;
5834 }
5835 }
5836
5837 if !join.using.is_empty() {
5838 if self.config.pretty {
5839 self.write_newline();
5840 self.indent_level += 1;
5841 self.write_indent();
5842 self.write_keyword("USING");
5843 self.write(" (");
5844 for (i, col) in join.using.iter().enumerate() {
5845 if i > 0 {
5846 self.write(", ");
5847 }
5848 self.generate_identifier(col)?;
5849 }
5850 self.write(")");
5851 self.indent_level -= 1;
5852 } else {
5853 self.write_space();
5854 self.write_keyword("USING");
5855 self.write(" (");
5856 for (i, col) in join.using.iter().enumerate() {
5857 if i > 0 {
5858 self.write(", ");
5859 }
5860 self.generate_identifier(col)?;
5861 }
5862 self.write(")");
5863 }
5864 }
5865
5866 for pivot in &join.pivots {
5868 self.write_space();
5869 self.generate_expression(pivot)?;
5870 }
5871
5872 Ok(())
5873 }
5874
5875 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
5877 if let Expression::And(and_op) = expr {
5878 if let Some(conditions) = self.flatten_connector_terms(and_op, ConnectorOperator::And) {
5879 self.generate_expression(conditions[0])?;
5880 for condition in conditions.iter().skip(1) {
5881 self.write_newline();
5882 self.write_indent();
5883 self.write_keyword("AND");
5884 self.write_space();
5885 self.generate_expression(condition)?;
5886 }
5887 return Ok(());
5888 }
5889 }
5890
5891 self.generate_expression(expr)
5892 }
5893
5894 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
5895 self.write("(");
5897 self.generate_expression(&jt.left)?;
5898
5899 for join in &jt.joins {
5901 self.generate_join(join)?;
5902 }
5903
5904 for (lv_idx, lv) in jt.lateral_views.iter().enumerate() {
5906 self.generate_lateral_view(lv, lv_idx)?;
5907 }
5908
5909 self.write(")");
5910
5911 if let Some(alias) = &jt.alias {
5913 self.write_space();
5914 self.write_keyword("AS");
5915 self.write_space();
5916 self.generate_identifier(alias)?;
5917 }
5918
5919 Ok(())
5920 }
5921
5922 fn generate_lateral_view(&mut self, lv: &LateralView, lv_index: usize) -> Result<()> {
5923 use crate::dialects::DialectType;
5924
5925 if self.config.pretty {
5926 self.write_newline();
5927 self.write_indent();
5928 } else {
5929 self.write_space();
5930 }
5931
5932 let use_lateral_join = matches!(
5935 self.config.dialect,
5936 Some(DialectType::PostgreSQL)
5937 | Some(DialectType::DuckDB)
5938 | Some(DialectType::Snowflake)
5939 | Some(DialectType::TSQL)
5940 | Some(DialectType::Presto)
5941 | Some(DialectType::Trino)
5942 | Some(DialectType::Athena)
5943 );
5944
5945 let use_unnest = matches!(
5947 self.config.dialect,
5948 Some(DialectType::DuckDB)
5949 | Some(DialectType::Presto)
5950 | Some(DialectType::Trino)
5951 | Some(DialectType::Athena)
5952 );
5953
5954 let (is_posexplode, is_inline, func_args) = match &lv.this {
5956 Expression::Explode(uf) => {
5957 (false, false, vec![uf.this.clone()])
5959 }
5960 Expression::Unnest(uf) => {
5961 let mut args = vec![uf.this.clone()];
5962 args.extend(uf.expressions.clone());
5963 (false, false, args)
5964 }
5965 Expression::Function(func) => {
5966 if func.name.eq_ignore_ascii_case("POSEXPLODE")
5967 || func.name.eq_ignore_ascii_case("POSEXPLODE_OUTER")
5968 {
5969 (true, false, func.args.clone())
5970 } else if func.name.eq_ignore_ascii_case("INLINE") {
5971 (false, true, func.args.clone())
5972 } else if func.name.eq_ignore_ascii_case("EXPLODE")
5973 || func.name.eq_ignore_ascii_case("EXPLODE_OUTER")
5974 {
5975 (false, false, func.args.clone())
5976 } else {
5977 (false, false, vec![])
5978 }
5979 }
5980 _ => (false, false, vec![]),
5981 };
5982
5983 if use_lateral_join {
5984 if lv.outer {
5986 self.write_keyword("LEFT JOIN LATERAL");
5987 } else {
5988 self.write_keyword("CROSS JOIN");
5989 }
5990 self.write_space();
5991
5992 if use_unnest && !func_args.is_empty() {
5993 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
5996 func_args
5998 .iter()
5999 .map(|a| {
6000 if let Expression::Function(ref f) = a {
6001 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() == 1 {
6002 return Expression::ArrayFunc(Box::new(
6003 crate::expressions::ArrayConstructor {
6004 expressions: f.args.clone(),
6005 bracket_notation: true,
6006 use_list_keyword: false,
6007 },
6008 ));
6009 }
6010 }
6011 a.clone()
6012 })
6013 .collect::<Vec<_>>()
6014 } else if matches!(
6015 self.config.dialect,
6016 Some(DialectType::Presto)
6017 | Some(DialectType::Trino)
6018 | Some(DialectType::Athena)
6019 ) {
6020 func_args
6022 .iter()
6023 .map(|a| {
6024 if let Expression::Function(ref f) = a {
6025 if f.name.eq_ignore_ascii_case("ARRAY") && f.args.len() >= 1 {
6026 return Expression::ArrayFunc(Box::new(
6027 crate::expressions::ArrayConstructor {
6028 expressions: f.args.clone(),
6029 bracket_notation: true,
6030 use_list_keyword: false,
6031 },
6032 ));
6033 }
6034 }
6035 a.clone()
6036 })
6037 .collect::<Vec<_>>()
6038 } else {
6039 func_args
6040 };
6041
6042 if is_posexplode {
6044 self.write_keyword("LATERAL");
6045 self.write(" (");
6046 self.write_keyword("SELECT");
6047 self.write_space();
6048
6049 let pos_alias = if !lv.column_aliases.is_empty() {
6052 lv.column_aliases[0].clone()
6053 } else {
6054 Identifier::new("pos")
6055 };
6056 let data_aliases: Vec<Identifier> = if lv.column_aliases.len() > 1 {
6057 lv.column_aliases[1..].to_vec()
6058 } else {
6059 vec![Identifier::new("col")]
6060 };
6061
6062 self.generate_identifier(&pos_alias)?;
6064 self.write(" - 1");
6065 self.write_space();
6066 self.write_keyword("AS");
6067 self.write_space();
6068 self.generate_identifier(&pos_alias)?;
6069
6070 for data_col in &data_aliases {
6072 self.write(", ");
6073 self.generate_identifier(data_col)?;
6074 }
6075
6076 self.write_space();
6077 self.write_keyword("FROM");
6078 self.write_space();
6079 self.write_keyword("UNNEST");
6080 self.write("(");
6081 for (i, arg) in unnest_args.iter().enumerate() {
6082 if i > 0 {
6083 self.write(", ");
6084 }
6085 self.generate_expression(arg)?;
6086 }
6087 self.write(")");
6088 self.write_space();
6089 self.write_keyword("WITH ORDINALITY");
6090 self.write_space();
6091 self.write_keyword("AS");
6092 self.write_space();
6093
6094 let table_alias_ident = lv
6096 .table_alias
6097 .clone()
6098 .unwrap_or_else(|| Identifier::new("t"));
6099 self.generate_identifier(&table_alias_ident)?;
6100 self.write("(");
6101 for (i, data_col) in data_aliases.iter().enumerate() {
6102 if i > 0 {
6103 self.write(", ");
6104 }
6105 self.generate_identifier(data_col)?;
6106 }
6107 self.write(", ");
6108 self.generate_identifier(&pos_alias)?;
6109 self.write("))");
6110 } else if is_inline && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6111 self.write_keyword("LATERAL");
6113 self.write(" (");
6114 self.write_keyword("SELECT");
6115 self.write_space();
6116 self.write_keyword("UNNEST");
6117 self.write("(");
6118 for (i, arg) in unnest_args.iter().enumerate() {
6119 if i > 0 {
6120 self.write(", ");
6121 }
6122 self.generate_expression(arg)?;
6123 }
6124 self.write(", ");
6125 self.write_keyword("max_depth");
6126 self.write(" => 2))");
6127
6128 if let Some(alias) = &lv.table_alias {
6130 self.write_space();
6131 self.write_keyword("AS");
6132 self.write_space();
6133 self.generate_identifier(alias)?;
6134 if !lv.column_aliases.is_empty() {
6135 self.write("(");
6136 for (i, col) in lv.column_aliases.iter().enumerate() {
6137 if i > 0 {
6138 self.write(", ");
6139 }
6140 self.generate_identifier(col)?;
6141 }
6142 self.write(")");
6143 }
6144 } else if !lv.column_aliases.is_empty() {
6145 self.write_space();
6147 self.write_keyword("AS");
6148 self.write_space();
6149 self.write(&format!("_u_{}", lv_index));
6150 self.write("(");
6151 for (i, col) in lv.column_aliases.iter().enumerate() {
6152 if i > 0 {
6153 self.write(", ");
6154 }
6155 self.generate_identifier(col)?;
6156 }
6157 self.write(")");
6158 }
6159 } else {
6160 self.write_keyword("UNNEST");
6161 self.write("(");
6162 for (i, arg) in unnest_args.iter().enumerate() {
6163 if i > 0 {
6164 self.write(", ");
6165 }
6166 self.generate_expression(arg)?;
6167 }
6168 self.write(")");
6169
6170 if let Some(alias) = &lv.table_alias {
6172 self.write_space();
6173 self.write_keyword("AS");
6174 self.write_space();
6175 self.generate_identifier(alias)?;
6176 if !lv.column_aliases.is_empty() {
6177 self.write("(");
6178 for (i, col) in lv.column_aliases.iter().enumerate() {
6179 if i > 0 {
6180 self.write(", ");
6181 }
6182 self.generate_identifier(col)?;
6183 }
6184 self.write(")");
6185 }
6186 } else if !lv.column_aliases.is_empty() {
6187 self.write_space();
6188 self.write_keyword("AS");
6189 self.write(" t(");
6190 for (i, col) in lv.column_aliases.iter().enumerate() {
6191 if i > 0 {
6192 self.write(", ");
6193 }
6194 self.generate_identifier(col)?;
6195 }
6196 self.write(")");
6197 }
6198 }
6199 } else {
6200 if !lv.outer {
6202 self.write_keyword("LATERAL");
6203 self.write_space();
6204 }
6205 self.generate_expression(&lv.this)?;
6206
6207 if let Some(alias) = &lv.table_alias {
6209 self.write_space();
6210 self.write_keyword("AS");
6211 self.write_space();
6212 self.generate_identifier(alias)?;
6213 if !lv.column_aliases.is_empty() {
6214 self.write("(");
6215 for (i, col) in lv.column_aliases.iter().enumerate() {
6216 if i > 0 {
6217 self.write(", ");
6218 }
6219 self.generate_identifier(col)?;
6220 }
6221 self.write(")");
6222 }
6223 } else if !lv.column_aliases.is_empty() {
6224 self.write_space();
6225 self.write_keyword("AS");
6226 self.write(" t(");
6227 for (i, col) in lv.column_aliases.iter().enumerate() {
6228 if i > 0 {
6229 self.write(", ");
6230 }
6231 self.generate_identifier(col)?;
6232 }
6233 self.write(")");
6234 }
6235 }
6236
6237 if lv.outer {
6239 self.write_space();
6240 self.write_keyword("ON TRUE");
6241 }
6242 } else {
6243 self.write_keyword("LATERAL VIEW");
6245 if lv.outer {
6246 self.write_space();
6247 self.write_keyword("OUTER");
6248 }
6249 if self.config.pretty {
6250 self.write_newline();
6251 self.write_indent();
6252 } else {
6253 self.write_space();
6254 }
6255 self.generate_expression(&lv.this)?;
6256
6257 if let Some(alias) = &lv.table_alias {
6259 self.write_space();
6260 self.generate_identifier(alias)?;
6261 }
6262
6263 if !lv.column_aliases.is_empty() {
6265 self.write_space();
6266 self.write_keyword("AS");
6267 self.write_space();
6268 for (i, col) in lv.column_aliases.iter().enumerate() {
6269 if i > 0 {
6270 self.write(", ");
6271 }
6272 self.generate_identifier(col)?;
6273 }
6274 }
6275 }
6276
6277 Ok(())
6278 }
6279
6280 fn generate_union(&mut self, outermost: &Union) -> Result<()> {
6281 let mut chain: Vec<&Union> = vec![outermost];
6286 let mut leftmost: &Expression = &outermost.left;
6287 while let Expression::Union(inner) = leftmost {
6288 chain.push(inner);
6289 leftmost = &inner.left;
6290 }
6291 if let Some(with) = &outermost.with {
6296 self.generate_with(with)?;
6297 self.write_space();
6298 }
6299
6300 self.generate_expression(leftmost)?;
6302
6303 for union in chain.iter().rev() {
6305 self.generate_union_step(union)?;
6306 }
6307 Ok(())
6308 }
6309
6310 fn generate_union_step(&mut self, union: &Union) -> Result<()> {
6312 if self.config.pretty {
6313 self.write_newline();
6314 self.write_indent();
6315 } else {
6316 self.write_space();
6317 }
6318
6319 if let Some(side) = &union.side {
6321 self.write_keyword(side);
6322 self.write_space();
6323 }
6324 if let Some(kind) = &union.kind {
6325 self.write_keyword(kind);
6326 self.write_space();
6327 }
6328
6329 self.write_keyword("UNION");
6330 if union.all {
6331 self.write_space();
6332 self.write_keyword("ALL");
6333 } else if union.distinct {
6334 self.write_space();
6335 self.write_keyword("DISTINCT");
6336 }
6337
6338 if union.corresponding || union.by_name {
6341 self.write_space();
6342 self.write_keyword("BY NAME");
6343 }
6344 if !union.on_columns.is_empty() {
6345 self.write_space();
6346 self.write_keyword("ON");
6347 self.write(" (");
6348 for (i, col) in union.on_columns.iter().enumerate() {
6349 if i > 0 {
6350 self.write(", ");
6351 }
6352 self.generate_expression(col)?;
6353 }
6354 self.write(")");
6355 }
6356
6357 if self.config.pretty {
6358 self.write_newline();
6359 self.write_indent();
6360 } else {
6361 self.write_space();
6362 }
6363 self.generate_expression(&union.right)?;
6364 if let Some(order_by) = &union.order_by {
6366 if self.config.pretty {
6367 self.write_newline();
6368 } else {
6369 self.write_space();
6370 }
6371 self.write_keyword("ORDER BY");
6372 self.write_space();
6373 for (i, ordered) in order_by.expressions.iter().enumerate() {
6374 if i > 0 {
6375 self.write(", ");
6376 }
6377 self.generate_ordered(ordered)?;
6378 }
6379 }
6380 if let Some(limit) = &union.limit {
6381 if self.config.pretty {
6382 self.write_newline();
6383 } else {
6384 self.write_space();
6385 }
6386 self.write_keyword("LIMIT");
6387 self.write_space();
6388 self.generate_expression(limit)?;
6389 }
6390 if let Some(offset) = &union.offset {
6391 if self.config.pretty {
6392 self.write_newline();
6393 } else {
6394 self.write_space();
6395 }
6396 self.write_keyword("OFFSET");
6397 self.write_space();
6398 self.generate_expression(offset)?;
6399 }
6400 if let Some(distribute_by) = &union.distribute_by {
6402 self.write_space();
6403 self.write_keyword("DISTRIBUTE BY");
6404 self.write_space();
6405 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6406 if i > 0 {
6407 self.write(", ");
6408 }
6409 self.generate_expression(expr)?;
6410 }
6411 }
6412 if let Some(sort_by) = &union.sort_by {
6414 self.write_space();
6415 self.write_keyword("SORT BY");
6416 self.write_space();
6417 for (i, ord) in sort_by.expressions.iter().enumerate() {
6418 if i > 0 {
6419 self.write(", ");
6420 }
6421 self.generate_ordered(ord)?;
6422 }
6423 }
6424 if let Some(cluster_by) = &union.cluster_by {
6426 self.write_space();
6427 self.write_keyword("CLUSTER BY");
6428 self.write_space();
6429 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6430 if i > 0 {
6431 self.write(", ");
6432 }
6433 self.generate_ordered(ord)?;
6434 }
6435 }
6436 Ok(())
6437 }
6438
6439 fn generate_intersect(&mut self, outermost: &Intersect) -> Result<()> {
6440 let mut chain: Vec<&Intersect> = vec![outermost];
6442 let mut leftmost: &Expression = &outermost.left;
6443 while let Expression::Intersect(inner) = leftmost {
6444 chain.push(inner);
6445 leftmost = &inner.left;
6446 }
6447
6448 if let Some(with) = &outermost.with {
6449 self.generate_with(with)?;
6450 self.write_space();
6451 }
6452
6453 self.generate_expression(leftmost)?;
6454
6455 for intersect in chain.iter().rev() {
6456 self.generate_intersect_step(intersect)?;
6457 }
6458 Ok(())
6459 }
6460
6461 fn generate_intersect_step(&mut self, intersect: &Intersect) -> Result<()> {
6463 if self.config.pretty {
6464 self.write_newline();
6465 self.write_indent();
6466 } else {
6467 self.write_space();
6468 }
6469
6470 if let Some(side) = &intersect.side {
6472 self.write_keyword(side);
6473 self.write_space();
6474 }
6475 if let Some(kind) = &intersect.kind {
6476 self.write_keyword(kind);
6477 self.write_space();
6478 }
6479
6480 self.write_keyword("INTERSECT");
6481 if intersect.all {
6482 self.write_space();
6483 self.write_keyword("ALL");
6484 } else if intersect.distinct {
6485 self.write_space();
6486 self.write_keyword("DISTINCT");
6487 }
6488
6489 if intersect.corresponding || intersect.by_name {
6492 self.write_space();
6493 self.write_keyword("BY NAME");
6494 }
6495 if !intersect.on_columns.is_empty() {
6496 self.write_space();
6497 self.write_keyword("ON");
6498 self.write(" (");
6499 for (i, col) in intersect.on_columns.iter().enumerate() {
6500 if i > 0 {
6501 self.write(", ");
6502 }
6503 self.generate_expression(col)?;
6504 }
6505 self.write(")");
6506 }
6507
6508 if self.config.pretty {
6509 self.write_newline();
6510 self.write_indent();
6511 } else {
6512 self.write_space();
6513 }
6514 self.generate_expression(&intersect.right)?;
6515 if let Some(order_by) = &intersect.order_by {
6517 if self.config.pretty {
6518 self.write_newline();
6519 } else {
6520 self.write_space();
6521 }
6522 self.write_keyword("ORDER BY");
6523 self.write_space();
6524 for (i, ordered) in order_by.expressions.iter().enumerate() {
6525 if i > 0 {
6526 self.write(", ");
6527 }
6528 self.generate_ordered(ordered)?;
6529 }
6530 }
6531 if let Some(limit) = &intersect.limit {
6532 if self.config.pretty {
6533 self.write_newline();
6534 } else {
6535 self.write_space();
6536 }
6537 self.write_keyword("LIMIT");
6538 self.write_space();
6539 self.generate_expression(limit)?;
6540 }
6541 if let Some(offset) = &intersect.offset {
6542 if self.config.pretty {
6543 self.write_newline();
6544 } else {
6545 self.write_space();
6546 }
6547 self.write_keyword("OFFSET");
6548 self.write_space();
6549 self.generate_expression(offset)?;
6550 }
6551 if let Some(distribute_by) = &intersect.distribute_by {
6553 self.write_space();
6554 self.write_keyword("DISTRIBUTE BY");
6555 self.write_space();
6556 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6557 if i > 0 {
6558 self.write(", ");
6559 }
6560 self.generate_expression(expr)?;
6561 }
6562 }
6563 if let Some(sort_by) = &intersect.sort_by {
6565 self.write_space();
6566 self.write_keyword("SORT BY");
6567 self.write_space();
6568 for (i, ord) in sort_by.expressions.iter().enumerate() {
6569 if i > 0 {
6570 self.write(", ");
6571 }
6572 self.generate_ordered(ord)?;
6573 }
6574 }
6575 if let Some(cluster_by) = &intersect.cluster_by {
6577 self.write_space();
6578 self.write_keyword("CLUSTER BY");
6579 self.write_space();
6580 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6581 if i > 0 {
6582 self.write(", ");
6583 }
6584 self.generate_ordered(ord)?;
6585 }
6586 }
6587 Ok(())
6588 }
6589
6590 fn generate_except(&mut self, outermost: &Except) -> Result<()> {
6591 let mut chain: Vec<&Except> = vec![outermost];
6593 let mut leftmost: &Expression = &outermost.left;
6594 while let Expression::Except(inner) = leftmost {
6595 chain.push(inner);
6596 leftmost = &inner.left;
6597 }
6598
6599 if let Some(with) = &outermost.with {
6600 self.generate_with(with)?;
6601 self.write_space();
6602 }
6603
6604 self.generate_expression(leftmost)?;
6605
6606 for except in chain.iter().rev() {
6607 self.generate_except_step(except)?;
6608 }
6609 Ok(())
6610 }
6611
6612 fn generate_except_step(&mut self, except: &Except) -> Result<()> {
6614 use crate::dialects::DialectType;
6615
6616 if self.config.pretty {
6617 self.write_newline();
6618 self.write_indent();
6619 } else {
6620 self.write_space();
6621 }
6622
6623 if let Some(side) = &except.side {
6625 self.write_keyword(side);
6626 self.write_space();
6627 }
6628 if let Some(kind) = &except.kind {
6629 self.write_keyword(kind);
6630 self.write_space();
6631 }
6632
6633 match self.config.dialect {
6635 Some(DialectType::Oracle) if !except.all => {
6636 self.write_keyword("MINUS");
6637 }
6638 Some(DialectType::ClickHouse) => {
6639 self.write_keyword("EXCEPT");
6641 if except.distinct {
6642 self.write_space();
6643 self.write_keyword("DISTINCT");
6644 }
6645 }
6646 Some(DialectType::BigQuery) => {
6647 self.write_keyword("EXCEPT");
6649 if except.all {
6650 self.write_space();
6651 self.write_keyword("ALL");
6652 } else {
6653 self.write_space();
6654 self.write_keyword("DISTINCT");
6655 }
6656 }
6657 _ => {
6658 self.write_keyword("EXCEPT");
6659 if except.all {
6660 self.write_space();
6661 self.write_keyword("ALL");
6662 } else if except.distinct {
6663 self.write_space();
6664 self.write_keyword("DISTINCT");
6665 }
6666 }
6667 }
6668
6669 if except.corresponding || except.by_name {
6672 self.write_space();
6673 self.write_keyword("BY NAME");
6674 }
6675 if !except.on_columns.is_empty() {
6676 self.write_space();
6677 self.write_keyword("ON");
6678 self.write(" (");
6679 for (i, col) in except.on_columns.iter().enumerate() {
6680 if i > 0 {
6681 self.write(", ");
6682 }
6683 self.generate_expression(col)?;
6684 }
6685 self.write(")");
6686 }
6687
6688 if self.config.pretty {
6689 self.write_newline();
6690 self.write_indent();
6691 } else {
6692 self.write_space();
6693 }
6694 self.generate_expression(&except.right)?;
6695 if let Some(order_by) = &except.order_by {
6697 if self.config.pretty {
6698 self.write_newline();
6699 } else {
6700 self.write_space();
6701 }
6702 self.write_keyword("ORDER BY");
6703 self.write_space();
6704 for (i, ordered) in order_by.expressions.iter().enumerate() {
6705 if i > 0 {
6706 self.write(", ");
6707 }
6708 self.generate_ordered(ordered)?;
6709 }
6710 }
6711 if let Some(limit) = &except.limit {
6712 if self.config.pretty {
6713 self.write_newline();
6714 } else {
6715 self.write_space();
6716 }
6717 self.write_keyword("LIMIT");
6718 self.write_space();
6719 self.generate_expression(limit)?;
6720 }
6721 if let Some(offset) = &except.offset {
6722 if self.config.pretty {
6723 self.write_newline();
6724 } else {
6725 self.write_space();
6726 }
6727 self.write_keyword("OFFSET");
6728 self.write_space();
6729 self.generate_expression(offset)?;
6730 }
6731 if let Some(distribute_by) = &except.distribute_by {
6733 self.write_space();
6734 self.write_keyword("DISTRIBUTE BY");
6735 self.write_space();
6736 for (i, expr) in distribute_by.expressions.iter().enumerate() {
6737 if i > 0 {
6738 self.write(", ");
6739 }
6740 self.generate_expression(expr)?;
6741 }
6742 }
6743 if let Some(sort_by) = &except.sort_by {
6745 self.write_space();
6746 self.write_keyword("SORT BY");
6747 self.write_space();
6748 for (i, ord) in sort_by.expressions.iter().enumerate() {
6749 if i > 0 {
6750 self.write(", ");
6751 }
6752 self.generate_ordered(ord)?;
6753 }
6754 }
6755 if let Some(cluster_by) = &except.cluster_by {
6757 self.write_space();
6758 self.write_keyword("CLUSTER BY");
6759 self.write_space();
6760 for (i, ord) in cluster_by.expressions.iter().enumerate() {
6761 if i > 0 {
6762 self.write(", ");
6763 }
6764 self.generate_ordered(ord)?;
6765 }
6766 }
6767 Ok(())
6768 }
6769
6770 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
6771 let prepend_query_cte = if insert.with.is_none() {
6773 use crate::dialects::DialectType;
6774 let should_prepend = matches!(
6775 self.config.dialect,
6776 Some(DialectType::TSQL)
6777 | Some(DialectType::Fabric)
6778 | Some(DialectType::Spark)
6779 | Some(DialectType::Databricks)
6780 | Some(DialectType::Hive)
6781 );
6782 if should_prepend {
6783 if let Some(Expression::Select(select)) = &insert.query {
6784 select.with.clone()
6785 } else {
6786 None
6787 }
6788 } else {
6789 None
6790 }
6791 } else {
6792 None
6793 };
6794
6795 if let Some(with) = &insert.with {
6797 self.generate_with(with)?;
6798 self.write_space();
6799 } else if let Some(with) = &prepend_query_cte {
6800 self.generate_with(with)?;
6801 self.write_space();
6802 }
6803
6804 for comment in &insert.leading_comments {
6806 self.write_formatted_comment(comment);
6807 self.write(" ");
6808 }
6809
6810 if let Some(dir) = &insert.directory {
6812 self.write_keyword("INSERT OVERWRITE");
6813 if dir.local {
6814 self.write_space();
6815 self.write_keyword("LOCAL");
6816 }
6817 self.write_space();
6818 self.write_keyword("DIRECTORY");
6819 self.write_space();
6820 self.write("'");
6821 self.write(&dir.path);
6822 self.write("'");
6823
6824 if let Some(row_format) = &dir.row_format {
6826 self.write_space();
6827 self.write_keyword("ROW FORMAT");
6828 if row_format.delimited {
6829 self.write_space();
6830 self.write_keyword("DELIMITED");
6831 }
6832 if let Some(val) = &row_format.fields_terminated_by {
6833 self.write_space();
6834 self.write_keyword("FIELDS TERMINATED BY");
6835 self.write_space();
6836 self.write("'");
6837 self.write(val);
6838 self.write("'");
6839 }
6840 if let Some(val) = &row_format.collection_items_terminated_by {
6841 self.write_space();
6842 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
6843 self.write_space();
6844 self.write("'");
6845 self.write(val);
6846 self.write("'");
6847 }
6848 if let Some(val) = &row_format.map_keys_terminated_by {
6849 self.write_space();
6850 self.write_keyword("MAP KEYS TERMINATED BY");
6851 self.write_space();
6852 self.write("'");
6853 self.write(val);
6854 self.write("'");
6855 }
6856 if let Some(val) = &row_format.lines_terminated_by {
6857 self.write_space();
6858 self.write_keyword("LINES TERMINATED BY");
6859 self.write_space();
6860 self.write("'");
6861 self.write(val);
6862 self.write("'");
6863 }
6864 if let Some(val) = &row_format.null_defined_as {
6865 self.write_space();
6866 self.write_keyword("NULL DEFINED AS");
6867 self.write_space();
6868 self.write("'");
6869 self.write(val);
6870 self.write("'");
6871 }
6872 }
6873
6874 if let Some(format) = &dir.stored_as {
6876 self.write_space();
6877 self.write_keyword("STORED AS");
6878 self.write_space();
6879 self.write_keyword(format);
6880 }
6881
6882 if let Some(query) = &insert.query {
6884 self.write_space();
6885 self.generate_expression(query)?;
6886 }
6887
6888 return Ok(());
6889 }
6890
6891 if insert.is_replace {
6892 self.write_keyword("REPLACE INTO");
6894 } else if insert.overwrite {
6895 self.write_keyword("INSERT");
6897 if let Some(ref hint) = insert.hint {
6899 self.generate_hint(hint)?;
6900 }
6901 self.write(&self.config.insert_overwrite.to_ascii_uppercase());
6902 } else if let Some(ref action) = insert.conflict_action {
6903 self.write_keyword("INSERT OR");
6905 self.write_space();
6906 self.write_keyword(action);
6907 self.write_space();
6908 self.write_keyword("INTO");
6909 } else if insert.ignore {
6910 self.write_keyword("INSERT IGNORE INTO");
6912 } else {
6913 self.write_keyword("INSERT");
6914 if let Some(ref hint) = insert.hint {
6916 self.generate_hint(hint)?;
6917 }
6918 self.write_space();
6919 self.write_keyword("INTO");
6920 }
6921 if let Some(ref func) = insert.function_target {
6923 self.write_space();
6924 self.write_keyword("FUNCTION");
6925 self.write_space();
6926 self.generate_expression(func)?;
6927 } else {
6928 self.write_space();
6929 self.generate_table(&insert.table)?;
6930 }
6931
6932 if let Some(ref alias) = insert.alias {
6934 self.write_space();
6935 if insert.alias_explicit_as {
6936 self.write_keyword("AS");
6937 self.write_space();
6938 }
6939 self.generate_identifier(alias)?;
6940 }
6941
6942 if insert.if_exists {
6944 self.write_space();
6945 self.write_keyword("IF EXISTS");
6946 }
6947
6948 if let Some(ref replace_where) = insert.replace_where {
6950 if self.config.pretty {
6951 self.write_newline();
6952 self.write_indent();
6953 } else {
6954 self.write_space();
6955 }
6956 self.write_keyword("REPLACE WHERE");
6957 self.write_space();
6958 self.generate_expression(replace_where)?;
6959 }
6960
6961 if !insert.partition.is_empty() {
6963 self.write_space();
6964 self.write_keyword("PARTITION");
6965 self.write("(");
6966 for (i, (col, val)) in insert.partition.iter().enumerate() {
6967 if i > 0 {
6968 self.write(", ");
6969 }
6970 self.generate_identifier(col)?;
6971 if let Some(v) = val {
6972 self.write(" = ");
6973 self.generate_expression(v)?;
6974 }
6975 }
6976 self.write(")");
6977 }
6978
6979 if let Some(ref partition_by) = insert.partition_by {
6981 self.write_space();
6982 self.write_keyword("PARTITION BY");
6983 self.write_space();
6984 self.generate_expression(partition_by)?;
6985 }
6986
6987 if !insert.settings.is_empty() {
6989 self.write_space();
6990 self.write_keyword("SETTINGS");
6991 self.write_space();
6992 for (i, setting) in insert.settings.iter().enumerate() {
6993 if i > 0 {
6994 self.write(", ");
6995 }
6996 self.generate_expression(setting)?;
6997 }
6998 }
6999
7000 if !insert.columns.is_empty() {
7001 if insert.alias.is_some() && insert.alias_explicit_as {
7002 self.write("(");
7004 } else {
7005 self.write(" (");
7007 }
7008 for (i, col) in insert.columns.iter().enumerate() {
7009 if i > 0 {
7010 self.write(", ");
7011 }
7012 self.generate_identifier(col)?;
7013 }
7014 self.write(")");
7015 }
7016
7017 if let Some(ref output) = insert.output {
7019 self.generate_output_clause(output)?;
7020 }
7021
7022 if insert.by_name {
7024 self.write_space();
7025 self.write_keyword("BY NAME");
7026 }
7027
7028 if insert.default_values {
7029 self.write_space();
7030 self.write_keyword("DEFAULT VALUES");
7031 } else if let Some(query) = &insert.query {
7032 if self.config.pretty {
7033 self.write_newline();
7034 } else {
7035 self.write_space();
7036 }
7037 if prepend_query_cte.is_some() {
7039 if let Expression::Select(select) = query {
7040 let mut select_no_with = select.clone();
7041 select_no_with.with = None;
7042 self.generate_select(&select_no_with)?;
7043 } else {
7044 self.generate_expression(query)?;
7045 }
7046 } else {
7047 self.generate_expression(query)?;
7048 }
7049 } else if !insert.values.is_empty() {
7050 if self.config.pretty {
7051 self.write_newline();
7053 self.write_keyword("VALUES");
7054 self.write_newline();
7055 self.indent_level += 1;
7056 for (i, row) in insert.values.iter().enumerate() {
7057 if i > 0 {
7058 self.write(",");
7059 self.write_newline();
7060 }
7061 self.write_indent();
7062 self.write("(");
7063 for (j, val) in row.iter().enumerate() {
7064 if j > 0 {
7065 self.write(", ");
7066 }
7067 self.generate_expression(val)?;
7068 }
7069 self.write(")");
7070 }
7071 self.indent_level -= 1;
7072 } else {
7073 self.write_space();
7075 self.write_keyword("VALUES");
7076 for (i, row) in insert.values.iter().enumerate() {
7077 if i > 0 {
7078 self.write(",");
7079 }
7080 self.write(" (");
7081 for (j, val) in row.iter().enumerate() {
7082 if j > 0 {
7083 self.write(", ");
7084 }
7085 self.generate_expression(val)?;
7086 }
7087 self.write(")");
7088 }
7089 }
7090 }
7091
7092 if let Some(ref source) = insert.source {
7094 self.write_space();
7095 self.write_keyword("TABLE");
7096 self.write_space();
7097 self.generate_expression(source)?;
7098 }
7099
7100 if let Some(alias) = &insert.source_alias {
7102 self.write_space();
7103 self.write_keyword("AS");
7104 self.write_space();
7105 self.generate_identifier(alias)?;
7106 }
7107
7108 if let Some(on_conflict) = &insert.on_conflict {
7110 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
7111 self.write_space();
7112 self.generate_expression(on_conflict)?;
7113 }
7114 }
7115
7116 if !insert.returning.is_empty() {
7118 self.write_space();
7119 self.write_keyword("RETURNING");
7120 self.write_space();
7121 for (i, expr) in insert.returning.iter().enumerate() {
7122 if i > 0 {
7123 self.write(", ");
7124 }
7125 self.generate_expression(expr)?;
7126 }
7127 }
7128
7129 Ok(())
7130 }
7131
7132 fn generate_update(&mut self, update: &Update) -> Result<()> {
7133 for comment in &update.leading_comments {
7135 self.write_formatted_comment(comment);
7136 self.write(" ");
7137 }
7138
7139 if let Some(ref with) = update.with {
7141 self.generate_with(with)?;
7142 self.write_space();
7143 }
7144
7145 self.write_keyword("UPDATE");
7146 self.write_space();
7147 self.generate_table(&update.table)?;
7148
7149 let mysql_like_update_from = matches!(
7150 self.config.dialect,
7151 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
7152 ) && update.from_clause.is_some();
7153
7154 let mut set_pairs = update.set.clone();
7155
7156 let mut pre_set_joins = update.table_joins.clone();
7158 if mysql_like_update_from {
7159 let target_name = update
7160 .table
7161 .alias
7162 .as_ref()
7163 .map(|a| a.name.clone())
7164 .unwrap_or_else(|| update.table.name.name.clone());
7165
7166 for (col, _) in &mut set_pairs {
7167 if !col.name.contains('.') {
7168 col.name = format!("{}.{}", target_name, col.name);
7169 }
7170 }
7171
7172 if let Some(from_clause) = &update.from_clause {
7173 for table_expr in &from_clause.expressions {
7174 pre_set_joins.push(crate::expressions::Join {
7175 this: table_expr.clone(),
7176 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7177 value: true,
7178 })),
7179 using: Vec::new(),
7180 kind: crate::expressions::JoinKind::Inner,
7181 use_inner_keyword: false,
7182 use_outer_keyword: false,
7183 deferred_condition: false,
7184 join_hint: None,
7185 match_condition: None,
7186 pivots: Vec::new(),
7187 comments: Vec::new(),
7188 nesting_group: 0,
7189 directed: false,
7190 });
7191 }
7192 }
7193 for join in &update.from_joins {
7194 let mut join = join.clone();
7195 if join.on.is_none() && join.using.is_empty() {
7196 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral {
7197 value: true,
7198 }));
7199 }
7200 pre_set_joins.push(join);
7201 }
7202 }
7203
7204 for extra_table in &update.extra_tables {
7206 self.write(", ");
7207 self.generate_table(extra_table)?;
7208 }
7209
7210 for join in &pre_set_joins {
7212 self.generate_join(join)?;
7214 }
7215
7216 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
7218 if teradata_from_before_set && !mysql_like_update_from {
7219 if let Some(ref from_clause) = update.from_clause {
7220 self.write_space();
7221 self.write_keyword("FROM");
7222 self.write_space();
7223 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7224 if i > 0 {
7225 self.write(", ");
7226 }
7227 self.generate_expression(table_expr)?;
7228 }
7229 }
7230 for join in &update.from_joins {
7231 self.generate_join(join)?;
7232 }
7233 }
7234
7235 self.write_space();
7236 self.write_keyword("SET");
7237 self.write_space();
7238
7239 for (i, (col, val)) in set_pairs.iter().enumerate() {
7240 if i > 0 {
7241 self.write(", ");
7242 }
7243 self.generate_identifier(col)?;
7244 self.write(" = ");
7245 self.generate_expression(val)?;
7246 }
7247
7248 if let Some(ref output) = update.output {
7250 self.generate_output_clause(output)?;
7251 }
7252
7253 if !mysql_like_update_from && !teradata_from_before_set {
7255 if let Some(ref from_clause) = update.from_clause {
7256 self.write_space();
7257 self.write_keyword("FROM");
7258 self.write_space();
7259 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
7261 if i > 0 {
7262 self.write(", ");
7263 }
7264 self.generate_expression(table_expr)?;
7265 }
7266 }
7267 }
7268
7269 if !mysql_like_update_from && !teradata_from_before_set {
7270 for join in &update.from_joins {
7272 self.generate_join(join)?;
7273 }
7274 }
7275
7276 if let Some(where_clause) = &update.where_clause {
7277 self.write_space();
7278 self.write_keyword("WHERE");
7279 self.write_space();
7280 self.generate_expression(&where_clause.this)?;
7281 }
7282
7283 if !update.returning.is_empty() {
7285 self.write_space();
7286 self.write_keyword("RETURNING");
7287 self.write_space();
7288 for (i, expr) in update.returning.iter().enumerate() {
7289 if i > 0 {
7290 self.write(", ");
7291 }
7292 self.generate_expression(expr)?;
7293 }
7294 }
7295
7296 if let Some(ref order_by) = update.order_by {
7298 self.write_space();
7299 self.generate_order_by(order_by)?;
7300 }
7301
7302 if let Some(ref limit) = update.limit {
7304 self.write_space();
7305 self.write_keyword("LIMIT");
7306 self.write_space();
7307 self.generate_expression(limit)?;
7308 }
7309
7310 Ok(())
7311 }
7312
7313 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
7314 if let Some(with) = &delete.with {
7316 self.generate_with(with)?;
7317 self.write_space();
7318 }
7319
7320 for comment in &delete.leading_comments {
7322 self.write_formatted_comment(comment);
7323 self.write(" ");
7324 }
7325
7326 if !delete.tables.is_empty() && !delete.tables_from_using {
7328 self.write_keyword("DELETE");
7330 self.write_space();
7331 for (i, tbl) in delete.tables.iter().enumerate() {
7332 if i > 0 {
7333 self.write(", ");
7334 }
7335 self.generate_table(tbl)?;
7336 }
7337 if let Some(ref output) = delete.output {
7339 self.generate_output_clause(output)?;
7340 }
7341 self.write_space();
7342 self.write_keyword("FROM");
7343 self.write_space();
7344 self.generate_table(&delete.table)?;
7345 } else if !delete.tables.is_empty() && delete.tables_from_using {
7346 self.write_keyword("DELETE FROM");
7348 self.write_space();
7349 for (i, tbl) in delete.tables.iter().enumerate() {
7350 if i > 0 {
7351 self.write(", ");
7352 }
7353 self.generate_table(tbl)?;
7354 }
7355 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
7356 self.write_keyword("DELETE");
7358 self.write_space();
7359 self.generate_table(&delete.table)?;
7360 } else {
7361 self.write_keyword("DELETE FROM");
7362 self.write_space();
7363 self.generate_table(&delete.table)?;
7364 }
7365
7366 if let Some(ref on_cluster) = delete.on_cluster {
7368 self.write_space();
7369 self.generate_on_cluster(on_cluster)?;
7370 }
7371
7372 if let Some(ref idx) = delete.force_index {
7374 self.write_space();
7375 self.write_keyword("FORCE INDEX");
7376 self.write(" (");
7377 self.write(idx);
7378 self.write(")");
7379 }
7380
7381 if let Some(ref alias) = delete.alias {
7383 self.write_space();
7384 if delete.alias_explicit_as
7385 || matches!(self.config.dialect, Some(DialectType::BigQuery))
7386 {
7387 self.write_keyword("AS");
7388 self.write_space();
7389 }
7390 self.generate_identifier(alias)?;
7391 }
7392
7393 if !delete.tables_from_using {
7395 for join in &delete.joins {
7396 self.generate_join(join)?;
7397 }
7398 }
7399
7400 if !delete.using.is_empty() {
7402 self.write_space();
7403 self.write_keyword("USING");
7404 for (i, table) in delete.using.iter().enumerate() {
7405 if i > 0 {
7406 self.write(",");
7407 }
7408 self.write_space();
7409 if !table.hints.is_empty() && table.name.is_empty() {
7411 self.generate_expression(&table.hints[0])?;
7413 if let Some(ref alias) = table.alias {
7414 self.write_space();
7415 if table.alias_explicit_as {
7416 self.write_keyword("AS");
7417 self.write_space();
7418 }
7419 self.generate_identifier(alias)?;
7420 if !table.column_aliases.is_empty() {
7421 self.write("(");
7422 for (j, col_alias) in table.column_aliases.iter().enumerate() {
7423 if j > 0 {
7424 self.write(", ");
7425 }
7426 self.generate_identifier(col_alias)?;
7427 }
7428 self.write(")");
7429 }
7430 }
7431 } else {
7432 self.generate_table(table)?;
7433 }
7434 }
7435 }
7436
7437 if delete.tables_from_using {
7439 for join in &delete.joins {
7440 self.generate_join(join)?;
7441 }
7442 }
7443
7444 let output_already_emitted =
7446 !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
7447 if !output_already_emitted {
7448 if let Some(ref output) = delete.output {
7449 self.generate_output_clause(output)?;
7450 }
7451 }
7452
7453 if let Some(where_clause) = &delete.where_clause {
7454 self.write_space();
7455 self.write_keyword("WHERE");
7456 self.write_space();
7457 self.generate_expression(&where_clause.this)?;
7458 }
7459
7460 if let Some(ref order_by) = delete.order_by {
7462 self.write_space();
7463 self.generate_order_by(order_by)?;
7464 }
7465
7466 if let Some(ref limit) = delete.limit {
7468 self.write_space();
7469 self.write_keyword("LIMIT");
7470 self.write_space();
7471 self.generate_expression(limit)?;
7472 }
7473
7474 if !delete.returning.is_empty() {
7476 self.write_space();
7477 self.write_keyword("RETURNING");
7478 self.write_space();
7479 for (i, expr) in delete.returning.iter().enumerate() {
7480 if i > 0 {
7481 self.write(", ");
7482 }
7483 self.generate_expression(expr)?;
7484 }
7485 }
7486
7487 Ok(())
7488 }
7489
7490 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
7493 let saved_athena_hive_context = self.athena_hive_context;
7497 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
7498 if matches!(
7499 self.config.dialect,
7500 Some(crate::dialects::DialectType::Athena)
7501 ) {
7502 let is_external = ct
7506 .table_modifier
7507 .as_ref()
7508 .map(|m| m.eq_ignore_ascii_case("EXTERNAL"))
7509 .unwrap_or(false);
7510 let has_as_select = ct.as_select.is_some();
7511 self.athena_hive_context = is_external || !has_as_select;
7512 }
7513
7514 if matches!(
7516 self.config.dialect,
7517 Some(crate::dialects::DialectType::TSQL)
7518 ) {
7519 if let Some(ref query) = ct.as_select {
7520 if let Some(with_cte) = &ct.with_cte {
7522 self.generate_with(with_cte)?;
7523 self.write_space();
7524 }
7525
7526 self.write_keyword("SELECT");
7528 self.write(" * ");
7529 self.write_keyword("INTO");
7530 self.write_space();
7531
7532 if ct.temporary {
7534 self.write("#");
7535 }
7536 self.generate_table(&ct.name)?;
7537
7538 self.write_space();
7539 self.write_keyword("FROM");
7540 self.write(" (");
7541 let aliased_query = Self::add_column_aliases_to_query(query.clone());
7543 self.generate_expression(&aliased_query)?;
7544 self.write(") ");
7545 self.write_keyword("AS");
7546 self.write(" temp");
7547 return Ok(());
7548 }
7549 }
7550
7551 if let Some(with_cte) = &ct.with_cte {
7553 self.generate_with(with_cte)?;
7554 self.write_space();
7555 }
7556
7557 for comment in &ct.leading_comments {
7559 self.write_formatted_comment(comment);
7560 self.write(" ");
7561 }
7562 self.write_keyword("CREATE");
7563
7564 if ct.or_replace {
7565 self.write_space();
7566 self.write_keyword("OR REPLACE");
7567 }
7568
7569 if ct.temporary {
7570 self.write_space();
7571 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
7573 self.write_keyword("GLOBAL TEMPORARY");
7574 } else {
7575 self.write_keyword("TEMPORARY");
7576 }
7577 }
7578
7579 let is_dictionary = ct
7581 .table_modifier
7582 .as_ref()
7583 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
7584 .unwrap_or(false);
7585 if let Some(ref modifier) = ct.table_modifier {
7586 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
7588 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
7589 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
7591 || modifier.eq_ignore_ascii_case("SET")
7592 || modifier.eq_ignore_ascii_case("MULTISET")
7593 || modifier.to_ascii_uppercase().contains("VOLATILE")
7594 || modifier.to_ascii_uppercase().starts_with("SET ")
7595 || modifier.to_ascii_uppercase().starts_with("MULTISET ");
7596 let skip_teradata =
7597 is_teradata_modifier && !matches!(self.config.dialect, Some(DialectType::Teradata));
7598 if !skip_transient && !skip_teradata {
7599 self.write_space();
7600 self.write_keyword(modifier);
7601 }
7602 }
7603
7604 if !is_dictionary {
7605 self.write_space();
7606 self.write_keyword("TABLE");
7607 }
7608
7609 if ct.if_not_exists {
7610 self.write_space();
7611 self.write_keyword("IF NOT EXISTS");
7612 }
7613
7614 self.write_space();
7615 self.generate_table(&ct.name)?;
7616
7617 if let Some(ref uuid) = ct.uuid {
7619 self.write_space();
7620 self.write_keyword("UUID");
7621 self.write(" '");
7622 self.write(uuid);
7623 self.write("'");
7624 }
7625
7626 if let Some(ref on_cluster) = ct.on_cluster {
7628 self.write_space();
7629 self.generate_on_cluster(on_cluster)?;
7630 }
7631
7632 if matches!(
7634 self.config.dialect,
7635 Some(crate::dialects::DialectType::Teradata)
7636 ) && !ct.teradata_post_name_options.is_empty()
7637 {
7638 for opt in &ct.teradata_post_name_options {
7639 self.write(", ");
7640 self.write(opt);
7641 }
7642 }
7643
7644 if ct.copy_grants {
7646 self.write_space();
7647 self.write_keyword("COPY GRANTS");
7648 }
7649
7650 if let Some(ref using_template) = ct.using_template {
7652 self.write_space();
7653 self.write_keyword("USING TEMPLATE");
7654 self.write_space();
7655 self.generate_expression(using_template)?;
7656 return Ok(());
7657 }
7658
7659 if let Some(ref clone_source) = ct.clone_source {
7661 self.write_space();
7662 if ct.is_copy && self.config.supports_table_copy {
7663 self.write_keyword("COPY");
7665 } else if ct.shallow_clone {
7666 self.write_keyword("SHALLOW CLONE");
7667 } else {
7668 self.write_keyword("CLONE");
7669 }
7670 self.write_space();
7671 self.generate_table(clone_source)?;
7672 if let Some(ref at_clause) = ct.clone_at_clause {
7674 self.write_space();
7675 self.generate_expression(at_clause)?;
7676 }
7677 return Ok(());
7678 }
7679
7680 if let Some(ref partition_of) = ct.partition_of {
7684 self.write_space();
7685
7686 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
7688 self.write_keyword("PARTITION OF");
7690 self.write_space();
7691 self.generate_expression(&pop.this)?;
7692
7693 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7695 self.write(" (");
7696 let mut first = true;
7697 for col in &ct.columns {
7698 if !first {
7699 self.write(", ");
7700 }
7701 first = false;
7702 self.generate_column_def(col)?;
7703 }
7704 for constraint in &ct.constraints {
7705 if !first {
7706 self.write(", ");
7707 }
7708 first = false;
7709 self.generate_table_constraint(constraint)?;
7710 }
7711 self.write(")");
7712 }
7713
7714 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
7716 self.write_space();
7717 self.write_keyword("FOR VALUES");
7718 self.write_space();
7719 self.generate_expression(&pop.expression)?;
7720 } else {
7721 self.write_space();
7722 self.write_keyword("DEFAULT");
7723 }
7724 } else {
7725 self.generate_expression(partition_of)?;
7727
7728 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
7730 self.write(" (");
7731 let mut first = true;
7732 for col in &ct.columns {
7733 if !first {
7734 self.write(", ");
7735 }
7736 first = false;
7737 self.generate_column_def(col)?;
7738 }
7739 for constraint in &ct.constraints {
7740 if !first {
7741 self.write(", ");
7742 }
7743 first = false;
7744 self.generate_table_constraint(constraint)?;
7745 }
7746 self.write(")");
7747 }
7748 }
7749
7750 for prop in &ct.properties {
7752 self.write_space();
7753 self.generate_expression(prop)?;
7754 }
7755
7756 return Ok(());
7757 }
7758
7759 self.sqlite_inline_pk_columns.clear();
7762 if matches!(
7763 self.config.dialect,
7764 Some(crate::dialects::DialectType::SQLite)
7765 ) {
7766 for constraint in &ct.constraints {
7767 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7768 if columns.len() == 1 && name.is_none() {
7770 let pk_col_name = columns[0].name.to_ascii_lowercase();
7771 if ct
7773 .columns
7774 .iter()
7775 .any(|c| c.name.name.to_ascii_lowercase() == pk_col_name)
7776 {
7777 self.sqlite_inline_pk_columns.insert(pk_col_name);
7778 }
7779 }
7780 }
7781 }
7782 }
7783
7784 if !ct.columns.is_empty() {
7786 if self.config.pretty {
7787 self.write(" (");
7789 self.write_newline();
7790 self.indent_level += 1;
7791 for (i, col) in ct.columns.iter().enumerate() {
7792 if i > 0 {
7793 self.write(",");
7794 self.write_newline();
7795 }
7796 self.write_indent();
7797 self.generate_column_def(col)?;
7798 }
7799 for constraint in &ct.constraints {
7801 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7803 if columns.len() == 1
7804 && name.is_none()
7805 && self
7806 .sqlite_inline_pk_columns
7807 .contains(&columns[0].name.to_ascii_lowercase())
7808 {
7809 continue;
7810 }
7811 }
7812 self.write(",");
7813 self.write_newline();
7814 self.write_indent();
7815 self.generate_table_constraint(constraint)?;
7816 }
7817 self.indent_level -= 1;
7818 self.write_newline();
7819 self.write(")");
7820 } else {
7821 self.write(" (");
7822 for (i, col) in ct.columns.iter().enumerate() {
7823 if i > 0 {
7824 self.write(", ");
7825 }
7826 self.generate_column_def(col)?;
7827 }
7828 let mut first_constraint = true;
7830 for constraint in &ct.constraints {
7831 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
7833 if columns.len() == 1
7834 && name.is_none()
7835 && self
7836 .sqlite_inline_pk_columns
7837 .contains(&columns[0].name.to_ascii_lowercase())
7838 {
7839 continue;
7840 }
7841 }
7842 if first_constraint {
7843 self.write(", ");
7844 first_constraint = false;
7845 } else {
7846 self.write(", ");
7847 }
7848 self.generate_table_constraint(constraint)?;
7849 }
7850 self.write(")");
7851 }
7852 } else if !ct.constraints.is_empty() {
7853 let has_like_only = ct
7855 .constraints
7856 .iter()
7857 .all(|c| matches!(c, TableConstraint::Like { .. }));
7858 let has_tags_only = ct
7859 .constraints
7860 .iter()
7861 .all(|c| matches!(c, TableConstraint::Tags(_)));
7862 let is_pg_like = matches!(
7866 self.config.dialect,
7867 Some(crate::dialects::DialectType::PostgreSQL)
7868 | Some(crate::dialects::DialectType::CockroachDB)
7869 | Some(crate::dialects::DialectType::Materialize)
7870 | Some(crate::dialects::DialectType::RisingWave)
7871 | Some(crate::dialects::DialectType::Redshift)
7872 | Some(crate::dialects::DialectType::Presto)
7873 | Some(crate::dialects::DialectType::Trino)
7874 | Some(crate::dialects::DialectType::Athena)
7875 );
7876 let use_parens = if has_like_only {
7877 is_pg_like
7878 } else {
7879 !has_tags_only
7880 };
7881 if self.config.pretty && use_parens {
7882 self.write(" (");
7883 self.write_newline();
7884 self.indent_level += 1;
7885 for (i, constraint) in ct.constraints.iter().enumerate() {
7886 if i > 0 {
7887 self.write(",");
7888 self.write_newline();
7889 }
7890 self.write_indent();
7891 self.generate_table_constraint(constraint)?;
7892 }
7893 self.indent_level -= 1;
7894 self.write_newline();
7895 self.write(")");
7896 } else {
7897 if use_parens {
7898 self.write(" (");
7899 } else {
7900 self.write_space();
7901 }
7902 for (i, constraint) in ct.constraints.iter().enumerate() {
7903 if i > 0 {
7904 self.write(", ");
7905 }
7906 self.generate_table_constraint(constraint)?;
7907 }
7908 if use_parens {
7909 self.write(")");
7910 }
7911 }
7912 }
7913
7914 if let Some(ref on_prop) = ct.on_property {
7916 self.write(" ");
7917 self.write_keyword("ON");
7918 self.write(" ");
7919 self.generate_expression(&on_prop.this)?;
7920 }
7921
7922 if !is_clickhouse {
7925 for prop in &ct.properties {
7926 if let Expression::SchemaCommentProperty(_) = prop {
7927 if self.config.pretty {
7928 self.write_newline();
7929 } else {
7930 self.write_space();
7931 }
7932 self.generate_expression(prop)?;
7933 }
7934 }
7935 }
7936
7937 if !ct.with_properties.is_empty() {
7939 let is_snowflake_special_table = matches!(
7941 self.config.dialect,
7942 Some(crate::dialects::DialectType::Snowflake)
7943 ) && (ct.table_modifier.as_deref() == Some("ICEBERG")
7944 || ct.table_modifier.as_deref() == Some("DYNAMIC"));
7945 if is_snowflake_special_table {
7946 for (key, value) in &ct.with_properties {
7947 self.write_space();
7948 self.write(key);
7949 self.write("=");
7950 self.write(value);
7951 }
7952 } else if self.config.pretty {
7953 self.write_newline();
7954 self.write_keyword("WITH");
7955 self.write(" (");
7956 self.write_newline();
7957 self.indent_level += 1;
7958 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7959 if i > 0 {
7960 self.write(",");
7961 self.write_newline();
7962 }
7963 self.write_indent();
7964 self.write(key);
7965 self.write("=");
7966 self.write(value);
7967 }
7968 self.indent_level -= 1;
7969 self.write_newline();
7970 self.write(")");
7971 } else {
7972 self.write_space();
7973 self.write_keyword("WITH");
7974 self.write(" (");
7975 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
7976 if i > 0 {
7977 self.write(", ");
7978 }
7979 self.write(key);
7980 self.write("=");
7981 self.write(value);
7982 }
7983 self.write(")");
7984 }
7985 }
7986
7987 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) =
7988 if is_clickhouse && ct.as_select.is_some() {
7989 let mut pre = Vec::new();
7990 let mut post = Vec::new();
7991 for prop in &ct.properties {
7992 if matches!(prop, Expression::SchemaCommentProperty(_)) {
7993 post.push(prop);
7994 } else {
7995 pre.push(prop);
7996 }
7997 }
7998 (pre, post)
7999 } else {
8000 (ct.properties.iter().collect(), Vec::new())
8001 };
8002
8003 for prop in pre_as_properties {
8005 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
8007 continue;
8008 }
8009 if self.config.pretty {
8010 self.write_newline();
8011 } else {
8012 self.write_space();
8013 }
8014 if let Expression::Properties(props) = prop {
8018 let is_hive_dialect = matches!(
8019 self.config.dialect,
8020 Some(crate::dialects::DialectType::Hive)
8021 | Some(crate::dialects::DialectType::Spark)
8022 | Some(crate::dialects::DialectType::Databricks)
8023 | Some(crate::dialects::DialectType::Athena)
8024 );
8025 let is_doris_starrocks = matches!(
8026 self.config.dialect,
8027 Some(crate::dialects::DialectType::Doris)
8028 | Some(crate::dialects::DialectType::StarRocks)
8029 );
8030 if is_hive_dialect {
8031 self.generate_tblproperties_clause(&props.expressions)?;
8032 } else if is_doris_starrocks {
8033 self.generate_properties_clause(&props.expressions)?;
8034 } else {
8035 self.generate_options_clause(&props.expressions)?;
8036 }
8037 } else {
8038 self.generate_expression(prop)?;
8039 }
8040 }
8041
8042 for prop in &ct.post_table_properties {
8044 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
8045 self.write(" WITH(");
8046 self.generate_system_versioning_content(svp)?;
8047 self.write(")");
8048 } else if let Expression::Properties(props) = prop {
8049 let is_doris_starrocks = matches!(
8051 self.config.dialect,
8052 Some(crate::dialects::DialectType::Doris)
8053 | Some(crate::dialects::DialectType::StarRocks)
8054 );
8055 self.write_space();
8056 if is_doris_starrocks {
8057 self.generate_properties_clause(&props.expressions)?;
8058 } else {
8059 self.generate_options_clause(&props.expressions)?;
8060 }
8061 } else {
8062 self.write_space();
8063 self.generate_expression(prop)?;
8064 }
8065 }
8066
8067 if let Some(ref rollup) = ct.rollup {
8070 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
8071 self.write_space();
8072 self.generate_rollup_property(rollup)?;
8073 }
8074 }
8075
8076 let is_mysql_compatible = matches!(
8080 self.config.dialect,
8081 Some(DialectType::MySQL)
8082 | Some(DialectType::SingleStore)
8083 | Some(DialectType::Doris)
8084 | Some(DialectType::StarRocks)
8085 | None
8086 );
8087 let is_hive_compatible = matches!(
8088 self.config.dialect,
8089 Some(DialectType::Hive)
8090 | Some(DialectType::Spark)
8091 | Some(DialectType::Databricks)
8092 | Some(DialectType::Athena)
8093 );
8094 let mysql_pretty_options =
8095 self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
8096 for (key, value) in &ct.mysql_table_options {
8097 let should_output = if is_mysql_compatible {
8099 true
8100 } else if is_hive_compatible && key == "COMMENT" {
8101 true } else {
8103 false
8104 };
8105 if should_output {
8106 if mysql_pretty_options {
8107 self.write_newline();
8108 self.write_indent();
8109 } else {
8110 self.write_space();
8111 }
8112 self.write_keyword(key);
8113 if key == "COMMENT" && !self.config.schema_comment_with_eq {
8115 self.write_space();
8116 } else {
8117 self.write("=");
8118 }
8119 self.write(value);
8120 }
8121 }
8122
8123 if ct.temporary
8125 && matches!(
8126 self.config.dialect,
8127 Some(DialectType::Spark) | Some(DialectType::Databricks)
8128 )
8129 && ct.as_select.is_none()
8130 {
8131 self.write_space();
8132 self.write_keyword("USING PARQUET");
8133 }
8134
8135 if !ct.inherits.is_empty() {
8137 self.write_space();
8138 self.write_keyword("INHERITS");
8139 self.write(" (");
8140 for (i, parent) in ct.inherits.iter().enumerate() {
8141 if i > 0 {
8142 self.write(", ");
8143 }
8144 self.generate_table(parent)?;
8145 }
8146 self.write(")");
8147 }
8148
8149 if let Some(ref query) = ct.as_select {
8151 self.write_space();
8152 self.write_keyword("AS");
8153 self.write_space();
8154 if ct.as_select_parenthesized {
8155 self.write("(");
8156 }
8157 self.generate_expression(query)?;
8158 if ct.as_select_parenthesized {
8159 self.write(")");
8160 }
8161
8162 if let Some(with_data) = ct.with_data {
8164 self.write_space();
8165 self.write_keyword("WITH");
8166 if !with_data {
8167 self.write_space();
8168 self.write_keyword("NO");
8169 }
8170 self.write_space();
8171 self.write_keyword("DATA");
8172 }
8173
8174 if let Some(with_statistics) = ct.with_statistics {
8176 self.write_space();
8177 self.write_keyword("AND");
8178 if !with_statistics {
8179 self.write_space();
8180 self.write_keyword("NO");
8181 }
8182 self.write_space();
8183 self.write_keyword("STATISTICS");
8184 }
8185
8186 for index in &ct.teradata_indexes {
8188 self.write_space();
8189 match index.kind {
8190 TeradataIndexKind::NoPrimary => {
8191 self.write_keyword("NO PRIMARY INDEX");
8192 }
8193 TeradataIndexKind::Primary => {
8194 self.write_keyword("PRIMARY INDEX");
8195 }
8196 TeradataIndexKind::PrimaryAmp => {
8197 self.write_keyword("PRIMARY AMP INDEX");
8198 }
8199 TeradataIndexKind::Unique => {
8200 self.write_keyword("UNIQUE INDEX");
8201 }
8202 TeradataIndexKind::UniquePrimary => {
8203 self.write_keyword("UNIQUE PRIMARY INDEX");
8204 }
8205 TeradataIndexKind::Secondary => {
8206 self.write_keyword("INDEX");
8207 }
8208 }
8209 if let Some(ref name) = index.name {
8211 self.write_space();
8212 self.write(name);
8213 }
8214 if !index.columns.is_empty() {
8216 self.write(" (");
8217 for (i, col) in index.columns.iter().enumerate() {
8218 if i > 0 {
8219 self.write(", ");
8220 }
8221 self.write(col);
8222 }
8223 self.write(")");
8224 }
8225 }
8226
8227 if let Some(ref on_commit) = ct.on_commit {
8229 self.write_space();
8230 self.write_keyword("ON COMMIT");
8231 self.write_space();
8232 match on_commit {
8233 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8234 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8235 }
8236 }
8237
8238 if !post_as_properties.is_empty() {
8239 for prop in post_as_properties {
8240 self.write_space();
8241 self.generate_expression(prop)?;
8242 }
8243 }
8244
8245 self.athena_hive_context = saved_athena_hive_context;
8247 return Ok(());
8248 }
8249
8250 if let Some(ref on_commit) = ct.on_commit {
8252 self.write_space();
8253 self.write_keyword("ON COMMIT");
8254 self.write_space();
8255 match on_commit {
8256 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
8257 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
8258 }
8259 }
8260
8261 self.athena_hive_context = saved_athena_hive_context;
8263
8264 Ok(())
8265 }
8266
8267 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
8270 self.generate_identifier(&col.name)?;
8272 if !matches!(col.data_type, DataType::Unknown) {
8274 self.write_space();
8275 self.generate_data_type(&col.data_type)?;
8276 }
8277 for constraint in &col.constraints {
8279 if let ColumnConstraint::Path(path_expr) = constraint {
8280 self.write_space();
8281 self.write_keyword("PATH");
8282 self.write_space();
8283 self.generate_expression(path_expr)?;
8284 }
8285 }
8286 Ok(())
8287 }
8288
8289 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
8290 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8292 && col
8293 .constraints
8294 .iter()
8295 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8296 let omit_computed_type = !self.config.computed_column_with_type
8298 && col
8299 .constraints
8300 .iter()
8301 .any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
8302
8303 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
8306
8307 let has_no_type = col.no_type
8310 || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
8311 && col.constraints.is_empty());
8312
8313 self.generate_identifier(&col.name)?;
8314
8315 let serial_expansion = if matches!(
8317 self.config.dialect,
8318 Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)
8319 ) {
8320 if let DataType::Custom { ref name } = col.data_type {
8321 if name.eq_ignore_ascii_case("SERIAL") {
8322 Some("INT")
8323 } else if name.eq_ignore_ascii_case("BIGSERIAL") {
8324 Some("BIGINT")
8325 } else if name.eq_ignore_ascii_case("SMALLSERIAL") {
8326 Some("SMALLINT")
8327 } else {
8328 None
8329 }
8330 } else {
8331 None
8332 }
8333 } else {
8334 None
8335 };
8336
8337 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type
8338 {
8339 self.write_space();
8340 let saved_nullable_depth = self.clickhouse_nullable_depth;
8343 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
8344 self.clickhouse_nullable_depth = -1;
8345 }
8346 if let Some(int_type) = serial_expansion {
8347 self.write_keyword(int_type);
8349 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8350 let unsigned_type = match &col.data_type {
8352 DataType::Int { .. } => Some("UINTEGER"),
8353 DataType::BigInt { .. } => Some("UBIGINT"),
8354 DataType::SmallInt { .. } => Some("USMALLINT"),
8355 DataType::TinyInt { .. } => Some("UTINYINT"),
8356 _ => None,
8357 };
8358 if let Some(utype) = unsigned_type {
8359 self.write_keyword(utype);
8360 } else {
8361 self.generate_data_type(&col.data_type)?;
8362 }
8363 } else {
8364 self.generate_data_type(&col.data_type)?;
8365 }
8366 self.clickhouse_nullable_depth = saved_nullable_depth;
8367 }
8368
8369 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
8372 self.write_space();
8373 self.write_keyword("UNSIGNED");
8374 }
8375 if col.zerofill {
8376 self.write_space();
8377 self.write_keyword("ZEROFILL");
8378 }
8379
8380 if let Some(ref charset) = col.character_set {
8384 self.write_space();
8385 self.write_keyword("CHARACTER SET");
8386 self.write_space();
8387 self.write(charset);
8388 }
8389
8390 if col.uppercase {
8391 self.write_space();
8392 self.write_keyword("UPPERCASE");
8393 }
8394
8395 if let Some(casespecific) = col.casespecific {
8396 self.write_space();
8397 if casespecific {
8398 self.write_keyword("CASESPECIFIC");
8399 } else {
8400 self.write_keyword("NOT CASESPECIFIC");
8401 }
8402 }
8403
8404 if let Some(ref format) = col.format {
8405 self.write_space();
8406 self.write_keyword("FORMAT");
8407 self.write(" '");
8408 self.write(format);
8409 self.write("'");
8410 }
8411
8412 if let Some(ref title) = col.title {
8413 self.write_space();
8414 self.write_keyword("TITLE");
8415 self.write(" '");
8416 self.write(title);
8417 self.write("'");
8418 }
8419
8420 if let Some(length) = col.inline_length {
8421 self.write_space();
8422 self.write_keyword("INLINE LENGTH");
8423 self.write(" ");
8424 self.write(&length.to_string());
8425 }
8426
8427 if let Some(ref compress) = col.compress {
8428 self.write_space();
8429 self.write_keyword("COMPRESS");
8430 if !compress.is_empty() {
8431 if compress.len() == 1 {
8433 if let Expression::Literal(lit) = &compress[0] {
8434 if let Literal::String(_) = lit.as_ref() {
8435 self.write_space();
8436 self.generate_expression(&compress[0])?;
8437 }
8438 } else {
8439 self.write(" (");
8440 self.generate_expression(&compress[0])?;
8441 self.write(")");
8442 }
8443 } else {
8444 self.write(" (");
8445 for (i, val) in compress.iter().enumerate() {
8446 if i > 0 {
8447 self.write(", ");
8448 }
8449 self.generate_expression(val)?;
8450 }
8451 self.write(")");
8452 }
8453 }
8454 }
8455
8456 if !col.constraint_order.is_empty() {
8459 let mut references_idx = 0;
8462 let mut check_idx = 0;
8463 let mut generated_idx = 0;
8464 let mut collate_idx = 0;
8465 let mut comment_idx = 0;
8466 let defer_not_null_after_identity = false;
8469 let mut pending_not_null_after_identity = false;
8470
8471 for constraint_type in &col.constraint_order {
8472 match constraint_type {
8473 ConstraintType::PrimaryKey => {
8474 if col.primary_key
8476 && !matches!(self.config.dialect, Some(DialectType::Materialize))
8477 {
8478 if let Some(ref cname) = col.primary_key_constraint_name {
8479 self.write_space();
8480 self.write_keyword("CONSTRAINT");
8481 self.write_space();
8482 self.write(cname);
8483 }
8484 self.write_space();
8485 self.write_keyword("PRIMARY KEY");
8486 if let Some(ref order) = col.primary_key_order {
8487 self.write_space();
8488 match order {
8489 SortOrder::Asc => self.write_keyword("ASC"),
8490 SortOrder::Desc => self.write_keyword("DESC"),
8491 }
8492 }
8493 }
8494 }
8495 ConstraintType::Unique => {
8496 if col.unique {
8497 if let Some(ref cname) = col.unique_constraint_name {
8498 self.write_space();
8499 self.write_keyword("CONSTRAINT");
8500 self.write_space();
8501 self.write(cname);
8502 }
8503 self.write_space();
8504 self.write_keyword("UNIQUE");
8505 if col.unique_nulls_not_distinct {
8507 self.write(" NULLS NOT DISTINCT");
8508 }
8509 }
8510 }
8511 ConstraintType::NotNull => {
8512 if col.nullable == Some(false) {
8513 if defer_not_null_after_identity {
8514 pending_not_null_after_identity = true;
8515 continue;
8516 }
8517 if let Some(ref cname) = col.not_null_constraint_name {
8518 self.write_space();
8519 self.write_keyword("CONSTRAINT");
8520 self.write_space();
8521 self.write(cname);
8522 }
8523 self.write_space();
8524 self.write_keyword("NOT NULL");
8525 }
8526 }
8527 ConstraintType::Null => {
8528 if col.nullable == Some(true) {
8529 self.write_space();
8530 self.write_keyword("NULL");
8531 }
8532 }
8533 ConstraintType::Default => {
8534 if let Some(ref default) = col.default {
8535 self.write_space();
8536 self.write_keyword("DEFAULT");
8537 self.write_space();
8538 self.generate_expression(default)?;
8539 }
8540 }
8541 ConstraintType::AutoIncrement => {
8542 if col.auto_increment {
8543 if matches!(
8545 self.config.dialect,
8546 Some(crate::dialects::DialectType::DuckDB)
8547 ) {
8548 } else if matches!(
8550 self.config.dialect,
8551 Some(crate::dialects::DialectType::Materialize)
8552 ) {
8553 if !matches!(col.nullable, Some(false)) {
8555 self.write_space();
8556 self.write_keyword("NOT NULL");
8557 }
8558 } else if matches!(
8559 self.config.dialect,
8560 Some(crate::dialects::DialectType::PostgreSQL)
8561 ) {
8562 self.write_space();
8564 self.generate_auto_increment_keyword(col)?;
8565 } else {
8566 self.write_space();
8567 self.generate_auto_increment_keyword(col)?;
8568 if pending_not_null_after_identity {
8569 self.write_space();
8570 self.write_keyword("NOT NULL");
8571 pending_not_null_after_identity = false;
8572 }
8573 }
8574 } }
8576 ConstraintType::References => {
8577 while references_idx < col.constraints.len() {
8579 if let ColumnConstraint::References(fk_ref) =
8580 &col.constraints[references_idx]
8581 {
8582 if let Some(ref name) = fk_ref.constraint_name {
8584 self.write_space();
8585 self.write_keyword("CONSTRAINT");
8586 self.write_space();
8587 self.write(name);
8588 }
8589 self.write_space();
8590 if fk_ref.has_foreign_key_keywords {
8591 self.write_keyword("FOREIGN KEY");
8592 self.write_space();
8593 }
8594 self.write_keyword("REFERENCES");
8595 self.write_space();
8596 self.generate_table(&fk_ref.table)?;
8597 if !fk_ref.columns.is_empty() {
8598 self.write(" (");
8599 for (i, c) in fk_ref.columns.iter().enumerate() {
8600 if i > 0 {
8601 self.write(", ");
8602 }
8603 self.generate_identifier(c)?;
8604 }
8605 self.write(")");
8606 }
8607 self.generate_referential_actions(fk_ref)?;
8608 references_idx += 1;
8609 break;
8610 }
8611 references_idx += 1;
8612 }
8613 }
8614 ConstraintType::Check => {
8615 while check_idx < col.constraints.len() {
8617 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
8618 if check_idx == 0 {
8620 if let Some(ref cname) = col.check_constraint_name {
8621 self.write_space();
8622 self.write_keyword("CONSTRAINT");
8623 self.write_space();
8624 self.write(cname);
8625 }
8626 }
8627 self.write_space();
8628 self.write_keyword("CHECK");
8629 self.write(" (");
8630 self.generate_expression(expr)?;
8631 self.write(")");
8632 check_idx += 1;
8633 break;
8634 }
8635 check_idx += 1;
8636 }
8637 }
8638 ConstraintType::GeneratedAsIdentity => {
8639 while generated_idx < col.constraints.len() {
8641 if let ColumnConstraint::GeneratedAsIdentity(gen) =
8642 &col.constraints[generated_idx]
8643 {
8644 self.write_space();
8645 if matches!(
8647 self.config.dialect,
8648 Some(crate::dialects::DialectType::Redshift)
8649 ) {
8650 self.write_keyword("IDENTITY");
8651 self.write("(");
8652 if let Some(ref start) = gen.start {
8653 self.generate_expression(start)?;
8654 } else {
8655 self.write("0");
8656 }
8657 self.write(", ");
8658 if let Some(ref incr) = gen.increment {
8659 self.generate_expression(incr)?;
8660 } else {
8661 self.write("1");
8662 }
8663 self.write(")");
8664 } else {
8665 self.write_keyword("GENERATED");
8666 if gen.always {
8667 self.write_space();
8668 self.write_keyword("ALWAYS");
8669 } else {
8670 self.write_space();
8671 self.write_keyword("BY DEFAULT");
8672 if gen.on_null {
8673 self.write_space();
8674 self.write_keyword("ON NULL");
8675 }
8676 }
8677 self.write_space();
8678 self.write_keyword("AS IDENTITY");
8679
8680 let has_options = gen.start.is_some()
8681 || gen.increment.is_some()
8682 || gen.minvalue.is_some()
8683 || gen.maxvalue.is_some()
8684 || gen.cycle.is_some();
8685 if has_options {
8686 self.write(" (");
8687 let mut first = true;
8688 if let Some(ref start) = gen.start {
8689 if !first {
8690 self.write(" ");
8691 }
8692 first = false;
8693 self.write_keyword("START WITH");
8694 self.write_space();
8695 self.generate_expression(start)?;
8696 }
8697 if let Some(ref incr) = gen.increment {
8698 if !first {
8699 self.write(" ");
8700 }
8701 first = false;
8702 self.write_keyword("INCREMENT BY");
8703 self.write_space();
8704 self.generate_expression(incr)?;
8705 }
8706 if let Some(ref minv) = gen.minvalue {
8707 if !first {
8708 self.write(" ");
8709 }
8710 first = false;
8711 self.write_keyword("MINVALUE");
8712 self.write_space();
8713 self.generate_expression(minv)?;
8714 }
8715 if let Some(ref maxv) = gen.maxvalue {
8716 if !first {
8717 self.write(" ");
8718 }
8719 first = false;
8720 self.write_keyword("MAXVALUE");
8721 self.write_space();
8722 self.generate_expression(maxv)?;
8723 }
8724 if let Some(cycle) = gen.cycle {
8725 if !first {
8726 self.write(" ");
8727 }
8728 if cycle {
8729 self.write_keyword("CYCLE");
8730 } else {
8731 self.write_keyword("NO CYCLE");
8732 }
8733 }
8734 self.write(")");
8735 }
8736 }
8737 generated_idx += 1;
8738 break;
8739 }
8740 generated_idx += 1;
8741 }
8742 }
8743 ConstraintType::Collate => {
8744 while collate_idx < col.constraints.len() {
8746 if let ColumnConstraint::Collate(collation) =
8747 &col.constraints[collate_idx]
8748 {
8749 self.write_space();
8750 self.write_keyword("COLLATE");
8751 self.write_space();
8752 self.generate_identifier(collation)?;
8753 collate_idx += 1;
8754 break;
8755 }
8756 collate_idx += 1;
8757 }
8758 }
8759 ConstraintType::Comment => {
8760 while comment_idx < col.constraints.len() {
8762 if let ColumnConstraint::Comment(comment) =
8763 &col.constraints[comment_idx]
8764 {
8765 self.write_space();
8766 self.write_keyword("COMMENT");
8767 self.write_space();
8768 self.generate_string_literal(comment)?;
8769 comment_idx += 1;
8770 break;
8771 }
8772 comment_idx += 1;
8773 }
8774 }
8775 ConstraintType::Tags => {
8776 for constraint in &col.constraints {
8778 if let ColumnConstraint::Tags(tags) = constraint {
8779 self.write_space();
8780 self.write_keyword("TAG");
8781 self.write(" (");
8782 for (i, expr) in tags.expressions.iter().enumerate() {
8783 if i > 0 {
8784 self.write(", ");
8785 }
8786 self.generate_expression(expr)?;
8787 }
8788 self.write(")");
8789 break;
8790 }
8791 }
8792 }
8793 ConstraintType::ComputedColumn => {
8794 for constraint in &col.constraints {
8796 if let ColumnConstraint::ComputedColumn(cc) = constraint {
8797 self.write_space();
8798 self.generate_computed_column_inline(cc)?;
8799 break;
8800 }
8801 }
8802 }
8803 ConstraintType::GeneratedAsRow => {
8804 for constraint in &col.constraints {
8806 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
8807 self.write_space();
8808 self.generate_generated_as_row_inline(gar)?;
8809 break;
8810 }
8811 }
8812 }
8813 ConstraintType::OnUpdate => {
8814 if let Some(ref expr) = col.on_update {
8815 self.write_space();
8816 self.write_keyword("ON UPDATE");
8817 self.write_space();
8818 self.generate_expression(expr)?;
8819 }
8820 }
8821 ConstraintType::Encode => {
8822 if let Some(ref encoding) = col.encoding {
8823 self.write_space();
8824 self.write_keyword("ENCODE");
8825 self.write_space();
8826 self.write(encoding);
8827 }
8828 }
8829 ConstraintType::Path => {
8830 for constraint in &col.constraints {
8832 if let ColumnConstraint::Path(path_expr) = constraint {
8833 self.write_space();
8834 self.write_keyword("PATH");
8835 self.write_space();
8836 self.generate_expression(path_expr)?;
8837 break;
8838 }
8839 }
8840 }
8841 }
8842 }
8843 if pending_not_null_after_identity {
8844 self.write_space();
8845 self.write_keyword("NOT NULL");
8846 }
8847 } else {
8848 if col.primary_key {
8850 self.write_space();
8851 self.write_keyword("PRIMARY KEY");
8852 if let Some(ref order) = col.primary_key_order {
8853 self.write_space();
8854 match order {
8855 SortOrder::Asc => self.write_keyword("ASC"),
8856 SortOrder::Desc => self.write_keyword("DESC"),
8857 }
8858 }
8859 }
8860
8861 if col.unique {
8862 self.write_space();
8863 self.write_keyword("UNIQUE");
8864 if col.unique_nulls_not_distinct {
8866 self.write(" NULLS NOT DISTINCT");
8867 }
8868 }
8869
8870 match col.nullable {
8871 Some(false) => {
8872 self.write_space();
8873 self.write_keyword("NOT NULL");
8874 }
8875 Some(true) => {
8876 self.write_space();
8877 self.write_keyword("NULL");
8878 }
8879 None => {}
8880 }
8881
8882 if let Some(ref default) = col.default {
8883 self.write_space();
8884 self.write_keyword("DEFAULT");
8885 self.write_space();
8886 self.generate_expression(default)?;
8887 }
8888
8889 if col.auto_increment {
8890 self.write_space();
8891 self.generate_auto_increment_keyword(col)?;
8892 }
8893
8894 for constraint in &col.constraints {
8896 match constraint {
8897 ColumnConstraint::References(fk_ref) => {
8898 self.write_space();
8899 if fk_ref.has_foreign_key_keywords {
8900 self.write_keyword("FOREIGN KEY");
8901 self.write_space();
8902 }
8903 self.write_keyword("REFERENCES");
8904 self.write_space();
8905 self.generate_table(&fk_ref.table)?;
8906 if !fk_ref.columns.is_empty() {
8907 self.write(" (");
8908 for (i, c) in fk_ref.columns.iter().enumerate() {
8909 if i > 0 {
8910 self.write(", ");
8911 }
8912 self.generate_identifier(c)?;
8913 }
8914 self.write(")");
8915 }
8916 self.generate_referential_actions(fk_ref)?;
8917 }
8918 ColumnConstraint::Check(expr) => {
8919 self.write_space();
8920 self.write_keyword("CHECK");
8921 self.write(" (");
8922 self.generate_expression(expr)?;
8923 self.write(")");
8924 }
8925 ColumnConstraint::GeneratedAsIdentity(gen) => {
8926 self.write_space();
8927 if matches!(
8929 self.config.dialect,
8930 Some(crate::dialects::DialectType::Redshift)
8931 ) {
8932 self.write_keyword("IDENTITY");
8933 self.write("(");
8934 if let Some(ref start) = gen.start {
8935 self.generate_expression(start)?;
8936 } else {
8937 self.write("0");
8938 }
8939 self.write(", ");
8940 if let Some(ref incr) = gen.increment {
8941 self.generate_expression(incr)?;
8942 } else {
8943 self.write("1");
8944 }
8945 self.write(")");
8946 } else {
8947 self.write_keyword("GENERATED");
8948 if gen.always {
8949 self.write_space();
8950 self.write_keyword("ALWAYS");
8951 } else {
8952 self.write_space();
8953 self.write_keyword("BY DEFAULT");
8954 if gen.on_null {
8955 self.write_space();
8956 self.write_keyword("ON NULL");
8957 }
8958 }
8959 self.write_space();
8960 self.write_keyword("AS IDENTITY");
8961
8962 let has_options = gen.start.is_some()
8963 || gen.increment.is_some()
8964 || gen.minvalue.is_some()
8965 || gen.maxvalue.is_some()
8966 || gen.cycle.is_some();
8967 if has_options {
8968 self.write(" (");
8969 let mut first = true;
8970 if let Some(ref start) = gen.start {
8971 if !first {
8972 self.write(" ");
8973 }
8974 first = false;
8975 self.write_keyword("START WITH");
8976 self.write_space();
8977 self.generate_expression(start)?;
8978 }
8979 if let Some(ref incr) = gen.increment {
8980 if !first {
8981 self.write(" ");
8982 }
8983 first = false;
8984 self.write_keyword("INCREMENT BY");
8985 self.write_space();
8986 self.generate_expression(incr)?;
8987 }
8988 if let Some(ref minv) = gen.minvalue {
8989 if !first {
8990 self.write(" ");
8991 }
8992 first = false;
8993 self.write_keyword("MINVALUE");
8994 self.write_space();
8995 self.generate_expression(minv)?;
8996 }
8997 if let Some(ref maxv) = gen.maxvalue {
8998 if !first {
8999 self.write(" ");
9000 }
9001 first = false;
9002 self.write_keyword("MAXVALUE");
9003 self.write_space();
9004 self.generate_expression(maxv)?;
9005 }
9006 if let Some(cycle) = gen.cycle {
9007 if !first {
9008 self.write(" ");
9009 }
9010 if cycle {
9011 self.write_keyword("CYCLE");
9012 } else {
9013 self.write_keyword("NO CYCLE");
9014 }
9015 }
9016 self.write(")");
9017 }
9018 }
9019 }
9020 ColumnConstraint::Collate(collation) => {
9021 self.write_space();
9022 self.write_keyword("COLLATE");
9023 self.write_space();
9024 self.generate_identifier(collation)?;
9025 }
9026 ColumnConstraint::Comment(comment) => {
9027 self.write_space();
9028 self.write_keyword("COMMENT");
9029 self.write_space();
9030 self.generate_string_literal(comment)?;
9031 }
9032 ColumnConstraint::Path(path_expr) => {
9033 self.write_space();
9034 self.write_keyword("PATH");
9035 self.write_space();
9036 self.generate_expression(path_expr)?;
9037 }
9038 _ => {} }
9040 }
9041
9042 if let Some(ref encoding) = col.encoding {
9044 self.write_space();
9045 self.write_keyword("ENCODE");
9046 self.write_space();
9047 self.write(encoding);
9048 }
9049 }
9050
9051 if let Some(ref codec) = col.codec {
9053 self.write_space();
9054 self.write_keyword("CODEC");
9055 self.write("(");
9056 self.write(codec);
9057 self.write(")");
9058 }
9059
9060 if let Some(ref ephemeral) = col.ephemeral {
9062 self.write_space();
9063 self.write_keyword("EPHEMERAL");
9064 if let Some(ref expr) = ephemeral {
9065 self.write_space();
9066 self.generate_expression(expr)?;
9067 }
9068 }
9069
9070 if let Some(ref mat_expr) = col.materialized_expr {
9072 self.write_space();
9073 self.write_keyword("MATERIALIZED");
9074 self.write_space();
9075 self.generate_expression(mat_expr)?;
9076 }
9077
9078 if let Some(ref alias_expr) = col.alias_expr {
9080 self.write_space();
9081 self.write_keyword("ALIAS");
9082 self.write_space();
9083 self.generate_expression(alias_expr)?;
9084 }
9085
9086 if let Some(ref ttl_expr) = col.ttl_expr {
9088 self.write_space();
9089 self.write_keyword("TTL");
9090 self.write_space();
9091 self.generate_expression(ttl_expr)?;
9092 }
9093
9094 if col.not_for_replication
9096 && matches!(
9097 self.config.dialect,
9098 Some(crate::dialects::DialectType::TSQL)
9099 | Some(crate::dialects::DialectType::Fabric)
9100 )
9101 {
9102 self.write_space();
9103 self.write_keyword("NOT FOR REPLICATION");
9104 }
9105
9106 if !col.options.is_empty() {
9108 self.write_space();
9109 self.generate_options_clause(&col.options)?;
9110 }
9111
9112 if !col.primary_key
9115 && self
9116 .sqlite_inline_pk_columns
9117 .contains(&col.name.name.to_ascii_lowercase())
9118 {
9119 self.write_space();
9120 self.write_keyword("PRIMARY KEY");
9121 }
9122
9123 if serial_expansion.is_some() {
9126 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
9127 self.write_space();
9128 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
9129 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
9130 self.write_space();
9131 self.write_keyword("NOT NULL");
9132 }
9133 }
9134
9135 Ok(())
9136 }
9137
9138 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
9139 match constraint {
9140 TableConstraint::PrimaryKey {
9141 name,
9142 columns,
9143 include_columns,
9144 modifiers,
9145 has_constraint_keyword,
9146 } => {
9147 if let Some(ref n) = name {
9148 if *has_constraint_keyword {
9149 self.write_keyword("CONSTRAINT");
9150 self.write_space();
9151 self.generate_identifier(n)?;
9152 self.write_space();
9153 }
9154 }
9155 self.write_keyword("PRIMARY KEY");
9156 if let Some(ref clustered) = modifiers.clustered {
9158 self.write_space();
9159 self.write_keyword(clustered);
9160 }
9161 if let Some(ref n) = name {
9163 if !*has_constraint_keyword {
9164 self.write_space();
9165 self.generate_identifier(n)?;
9166 }
9167 }
9168 self.write(" (");
9169 for (i, col) in columns.iter().enumerate() {
9170 if i > 0 {
9171 self.write(", ");
9172 }
9173 self.generate_identifier(col)?;
9174 }
9175 self.write(")");
9176 if !include_columns.is_empty() {
9177 self.write_space();
9178 self.write_keyword("INCLUDE");
9179 self.write(" (");
9180 for (i, col) in include_columns.iter().enumerate() {
9181 if i > 0 {
9182 self.write(", ");
9183 }
9184 self.generate_identifier(col)?;
9185 }
9186 self.write(")");
9187 }
9188 self.generate_constraint_modifiers(modifiers);
9189 }
9190 TableConstraint::Unique {
9191 name,
9192 columns,
9193 columns_parenthesized,
9194 modifiers,
9195 has_constraint_keyword,
9196 nulls_not_distinct,
9197 } => {
9198 if let Some(ref n) = name {
9199 if *has_constraint_keyword {
9200 self.write_keyword("CONSTRAINT");
9201 self.write_space();
9202 self.generate_identifier(n)?;
9203 self.write_space();
9204 }
9205 }
9206 self.write_keyword("UNIQUE");
9207 if let Some(ref clustered) = modifiers.clustered {
9209 self.write_space();
9210 self.write_keyword(clustered);
9211 }
9212 if *nulls_not_distinct {
9214 self.write(" NULLS NOT DISTINCT");
9215 }
9216 if let Some(ref n) = name {
9218 if !*has_constraint_keyword {
9219 self.write_space();
9220 self.generate_identifier(n)?;
9221 }
9222 }
9223 if *columns_parenthesized {
9224 self.write(" (");
9225 for (i, col) in columns.iter().enumerate() {
9226 if i > 0 {
9227 self.write(", ");
9228 }
9229 self.generate_identifier(col)?;
9230 }
9231 self.write(")");
9232 } else {
9233 for col in columns.iter() {
9235 self.write_space();
9236 self.generate_identifier(col)?;
9237 }
9238 }
9239 self.generate_constraint_modifiers(modifiers);
9240 }
9241 TableConstraint::ForeignKey {
9242 name,
9243 columns,
9244 references,
9245 on_delete,
9246 on_update,
9247 modifiers,
9248 } => {
9249 if let Some(ref n) = name {
9250 self.write_keyword("CONSTRAINT");
9251 self.write_space();
9252 self.generate_identifier(n)?;
9253 self.write_space();
9254 }
9255 self.write_keyword("FOREIGN KEY");
9256 self.write(" (");
9257 for (i, col) in columns.iter().enumerate() {
9258 if i > 0 {
9259 self.write(", ");
9260 }
9261 self.generate_identifier(col)?;
9262 }
9263 self.write(")");
9264 if let Some(ref refs) = references {
9265 self.write(" ");
9266 self.write_keyword("REFERENCES");
9267 self.write_space();
9268 self.generate_table(&refs.table)?;
9269 if !refs.columns.is_empty() {
9270 if self.config.pretty {
9271 self.write(" (");
9272 self.write_newline();
9273 self.indent_level += 1;
9274 for (i, col) in refs.columns.iter().enumerate() {
9275 if i > 0 {
9276 self.write(",");
9277 self.write_newline();
9278 }
9279 self.write_indent();
9280 self.generate_identifier(col)?;
9281 }
9282 self.indent_level -= 1;
9283 self.write_newline();
9284 self.write_indent();
9285 self.write(")");
9286 } else {
9287 self.write(" (");
9288 for (i, col) in refs.columns.iter().enumerate() {
9289 if i > 0 {
9290 self.write(", ");
9291 }
9292 self.generate_identifier(col)?;
9293 }
9294 self.write(")");
9295 }
9296 }
9297 self.generate_referential_actions(refs)?;
9298 } else {
9299 if let Some(ref action) = on_delete {
9301 self.write_space();
9302 self.write_keyword("ON DELETE");
9303 self.write_space();
9304 self.generate_referential_action(action);
9305 }
9306 if let Some(ref action) = on_update {
9307 self.write_space();
9308 self.write_keyword("ON UPDATE");
9309 self.write_space();
9310 self.generate_referential_action(action);
9311 }
9312 }
9313 self.generate_constraint_modifiers(modifiers);
9314 }
9315 TableConstraint::Check {
9316 name,
9317 expression,
9318 modifiers,
9319 } => {
9320 if let Some(ref n) = name {
9321 self.write_keyword("CONSTRAINT");
9322 self.write_space();
9323 self.generate_identifier(n)?;
9324 self.write_space();
9325 }
9326 self.write_keyword("CHECK");
9327 self.write(" (");
9328 self.generate_expression(expression)?;
9329 self.write(")");
9330 self.generate_constraint_modifiers(modifiers);
9331 }
9332 TableConstraint::Assume { name, expression } => {
9333 if let Some(ref n) = name {
9334 self.write_keyword("CONSTRAINT");
9335 self.write_space();
9336 self.generate_identifier(n)?;
9337 self.write_space();
9338 }
9339 self.write_keyword("ASSUME");
9340 self.write(" (");
9341 self.generate_expression(expression)?;
9342 self.write(")");
9343 }
9344 TableConstraint::Index {
9345 name,
9346 columns,
9347 kind,
9348 modifiers,
9349 use_key_keyword,
9350 expression,
9351 index_type,
9352 granularity,
9353 } => {
9354 if expression.is_some() {
9356 self.write_keyword("INDEX");
9357 if let Some(ref n) = name {
9358 self.write_space();
9359 self.generate_identifier(n)?;
9360 }
9361 if let Some(ref expr) = expression {
9362 self.write_space();
9363 self.generate_expression(expr)?;
9364 }
9365 if let Some(ref idx_type) = index_type {
9366 self.write_space();
9367 self.write_keyword("TYPE");
9368 self.write_space();
9369 self.generate_expression(idx_type)?;
9370 }
9371 if let Some(ref gran) = granularity {
9372 self.write_space();
9373 self.write_keyword("GRANULARITY");
9374 self.write_space();
9375 self.generate_expression(gran)?;
9376 }
9377 } else {
9378 use crate::dialects::DialectType;
9382 let index_keyword = if *use_key_keyword
9383 && !matches!(self.config.dialect, Some(DialectType::MySQL))
9384 {
9385 "KEY"
9386 } else {
9387 "INDEX"
9388 };
9389
9390 if let Some(ref k) = kind {
9392 self.write_keyword(k);
9393 if k != "UNIQUE" {
9395 self.write_space();
9396 self.write_keyword(index_keyword);
9397 }
9398 } else {
9399 self.write_keyword(index_keyword);
9400 }
9401
9402 if modifiers.using_before_columns && name.is_none() {
9404 if let Some(ref using) = modifiers.using {
9405 self.write_space();
9406 self.write_keyword("USING");
9407 self.write_space();
9408 self.write_keyword(using);
9409 }
9410 }
9411
9412 if let Some(ref n) = name {
9414 self.write_space();
9415 self.generate_identifier(n)?;
9416 }
9417
9418 if modifiers.using_before_columns && name.is_some() {
9420 if let Some(ref using) = modifiers.using {
9421 self.write_space();
9422 self.write_keyword("USING");
9423 self.write_space();
9424 self.write_keyword(using);
9425 }
9426 }
9427
9428 self.write(" (");
9430 for (i, col) in columns.iter().enumerate() {
9431 if i > 0 {
9432 self.write(", ");
9433 }
9434 self.generate_identifier(col)?;
9435 }
9436 self.write(")");
9437
9438 if !modifiers.using_before_columns {
9440 if let Some(ref using) = modifiers.using {
9441 self.write_space();
9442 self.write_keyword("USING");
9443 self.write_space();
9444 self.write_keyword(using);
9445 }
9446 }
9447
9448 self.generate_constraint_modifiers_without_using(modifiers);
9450 }
9451 }
9452 TableConstraint::Projection { name, expression } => {
9453 self.write_keyword("PROJECTION");
9455 self.write_space();
9456 self.generate_identifier(name)?;
9457 self.write(" (");
9458 self.generate_expression(expression)?;
9459 self.write(")");
9460 }
9461 TableConstraint::Like { source, options } => {
9462 self.write_keyword("LIKE");
9463 self.write_space();
9464 self.generate_table(source)?;
9465 for (action, prop) in options {
9466 self.write_space();
9467 match action {
9468 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
9469 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
9470 }
9471 self.write_space();
9472 self.write_keyword(prop);
9473 }
9474 }
9475 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
9476 self.write_keyword("PERIOD FOR SYSTEM_TIME");
9477 self.write(" (");
9478 self.generate_identifier(start_col)?;
9479 self.write(", ");
9480 self.generate_identifier(end_col)?;
9481 self.write(")");
9482 }
9483 TableConstraint::Exclude {
9484 name,
9485 using,
9486 elements,
9487 include_columns,
9488 where_clause,
9489 with_params,
9490 using_index_tablespace,
9491 modifiers: _,
9492 } => {
9493 if let Some(ref n) = name {
9494 self.write_keyword("CONSTRAINT");
9495 self.write_space();
9496 self.generate_identifier(n)?;
9497 self.write_space();
9498 }
9499 self.write_keyword("EXCLUDE");
9500 if let Some(ref method) = using {
9501 self.write_space();
9502 self.write_keyword("USING");
9503 self.write_space();
9504 self.write(method);
9505 self.write("(");
9506 } else {
9507 self.write(" (");
9508 }
9509 for (i, elem) in elements.iter().enumerate() {
9510 if i > 0 {
9511 self.write(", ");
9512 }
9513 self.write(&elem.expression);
9514 self.write_space();
9515 self.write_keyword("WITH");
9516 self.write_space();
9517 self.write(&elem.operator);
9518 }
9519 self.write(")");
9520 if !include_columns.is_empty() {
9521 self.write_space();
9522 self.write_keyword("INCLUDE");
9523 self.write(" (");
9524 for (i, col) in include_columns.iter().enumerate() {
9525 if i > 0 {
9526 self.write(", ");
9527 }
9528 self.generate_identifier(col)?;
9529 }
9530 self.write(")");
9531 }
9532 if !with_params.is_empty() {
9533 self.write_space();
9534 self.write_keyword("WITH");
9535 self.write(" (");
9536 for (i, (key, val)) in with_params.iter().enumerate() {
9537 if i > 0 {
9538 self.write(", ");
9539 }
9540 self.write(key);
9541 self.write("=");
9542 self.write(val);
9543 }
9544 self.write(")");
9545 }
9546 if let Some(ref tablespace) = using_index_tablespace {
9547 self.write_space();
9548 self.write_keyword("USING INDEX TABLESPACE");
9549 self.write_space();
9550 self.write(tablespace);
9551 }
9552 if let Some(ref where_expr) = where_clause {
9553 self.write_space();
9554 self.write_keyword("WHERE");
9555 self.write(" (");
9556 self.generate_expression(where_expr)?;
9557 self.write(")");
9558 }
9559 }
9560 TableConstraint::Tags(tags) => {
9561 self.write_keyword("TAG");
9562 self.write(" (");
9563 for (i, expr) in tags.expressions.iter().enumerate() {
9564 if i > 0 {
9565 self.write(", ");
9566 }
9567 self.generate_expression(expr)?;
9568 }
9569 self.write(")");
9570 }
9571 TableConstraint::InitiallyDeferred { deferred } => {
9572 self.write_keyword("INITIALLY");
9573 self.write_space();
9574 if *deferred {
9575 self.write_keyword("DEFERRED");
9576 } else {
9577 self.write_keyword("IMMEDIATE");
9578 }
9579 }
9580 }
9581 Ok(())
9582 }
9583
9584 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9585 if let Some(using) = &modifiers.using {
9587 self.write_space();
9588 self.write_keyword("USING");
9589 self.write_space();
9590 self.write_keyword(using);
9591 }
9592 if let Some(enforced) = modifiers.enforced {
9594 self.write_space();
9595 if enforced {
9596 self.write_keyword("ENFORCED");
9597 } else {
9598 self.write_keyword("NOT ENFORCED");
9599 }
9600 }
9601 if let Some(deferrable) = modifiers.deferrable {
9603 self.write_space();
9604 if deferrable {
9605 self.write_keyword("DEFERRABLE");
9606 } else {
9607 self.write_keyword("NOT DEFERRABLE");
9608 }
9609 }
9610 if let Some(initially_deferred) = modifiers.initially_deferred {
9612 self.write_space();
9613 if initially_deferred {
9614 self.write_keyword("INITIALLY DEFERRED");
9615 } else {
9616 self.write_keyword("INITIALLY IMMEDIATE");
9617 }
9618 }
9619 if modifiers.norely {
9621 self.write_space();
9622 self.write_keyword("NORELY");
9623 }
9624 if modifiers.rely {
9626 self.write_space();
9627 self.write_keyword("RELY");
9628 }
9629 if modifiers.not_valid {
9631 self.write_space();
9632 self.write_keyword("NOT VALID");
9633 }
9634 if let Some(on_conflict) = &modifiers.on_conflict {
9636 self.write_space();
9637 self.write_keyword("ON CONFLICT");
9638 self.write_space();
9639 self.write_keyword(on_conflict);
9640 }
9641 if !modifiers.with_options.is_empty() {
9643 self.write_space();
9644 self.write_keyword("WITH");
9645 self.write(" (");
9646 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
9647 if i > 0 {
9648 self.write(", ");
9649 }
9650 self.write(key);
9651 self.write("=");
9652 self.write(value);
9653 }
9654 self.write(")");
9655 }
9656 if let Some(ref fg) = modifiers.on_filegroup {
9658 self.write_space();
9659 self.write_keyword("ON");
9660 self.write_space();
9661 let _ = self.generate_identifier(fg);
9662 }
9663 }
9664
9665 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
9667 if let Some(enforced) = modifiers.enforced {
9669 self.write_space();
9670 if enforced {
9671 self.write_keyword("ENFORCED");
9672 } else {
9673 self.write_keyword("NOT ENFORCED");
9674 }
9675 }
9676 if let Some(deferrable) = modifiers.deferrable {
9678 self.write_space();
9679 if deferrable {
9680 self.write_keyword("DEFERRABLE");
9681 } else {
9682 self.write_keyword("NOT DEFERRABLE");
9683 }
9684 }
9685 if let Some(initially_deferred) = modifiers.initially_deferred {
9687 self.write_space();
9688 if initially_deferred {
9689 self.write_keyword("INITIALLY DEFERRED");
9690 } else {
9691 self.write_keyword("INITIALLY IMMEDIATE");
9692 }
9693 }
9694 if modifiers.norely {
9696 self.write_space();
9697 self.write_keyword("NORELY");
9698 }
9699 if modifiers.rely {
9701 self.write_space();
9702 self.write_keyword("RELY");
9703 }
9704 if modifiers.not_valid {
9706 self.write_space();
9707 self.write_keyword("NOT VALID");
9708 }
9709 if let Some(on_conflict) = &modifiers.on_conflict {
9711 self.write_space();
9712 self.write_keyword("ON CONFLICT");
9713 self.write_space();
9714 self.write_keyword(on_conflict);
9715 }
9716 self.generate_index_specific_modifiers(modifiers);
9718 }
9719
9720 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
9722 if let Some(ref comment) = modifiers.comment {
9723 self.write_space();
9724 self.write_keyword("COMMENT");
9725 self.write(" '");
9726 self.write(comment);
9727 self.write("'");
9728 }
9729 if let Some(visible) = modifiers.visible {
9730 self.write_space();
9731 if visible {
9732 self.write_keyword("VISIBLE");
9733 } else {
9734 self.write_keyword("INVISIBLE");
9735 }
9736 }
9737 if let Some(ref attr) = modifiers.engine_attribute {
9738 self.write_space();
9739 self.write_keyword("ENGINE_ATTRIBUTE");
9740 self.write(" = '");
9741 self.write(attr);
9742 self.write("'");
9743 }
9744 if let Some(ref parser) = modifiers.with_parser {
9745 self.write_space();
9746 self.write_keyword("WITH PARSER");
9747 self.write_space();
9748 self.write(parser);
9749 }
9750 }
9751
9752 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
9753 if !fk_ref.match_after_actions {
9755 if let Some(ref match_type) = fk_ref.match_type {
9756 self.write_space();
9757 self.write_keyword("MATCH");
9758 self.write_space();
9759 match match_type {
9760 MatchType::Full => self.write_keyword("FULL"),
9761 MatchType::Partial => self.write_keyword("PARTIAL"),
9762 MatchType::Simple => self.write_keyword("SIMPLE"),
9763 }
9764 }
9765 }
9766
9767 if fk_ref.on_update_first {
9769 if let Some(ref action) = fk_ref.on_update {
9770 self.write_space();
9771 self.write_keyword("ON UPDATE");
9772 self.write_space();
9773 self.generate_referential_action(action);
9774 }
9775 if let Some(ref action) = fk_ref.on_delete {
9776 self.write_space();
9777 self.write_keyword("ON DELETE");
9778 self.write_space();
9779 self.generate_referential_action(action);
9780 }
9781 } else {
9782 if let Some(ref action) = fk_ref.on_delete {
9783 self.write_space();
9784 self.write_keyword("ON DELETE");
9785 self.write_space();
9786 self.generate_referential_action(action);
9787 }
9788 if let Some(ref action) = fk_ref.on_update {
9789 self.write_space();
9790 self.write_keyword("ON UPDATE");
9791 self.write_space();
9792 self.generate_referential_action(action);
9793 }
9794 }
9795
9796 if fk_ref.match_after_actions {
9798 if let Some(ref match_type) = fk_ref.match_type {
9799 self.write_space();
9800 self.write_keyword("MATCH");
9801 self.write_space();
9802 match match_type {
9803 MatchType::Full => self.write_keyword("FULL"),
9804 MatchType::Partial => self.write_keyword("PARTIAL"),
9805 MatchType::Simple => self.write_keyword("SIMPLE"),
9806 }
9807 }
9808 }
9809
9810 if let Some(deferrable) = fk_ref.deferrable {
9812 self.write_space();
9813 if deferrable {
9814 self.write_keyword("DEFERRABLE");
9815 } else {
9816 self.write_keyword("NOT DEFERRABLE");
9817 }
9818 }
9819
9820 Ok(())
9821 }
9822
9823 fn generate_referential_action(&mut self, action: &ReferentialAction) {
9824 match action {
9825 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
9826 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
9827 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
9828 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
9829 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
9830 }
9831 }
9832
9833 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
9834 if let Some(ref object_id_args) = dt.object_id_args {
9836 if matches!(
9837 self.config.dialect,
9838 Some(crate::dialects::DialectType::TSQL)
9839 | Some(crate::dialects::DialectType::Fabric)
9840 ) {
9841 self.write_keyword("IF NOT OBJECT_ID");
9842 self.write("(");
9843 self.write(object_id_args);
9844 self.write(")");
9845 self.write_space();
9846 self.write_keyword("IS NULL BEGIN DROP TABLE");
9847 self.write_space();
9848 for (i, table) in dt.names.iter().enumerate() {
9849 if i > 0 {
9850 self.write(", ");
9851 }
9852 self.generate_table(table)?;
9853 }
9854 self.write("; ");
9855 self.write_keyword("END");
9856 return Ok(());
9857 }
9858 }
9859
9860 let saved_athena_hive_context = self.athena_hive_context;
9862 if matches!(
9863 self.config.dialect,
9864 Some(crate::dialects::DialectType::Athena)
9865 ) {
9866 self.athena_hive_context = true;
9867 }
9868
9869 for comment in &dt.leading_comments {
9871 self.write_formatted_comment(comment);
9872 self.write_space();
9873 }
9874 if dt.iceberg {
9875 self.write_keyword("DROP ICEBERG TABLE");
9876 } else {
9877 self.write_keyword("DROP TABLE");
9878 }
9879
9880 if dt.if_exists {
9881 self.write_space();
9882 self.write_keyword("IF EXISTS");
9883 }
9884
9885 self.write_space();
9886 for (i, table) in dt.names.iter().enumerate() {
9887 if i > 0 {
9888 self.write(", ");
9889 }
9890 self.generate_table(table)?;
9891 }
9892
9893 if dt.cascade_constraints {
9894 self.write_space();
9895 self.write_keyword("CASCADE CONSTRAINTS");
9896 } else if dt.cascade {
9897 self.write_space();
9898 self.write_keyword("CASCADE");
9899 }
9900
9901 if dt.restrict {
9902 self.write_space();
9903 self.write_keyword("RESTRICT");
9904 }
9905
9906 if dt.purge {
9907 self.write_space();
9908 self.write_keyword("PURGE");
9909 }
9910
9911 if dt.sync {
9912 self.write_space();
9913 self.write_keyword("SYNC");
9914 }
9915
9916 self.athena_hive_context = saved_athena_hive_context;
9918
9919 Ok(())
9920 }
9921
9922 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
9923 let saved_athena_hive_context = self.athena_hive_context;
9925 if matches!(
9926 self.config.dialect,
9927 Some(crate::dialects::DialectType::Athena)
9928 ) {
9929 self.athena_hive_context = true;
9930 }
9931
9932 self.write_keyword("ALTER");
9933 if let Some(ref modifier) = at.table_modifier {
9935 if !matches!(
9936 self.config.dialect,
9937 Some(crate::dialects::DialectType::DuckDB)
9938 ) {
9939 self.write_space();
9940 self.write_keyword(modifier);
9941 }
9942 }
9943 self.write(" ");
9944 self.write_keyword("TABLE");
9945 if at.if_exists {
9946 self.write_space();
9947 self.write_keyword("IF EXISTS");
9948 }
9949 self.write_space();
9950 self.generate_table(&at.name)?;
9951
9952 if let Some(ref on_cluster) = at.on_cluster {
9954 self.write_space();
9955 self.generate_on_cluster(on_cluster)?;
9956 }
9957
9958 if let Some(ref partition) = at.partition {
9960 self.write_space();
9961 self.write_keyword("PARTITION");
9962 self.write("(");
9963 for (i, (key, value)) in partition.iter().enumerate() {
9964 if i > 0 {
9965 self.write(", ");
9966 }
9967 self.generate_identifier(key)?;
9968 self.write(" = ");
9969 self.generate_expression(value)?;
9970 }
9971 self.write(")");
9972 }
9973
9974 if let Some(ref with_check) = at.with_check {
9976 self.write_space();
9977 self.write_keyword(with_check);
9978 }
9979
9980 if self.config.pretty {
9981 self.write_newline();
9983 self.indent_level += 1;
9984 for (i, action) in at.actions.iter().enumerate() {
9985 let is_continuation = i > 0
9987 && matches!(
9988 (&at.actions[i - 1], action),
9989 (
9990 AlterTableAction::AddColumn { .. },
9991 AlterTableAction::AddColumn { .. }
9992 ) | (
9993 AlterTableAction::AddConstraint(_),
9994 AlterTableAction::AddConstraint(_)
9995 )
9996 );
9997 if i > 0 {
9998 self.write(",");
9999 self.write_newline();
10000 }
10001 self.write_indent();
10002 self.generate_alter_action_with_continuation(action, is_continuation)?;
10003 }
10004 self.indent_level -= 1;
10005 } else {
10006 for (i, action) in at.actions.iter().enumerate() {
10007 let is_continuation = i > 0
10009 && matches!(
10010 (&at.actions[i - 1], action),
10011 (
10012 AlterTableAction::AddColumn { .. },
10013 AlterTableAction::AddColumn { .. }
10014 ) | (
10015 AlterTableAction::AddConstraint(_),
10016 AlterTableAction::AddConstraint(_)
10017 )
10018 );
10019 if i > 0 {
10020 self.write(",");
10021 }
10022 self.write_space();
10023 self.generate_alter_action_with_continuation(action, is_continuation)?;
10024 }
10025 }
10026
10027 if let Some(ref algorithm) = at.algorithm {
10029 self.write(", ");
10030 self.write_keyword("ALGORITHM");
10031 self.write("=");
10032 self.write_keyword(algorithm);
10033 }
10034 if let Some(ref lock) = at.lock {
10035 self.write(", ");
10036 self.write_keyword("LOCK");
10037 self.write("=");
10038 self.write_keyword(lock);
10039 }
10040
10041 self.athena_hive_context = saved_athena_hive_context;
10043
10044 Ok(())
10045 }
10046
10047 fn generate_alter_action_with_continuation(
10048 &mut self,
10049 action: &AlterTableAction,
10050 is_continuation: bool,
10051 ) -> Result<()> {
10052 match action {
10053 AlterTableAction::AddColumn {
10054 column,
10055 if_not_exists,
10056 position,
10057 } => {
10058 use crate::dialects::DialectType;
10059 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
10063 let is_tsql_like = matches!(
10064 self.config.dialect,
10065 Some(DialectType::TSQL) | Some(DialectType::Fabric)
10066 );
10067 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
10069
10070 if is_continuation && (is_snowflake || is_tsql_like) {
10071 } else if is_snowflake {
10073 self.write_keyword("ADD");
10074 self.write_space();
10075 } else if is_athena {
10076 self.write_keyword("ADD COLUMNS");
10078 self.write(" (");
10079 } else if self.config.alter_table_include_column_keyword {
10080 self.write_keyword("ADD COLUMN");
10081 self.write_space();
10082 } else {
10083 self.write_keyword("ADD");
10085 self.write_space();
10086 }
10087
10088 if *if_not_exists {
10089 self.write_keyword("IF NOT EXISTS");
10090 self.write_space();
10091 }
10092 self.generate_column_def(column)?;
10093
10094 if is_athena {
10096 self.write(")");
10097 }
10098
10099 if let Some(pos) = position {
10101 self.write_space();
10102 match pos {
10103 ColumnPosition::First => self.write_keyword("FIRST"),
10104 ColumnPosition::After(col_name) => {
10105 self.write_keyword("AFTER");
10106 self.write_space();
10107 self.generate_identifier(col_name)?;
10108 }
10109 }
10110 }
10111 }
10112 AlterTableAction::DropColumn {
10113 name,
10114 if_exists,
10115 cascade,
10116 } => {
10117 self.write_keyword("DROP COLUMN");
10118 if *if_exists {
10119 self.write_space();
10120 self.write_keyword("IF EXISTS");
10121 }
10122 self.write_space();
10123 self.generate_identifier(name)?;
10124 if *cascade {
10125 self.write_space();
10126 self.write_keyword("CASCADE");
10127 }
10128 }
10129 AlterTableAction::DropColumns { names } => {
10130 self.write_keyword("DROP COLUMNS");
10131 self.write(" (");
10132 for (i, name) in names.iter().enumerate() {
10133 if i > 0 {
10134 self.write(", ");
10135 }
10136 self.generate_identifier(name)?;
10137 }
10138 self.write(")");
10139 }
10140 AlterTableAction::RenameColumn {
10141 old_name,
10142 new_name,
10143 if_exists,
10144 } => {
10145 self.write_keyword("RENAME COLUMN");
10146 if *if_exists {
10147 self.write_space();
10148 self.write_keyword("IF EXISTS");
10149 }
10150 self.write_space();
10151 self.generate_identifier(old_name)?;
10152 self.write_space();
10153 self.write_keyword("TO");
10154 self.write_space();
10155 self.generate_identifier(new_name)?;
10156 }
10157 AlterTableAction::AlterColumn {
10158 name,
10159 action,
10160 use_modify_keyword,
10161 } => {
10162 use crate::dialects::DialectType;
10163 let use_modify = *use_modify_keyword
10166 || (matches!(self.config.dialect, Some(DialectType::MySQL))
10167 && matches!(action, AlterColumnAction::SetDataType { .. }));
10168 if use_modify {
10169 self.write_keyword("MODIFY COLUMN");
10170 self.write_space();
10171 self.generate_identifier(name)?;
10172 if let AlterColumnAction::SetDataType {
10174 data_type,
10175 using: _,
10176 collate,
10177 } = action
10178 {
10179 self.write_space();
10180 self.generate_data_type(data_type)?;
10181 if let Some(collate_name) = collate {
10183 self.write_space();
10184 self.write_keyword("COLLATE");
10185 self.write_space();
10186 self.write(&format!("'{}'", collate_name));
10188 }
10189 } else {
10190 self.write_space();
10191 self.generate_alter_column_action(action)?;
10192 }
10193 } else if matches!(self.config.dialect, Some(DialectType::Hive))
10194 && matches!(action, AlterColumnAction::SetDataType { .. })
10195 {
10196 self.write_keyword("CHANGE COLUMN");
10198 self.write_space();
10199 self.generate_identifier(name)?;
10200 self.write_space();
10201 self.generate_identifier(name)?;
10202 if let AlterColumnAction::SetDataType { data_type, .. } = action {
10203 self.write_space();
10204 self.generate_data_type(data_type)?;
10205 }
10206 } else {
10207 self.write_keyword("ALTER COLUMN");
10208 self.write_space();
10209 self.generate_identifier(name)?;
10210 self.write_space();
10211 self.generate_alter_column_action(action)?;
10212 }
10213 }
10214 AlterTableAction::RenameTable(new_name) => {
10215 let mysql_like = matches!(
10217 self.config.dialect,
10218 Some(DialectType::MySQL)
10219 | Some(DialectType::Doris)
10220 | Some(DialectType::StarRocks)
10221 | Some(DialectType::SingleStore)
10222 );
10223 if mysql_like {
10224 self.write_keyword("RENAME");
10225 } else {
10226 self.write_keyword("RENAME TO");
10227 }
10228 self.write_space();
10229 let rename_table_with_db = !matches!(
10231 self.config.dialect,
10232 Some(DialectType::Doris)
10233 | Some(DialectType::DuckDB)
10234 | Some(DialectType::BigQuery)
10235 | Some(DialectType::PostgreSQL)
10236 );
10237 if !rename_table_with_db {
10238 let mut stripped = new_name.clone();
10239 stripped.schema = None;
10240 stripped.catalog = None;
10241 self.generate_table(&stripped)?;
10242 } else {
10243 self.generate_table(new_name)?;
10244 }
10245 }
10246 AlterTableAction::AddConstraint(constraint) => {
10247 if !is_continuation {
10250 self.write_keyword("ADD");
10251 self.write_space();
10252 }
10253 self.generate_table_constraint(constraint)?;
10254 }
10255 AlterTableAction::DropConstraint { name, if_exists } => {
10256 self.write_keyword("DROP CONSTRAINT");
10257 if *if_exists {
10258 self.write_space();
10259 self.write_keyword("IF EXISTS");
10260 }
10261 self.write_space();
10262 self.generate_identifier(name)?;
10263 }
10264 AlterTableAction::DropForeignKey { name } => {
10265 self.write_keyword("DROP FOREIGN KEY");
10266 self.write_space();
10267 self.generate_identifier(name)?;
10268 }
10269 AlterTableAction::DropPartition {
10270 partitions,
10271 if_exists,
10272 } => {
10273 self.write_keyword("DROP");
10274 if *if_exists {
10275 self.write_space();
10276 self.write_keyword("IF EXISTS");
10277 }
10278 for (i, partition) in partitions.iter().enumerate() {
10279 if i > 0 {
10280 self.write(",");
10281 }
10282 self.write_space();
10283 self.write_keyword("PARTITION");
10284 if partition.len() == 1 && partition[0].0.name == "__expr__" {
10286 self.write_space();
10288 self.generate_expression(&partition[0].1)?;
10289 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
10290 self.write_space();
10292 self.write_keyword("ALL");
10293 } else if partition.len() == 1 && partition[0].0.name == "ID" {
10294 self.write_space();
10296 self.write_keyword("ID");
10297 self.write_space();
10298 self.generate_expression(&partition[0].1)?;
10299 } else {
10300 self.write("(");
10302 for (j, (key, value)) in partition.iter().enumerate() {
10303 if j > 0 {
10304 self.write(", ");
10305 }
10306 self.generate_identifier(key)?;
10307 self.write(" = ");
10308 self.generate_expression(value)?;
10309 }
10310 self.write(")");
10311 }
10312 }
10313 }
10314 AlterTableAction::Delete { where_clause } => {
10315 self.write_keyword("DELETE");
10316 self.write_space();
10317 self.write_keyword("WHERE");
10318 self.write_space();
10319 self.generate_expression(where_clause)?;
10320 }
10321 AlterTableAction::SwapWith(target) => {
10322 self.write_keyword("SWAP WITH");
10323 self.write_space();
10324 self.generate_table(target)?;
10325 }
10326 AlterTableAction::SetProperty { properties } => {
10327 use crate::dialects::DialectType;
10328 self.write_keyword("SET");
10329 let is_trino_presto = matches!(
10331 self.config.dialect,
10332 Some(DialectType::Trino) | Some(DialectType::Presto)
10333 );
10334 if is_trino_presto {
10335 self.write_space();
10336 self.write_keyword("PROPERTIES");
10337 }
10338 let eq = if is_trino_presto { " = " } else { "=" };
10339 for (i, (key, value)) in properties.iter().enumerate() {
10340 if i > 0 {
10341 self.write(",");
10342 }
10343 self.write_space();
10344 if key.contains(' ') {
10346 self.generate_string_literal(key)?;
10347 } else {
10348 self.write(key);
10349 }
10350 self.write(eq);
10351 self.generate_expression(value)?;
10352 }
10353 }
10354 AlterTableAction::UnsetProperty { properties } => {
10355 self.write_keyword("UNSET");
10356 for (i, name) in properties.iter().enumerate() {
10357 if i > 0 {
10358 self.write(",");
10359 }
10360 self.write_space();
10361 self.write(name);
10362 }
10363 }
10364 AlterTableAction::ClusterBy { expressions } => {
10365 self.write_keyword("CLUSTER BY");
10366 self.write(" (");
10367 for (i, expr) in expressions.iter().enumerate() {
10368 if i > 0 {
10369 self.write(", ");
10370 }
10371 self.generate_expression(expr)?;
10372 }
10373 self.write(")");
10374 }
10375 AlterTableAction::SetTag { expressions } => {
10376 self.write_keyword("SET TAG");
10377 for (i, (key, value)) in expressions.iter().enumerate() {
10378 if i > 0 {
10379 self.write(",");
10380 }
10381 self.write_space();
10382 self.write(key);
10383 self.write(" = ");
10384 self.generate_expression(value)?;
10385 }
10386 }
10387 AlterTableAction::UnsetTag { names } => {
10388 self.write_keyword("UNSET TAG");
10389 for (i, name) in names.iter().enumerate() {
10390 if i > 0 {
10391 self.write(",");
10392 }
10393 self.write_space();
10394 self.write(name);
10395 }
10396 }
10397 AlterTableAction::SetOptions { expressions } => {
10398 self.write_keyword("SET");
10399 self.write(" (");
10400 for (i, expr) in expressions.iter().enumerate() {
10401 if i > 0 {
10402 self.write(", ");
10403 }
10404 self.generate_expression(expr)?;
10405 }
10406 self.write(")");
10407 }
10408 AlterTableAction::AlterIndex { name, visible } => {
10409 self.write_keyword("ALTER INDEX");
10410 self.write_space();
10411 self.generate_identifier(name)?;
10412 self.write_space();
10413 if *visible {
10414 self.write_keyword("VISIBLE");
10415 } else {
10416 self.write_keyword("INVISIBLE");
10417 }
10418 }
10419 AlterTableAction::SetAttribute { attribute } => {
10420 self.write_keyword("SET");
10421 self.write_space();
10422 self.write_keyword(attribute);
10423 }
10424 AlterTableAction::SetStageFileFormat { options } => {
10425 self.write_keyword("SET");
10426 self.write_space();
10427 self.write_keyword("STAGE_FILE_FORMAT");
10428 self.write(" = (");
10429 if let Some(opts) = options {
10430 self.generate_space_separated_properties(opts)?;
10431 }
10432 self.write(")");
10433 }
10434 AlterTableAction::SetStageCopyOptions { options } => {
10435 self.write_keyword("SET");
10436 self.write_space();
10437 self.write_keyword("STAGE_COPY_OPTIONS");
10438 self.write(" = (");
10439 if let Some(opts) = options {
10440 self.generate_space_separated_properties(opts)?;
10441 }
10442 self.write(")");
10443 }
10444 AlterTableAction::AddColumns { columns, cascade } => {
10445 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
10448 if is_oracle {
10449 self.write_keyword("ADD");
10450 } else {
10451 self.write_keyword("ADD COLUMNS");
10452 }
10453 self.write(" (");
10454 for (i, col) in columns.iter().enumerate() {
10455 if i > 0 {
10456 self.write(", ");
10457 }
10458 self.generate_column_def(col)?;
10459 }
10460 self.write(")");
10461 if *cascade {
10462 self.write_space();
10463 self.write_keyword("CASCADE");
10464 }
10465 }
10466 AlterTableAction::ChangeColumn {
10467 old_name,
10468 new_name,
10469 data_type,
10470 comment,
10471 cascade,
10472 } => {
10473 use crate::dialects::DialectType;
10474 let is_spark = matches!(
10475 self.config.dialect,
10476 Some(DialectType::Spark) | Some(DialectType::Databricks)
10477 );
10478 let is_rename = old_name.name != new_name.name;
10479
10480 if is_spark {
10481 if is_rename {
10482 self.write_keyword("RENAME COLUMN");
10484 self.write_space();
10485 self.generate_identifier(old_name)?;
10486 self.write_space();
10487 self.write_keyword("TO");
10488 self.write_space();
10489 self.generate_identifier(new_name)?;
10490 } else if comment.is_some() {
10491 self.write_keyword("ALTER COLUMN");
10493 self.write_space();
10494 self.generate_identifier(old_name)?;
10495 self.write_space();
10496 self.write_keyword("COMMENT");
10497 self.write_space();
10498 self.write("'");
10499 self.write(comment.as_ref().unwrap());
10500 self.write("'");
10501 } else if data_type.is_some() {
10502 self.write_keyword("ALTER COLUMN");
10504 self.write_space();
10505 self.generate_identifier(old_name)?;
10506 self.write_space();
10507 self.write_keyword("TYPE");
10508 self.write_space();
10509 self.generate_data_type(data_type.as_ref().unwrap())?;
10510 } else {
10511 self.write_keyword("CHANGE COLUMN");
10513 self.write_space();
10514 self.generate_identifier(old_name)?;
10515 self.write_space();
10516 self.generate_identifier(new_name)?;
10517 }
10518 } else {
10519 if data_type.is_some() {
10521 self.write_keyword("CHANGE COLUMN");
10522 } else {
10523 self.write_keyword("CHANGE");
10524 }
10525 self.write_space();
10526 self.generate_identifier(old_name)?;
10527 self.write_space();
10528 self.generate_identifier(new_name)?;
10529 if let Some(ref dt) = data_type {
10530 self.write_space();
10531 self.generate_data_type(dt)?;
10532 }
10533 if let Some(ref c) = comment {
10534 self.write_space();
10535 self.write_keyword("COMMENT");
10536 self.write_space();
10537 self.write("'");
10538 self.write(c);
10539 self.write("'");
10540 }
10541 if *cascade {
10542 self.write_space();
10543 self.write_keyword("CASCADE");
10544 }
10545 }
10546 }
10547 AlterTableAction::AddPartition {
10548 partition,
10549 if_not_exists,
10550 location,
10551 } => {
10552 self.write_keyword("ADD");
10553 self.write_space();
10554 if *if_not_exists {
10555 self.write_keyword("IF NOT EXISTS");
10556 self.write_space();
10557 }
10558 self.generate_expression(partition)?;
10559 if let Some(ref loc) = location {
10560 self.write_space();
10561 self.write_keyword("LOCATION");
10562 self.write_space();
10563 self.generate_expression(loc)?;
10564 }
10565 }
10566 AlterTableAction::AlterSortKey {
10567 this,
10568 expressions,
10569 compound,
10570 } => {
10571 self.write_keyword("ALTER");
10573 if *compound {
10574 self.write_space();
10575 self.write_keyword("COMPOUND");
10576 }
10577 self.write_space();
10578 self.write_keyword("SORTKEY");
10579 self.write_space();
10580 if let Some(style) = this {
10581 self.write_keyword(style);
10582 } else if !expressions.is_empty() {
10583 self.write("(");
10584 for (i, expr) in expressions.iter().enumerate() {
10585 if i > 0 {
10586 self.write(", ");
10587 }
10588 self.generate_expression(expr)?;
10589 }
10590 self.write(")");
10591 }
10592 }
10593 AlterTableAction::AlterDistStyle { style, distkey } => {
10594 self.write_keyword("ALTER");
10596 self.write_space();
10597 self.write_keyword("DISTSTYLE");
10598 self.write_space();
10599 self.write_keyword(style);
10600 if let Some(col) = distkey {
10601 self.write_space();
10602 self.write_keyword("DISTKEY");
10603 self.write_space();
10604 self.generate_identifier(col)?;
10605 }
10606 }
10607 AlterTableAction::SetTableProperties { properties } => {
10608 self.write_keyword("SET TABLE PROPERTIES");
10610 self.write(" (");
10611 for (i, (key, value)) in properties.iter().enumerate() {
10612 if i > 0 {
10613 self.write(", ");
10614 }
10615 self.generate_expression(key)?;
10616 self.write(" = ");
10617 self.generate_expression(value)?;
10618 }
10619 self.write(")");
10620 }
10621 AlterTableAction::SetLocation { location } => {
10622 self.write_keyword("SET LOCATION");
10624 self.write_space();
10625 self.write("'");
10626 self.write(location);
10627 self.write("'");
10628 }
10629 AlterTableAction::SetFileFormat { format } => {
10630 self.write_keyword("SET FILE FORMAT");
10632 self.write_space();
10633 self.write_keyword(format);
10634 }
10635 AlterTableAction::ReplacePartition { partition, source } => {
10636 self.write_keyword("REPLACE PARTITION");
10638 self.write_space();
10639 self.generate_expression(partition)?;
10640 if let Some(src) = source {
10641 self.write_space();
10642 self.write_keyword("FROM");
10643 self.write_space();
10644 self.generate_expression(src)?;
10645 }
10646 }
10647 AlterTableAction::Raw { sql } => {
10648 self.write(sql);
10649 }
10650 }
10651 Ok(())
10652 }
10653
10654 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
10655 match action {
10656 AlterColumnAction::SetDataType {
10657 data_type,
10658 using,
10659 collate,
10660 } => {
10661 use crate::dialects::DialectType;
10662 let is_no_prefix = matches!(
10667 self.config.dialect,
10668 Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive)
10669 );
10670 let is_type_only = matches!(
10671 self.config.dialect,
10672 Some(DialectType::Redshift)
10673 | Some(DialectType::Spark)
10674 | Some(DialectType::Databricks)
10675 );
10676 if is_type_only {
10677 self.write_keyword("TYPE");
10678 self.write_space();
10679 } else if !is_no_prefix {
10680 self.write_keyword("SET DATA TYPE");
10681 self.write_space();
10682 }
10683 self.generate_data_type(data_type)?;
10684 if let Some(ref collation) = collate {
10685 self.write_space();
10686 self.write_keyword("COLLATE");
10687 self.write_space();
10688 self.write(collation);
10689 }
10690 if let Some(ref using_expr) = using {
10691 self.write_space();
10692 self.write_keyword("USING");
10693 self.write_space();
10694 self.generate_expression(using_expr)?;
10695 }
10696 }
10697 AlterColumnAction::SetDefault(expr) => {
10698 self.write_keyword("SET DEFAULT");
10699 self.write_space();
10700 self.generate_expression(expr)?;
10701 }
10702 AlterColumnAction::DropDefault => {
10703 self.write_keyword("DROP DEFAULT");
10704 }
10705 AlterColumnAction::SetNotNull => {
10706 self.write_keyword("SET NOT NULL");
10707 }
10708 AlterColumnAction::DropNotNull => {
10709 self.write_keyword("DROP NOT NULL");
10710 }
10711 AlterColumnAction::Comment(comment) => {
10712 self.write_keyword("COMMENT");
10713 self.write_space();
10714 self.generate_string_literal(comment)?;
10715 }
10716 AlterColumnAction::SetVisible => {
10717 self.write_keyword("SET VISIBLE");
10718 }
10719 AlterColumnAction::SetInvisible => {
10720 self.write_keyword("SET INVISIBLE");
10721 }
10722 }
10723 Ok(())
10724 }
10725
10726 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
10727 self.write_keyword("CREATE");
10728
10729 if ci.unique {
10730 self.write_space();
10731 self.write_keyword("UNIQUE");
10732 }
10733
10734 if let Some(ref clustered) = ci.clustered {
10736 self.write_space();
10737 self.write_keyword(clustered);
10738 }
10739
10740 self.write_space();
10741 self.write_keyword("INDEX");
10742
10743 if ci.concurrently {
10745 self.write_space();
10746 self.write_keyword("CONCURRENTLY");
10747 }
10748
10749 if ci.if_not_exists {
10750 self.write_space();
10751 self.write_keyword("IF NOT EXISTS");
10752 }
10753
10754 if !ci.name.name.is_empty() {
10756 self.write_space();
10757 self.generate_identifier(&ci.name)?;
10758 }
10759 self.write_space();
10760 self.write_keyword("ON");
10761 if matches!(self.config.dialect, Some(DialectType::Hive)) {
10763 self.write_space();
10764 self.write_keyword("TABLE");
10765 }
10766 self.write_space();
10767 self.generate_table(&ci.table)?;
10768
10769 if !ci.columns.is_empty() || ci.using.is_some() {
10772 let space_before_paren = false;
10773
10774 if let Some(ref using) = ci.using {
10775 self.write_space();
10776 self.write_keyword("USING");
10777 self.write_space();
10778 self.write(using);
10779 if space_before_paren {
10780 self.write(" (");
10781 } else {
10782 self.write("(");
10783 }
10784 } else {
10785 if space_before_paren {
10786 self.write(" (");
10787 } else {
10788 self.write("(");
10789 }
10790 }
10791 for (i, col) in ci.columns.iter().enumerate() {
10792 if i > 0 {
10793 self.write(", ");
10794 }
10795 self.generate_identifier(&col.column)?;
10796 if let Some(ref opclass) = col.opclass {
10797 self.write_space();
10798 self.write(opclass);
10799 }
10800 if col.desc {
10801 self.write_space();
10802 self.write_keyword("DESC");
10803 } else if col.asc {
10804 self.write_space();
10805 self.write_keyword("ASC");
10806 }
10807 if let Some(nulls_first) = col.nulls_first {
10808 self.write_space();
10809 self.write_keyword("NULLS");
10810 self.write_space();
10811 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
10812 }
10813 }
10814 self.write(")");
10815 }
10816
10817 if !ci.include_columns.is_empty() {
10819 self.write_space();
10820 self.write_keyword("INCLUDE");
10821 self.write(" (");
10822 for (i, col) in ci.include_columns.iter().enumerate() {
10823 if i > 0 {
10824 self.write(", ");
10825 }
10826 self.generate_identifier(col)?;
10827 }
10828 self.write(")");
10829 }
10830
10831 if !ci.with_options.is_empty() {
10833 self.write_space();
10834 self.write_keyword("WITH");
10835 self.write(" (");
10836 for (i, (key, value)) in ci.with_options.iter().enumerate() {
10837 if i > 0 {
10838 self.write(", ");
10839 }
10840 self.write(key);
10841 self.write("=");
10842 self.write(value);
10843 }
10844 self.write(")");
10845 }
10846
10847 if let Some(ref where_clause) = ci.where_clause {
10849 self.write_space();
10850 self.write_keyword("WHERE");
10851 self.write_space();
10852 self.generate_expression(where_clause)?;
10853 }
10854
10855 if let Some(ref on_fg) = ci.on_filegroup {
10857 self.write_space();
10858 self.write_keyword("ON");
10859 self.write_space();
10860 self.write(on_fg);
10861 }
10862
10863 Ok(())
10864 }
10865
10866 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
10867 self.write_keyword("DROP INDEX");
10868
10869 if di.concurrently {
10870 self.write_space();
10871 self.write_keyword("CONCURRENTLY");
10872 }
10873
10874 if di.if_exists {
10875 self.write_space();
10876 self.write_keyword("IF EXISTS");
10877 }
10878
10879 self.write_space();
10880 self.generate_identifier(&di.name)?;
10881
10882 if let Some(ref table) = di.table {
10883 self.write_space();
10884 self.write_keyword("ON");
10885 self.write_space();
10886 self.generate_table(table)?;
10887 }
10888
10889 Ok(())
10890 }
10891
10892 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
10893 self.write_keyword("CREATE");
10894
10895 if let Some(ref algorithm) = cv.algorithm {
10897 self.write_space();
10898 self.write_keyword("ALGORITHM");
10899 self.write("=");
10900 self.write_keyword(algorithm);
10901 }
10902
10903 if let Some(ref definer) = cv.definer {
10905 self.write_space();
10906 self.write_keyword("DEFINER");
10907 self.write("=");
10908 self.write(definer);
10909 }
10910
10911 if cv.security_sql_style && !cv.security_after_name {
10913 if let Some(ref security) = cv.security {
10914 self.write_space();
10915 self.write_keyword("SQL SECURITY");
10916 self.write_space();
10917 match security {
10918 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10919 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10920 FunctionSecurity::None => self.write_keyword("NONE"),
10921 }
10922 }
10923 }
10924
10925 if cv.or_alter {
10926 self.write_space();
10927 self.write_keyword("OR ALTER");
10928 } else if cv.or_replace {
10929 self.write_space();
10930 self.write_keyword("OR REPLACE");
10931 }
10932
10933 if cv.temporary {
10934 self.write_space();
10935 self.write_keyword("TEMPORARY");
10936 }
10937
10938 if cv.materialized {
10939 self.write_space();
10940 self.write_keyword("MATERIALIZED");
10941 }
10942
10943 if cv.secure {
10945 self.write_space();
10946 self.write_keyword("SECURE");
10947 }
10948
10949 self.write_space();
10950 self.write_keyword("VIEW");
10951
10952 if cv.if_not_exists {
10953 self.write_space();
10954 self.write_keyword("IF NOT EXISTS");
10955 }
10956
10957 self.write_space();
10958 self.generate_table(&cv.name)?;
10959
10960 if let Some(ref on_cluster) = cv.on_cluster {
10962 self.write_space();
10963 self.generate_on_cluster(on_cluster)?;
10964 }
10965
10966 if let Some(ref to_table) = cv.to_table {
10968 self.write_space();
10969 self.write_keyword("TO");
10970 self.write_space();
10971 self.generate_table(to_table)?;
10972 }
10973
10974 if !cv.materialized {
10977 if !cv.columns.is_empty() {
10979 self.write(" (");
10980 for (i, col) in cv.columns.iter().enumerate() {
10981 if i > 0 {
10982 self.write(", ");
10983 }
10984 self.generate_identifier(&col.name)?;
10985 if !col.options.is_empty() {
10987 self.write_space();
10988 self.generate_options_clause(&col.options)?;
10989 }
10990 if let Some(ref comment) = col.comment {
10991 self.write_space();
10992 self.write_keyword("COMMENT");
10993 self.write_space();
10994 self.generate_string_literal(comment)?;
10995 }
10996 }
10997 self.write(")");
10998 }
10999
11000 if !cv.security_sql_style || cv.security_after_name {
11003 if let Some(ref security) = cv.security {
11004 self.write_space();
11005 if cv.security_sql_style {
11006 self.write_keyword("SQL SECURITY");
11007 } else {
11008 self.write_keyword("SECURITY");
11009 }
11010 self.write_space();
11011 match security {
11012 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
11013 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
11014 FunctionSecurity::None => self.write_keyword("NONE"),
11015 }
11016 }
11017 }
11018
11019 if cv.copy_grants {
11021 self.write_space();
11022 self.write_keyword("COPY GRANTS");
11023 }
11024 } else {
11025 if cv.copy_grants {
11027 self.write_space();
11028 self.write_keyword("COPY GRANTS");
11029 }
11030
11031 if let Some(ref schema) = cv.schema {
11033 self.write(" (");
11034 for (i, expr) in schema.expressions.iter().enumerate() {
11035 if i > 0 {
11036 self.write(", ");
11037 }
11038 self.generate_expression(expr)?;
11039 }
11040 self.write(")");
11041 } else if !cv.columns.is_empty() {
11042 self.write(" (");
11044 for (i, col) in cv.columns.iter().enumerate() {
11045 if i > 0 {
11046 self.write(", ");
11047 }
11048 self.generate_identifier(&col.name)?;
11049 if !col.options.is_empty() {
11051 self.write_space();
11052 self.generate_options_clause(&col.options)?;
11053 }
11054 if let Some(ref comment) = col.comment {
11055 self.write_space();
11056 self.write_keyword("COMMENT");
11057 self.write_space();
11058 self.generate_string_literal(comment)?;
11059 }
11060 }
11061 self.write(")");
11062 }
11063
11064 if let Some(ref unique_key) = cv.unique_key {
11066 self.write_space();
11067 self.write_keyword("KEY");
11068 self.write(" (");
11069 for (i, expr) in unique_key.expressions.iter().enumerate() {
11070 if i > 0 {
11071 self.write(", ");
11072 }
11073 self.generate_expression(expr)?;
11074 }
11075 self.write(")");
11076 }
11077 }
11078
11079 if let Some(ref comment) = cv.comment {
11081 self.write_space();
11082 self.write_keyword("COMMENT");
11083 self.write("=");
11084 self.generate_string_literal(comment)?;
11085 }
11086
11087 if !cv.tags.is_empty() {
11089 self.write_space();
11090 self.write_keyword("TAG");
11091 self.write(" (");
11092 for (i, (name, value)) in cv.tags.iter().enumerate() {
11093 if i > 0 {
11094 self.write(", ");
11095 }
11096 self.write(name);
11097 self.write("='");
11098 self.write(value);
11099 self.write("'");
11100 }
11101 self.write(")");
11102 }
11103
11104 if !cv.options.is_empty() {
11106 self.write_space();
11107 self.generate_options_clause(&cv.options)?;
11108 }
11109
11110 if let Some(ref build) = cv.build {
11112 self.write_space();
11113 self.write_keyword("BUILD");
11114 self.write_space();
11115 self.write_keyword(build);
11116 }
11117
11118 if let Some(ref refresh) = cv.refresh {
11120 self.write_space();
11121 self.generate_refresh_trigger_property(refresh)?;
11122 }
11123
11124 if let Some(auto_refresh) = cv.auto_refresh {
11126 self.write_space();
11127 self.write_keyword("AUTO REFRESH");
11128 self.write_space();
11129 if auto_refresh {
11130 self.write_keyword("YES");
11131 } else {
11132 self.write_keyword("NO");
11133 }
11134 }
11135
11136 for prop in &cv.table_properties {
11138 self.write_space();
11139 self.generate_expression(prop)?;
11140 }
11141
11142 if !matches!(&cv.query, Expression::Null(_)) {
11144 self.write_space();
11145 self.write_keyword("AS");
11146 self.write_space();
11147
11148 if let Some(ref mode) = cv.locking_mode {
11150 self.write_keyword("LOCKING");
11151 self.write_space();
11152 self.write_keyword(mode);
11153 if let Some(ref access) = cv.locking_access {
11154 self.write_space();
11155 self.write_keyword("FOR");
11156 self.write_space();
11157 self.write_keyword(access);
11158 }
11159 self.write_space();
11160 }
11161
11162 if cv.query_parenthesized {
11163 self.write("(");
11164 }
11165 self.generate_expression(&cv.query)?;
11166 if cv.query_parenthesized {
11167 self.write(")");
11168 }
11169 }
11170
11171 if cv.no_schema_binding {
11173 self.write_space();
11174 self.write_keyword("WITH NO SCHEMA BINDING");
11175 }
11176
11177 Ok(())
11178 }
11179
11180 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
11181 self.write_keyword("DROP");
11182
11183 if dv.materialized {
11184 self.write_space();
11185 self.write_keyword("MATERIALIZED");
11186 }
11187
11188 self.write_space();
11189 self.write_keyword("VIEW");
11190
11191 if dv.if_exists {
11192 self.write_space();
11193 self.write_keyword("IF EXISTS");
11194 }
11195
11196 self.write_space();
11197 self.generate_table(&dv.name)?;
11198
11199 Ok(())
11200 }
11201
11202 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
11203 match tr.target {
11204 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
11205 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
11206 }
11207 if tr.if_exists {
11208 self.write_space();
11209 self.write_keyword("IF EXISTS");
11210 }
11211 self.write_space();
11212 self.generate_table(&tr.table)?;
11213
11214 if let Some(ref on_cluster) = tr.on_cluster {
11216 self.write_space();
11217 self.generate_on_cluster(on_cluster)?;
11218 }
11219
11220 if !tr.extra_tables.is_empty() {
11222 let skip_first = if let Some(first) = tr.extra_tables.first() {
11224 first.table.name == tr.table.name && first.star
11225 } else {
11226 false
11227 };
11228
11229 let strip_star = matches!(
11231 self.config.dialect,
11232 Some(crate::dialects::DialectType::PostgreSQL)
11233 | Some(crate::dialects::DialectType::Redshift)
11234 );
11235 if skip_first && !strip_star {
11236 self.write("*");
11237 }
11238
11239 for (i, entry) in tr.extra_tables.iter().enumerate() {
11241 if i == 0 && skip_first {
11242 continue; }
11244 self.write(", ");
11245 self.generate_table(&entry.table)?;
11246 if entry.star && !strip_star {
11247 self.write("*");
11248 }
11249 }
11250 }
11251
11252 if let Some(identity) = &tr.identity {
11254 self.write_space();
11255 match identity {
11256 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
11257 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
11258 }
11259 }
11260
11261 if tr.cascade {
11262 self.write_space();
11263 self.write_keyword("CASCADE");
11264 }
11265
11266 if tr.restrict {
11267 self.write_space();
11268 self.write_keyword("RESTRICT");
11269 }
11270
11271 if let Some(ref partition) = tr.partition {
11273 self.write_space();
11274 self.generate_expression(partition)?;
11275 }
11276
11277 Ok(())
11278 }
11279
11280 fn generate_use(&mut self, u: &Use) -> Result<()> {
11281 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
11283 self.write_keyword("DATABASE");
11284 self.write_space();
11285 self.generate_identifier(&u.this)?;
11286 return Ok(());
11287 }
11288
11289 self.write_keyword("USE");
11290
11291 if let Some(kind) = &u.kind {
11292 self.write_space();
11293 match kind {
11294 UseKind::Database => self.write_keyword("DATABASE"),
11295 UseKind::Schema => self.write_keyword("SCHEMA"),
11296 UseKind::Role => self.write_keyword("ROLE"),
11297 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
11298 UseKind::Catalog => self.write_keyword("CATALOG"),
11299 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
11300 }
11301 }
11302
11303 self.write_space();
11304 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
11307 self.write(&u.this.name);
11308 } else {
11309 self.generate_identifier(&u.this)?;
11310 }
11311 Ok(())
11312 }
11313
11314 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
11315 self.write_keyword("CACHE");
11316 if c.lazy {
11317 self.write_space();
11318 self.write_keyword("LAZY");
11319 }
11320 self.write_space();
11321 self.write_keyword("TABLE");
11322 self.write_space();
11323 self.generate_identifier(&c.table)?;
11324
11325 if !c.options.is_empty() {
11327 self.write_space();
11328 self.write_keyword("OPTIONS");
11329 self.write("(");
11330 for (i, (key, value)) in c.options.iter().enumerate() {
11331 if i > 0 {
11332 self.write(", ");
11333 }
11334 self.generate_expression(key)?;
11335 self.write(" = ");
11336 self.generate_expression(value)?;
11337 }
11338 self.write(")");
11339 }
11340
11341 if let Some(query) = &c.query {
11343 self.write_space();
11344 self.write_keyword("AS");
11345 self.write_space();
11346 self.generate_expression(query)?;
11347 }
11348
11349 Ok(())
11350 }
11351
11352 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
11353 self.write_keyword("UNCACHE TABLE");
11354 if u.if_exists {
11355 self.write_space();
11356 self.write_keyword("IF EXISTS");
11357 }
11358 self.write_space();
11359 self.generate_identifier(&u.table)?;
11360 Ok(())
11361 }
11362
11363 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
11364 self.write_keyword("LOAD DATA");
11365 if l.local {
11366 self.write_space();
11367 self.write_keyword("LOCAL");
11368 }
11369 self.write_space();
11370 self.write_keyword("INPATH");
11371 self.write_space();
11372 self.write("'");
11373 self.write(&l.inpath);
11374 self.write("'");
11375
11376 if l.overwrite {
11377 self.write_space();
11378 self.write_keyword("OVERWRITE");
11379 }
11380
11381 self.write_space();
11382 self.write_keyword("INTO TABLE");
11383 self.write_space();
11384 self.generate_expression(&l.table)?;
11385
11386 if !l.partition.is_empty() {
11388 self.write_space();
11389 self.write_keyword("PARTITION");
11390 self.write("(");
11391 for (i, (col, val)) in l.partition.iter().enumerate() {
11392 if i > 0 {
11393 self.write(", ");
11394 }
11395 self.generate_identifier(col)?;
11396 self.write(" = ");
11397 self.generate_expression(val)?;
11398 }
11399 self.write(")");
11400 }
11401
11402 if let Some(fmt) = &l.input_format {
11404 self.write_space();
11405 self.write_keyword("INPUTFORMAT");
11406 self.write_space();
11407 self.write("'");
11408 self.write(fmt);
11409 self.write("'");
11410 }
11411
11412 if let Some(serde) = &l.serde {
11414 self.write_space();
11415 self.write_keyword("SERDE");
11416 self.write_space();
11417 self.write("'");
11418 self.write(serde);
11419 self.write("'");
11420 }
11421
11422 Ok(())
11423 }
11424
11425 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
11426 self.write_keyword("PRAGMA");
11427 self.write_space();
11428
11429 if let Some(schema) = &p.schema {
11431 self.generate_identifier(schema)?;
11432 self.write(".");
11433 }
11434
11435 self.generate_identifier(&p.name)?;
11437
11438 if let Some(value) = &p.value {
11440 self.write(" = ");
11441 self.generate_expression(value)?;
11442 } else if !p.args.is_empty() {
11443 self.write("(");
11444 for (i, arg) in p.args.iter().enumerate() {
11445 if i > 0 {
11446 self.write(", ");
11447 }
11448 self.generate_expression(arg)?;
11449 }
11450 self.write(")");
11451 }
11452
11453 Ok(())
11454 }
11455
11456 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
11457 self.write_keyword("GRANT");
11458 self.write_space();
11459
11460 for (i, privilege) in g.privileges.iter().enumerate() {
11462 if i > 0 {
11463 self.write(", ");
11464 }
11465 self.write_keyword(&privilege.name);
11466 if !privilege.columns.is_empty() {
11468 self.write("(");
11469 for (j, col) in privilege.columns.iter().enumerate() {
11470 if j > 0 {
11471 self.write(", ");
11472 }
11473 self.write(col);
11474 }
11475 self.write(")");
11476 }
11477 }
11478
11479 self.write_space();
11480 self.write_keyword("ON");
11481 self.write_space();
11482
11483 if let Some(kind) = &g.kind {
11485 self.write_keyword(kind);
11486 self.write_space();
11487 }
11488
11489 {
11491 use crate::dialects::DialectType;
11492 let should_upper = matches!(
11493 self.config.dialect,
11494 Some(DialectType::PostgreSQL)
11495 | Some(DialectType::CockroachDB)
11496 | Some(DialectType::Materialize)
11497 | Some(DialectType::RisingWave)
11498 ) && (g.kind.as_deref() == Some("FUNCTION")
11499 || g.kind.as_deref() == Some("PROCEDURE"));
11500 if should_upper {
11501 use crate::expressions::Identifier;
11502 let upper_id = Identifier {
11503 name: g.securable.name.to_ascii_uppercase(),
11504 quoted: g.securable.quoted,
11505 ..g.securable.clone()
11506 };
11507 self.generate_identifier(&upper_id)?;
11508 } else {
11509 self.generate_identifier(&g.securable)?;
11510 }
11511 }
11512
11513 if !g.function_params.is_empty() {
11515 self.write("(");
11516 for (i, param) in g.function_params.iter().enumerate() {
11517 if i > 0 {
11518 self.write(", ");
11519 }
11520 self.write(param);
11521 }
11522 self.write(")");
11523 }
11524
11525 self.write_space();
11526 self.write_keyword("TO");
11527 self.write_space();
11528
11529 for (i, principal) in g.principals.iter().enumerate() {
11531 if i > 0 {
11532 self.write(", ");
11533 }
11534 if principal.is_role {
11535 self.write_keyword("ROLE");
11536 self.write_space();
11537 } else if principal.is_group {
11538 self.write_keyword("GROUP");
11539 self.write_space();
11540 } else if principal.is_share {
11541 self.write_keyword("SHARE");
11542 self.write_space();
11543 }
11544 self.generate_identifier(&principal.name)?;
11545 }
11546
11547 if g.grant_option {
11549 self.write_space();
11550 self.write_keyword("WITH GRANT OPTION");
11551 }
11552
11553 if let Some(ref principal) = g.as_principal {
11555 self.write_space();
11556 self.write_keyword("AS");
11557 self.write_space();
11558 self.generate_identifier(principal)?;
11559 }
11560
11561 Ok(())
11562 }
11563
11564 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
11565 self.write_keyword("REVOKE");
11566 self.write_space();
11567
11568 if r.grant_option {
11570 self.write_keyword("GRANT OPTION FOR");
11571 self.write_space();
11572 }
11573
11574 for (i, privilege) in r.privileges.iter().enumerate() {
11576 if i > 0 {
11577 self.write(", ");
11578 }
11579 self.write_keyword(&privilege.name);
11580 if !privilege.columns.is_empty() {
11582 self.write("(");
11583 for (j, col) in privilege.columns.iter().enumerate() {
11584 if j > 0 {
11585 self.write(", ");
11586 }
11587 self.write(col);
11588 }
11589 self.write(")");
11590 }
11591 }
11592
11593 self.write_space();
11594 self.write_keyword("ON");
11595 self.write_space();
11596
11597 if let Some(kind) = &r.kind {
11599 self.write_keyword(kind);
11600 self.write_space();
11601 }
11602
11603 {
11605 use crate::dialects::DialectType;
11606 let should_upper = matches!(
11607 self.config.dialect,
11608 Some(DialectType::PostgreSQL)
11609 | Some(DialectType::CockroachDB)
11610 | Some(DialectType::Materialize)
11611 | Some(DialectType::RisingWave)
11612 ) && (r.kind.as_deref() == Some("FUNCTION")
11613 || r.kind.as_deref() == Some("PROCEDURE"));
11614 if should_upper {
11615 use crate::expressions::Identifier;
11616 let upper_id = Identifier {
11617 name: r.securable.name.to_ascii_uppercase(),
11618 quoted: r.securable.quoted,
11619 ..r.securable.clone()
11620 };
11621 self.generate_identifier(&upper_id)?;
11622 } else {
11623 self.generate_identifier(&r.securable)?;
11624 }
11625 }
11626
11627 if !r.function_params.is_empty() {
11629 self.write("(");
11630 for (i, param) in r.function_params.iter().enumerate() {
11631 if i > 0 {
11632 self.write(", ");
11633 }
11634 self.write(param);
11635 }
11636 self.write(")");
11637 }
11638
11639 self.write_space();
11640 self.write_keyword("FROM");
11641 self.write_space();
11642
11643 for (i, principal) in r.principals.iter().enumerate() {
11645 if i > 0 {
11646 self.write(", ");
11647 }
11648 if principal.is_role {
11649 self.write_keyword("ROLE");
11650 self.write_space();
11651 } else if principal.is_group {
11652 self.write_keyword("GROUP");
11653 self.write_space();
11654 } else if principal.is_share {
11655 self.write_keyword("SHARE");
11656 self.write_space();
11657 }
11658 self.generate_identifier(&principal.name)?;
11659 }
11660
11661 if r.cascade {
11663 self.write_space();
11664 self.write_keyword("CASCADE");
11665 } else if r.restrict {
11666 self.write_space();
11667 self.write_keyword("RESTRICT");
11668 }
11669
11670 Ok(())
11671 }
11672
11673 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
11674 self.write_keyword("COMMENT");
11675
11676 if c.exists {
11678 self.write_space();
11679 self.write_keyword("IF EXISTS");
11680 }
11681
11682 self.write_space();
11683 self.write_keyword("ON");
11684
11685 if c.materialized {
11687 self.write_space();
11688 self.write_keyword("MATERIALIZED");
11689 }
11690
11691 self.write_space();
11692 self.write_keyword(&c.kind);
11693 self.write_space();
11694
11695 self.generate_expression(&c.this)?;
11697
11698 self.write_space();
11699 self.write_keyword("IS");
11700 self.write_space();
11701
11702 self.generate_expression(&c.expression)?;
11704
11705 Ok(())
11706 }
11707
11708 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
11709 self.write_keyword("SET");
11710
11711 for (i, item) in s.items.iter().enumerate() {
11712 if i > 0 {
11713 self.write(",");
11714 }
11715 self.write_space();
11716
11717 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
11719 if let Some(ref kind) = item.kind {
11720 if has_variable_kind {
11724 if matches!(
11725 self.config.dialect,
11726 Some(DialectType::Spark | DialectType::Databricks | DialectType::DuckDB)
11727 ) {
11728 self.write_keyword("VARIABLE");
11729 self.write_space();
11730 }
11731 } else {
11732 self.write_keyword(kind);
11733 self.write_space();
11734 }
11735 }
11736
11737 let name_str = match &item.name {
11739 Expression::Identifier(id) => Some(id.name.as_str()),
11740 _ => None,
11741 };
11742
11743 let is_transaction = name_str == Some("TRANSACTION");
11744 let is_character_set = name_str == Some("CHARACTER SET");
11745 let is_names = name_str == Some("NAMES");
11746 let is_collate = name_str == Some("COLLATE");
11747 let is_value_only =
11748 matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
11749
11750 if is_transaction {
11751 self.write_keyword("TRANSACTION");
11753 if let Expression::Identifier(id) = &item.value {
11754 if !id.name.is_empty() {
11755 self.write_space();
11756 self.write(&id.name);
11757 }
11758 }
11759 } else if is_character_set {
11760 self.write_keyword("CHARACTER SET");
11762 self.write_space();
11763 self.generate_set_value(&item.value)?;
11764 } else if is_names {
11765 self.write_keyword("NAMES");
11767 self.write_space();
11768 self.generate_set_value(&item.value)?;
11769 } else if is_collate {
11770 self.write_keyword("COLLATE");
11772 self.write_space();
11773 self.generate_set_value(&item.value)?;
11774 } else if has_variable_kind {
11775 if let Some(ns) = name_str {
11778 self.write(ns);
11779 } else {
11780 self.generate_expression(&item.name)?;
11781 }
11782 self.write(" = ");
11783 self.generate_set_value(&item.value)?;
11784 } else if is_value_only {
11785 self.generate_expression(&item.name)?;
11787 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
11788 self.generate_expression(&item.name)?;
11790 self.write_space();
11791 self.generate_set_value(&item.value)?;
11792 } else {
11793 match &item.name {
11796 Expression::Identifier(id) => {
11797 self.write(&id.name);
11798 }
11799 _ => {
11800 self.generate_expression(&item.name)?;
11801 }
11802 }
11803 self.write(" = ");
11804 self.generate_set_value(&item.value)?;
11805 }
11806 }
11807
11808 Ok(())
11809 }
11810
11811 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
11814 if let Expression::Identifier(id) = value {
11815 match id.name.as_str() {
11816 "DEFAULT" | "ON" | "OFF" => {
11817 self.write_keyword(&id.name);
11818 return Ok(());
11819 }
11820 _ => {}
11821 }
11822 }
11823 self.generate_expression(value)
11824 }
11825
11826 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
11829 self.write_keyword("ALTER");
11830 if let Some(ref algorithm) = av.algorithm {
11832 self.write_space();
11833 self.write_keyword("ALGORITHM");
11834 self.write(" = ");
11835 self.write_keyword(algorithm);
11836 }
11837 if let Some(ref definer) = av.definer {
11838 self.write_space();
11839 self.write_keyword("DEFINER");
11840 self.write(" = ");
11841 self.write(definer);
11842 }
11843 if let Some(ref sql_security) = av.sql_security {
11844 self.write_space();
11845 self.write_keyword("SQL SECURITY");
11846 self.write(" = ");
11847 self.write_keyword(sql_security);
11848 }
11849 self.write_space();
11850 self.write_keyword("VIEW");
11851 self.write_space();
11852 self.generate_table(&av.name)?;
11853
11854 if !av.columns.is_empty() {
11856 self.write(" (");
11857 for (i, col) in av.columns.iter().enumerate() {
11858 if i > 0 {
11859 self.write(", ");
11860 }
11861 self.generate_identifier(&col.name)?;
11862 if let Some(ref comment) = col.comment {
11863 self.write_space();
11864 self.write_keyword("COMMENT");
11865 self.write(" ");
11866 self.generate_string_literal(comment)?;
11867 }
11868 }
11869 self.write(")");
11870 }
11871
11872 if let Some(ref opt) = av.with_option {
11874 self.write_space();
11875 self.write_keyword("WITH");
11876 self.write_space();
11877 self.write_keyword(opt);
11878 }
11879
11880 for action in &av.actions {
11881 self.write_space();
11882 match action {
11883 AlterViewAction::Rename(new_name) => {
11884 self.write_keyword("RENAME TO");
11885 self.write_space();
11886 self.generate_table(new_name)?;
11887 }
11888 AlterViewAction::OwnerTo(owner) => {
11889 self.write_keyword("OWNER TO");
11890 self.write_space();
11891 self.generate_identifier(owner)?;
11892 }
11893 AlterViewAction::SetSchema(schema) => {
11894 self.write_keyword("SET SCHEMA");
11895 self.write_space();
11896 self.generate_identifier(schema)?;
11897 }
11898 AlterViewAction::SetAuthorization(auth) => {
11899 self.write_keyword("SET AUTHORIZATION");
11900 self.write_space();
11901 self.write(auth);
11902 }
11903 AlterViewAction::AlterColumn { name, action } => {
11904 self.write_keyword("ALTER COLUMN");
11905 self.write_space();
11906 self.generate_identifier(name)?;
11907 self.write_space();
11908 self.generate_alter_column_action(action)?;
11909 }
11910 AlterViewAction::AsSelect(query) => {
11911 self.write_keyword("AS");
11912 self.write_space();
11913 self.generate_expression(query)?;
11914 }
11915 AlterViewAction::SetTblproperties(props) => {
11916 self.write_keyword("SET TBLPROPERTIES");
11917 self.write(" (");
11918 for (i, (key, value)) in props.iter().enumerate() {
11919 if i > 0 {
11920 self.write(", ");
11921 }
11922 self.generate_string_literal(key)?;
11923 self.write("=");
11924 self.generate_string_literal(value)?;
11925 }
11926 self.write(")");
11927 }
11928 AlterViewAction::UnsetTblproperties(keys) => {
11929 self.write_keyword("UNSET TBLPROPERTIES");
11930 self.write(" (");
11931 for (i, key) in keys.iter().enumerate() {
11932 if i > 0 {
11933 self.write(", ");
11934 }
11935 self.generate_string_literal(key)?;
11936 }
11937 self.write(")");
11938 }
11939 }
11940 }
11941
11942 Ok(())
11943 }
11944
11945 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
11946 self.write_keyword("ALTER INDEX");
11947 self.write_space();
11948 self.generate_identifier(&ai.name)?;
11949
11950 if let Some(table) = &ai.table {
11951 self.write_space();
11952 self.write_keyword("ON");
11953 self.write_space();
11954 self.generate_table(table)?;
11955 }
11956
11957 for action in &ai.actions {
11958 self.write_space();
11959 match action {
11960 AlterIndexAction::Rename(new_name) => {
11961 self.write_keyword("RENAME TO");
11962 self.write_space();
11963 self.generate_identifier(new_name)?;
11964 }
11965 AlterIndexAction::SetTablespace(tablespace) => {
11966 self.write_keyword("SET TABLESPACE");
11967 self.write_space();
11968 self.generate_identifier(tablespace)?;
11969 }
11970 AlterIndexAction::Visible(visible) => {
11971 if *visible {
11972 self.write_keyword("VISIBLE");
11973 } else {
11974 self.write_keyword("INVISIBLE");
11975 }
11976 }
11977 }
11978 }
11979
11980 Ok(())
11981 }
11982
11983 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
11984 for comment in &cs.leading_comments {
11986 self.write_formatted_comment(comment);
11987 self.write_space();
11988 }
11989
11990 let saved_athena_hive_context = self.athena_hive_context;
11992 if matches!(
11993 self.config.dialect,
11994 Some(crate::dialects::DialectType::Athena)
11995 ) {
11996 self.athena_hive_context = true;
11997 }
11998
11999 self.write_keyword("CREATE SCHEMA");
12000
12001 if cs.if_not_exists {
12002 self.write_space();
12003 self.write_keyword("IF NOT EXISTS");
12004 }
12005
12006 self.write_space();
12007 for (i, part) in cs.name.iter().enumerate() {
12008 if i > 0 {
12009 self.write(".");
12010 }
12011 self.generate_identifier(part)?;
12012 }
12013
12014 if let Some(ref clone_parts) = cs.clone_from {
12015 self.write_keyword(" CLONE ");
12016 for (i, part) in clone_parts.iter().enumerate() {
12017 if i > 0 {
12018 self.write(".");
12019 }
12020 self.generate_identifier(part)?;
12021 }
12022 }
12023
12024 if let Some(ref at_clause) = cs.at_clause {
12025 self.write_space();
12026 self.generate_expression(at_clause)?;
12027 }
12028
12029 if let Some(auth) = &cs.authorization {
12030 self.write_space();
12031 self.write_keyword("AUTHORIZATION");
12032 self.write_space();
12033 self.generate_identifier(auth)?;
12034 }
12035
12036 let with_properties: Vec<_> = cs
12039 .properties
12040 .iter()
12041 .filter(|p| matches!(p, Expression::Property(_)))
12042 .collect();
12043 let other_properties: Vec<_> = cs
12044 .properties
12045 .iter()
12046 .filter(|p| !matches!(p, Expression::Property(_)))
12047 .collect();
12048
12049 if !with_properties.is_empty() {
12051 self.write_space();
12052 self.write_keyword("WITH");
12053 self.write(" (");
12054 for (i, prop) in with_properties.iter().enumerate() {
12055 if i > 0 {
12056 self.write(", ");
12057 }
12058 self.generate_expression(prop)?;
12059 }
12060 self.write(")");
12061 }
12062
12063 for prop in other_properties {
12065 self.write_space();
12066 self.generate_expression(prop)?;
12067 }
12068
12069 self.athena_hive_context = saved_athena_hive_context;
12071
12072 Ok(())
12073 }
12074
12075 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
12076 self.write_keyword("DROP SCHEMA");
12077
12078 if ds.if_exists {
12079 self.write_space();
12080 self.write_keyword("IF EXISTS");
12081 }
12082
12083 self.write_space();
12084 self.generate_identifier(&ds.name)?;
12085
12086 if ds.cascade {
12087 self.write_space();
12088 self.write_keyword("CASCADE");
12089 }
12090
12091 Ok(())
12092 }
12093
12094 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
12095 self.write_keyword("DROP NAMESPACE");
12096
12097 if dn.if_exists {
12098 self.write_space();
12099 self.write_keyword("IF EXISTS");
12100 }
12101
12102 self.write_space();
12103 self.generate_identifier(&dn.name)?;
12104
12105 if dn.cascade {
12106 self.write_space();
12107 self.write_keyword("CASCADE");
12108 }
12109
12110 Ok(())
12111 }
12112
12113 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
12114 self.write_keyword("CREATE DATABASE");
12115
12116 if cd.if_not_exists {
12117 self.write_space();
12118 self.write_keyword("IF NOT EXISTS");
12119 }
12120
12121 self.write_space();
12122 self.generate_identifier(&cd.name)?;
12123
12124 if let Some(ref clone_src) = cd.clone_from {
12125 self.write_keyword(" CLONE ");
12126 self.generate_identifier(clone_src)?;
12127 }
12128
12129 if let Some(ref at_clause) = cd.at_clause {
12131 self.write_space();
12132 self.generate_expression(at_clause)?;
12133 }
12134
12135 for option in &cd.options {
12136 self.write_space();
12137 match option {
12138 DatabaseOption::CharacterSet(charset) => {
12139 self.write_keyword("CHARACTER SET");
12140 self.write(" = ");
12141 self.write(&format!("'{}'", charset));
12142 }
12143 DatabaseOption::Collate(collate) => {
12144 self.write_keyword("COLLATE");
12145 self.write(" = ");
12146 self.write(&format!("'{}'", collate));
12147 }
12148 DatabaseOption::Owner(owner) => {
12149 self.write_keyword("OWNER");
12150 self.write(" = ");
12151 self.generate_identifier(owner)?;
12152 }
12153 DatabaseOption::Template(template) => {
12154 self.write_keyword("TEMPLATE");
12155 self.write(" = ");
12156 self.generate_identifier(template)?;
12157 }
12158 DatabaseOption::Encoding(encoding) => {
12159 self.write_keyword("ENCODING");
12160 self.write(" = ");
12161 self.write(&format!("'{}'", encoding));
12162 }
12163 DatabaseOption::Location(location) => {
12164 self.write_keyword("LOCATION");
12165 self.write(" = ");
12166 self.write(&format!("'{}'", location));
12167 }
12168 }
12169 }
12170
12171 Ok(())
12172 }
12173
12174 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
12175 self.write_keyword("DROP DATABASE");
12176
12177 if dd.if_exists {
12178 self.write_space();
12179 self.write_keyword("IF EXISTS");
12180 }
12181
12182 self.write_space();
12183 self.generate_identifier(&dd.name)?;
12184
12185 if dd.sync {
12186 self.write_space();
12187 self.write_keyword("SYNC");
12188 }
12189
12190 Ok(())
12191 }
12192
12193 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
12194 self.write_keyword("CREATE");
12195
12196 if cf.or_alter {
12197 self.write_space();
12198 self.write_keyword("OR ALTER");
12199 } else if cf.or_replace {
12200 self.write_space();
12201 self.write_keyword("OR REPLACE");
12202 }
12203
12204 if cf.temporary {
12205 self.write_space();
12206 self.write_keyword("TEMPORARY");
12207 }
12208
12209 self.write_space();
12210 if cf.is_table_function {
12211 self.write_keyword("TABLE FUNCTION");
12212 } else {
12213 self.write_keyword("FUNCTION");
12214 }
12215
12216 if cf.if_not_exists {
12217 self.write_space();
12218 self.write_keyword("IF NOT EXISTS");
12219 }
12220
12221 self.write_space();
12222 self.generate_table(&cf.name)?;
12223 if cf.has_parens {
12224 let func_multiline = self.config.pretty
12225 && matches!(
12226 self.config.dialect,
12227 Some(crate::dialects::DialectType::TSQL)
12228 | Some(crate::dialects::DialectType::Fabric)
12229 )
12230 && !cf.parameters.is_empty();
12231 if func_multiline {
12232 self.write("(\n");
12233 self.indent_level += 2;
12234 self.write_indent();
12235 self.generate_function_parameters(&cf.parameters)?;
12236 self.write("\n");
12237 self.indent_level -= 2;
12238 self.write(")");
12239 } else {
12240 self.write("(");
12241 self.generate_function_parameters(&cf.parameters)?;
12242 self.write(")");
12243 }
12244 }
12245
12246 let use_multiline = self.config.pretty
12249 && matches!(
12250 self.config.dialect,
12251 Some(crate::dialects::DialectType::BigQuery)
12252 | Some(crate::dialects::DialectType::TSQL)
12253 | Some(crate::dialects::DialectType::Fabric)
12254 );
12255
12256 if cf.language_first {
12257 if let Some(lang) = &cf.language {
12259 if use_multiline {
12260 self.write_newline();
12261 } else {
12262 self.write_space();
12263 }
12264 self.write_keyword("LANGUAGE");
12265 self.write_space();
12266 self.write(lang);
12267 }
12268
12269 if let Some(sql_data) = &cf.sql_data_access {
12271 self.write_space();
12272 match sql_data {
12273 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12274 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12275 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12276 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12277 }
12278 }
12279
12280 if let Some(ref rtb) = cf.returns_table_body {
12281 if use_multiline {
12282 self.write_newline();
12283 } else {
12284 self.write_space();
12285 }
12286 self.write_keyword("RETURNS");
12287 self.write_space();
12288 self.write(rtb);
12289 } else if let Some(return_type) = &cf.return_type {
12290 if use_multiline {
12291 self.write_newline();
12292 } else {
12293 self.write_space();
12294 }
12295 self.write_keyword("RETURNS");
12296 self.write_space();
12297 self.generate_data_type(return_type)?;
12298 }
12299 } else {
12300 let is_duckdb = matches!(
12303 self.config.dialect,
12304 Some(crate::dialects::DialectType::DuckDB)
12305 );
12306 if let Some(ref rtb) = cf.returns_table_body {
12307 if !(is_duckdb && rtb.is_empty()) {
12308 if use_multiline {
12309 self.write_newline();
12310 } else {
12311 self.write_space();
12312 }
12313 self.write_keyword("RETURNS");
12314 self.write_space();
12315 self.write(rtb);
12316 }
12317 } else if let Some(return_type) = &cf.return_type {
12318 if !is_duckdb {
12320 let is_table_return = matches!(return_type, crate::expressions::DataType::Custom { ref name } if name.eq_ignore_ascii_case("TABLE"));
12321 if use_multiline {
12322 self.write_newline();
12323 } else {
12324 self.write_space();
12325 }
12326 self.write_keyword("RETURNS");
12327 self.write_space();
12328 if is_table_return {
12329 self.write_keyword("TABLE");
12330 } else {
12331 self.generate_data_type(return_type)?;
12332 }
12333 }
12334 }
12335 }
12336
12337 if !cf.property_order.is_empty() {
12339 let is_bigquery = matches!(
12341 self.config.dialect,
12342 Some(crate::dialects::DialectType::BigQuery)
12343 );
12344 let property_order = if is_bigquery {
12345 let mut reordered = Vec::new();
12347 let mut has_as = false;
12348 let mut has_options = false;
12349 for prop in &cf.property_order {
12350 match prop {
12351 FunctionPropertyKind::As => has_as = true,
12352 FunctionPropertyKind::Options => has_options = true,
12353 _ => {}
12354 }
12355 }
12356 if has_as && has_options {
12357 for prop in &cf.property_order {
12359 if *prop != FunctionPropertyKind::As
12360 && *prop != FunctionPropertyKind::Options
12361 {
12362 reordered.push(*prop);
12363 }
12364 }
12365 reordered.push(FunctionPropertyKind::Options);
12366 reordered.push(FunctionPropertyKind::As);
12367 reordered
12368 } else {
12369 cf.property_order.clone()
12370 }
12371 } else {
12372 cf.property_order.clone()
12373 };
12374
12375 for prop in &property_order {
12376 match prop {
12377 FunctionPropertyKind::Set => {
12378 self.generate_function_set_options(cf)?;
12379 }
12380 FunctionPropertyKind::As => {
12381 self.generate_function_body(cf)?;
12382 }
12383 FunctionPropertyKind::Language => {
12384 if !cf.language_first {
12385 if let Some(lang) = &cf.language {
12387 let use_multiline = self.config.pretty
12389 && matches!(
12390 self.config.dialect,
12391 Some(crate::dialects::DialectType::BigQuery)
12392 );
12393 if use_multiline {
12394 self.write_newline();
12395 } else {
12396 self.write_space();
12397 }
12398 self.write_keyword("LANGUAGE");
12399 self.write_space();
12400 self.write(lang);
12401 }
12402 }
12403 }
12404 FunctionPropertyKind::Determinism => {
12405 self.generate_function_determinism(cf)?;
12406 }
12407 FunctionPropertyKind::NullInput => {
12408 self.generate_function_null_input(cf)?;
12409 }
12410 FunctionPropertyKind::Security => {
12411 self.generate_function_security(cf)?;
12412 }
12413 FunctionPropertyKind::SqlDataAccess => {
12414 if !cf.language_first {
12415 self.generate_function_sql_data_access(cf)?;
12417 }
12418 }
12419 FunctionPropertyKind::Options => {
12420 if !cf.options.is_empty() {
12421 self.write_space();
12422 self.generate_options_clause(&cf.options)?;
12423 }
12424 }
12425 FunctionPropertyKind::Environment => {
12426 if !cf.environment.is_empty() {
12427 self.write_space();
12428 self.generate_environment_clause(&cf.environment)?;
12429 }
12430 }
12431 FunctionPropertyKind::Handler => {
12432 if let Some(ref h) = cf.handler {
12433 self.write_space();
12434 self.write_keyword("HANDLER");
12435 self.write_space();
12436 self.write("'");
12437 self.write(h);
12438 self.write("'");
12439 }
12440 }
12441 FunctionPropertyKind::ParameterStyle => {
12442 if let Some(ref ps) = cf.parameter_style {
12443 self.write_space();
12444 self.write_keyword("PARAMETER STYLE");
12445 self.write_space();
12446 self.write_keyword(ps);
12447 }
12448 }
12449 }
12450 }
12451
12452 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options)
12454 {
12455 self.write_space();
12456 self.generate_options_clause(&cf.options)?;
12457 }
12458
12459 if !cf.environment.is_empty()
12461 && !cf
12462 .property_order
12463 .contains(&FunctionPropertyKind::Environment)
12464 {
12465 self.write_space();
12466 self.generate_environment_clause(&cf.environment)?;
12467 }
12468 } else {
12469 if matches!(
12472 self.config.dialect,
12473 Some(crate::dialects::DialectType::BigQuery)
12474 ) {
12475 self.generate_function_determinism(cf)?;
12476 }
12477
12478 let use_multiline = self.config.pretty
12480 && matches!(
12481 self.config.dialect,
12482 Some(crate::dialects::DialectType::BigQuery)
12483 );
12484
12485 if !cf.language_first {
12486 if let Some(lang) = &cf.language {
12487 if use_multiline {
12488 self.write_newline();
12489 } else {
12490 self.write_space();
12491 }
12492 self.write_keyword("LANGUAGE");
12493 self.write_space();
12494 self.write(lang);
12495 }
12496
12497 self.generate_function_sql_data_access(cf)?;
12499 }
12500
12501 if !matches!(
12503 self.config.dialect,
12504 Some(crate::dialects::DialectType::BigQuery)
12505 ) {
12506 self.generate_function_determinism(cf)?;
12507 }
12508
12509 self.generate_function_null_input(cf)?;
12510 self.generate_function_security(cf)?;
12511 self.generate_function_set_options(cf)?;
12512
12513 if !cf.options.is_empty() {
12515 self.write_space();
12516 self.generate_options_clause(&cf.options)?;
12517 }
12518
12519 if !cf.environment.is_empty() {
12521 self.write_space();
12522 self.generate_environment_clause(&cf.environment)?;
12523 }
12524
12525 self.generate_function_body(cf)?;
12526 }
12527
12528 Ok(())
12529 }
12530
12531 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
12533 for opt in &cf.set_options {
12534 self.write_space();
12535 self.write_keyword("SET");
12536 self.write_space();
12537 self.write(&opt.name);
12538 match &opt.value {
12539 FunctionSetValue::Value { value, use_to } => {
12540 if *use_to {
12541 self.write(" TO ");
12542 } else {
12543 self.write(" = ");
12544 }
12545 self.write(value);
12546 }
12547 FunctionSetValue::FromCurrent => {
12548 self.write_space();
12549 self.write_keyword("FROM CURRENT");
12550 }
12551 }
12552 }
12553 Ok(())
12554 }
12555
12556 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
12558 if let Some(body) = &cf.body {
12559 self.write_space();
12561 let use_multiline = self.config.pretty
12563 && matches!(
12564 self.config.dialect,
12565 Some(crate::dialects::DialectType::BigQuery)
12566 );
12567 match body {
12568 FunctionBody::Block(block) => {
12569 self.write_keyword("AS");
12570 if matches!(
12571 self.config.dialect,
12572 Some(crate::dialects::DialectType::TSQL)
12573 ) {
12574 self.write(" BEGIN ");
12575 self.write(block);
12576 self.write(" END");
12577 } else if matches!(
12578 self.config.dialect,
12579 Some(crate::dialects::DialectType::PostgreSQL)
12580 ) {
12581 self.write(" $$");
12582 self.write(block);
12583 self.write("$$");
12584 } else {
12585 let escaped = self.escape_block_for_single_quote(block);
12587 if use_multiline {
12589 self.write_newline();
12590 } else {
12591 self.write(" ");
12592 }
12593 self.write("'");
12594 self.write(&escaped);
12595 self.write("'");
12596 }
12597 }
12598 FunctionBody::StringLiteral(s) => {
12599 self.write_keyword("AS");
12600 if use_multiline {
12602 self.write_newline();
12603 } else {
12604 self.write(" ");
12605 }
12606 self.write("'");
12607 self.write(s);
12608 self.write("'");
12609 }
12610 FunctionBody::Expression(expr) => {
12611 self.write_keyword("AS");
12612 self.write_space();
12613 self.generate_expression(expr)?;
12614 }
12615 FunctionBody::External(name) => {
12616 self.write_keyword("EXTERNAL NAME");
12617 self.write(" '");
12618 self.write(name);
12619 self.write("'");
12620 }
12621 FunctionBody::Return(expr) => {
12622 if matches!(
12623 self.config.dialect,
12624 Some(crate::dialects::DialectType::DuckDB)
12625 ) {
12626 self.write_keyword("AS");
12628 self.write_space();
12629 let is_table_return = cf.returns_table_body.is_some()
12631 || matches!(&cf.return_type, Some(crate::expressions::DataType::Custom { ref name }) if name.eq_ignore_ascii_case("TABLE"));
12632 if is_table_return {
12633 self.write_keyword("TABLE");
12634 self.write_space();
12635 }
12636 self.generate_expression(expr)?;
12637 } else {
12638 if self.config.create_function_return_as {
12639 self.write_keyword("AS");
12640 if self.config.pretty
12642 && matches!(
12643 self.config.dialect,
12644 Some(crate::dialects::DialectType::TSQL)
12645 | Some(crate::dialects::DialectType::Fabric)
12646 )
12647 {
12648 self.write_newline();
12649 } else {
12650 self.write_space();
12651 }
12652 }
12653 self.write_keyword("RETURN");
12654 self.write_space();
12655 self.generate_expression(expr)?;
12656 }
12657 }
12658 FunctionBody::Statements(stmts) => {
12659 self.write_keyword("AS");
12660 self.write(" BEGIN ");
12661 for (i, stmt) in stmts.iter().enumerate() {
12662 if i > 0 {
12663 self.write(" ");
12664 }
12665 self.generate_expression(stmt)?;
12666 self.write(";");
12667 }
12668 self.write(" END");
12669 }
12670 FunctionBody::DollarQuoted { content, tag } => {
12671 self.write_keyword("AS");
12672 self.write(" ");
12673 let supports_dollar_quoting = matches!(
12675 self.config.dialect,
12676 Some(crate::dialects::DialectType::PostgreSQL)
12677 | Some(crate::dialects::DialectType::Databricks)
12678 | Some(crate::dialects::DialectType::Redshift)
12679 | Some(crate::dialects::DialectType::DuckDB)
12680 );
12681 if supports_dollar_quoting {
12682 self.write("$");
12684 if let Some(t) = tag {
12685 self.write(t);
12686 }
12687 self.write("$");
12688 self.write(content);
12689 self.write("$");
12690 if let Some(t) = tag {
12691 self.write(t);
12692 }
12693 self.write("$");
12694 } else {
12695 let escaped = self.escape_block_for_single_quote(content);
12697 self.write("'");
12698 self.write(&escaped);
12699 self.write("'");
12700 }
12701 }
12702 }
12703 }
12704 Ok(())
12705 }
12706
12707 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
12709 if let Some(det) = cf.deterministic {
12710 self.write_space();
12711 if matches!(
12712 self.config.dialect,
12713 Some(crate::dialects::DialectType::BigQuery)
12714 ) {
12715 if det {
12717 self.write_keyword("DETERMINISTIC");
12718 } else {
12719 self.write_keyword("NOT DETERMINISTIC");
12720 }
12721 } else {
12722 if det {
12724 self.write_keyword("IMMUTABLE");
12725 } else {
12726 self.write_keyword("VOLATILE");
12727 }
12728 }
12729 }
12730 Ok(())
12731 }
12732
12733 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
12735 if let Some(returns_null) = cf.returns_null_on_null_input {
12736 self.write_space();
12737 if returns_null {
12738 if cf.strict {
12739 self.write_keyword("STRICT");
12740 } else {
12741 self.write_keyword("RETURNS NULL ON NULL INPUT");
12742 }
12743 } else {
12744 self.write_keyword("CALLED ON NULL INPUT");
12745 }
12746 }
12747 Ok(())
12748 }
12749
12750 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
12752 if let Some(security) = &cf.security {
12753 self.write_space();
12754 if matches!(
12756 self.config.dialect,
12757 Some(crate::dialects::DialectType::MySQL)
12758 ) {
12759 self.write_keyword("SQL SECURITY");
12760 } else {
12761 self.write_keyword("SECURITY");
12762 }
12763 self.write_space();
12764 match security {
12765 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12766 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12767 FunctionSecurity::None => self.write_keyword("NONE"),
12768 }
12769 }
12770 Ok(())
12771 }
12772
12773 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
12775 if let Some(sql_data) = &cf.sql_data_access {
12776 self.write_space();
12777 match sql_data {
12778 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
12779 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
12780 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
12781 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
12782 }
12783 }
12784 Ok(())
12785 }
12786
12787 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
12788 for (i, param) in params.iter().enumerate() {
12789 if i > 0 {
12790 self.write(", ");
12791 }
12792
12793 if let Some(mode) = ¶m.mode {
12794 if let Some(text) = ¶m.mode_text {
12795 self.write(text);
12796 } else {
12797 match mode {
12798 ParameterMode::In => self.write_keyword("IN"),
12799 ParameterMode::Out => self.write_keyword("OUT"),
12800 ParameterMode::InOut => self.write_keyword("INOUT"),
12801 ParameterMode::Variadic => self.write_keyword("VARIADIC"),
12802 }
12803 }
12804 self.write_space();
12805 }
12806
12807 if let Some(name) = ¶m.name {
12808 self.generate_identifier(name)?;
12809 let skip_type =
12811 matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
12812 if !skip_type {
12813 self.write_space();
12814 self.generate_data_type(¶m.data_type)?;
12815 }
12816 } else {
12817 self.generate_data_type(¶m.data_type)?;
12818 }
12819
12820 if let Some(default) = ¶m.default {
12821 if self.config.parameter_default_equals {
12822 self.write(" = ");
12823 } else {
12824 self.write(" DEFAULT ");
12825 }
12826 self.generate_expression(default)?;
12827 }
12828 }
12829
12830 Ok(())
12831 }
12832
12833 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
12834 self.write_keyword("DROP FUNCTION");
12835
12836 if df.if_exists {
12837 self.write_space();
12838 self.write_keyword("IF EXISTS");
12839 }
12840
12841 self.write_space();
12842 self.generate_table(&df.name)?;
12843
12844 if let Some(params) = &df.parameters {
12845 self.write(" (");
12846 for (i, dt) in params.iter().enumerate() {
12847 if i > 0 {
12848 self.write(", ");
12849 }
12850 self.generate_data_type(dt)?;
12851 }
12852 self.write(")");
12853 }
12854
12855 if df.cascade {
12856 self.write_space();
12857 self.write_keyword("CASCADE");
12858 }
12859
12860 Ok(())
12861 }
12862
12863 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
12864 self.write_keyword("CREATE");
12865
12866 if cp.or_alter {
12867 self.write_space();
12868 self.write_keyword("OR ALTER");
12869 } else if cp.or_replace {
12870 self.write_space();
12871 self.write_keyword("OR REPLACE");
12872 }
12873
12874 self.write_space();
12875 if cp.use_proc_keyword {
12876 self.write_keyword("PROC");
12877 } else {
12878 self.write_keyword("PROCEDURE");
12879 }
12880
12881 if cp.if_not_exists {
12882 self.write_space();
12883 self.write_keyword("IF NOT EXISTS");
12884 }
12885
12886 self.write_space();
12887 self.generate_table(&cp.name)?;
12888 if cp.has_parens {
12889 self.write("(");
12890 self.generate_function_parameters(&cp.parameters)?;
12891 self.write(")");
12892 } else if !cp.parameters.is_empty() {
12893 self.write_space();
12895 self.generate_function_parameters(&cp.parameters)?;
12896 }
12897
12898 if let Some(return_type) = &cp.return_type {
12900 self.write_space();
12901 self.write_keyword("RETURNS");
12902 self.write_space();
12903 self.generate_data_type(return_type)?;
12904 }
12905
12906 if let Some(execute_as) = &cp.execute_as {
12908 self.write_space();
12909 self.write_keyword("EXECUTE AS");
12910 self.write_space();
12911 self.write_keyword(execute_as);
12912 }
12913
12914 if let Some(lang) = &cp.language {
12915 self.write_space();
12916 self.write_keyword("LANGUAGE");
12917 self.write_space();
12918 self.write(lang);
12919 }
12920
12921 if let Some(security) = &cp.security {
12922 self.write_space();
12923 self.write_keyword("SECURITY");
12924 self.write_space();
12925 match security {
12926 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
12927 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
12928 FunctionSecurity::None => self.write_keyword("NONE"),
12929 }
12930 }
12931
12932 if !cp.with_options.is_empty() {
12934 self.write_space();
12935 self.write_keyword("WITH");
12936 self.write_space();
12937 for (i, opt) in cp.with_options.iter().enumerate() {
12938 if i > 0 {
12939 self.write(", ");
12940 }
12941 self.write(opt);
12942 }
12943 }
12944
12945 if let Some(body) = &cp.body {
12946 self.write_space();
12947 match body {
12948 FunctionBody::Block(block) => {
12949 self.write_keyword("AS");
12950 if matches!(
12951 self.config.dialect,
12952 Some(crate::dialects::DialectType::TSQL)
12953 ) {
12954 self.write(" BEGIN ");
12955 self.write(block);
12956 self.write(" END");
12957 } else if matches!(
12958 self.config.dialect,
12959 Some(crate::dialects::DialectType::PostgreSQL)
12960 ) {
12961 self.write(" $$");
12962 self.write(block);
12963 self.write("$$");
12964 } else {
12965 let escaped = self.escape_block_for_single_quote(block);
12967 self.write(" '");
12968 self.write(&escaped);
12969 self.write("'");
12970 }
12971 }
12972 FunctionBody::StringLiteral(s) => {
12973 self.write_keyword("AS");
12974 self.write(" '");
12975 self.write(s);
12976 self.write("'");
12977 }
12978 FunctionBody::Expression(expr) => {
12979 self.write_keyword("AS");
12980 self.write_space();
12981 self.generate_expression(expr)?;
12982 }
12983 FunctionBody::External(name) => {
12984 self.write_keyword("EXTERNAL NAME");
12985 self.write(" '");
12986 self.write(name);
12987 self.write("'");
12988 }
12989 FunctionBody::Return(expr) => {
12990 self.write_keyword("RETURN");
12991 self.write_space();
12992 self.generate_expression(expr)?;
12993 }
12994 FunctionBody::Statements(stmts) => {
12995 self.write_keyword("AS");
12996 self.write(" BEGIN ");
12997 for (i, stmt) in stmts.iter().enumerate() {
12998 if i > 0 {
12999 self.write(" ");
13000 }
13001 self.generate_expression(stmt)?;
13002 self.write(";");
13003 }
13004 self.write(" END");
13005 }
13006 FunctionBody::DollarQuoted { content, tag } => {
13007 self.write_keyword("AS");
13008 self.write(" ");
13009 let supports_dollar_quoting = matches!(
13011 self.config.dialect,
13012 Some(crate::dialects::DialectType::PostgreSQL)
13013 | Some(crate::dialects::DialectType::Databricks)
13014 | Some(crate::dialects::DialectType::Redshift)
13015 | Some(crate::dialects::DialectType::DuckDB)
13016 );
13017 if supports_dollar_quoting {
13018 self.write("$");
13020 if let Some(t) = tag {
13021 self.write(t);
13022 }
13023 self.write("$");
13024 self.write(content);
13025 self.write("$");
13026 if let Some(t) = tag {
13027 self.write(t);
13028 }
13029 self.write("$");
13030 } else {
13031 let escaped = self.escape_block_for_single_quote(content);
13033 self.write("'");
13034 self.write(&escaped);
13035 self.write("'");
13036 }
13037 }
13038 }
13039 }
13040
13041 Ok(())
13042 }
13043
13044 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
13045 self.write_keyword("DROP PROCEDURE");
13046
13047 if dp.if_exists {
13048 self.write_space();
13049 self.write_keyword("IF EXISTS");
13050 }
13051
13052 self.write_space();
13053 self.generate_table(&dp.name)?;
13054
13055 if let Some(params) = &dp.parameters {
13056 self.write(" (");
13057 for (i, dt) in params.iter().enumerate() {
13058 if i > 0 {
13059 self.write(", ");
13060 }
13061 self.generate_data_type(dt)?;
13062 }
13063 self.write(")");
13064 }
13065
13066 if dp.cascade {
13067 self.write_space();
13068 self.write_keyword("CASCADE");
13069 }
13070
13071 Ok(())
13072 }
13073
13074 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
13075 self.write_keyword("CREATE");
13076
13077 if cs.or_replace {
13078 self.write_space();
13079 self.write_keyword("OR REPLACE");
13080 }
13081
13082 if cs.temporary {
13083 self.write_space();
13084 self.write_keyword("TEMPORARY");
13085 }
13086
13087 self.write_space();
13088 self.write_keyword("SEQUENCE");
13089
13090 if cs.if_not_exists {
13091 self.write_space();
13092 self.write_keyword("IF NOT EXISTS");
13093 }
13094
13095 self.write_space();
13096 self.generate_table(&cs.name)?;
13097
13098 if let Some(as_type) = &cs.as_type {
13100 self.write_space();
13101 self.write_keyword("AS");
13102 self.write_space();
13103 self.generate_data_type(as_type)?;
13104 }
13105
13106 if let Some(comment) = &cs.comment {
13108 self.write_space();
13109 self.write_keyword("COMMENT");
13110 self.write("=");
13111 self.generate_string_literal(comment)?;
13112 }
13113
13114 if !cs.property_order.is_empty() {
13116 for prop in &cs.property_order {
13117 match prop {
13118 SeqPropKind::Start => {
13119 if let Some(start) = cs.start {
13120 self.write_space();
13121 self.write_keyword("START WITH");
13122 self.write(&format!(" {}", start));
13123 }
13124 }
13125 SeqPropKind::Increment => {
13126 if let Some(inc) = cs.increment {
13127 self.write_space();
13128 self.write_keyword("INCREMENT BY");
13129 self.write(&format!(" {}", inc));
13130 }
13131 }
13132 SeqPropKind::Minvalue => {
13133 if let Some(min) = &cs.minvalue {
13134 self.write_space();
13135 match min {
13136 SequenceBound::Value(v) => {
13137 self.write_keyword("MINVALUE");
13138 self.write(&format!(" {}", v));
13139 }
13140 SequenceBound::None => {
13141 self.write_keyword("NO MINVALUE");
13142 }
13143 }
13144 }
13145 }
13146 SeqPropKind::Maxvalue => {
13147 if let Some(max) = &cs.maxvalue {
13148 self.write_space();
13149 match max {
13150 SequenceBound::Value(v) => {
13151 self.write_keyword("MAXVALUE");
13152 self.write(&format!(" {}", v));
13153 }
13154 SequenceBound::None => {
13155 self.write_keyword("NO MAXVALUE");
13156 }
13157 }
13158 }
13159 }
13160 SeqPropKind::Cache => {
13161 if let Some(cache) = cs.cache {
13162 self.write_space();
13163 self.write_keyword("CACHE");
13164 self.write(&format!(" {}", cache));
13165 }
13166 }
13167 SeqPropKind::NoCache => {
13168 self.write_space();
13169 self.write_keyword("NO CACHE");
13170 }
13171 SeqPropKind::NoCacheWord => {
13172 self.write_space();
13173 self.write_keyword("NOCACHE");
13174 }
13175 SeqPropKind::Cycle => {
13176 self.write_space();
13177 self.write_keyword("CYCLE");
13178 }
13179 SeqPropKind::NoCycle => {
13180 self.write_space();
13181 self.write_keyword("NO CYCLE");
13182 }
13183 SeqPropKind::NoCycleWord => {
13184 self.write_space();
13185 self.write_keyword("NOCYCLE");
13186 }
13187 SeqPropKind::OwnedBy => {
13188 if !cs.owned_by_none {
13190 if let Some(owned) = &cs.owned_by {
13191 self.write_space();
13192 self.write_keyword("OWNED BY");
13193 self.write_space();
13194 self.generate_table(owned)?;
13195 }
13196 }
13197 }
13198 SeqPropKind::Order => {
13199 self.write_space();
13200 self.write_keyword("ORDER");
13201 }
13202 SeqPropKind::NoOrder => {
13203 self.write_space();
13204 self.write_keyword("NOORDER");
13205 }
13206 SeqPropKind::Comment => {
13207 }
13209 SeqPropKind::Sharing => {
13210 if let Some(val) = &cs.sharing {
13211 self.write_space();
13212 self.write(&format!("SHARING={}", val));
13213 }
13214 }
13215 SeqPropKind::Keep => {
13216 self.write_space();
13217 self.write_keyword("KEEP");
13218 }
13219 SeqPropKind::NoKeep => {
13220 self.write_space();
13221 self.write_keyword("NOKEEP");
13222 }
13223 SeqPropKind::Scale => {
13224 self.write_space();
13225 self.write_keyword("SCALE");
13226 if let Some(modifier) = &cs.scale_modifier {
13227 if !modifier.is_empty() {
13228 self.write_space();
13229 self.write_keyword(modifier);
13230 }
13231 }
13232 }
13233 SeqPropKind::NoScale => {
13234 self.write_space();
13235 self.write_keyword("NOSCALE");
13236 }
13237 SeqPropKind::Shard => {
13238 self.write_space();
13239 self.write_keyword("SHARD");
13240 if let Some(modifier) = &cs.shard_modifier {
13241 if !modifier.is_empty() {
13242 self.write_space();
13243 self.write_keyword(modifier);
13244 }
13245 }
13246 }
13247 SeqPropKind::NoShard => {
13248 self.write_space();
13249 self.write_keyword("NOSHARD");
13250 }
13251 SeqPropKind::Session => {
13252 self.write_space();
13253 self.write_keyword("SESSION");
13254 }
13255 SeqPropKind::Global => {
13256 self.write_space();
13257 self.write_keyword("GLOBAL");
13258 }
13259 SeqPropKind::NoMinvalueWord => {
13260 self.write_space();
13261 self.write_keyword("NOMINVALUE");
13262 }
13263 SeqPropKind::NoMaxvalueWord => {
13264 self.write_space();
13265 self.write_keyword("NOMAXVALUE");
13266 }
13267 }
13268 }
13269 } else {
13270 if let Some(inc) = cs.increment {
13272 self.write_space();
13273 self.write_keyword("INCREMENT BY");
13274 self.write(&format!(" {}", inc));
13275 }
13276
13277 if let Some(min) = &cs.minvalue {
13278 self.write_space();
13279 match min {
13280 SequenceBound::Value(v) => {
13281 self.write_keyword("MINVALUE");
13282 self.write(&format!(" {}", v));
13283 }
13284 SequenceBound::None => {
13285 self.write_keyword("NO MINVALUE");
13286 }
13287 }
13288 }
13289
13290 if let Some(max) = &cs.maxvalue {
13291 self.write_space();
13292 match max {
13293 SequenceBound::Value(v) => {
13294 self.write_keyword("MAXVALUE");
13295 self.write(&format!(" {}", v));
13296 }
13297 SequenceBound::None => {
13298 self.write_keyword("NO MAXVALUE");
13299 }
13300 }
13301 }
13302
13303 if let Some(start) = cs.start {
13304 self.write_space();
13305 self.write_keyword("START WITH");
13306 self.write(&format!(" {}", start));
13307 }
13308
13309 if let Some(cache) = cs.cache {
13310 self.write_space();
13311 self.write_keyword("CACHE");
13312 self.write(&format!(" {}", cache));
13313 }
13314
13315 if cs.cycle {
13316 self.write_space();
13317 self.write_keyword("CYCLE");
13318 }
13319
13320 if let Some(owned) = &cs.owned_by {
13321 self.write_space();
13322 self.write_keyword("OWNED BY");
13323 self.write_space();
13324 self.generate_table(owned)?;
13325 }
13326 }
13327
13328 Ok(())
13329 }
13330
13331 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
13332 self.write_keyword("DROP SEQUENCE");
13333
13334 if ds.if_exists {
13335 self.write_space();
13336 self.write_keyword("IF EXISTS");
13337 }
13338
13339 self.write_space();
13340 self.generate_table(&ds.name)?;
13341
13342 if ds.cascade {
13343 self.write_space();
13344 self.write_keyword("CASCADE");
13345 }
13346
13347 Ok(())
13348 }
13349
13350 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
13351 self.write_keyword("ALTER SEQUENCE");
13352
13353 if als.if_exists {
13354 self.write_space();
13355 self.write_keyword("IF EXISTS");
13356 }
13357
13358 self.write_space();
13359 self.generate_table(&als.name)?;
13360
13361 if let Some(inc) = als.increment {
13362 self.write_space();
13363 self.write_keyword("INCREMENT BY");
13364 self.write(&format!(" {}", inc));
13365 }
13366
13367 if let Some(min) = &als.minvalue {
13368 self.write_space();
13369 match min {
13370 SequenceBound::Value(v) => {
13371 self.write_keyword("MINVALUE");
13372 self.write(&format!(" {}", v));
13373 }
13374 SequenceBound::None => {
13375 self.write_keyword("NO MINVALUE");
13376 }
13377 }
13378 }
13379
13380 if let Some(max) = &als.maxvalue {
13381 self.write_space();
13382 match max {
13383 SequenceBound::Value(v) => {
13384 self.write_keyword("MAXVALUE");
13385 self.write(&format!(" {}", v));
13386 }
13387 SequenceBound::None => {
13388 self.write_keyword("NO MAXVALUE");
13389 }
13390 }
13391 }
13392
13393 if let Some(start) = als.start {
13394 self.write_space();
13395 self.write_keyword("START WITH");
13396 self.write(&format!(" {}", start));
13397 }
13398
13399 if let Some(restart) = &als.restart {
13400 self.write_space();
13401 self.write_keyword("RESTART");
13402 if let Some(val) = restart {
13403 self.write_keyword(" WITH");
13404 self.write(&format!(" {}", val));
13405 }
13406 }
13407
13408 if let Some(cache) = als.cache {
13409 self.write_space();
13410 self.write_keyword("CACHE");
13411 self.write(&format!(" {}", cache));
13412 }
13413
13414 if let Some(cycle) = als.cycle {
13415 self.write_space();
13416 if cycle {
13417 self.write_keyword("CYCLE");
13418 } else {
13419 self.write_keyword("NO CYCLE");
13420 }
13421 }
13422
13423 if let Some(owned) = &als.owned_by {
13424 self.write_space();
13425 self.write_keyword("OWNED BY");
13426 self.write_space();
13427 if let Some(table) = owned {
13428 self.generate_table(table)?;
13429 } else {
13430 self.write_keyword("NONE");
13431 }
13432 }
13433
13434 Ok(())
13435 }
13436
13437 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
13438 self.write_keyword("CREATE");
13439
13440 if ct.or_alter {
13441 self.write_space();
13442 self.write_keyword("OR ALTER");
13443 } else if ct.or_replace {
13444 self.write_space();
13445 self.write_keyword("OR REPLACE");
13446 }
13447
13448 if ct.constraint {
13449 self.write_space();
13450 self.write_keyword("CONSTRAINT");
13451 }
13452
13453 self.write_space();
13454 self.write_keyword("TRIGGER");
13455 self.write_space();
13456 self.generate_identifier(&ct.name)?;
13457
13458 self.write_space();
13459 match ct.timing {
13460 TriggerTiming::Before => self.write_keyword("BEFORE"),
13461 TriggerTiming::After => self.write_keyword("AFTER"),
13462 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
13463 }
13464
13465 for (i, event) in ct.events.iter().enumerate() {
13467 if i > 0 {
13468 self.write_keyword(" OR");
13469 }
13470 self.write_space();
13471 match event {
13472 TriggerEvent::Insert => self.write_keyword("INSERT"),
13473 TriggerEvent::Update(cols) => {
13474 self.write_keyword("UPDATE");
13475 if let Some(cols) = cols {
13476 self.write_space();
13477 self.write_keyword("OF");
13478 for (j, col) in cols.iter().enumerate() {
13479 if j > 0 {
13480 self.write(",");
13481 }
13482 self.write_space();
13483 self.generate_identifier(col)?;
13484 }
13485 }
13486 }
13487 TriggerEvent::Delete => self.write_keyword("DELETE"),
13488 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
13489 }
13490 }
13491
13492 self.write_space();
13493 self.write_keyword("ON");
13494 self.write_space();
13495 self.generate_table(&ct.table)?;
13496
13497 if let Some(ref_clause) = &ct.referencing {
13499 self.write_space();
13500 self.write_keyword("REFERENCING");
13501 if let Some(old_table) = &ref_clause.old_table {
13502 self.write_space();
13503 self.write_keyword("OLD TABLE AS");
13504 self.write_space();
13505 self.generate_identifier(old_table)?;
13506 }
13507 if let Some(new_table) = &ref_clause.new_table {
13508 self.write_space();
13509 self.write_keyword("NEW TABLE AS");
13510 self.write_space();
13511 self.generate_identifier(new_table)?;
13512 }
13513 if let Some(old_row) = &ref_clause.old_row {
13514 self.write_space();
13515 self.write_keyword("OLD ROW AS");
13516 self.write_space();
13517 self.generate_identifier(old_row)?;
13518 }
13519 if let Some(new_row) = &ref_clause.new_row {
13520 self.write_space();
13521 self.write_keyword("NEW ROW AS");
13522 self.write_space();
13523 self.generate_identifier(new_row)?;
13524 }
13525 }
13526
13527 if let Some(deferrable) = ct.deferrable {
13529 self.write_space();
13530 if deferrable {
13531 self.write_keyword("DEFERRABLE");
13532 } else {
13533 self.write_keyword("NOT DEFERRABLE");
13534 }
13535 }
13536
13537 if let Some(initially) = ct.initially_deferred {
13538 self.write_space();
13539 self.write_keyword("INITIALLY");
13540 self.write_space();
13541 if initially {
13542 self.write_keyword("DEFERRED");
13543 } else {
13544 self.write_keyword("IMMEDIATE");
13545 }
13546 }
13547
13548 if let Some(for_each) = ct.for_each {
13549 self.write_space();
13550 self.write_keyword("FOR EACH");
13551 self.write_space();
13552 match for_each {
13553 TriggerForEach::Row => self.write_keyword("ROW"),
13554 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
13555 }
13556 }
13557
13558 if let Some(when) = &ct.when {
13560 self.write_space();
13561 self.write_keyword("WHEN");
13562 if ct.when_paren {
13563 self.write(" (");
13564 self.generate_expression(when)?;
13565 self.write(")");
13566 } else {
13567 self.write_space();
13568 self.generate_expression(when)?;
13569 }
13570 }
13571
13572 self.write_space();
13574 match &ct.body {
13575 TriggerBody::Execute { function, args } => {
13576 self.write_keyword("EXECUTE FUNCTION");
13577 self.write_space();
13578 self.generate_table(function)?;
13579 self.write("(");
13580 for (i, arg) in args.iter().enumerate() {
13581 if i > 0 {
13582 self.write(", ");
13583 }
13584 self.generate_expression(arg)?;
13585 }
13586 self.write(")");
13587 }
13588 TriggerBody::Block(block) => {
13589 self.write_keyword("BEGIN");
13590 self.write_space();
13591 self.write(block);
13592 self.write_space();
13593 self.write_keyword("END");
13594 }
13595 }
13596
13597 Ok(())
13598 }
13599
13600 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
13601 self.write_keyword("DROP TRIGGER");
13602
13603 if dt.if_exists {
13604 self.write_space();
13605 self.write_keyword("IF EXISTS");
13606 }
13607
13608 self.write_space();
13609 self.generate_identifier(&dt.name)?;
13610
13611 if let Some(table) = &dt.table {
13612 self.write_space();
13613 self.write_keyword("ON");
13614 self.write_space();
13615 self.generate_table(table)?;
13616 }
13617
13618 if dt.cascade {
13619 self.write_space();
13620 self.write_keyword("CASCADE");
13621 }
13622
13623 Ok(())
13624 }
13625
13626 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
13627 self.write_keyword("CREATE TYPE");
13628
13629 if ct.if_not_exists {
13630 self.write_space();
13631 self.write_keyword("IF NOT EXISTS");
13632 }
13633
13634 self.write_space();
13635 self.generate_table(&ct.name)?;
13636
13637 self.write_space();
13638 self.write_keyword("AS");
13639 self.write_space();
13640
13641 match &ct.definition {
13642 TypeDefinition::Enum(values) => {
13643 self.write_keyword("ENUM");
13644 self.write(" (");
13645 for (i, val) in values.iter().enumerate() {
13646 if i > 0 {
13647 self.write(", ");
13648 }
13649 self.write(&format!("'{}'", val));
13650 }
13651 self.write(")");
13652 }
13653 TypeDefinition::Composite(attrs) => {
13654 self.write("(");
13655 for (i, attr) in attrs.iter().enumerate() {
13656 if i > 0 {
13657 self.write(", ");
13658 }
13659 self.generate_identifier(&attr.name)?;
13660 self.write_space();
13661 self.generate_data_type(&attr.data_type)?;
13662 if let Some(collate) = &attr.collate {
13663 self.write_space();
13664 self.write_keyword("COLLATE");
13665 self.write_space();
13666 self.generate_identifier(collate)?;
13667 }
13668 }
13669 self.write(")");
13670 }
13671 TypeDefinition::Range {
13672 subtype,
13673 subtype_diff,
13674 canonical,
13675 } => {
13676 self.write_keyword("RANGE");
13677 self.write(" (");
13678 self.write_keyword("SUBTYPE");
13679 self.write(" = ");
13680 self.generate_data_type(subtype)?;
13681 if let Some(diff) = subtype_diff {
13682 self.write(", ");
13683 self.write_keyword("SUBTYPE_DIFF");
13684 self.write(" = ");
13685 self.write(diff);
13686 }
13687 if let Some(canon) = canonical {
13688 self.write(", ");
13689 self.write_keyword("CANONICAL");
13690 self.write(" = ");
13691 self.write(canon);
13692 }
13693 self.write(")");
13694 }
13695 TypeDefinition::Base {
13696 input,
13697 output,
13698 internallength,
13699 } => {
13700 self.write("(");
13701 self.write_keyword("INPUT");
13702 self.write(" = ");
13703 self.write(input);
13704 self.write(", ");
13705 self.write_keyword("OUTPUT");
13706 self.write(" = ");
13707 self.write(output);
13708 if let Some(len) = internallength {
13709 self.write(", ");
13710 self.write_keyword("INTERNALLENGTH");
13711 self.write(" = ");
13712 self.write(&len.to_string());
13713 }
13714 self.write(")");
13715 }
13716 TypeDefinition::Domain {
13717 base_type,
13718 default,
13719 constraints,
13720 } => {
13721 self.generate_data_type(base_type)?;
13722 if let Some(def) = default {
13723 self.write_space();
13724 self.write_keyword("DEFAULT");
13725 self.write_space();
13726 self.generate_expression(def)?;
13727 }
13728 for constr in constraints {
13729 self.write_space();
13730 if let Some(name) = &constr.name {
13731 self.write_keyword("CONSTRAINT");
13732 self.write_space();
13733 self.generate_identifier(name)?;
13734 self.write_space();
13735 }
13736 self.write_keyword("CHECK");
13737 self.write(" (");
13738 self.generate_expression(&constr.check)?;
13739 self.write(")");
13740 }
13741 }
13742 }
13743
13744 Ok(())
13745 }
13746
13747 fn generate_create_task(&mut self, task: &crate::expressions::CreateTask) -> Result<()> {
13748 self.write_keyword("CREATE");
13749 if task.or_replace {
13750 self.write_space();
13751 self.write_keyword("OR REPLACE");
13752 }
13753 self.write_space();
13754 self.write_keyword("TASK");
13755 if task.if_not_exists {
13756 self.write_space();
13757 self.write_keyword("IF NOT EXISTS");
13758 }
13759 self.write_space();
13760 self.write(&task.name);
13761 if !task.properties.is_empty() {
13762 if !task.properties.starts_with('\n') && !task.properties.starts_with(' ') {
13764 self.write_space();
13765 }
13766 self.write(&task.properties);
13767 }
13768 self.write_space();
13769 self.write_keyword("AS");
13770 self.write_space();
13771 self.generate_expression(&task.body)?;
13772 Ok(())
13773 }
13774
13775 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
13776 self.write_keyword("DROP TYPE");
13777
13778 if dt.if_exists {
13779 self.write_space();
13780 self.write_keyword("IF EXISTS");
13781 }
13782
13783 self.write_space();
13784 self.generate_table(&dt.name)?;
13785
13786 if dt.cascade {
13787 self.write_space();
13788 self.write_keyword("CASCADE");
13789 }
13790
13791 Ok(())
13792 }
13793
13794 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
13795 let saved_athena_hive_context = self.athena_hive_context;
13797 if matches!(
13798 self.config.dialect,
13799 Some(crate::dialects::DialectType::Athena)
13800 ) {
13801 self.athena_hive_context = true;
13802 }
13803
13804 for comment in &d.leading_comments {
13806 self.write_formatted_comment(comment);
13807 self.write(" ");
13808 }
13809
13810 self.write_keyword("DESCRIBE");
13811
13812 if d.extended {
13813 self.write_space();
13814 self.write_keyword("EXTENDED");
13815 } else if d.formatted {
13816 self.write_space();
13817 self.write_keyword("FORMATTED");
13818 }
13819
13820 if let Some(ref style) = d.style {
13822 self.write_space();
13823 self.write_keyword(style);
13824 }
13825
13826 let should_output_kind = match self.config.dialect {
13828 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
13830 false
13831 }
13832 Some(DialectType::Snowflake) => true,
13834 _ => d.kind.is_some(),
13835 };
13836 if should_output_kind {
13837 if let Some(ref kind) = d.kind {
13838 self.write_space();
13839 self.write_keyword(kind);
13840 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
13841 self.write_space();
13842 self.write_keyword("TABLE");
13843 }
13844 }
13845
13846 self.write_space();
13847 self.generate_expression(&d.target)?;
13848
13849 if let Some(ref partition) = d.partition {
13851 self.write_space();
13852 self.generate_expression(partition)?;
13853 }
13854
13855 if d.as_json {
13857 self.write_space();
13858 self.write_keyword("AS JSON");
13859 }
13860
13861 for (name, value) in &d.properties {
13863 self.write_space();
13864 self.write(name);
13865 self.write("=");
13866 self.write(value);
13867 }
13868
13869 self.athena_hive_context = saved_athena_hive_context;
13871
13872 Ok(())
13873 }
13874
13875 fn generate_show(&mut self, s: &Show) -> Result<()> {
13878 self.write_keyword("SHOW");
13879 self.write_space();
13880
13881 let show_terse = s.terse
13884 && !matches!(
13885 s.this.as_str(),
13886 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
13887 );
13888 if show_terse {
13889 self.write_keyword("TERSE");
13890 self.write_space();
13891 }
13892
13893 self.write_keyword(&s.this);
13895
13896 if let Some(ref target_expr) = s.target {
13898 self.write_space();
13899 self.generate_expression(target_expr)?;
13900 }
13901
13902 if s.history {
13904 self.write_space();
13905 self.write_keyword("HISTORY");
13906 }
13907
13908 if let Some(ref for_target) = s.for_target {
13910 self.write_space();
13911 self.write_keyword("FOR");
13912 self.write_space();
13913 self.generate_expression(for_target)?;
13914 }
13915
13916 use crate::dialects::DialectType;
13920 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
13921
13922 if !is_snowflake && s.from.is_some() {
13923 if let Some(ref scope_kind) = s.scope_kind {
13927 self.write_space();
13928 self.write_keyword("IN");
13929 self.write_space();
13930 self.write_keyword(scope_kind);
13931 if let Some(ref scope) = s.scope {
13932 self.write_space();
13933 self.generate_expression(scope)?;
13934 }
13935 } else if let Some(ref scope) = s.scope {
13936 self.write_space();
13937 self.write_keyword("IN");
13938 self.write_space();
13939 self.generate_expression(scope)?;
13940 }
13941
13942 if let Some(ref from) = s.from {
13944 self.write_space();
13945 self.write_keyword("FROM");
13946 self.write_space();
13947 self.generate_expression(from)?;
13948 }
13949
13950 if let Some(ref db) = s.db {
13952 self.write_space();
13953 self.write_keyword("FROM");
13954 self.write_space();
13955 self.generate_expression(db)?;
13956 }
13957
13958 if let Some(ref like) = s.like {
13960 self.write_space();
13961 self.write_keyword("LIKE");
13962 self.write_space();
13963 self.generate_expression(like)?;
13964 }
13965 } else {
13966 if let Some(ref like) = s.like {
13970 self.write_space();
13971 self.write_keyword("LIKE");
13972 self.write_space();
13973 self.generate_expression(like)?;
13974 }
13975
13976 if let Some(ref scope_kind) = s.scope_kind {
13978 self.write_space();
13979 self.write_keyword("IN");
13980 self.write_space();
13981 self.write_keyword(scope_kind);
13982 if let Some(ref scope) = s.scope {
13983 self.write_space();
13984 self.generate_expression(scope)?;
13985 }
13986 } else if let Some(ref scope) = s.scope {
13987 self.write_space();
13988 self.write_keyword("IN");
13989 self.write_space();
13990 self.generate_expression(scope)?;
13991 }
13992 }
13993
13994 if let Some(ref starts_with) = s.starts_with {
13996 self.write_space();
13997 self.write_keyword("STARTS WITH");
13998 self.write_space();
13999 self.generate_expression(starts_with)?;
14000 }
14001
14002 if let Some(ref limit) = s.limit {
14004 self.write_space();
14005 self.generate_limit(limit)?;
14006 }
14007
14008 if is_snowflake {
14010 if let Some(ref from) = s.from {
14011 self.write_space();
14012 self.write_keyword("FROM");
14013 self.write_space();
14014 self.generate_expression(from)?;
14015 }
14016 }
14017
14018 if let Some(ref where_clause) = s.where_clause {
14020 self.write_space();
14021 self.write_keyword("WHERE");
14022 self.write_space();
14023 self.generate_expression(where_clause)?;
14024 }
14025
14026 if let Some(is_mutex) = s.mutex {
14028 self.write_space();
14029 if is_mutex {
14030 self.write_keyword("MUTEX");
14031 } else {
14032 self.write_keyword("STATUS");
14033 }
14034 }
14035
14036 if !s.privileges.is_empty() {
14038 self.write_space();
14039 self.write_keyword("WITH PRIVILEGES");
14040 self.write_space();
14041 for (i, priv_name) in s.privileges.iter().enumerate() {
14042 if i > 0 {
14043 self.write(", ");
14044 }
14045 self.write_keyword(priv_name);
14046 }
14047 }
14048
14049 Ok(())
14050 }
14051
14052 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
14055 use crate::dialects::DialectType;
14056 match lit {
14057 Literal::String(s) => {
14058 self.generate_string_literal(s)?;
14059 }
14060 Literal::Number(n) => {
14061 if matches!(self.config.dialect, Some(DialectType::MySQL))
14062 && n.len() > 2
14063 && (n.starts_with("0x") || n.starts_with("0X"))
14064 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
14065 {
14066 return self.generate_identifier(&Identifier {
14067 name: n.clone(),
14068 quoted: true,
14069 trailing_comments: Vec::new(),
14070 span: None,
14071 });
14072 }
14073 let n = if n.contains('_')
14077 && !matches!(
14078 self.config.dialect,
14079 Some(DialectType::ClickHouse)
14080 | Some(DialectType::DuckDB)
14081 | Some(DialectType::PostgreSQL)
14082 | Some(DialectType::Hive)
14083 | Some(DialectType::Spark)
14084 | Some(DialectType::Databricks)
14085 ) {
14086 std::borrow::Cow::Owned(n.replace('_', ""))
14087 } else {
14088 std::borrow::Cow::Borrowed(n.as_str())
14089 };
14090 if n.starts_with('.') {
14093 self.write("0");
14094 self.write(&n);
14095 } else if n.starts_with("-.") {
14096 self.write("-0");
14098 self.write(&n[1..]);
14099 } else {
14100 self.write(&n);
14101 }
14102 }
14103 Literal::HexString(h) => {
14104 match self.config.dialect {
14106 Some(DialectType::Spark)
14107 | Some(DialectType::Databricks)
14108 | Some(DialectType::Teradata) => self.write("X'"),
14109 _ => self.write("x'"),
14110 }
14111 self.write(h);
14112 self.write("'");
14113 }
14114 Literal::HexNumber(h) => {
14115 match self.config.dialect {
14119 Some(DialectType::BigQuery)
14120 | Some(DialectType::TSQL)
14121 | Some(DialectType::Fabric) => {
14122 self.write("0x");
14123 self.write(h);
14124 }
14125 _ => {
14126 if let Ok(val) = u64::from_str_radix(h, 16) {
14128 self.write(&val.to_string());
14129 } else {
14130 self.write("0x");
14132 self.write(h);
14133 }
14134 }
14135 }
14136 }
14137 Literal::BitString(b) => {
14138 self.write("B'");
14140 self.write(b);
14141 self.write("'");
14142 }
14143 Literal::ByteString(b) => {
14144 self.write("b'");
14146 self.write_escaped_byte_string(b);
14148 self.write("'");
14149 }
14150 Literal::NationalString(s) => {
14151 let keep_n_prefix = matches!(
14154 self.config.dialect,
14155 Some(DialectType::TSQL)
14156 | Some(DialectType::Oracle)
14157 | Some(DialectType::MySQL)
14158 | None
14159 );
14160 if keep_n_prefix {
14161 self.write("N'");
14162 } else {
14163 self.write("'");
14164 }
14165 self.write(s);
14166 self.write("'");
14167 }
14168 Literal::Date(d) => {
14169 self.generate_date_literal(d)?;
14170 }
14171 Literal::Time(t) => {
14172 self.generate_time_literal(t)?;
14173 }
14174 Literal::Timestamp(ts) => {
14175 self.generate_timestamp_literal(ts)?;
14176 }
14177 Literal::Datetime(dt) => {
14178 self.generate_datetime_literal(dt)?;
14179 }
14180 Literal::TripleQuotedString(s, _quote_char) => {
14181 if matches!(
14183 self.config.dialect,
14184 Some(crate::dialects::DialectType::BigQuery)
14185 | Some(crate::dialects::DialectType::DuckDB)
14186 | Some(crate::dialects::DialectType::Snowflake)
14187 | Some(crate::dialects::DialectType::Spark)
14188 | Some(crate::dialects::DialectType::Hive)
14189 | Some(crate::dialects::DialectType::Presto)
14190 | Some(crate::dialects::DialectType::Trino)
14191 | Some(crate::dialects::DialectType::PostgreSQL)
14192 | Some(crate::dialects::DialectType::MySQL)
14193 | Some(crate::dialects::DialectType::Redshift)
14194 | Some(crate::dialects::DialectType::TSQL)
14195 | Some(crate::dialects::DialectType::Oracle)
14196 | Some(crate::dialects::DialectType::ClickHouse)
14197 | Some(crate::dialects::DialectType::Databricks)
14198 | Some(crate::dialects::DialectType::SQLite)
14199 ) {
14200 self.generate_string_literal(s)?;
14201 } else {
14202 let quotes = format!("{0}{0}{0}", _quote_char);
14204 self.write("es);
14205 self.write(s);
14206 self.write("es);
14207 }
14208 }
14209 Literal::EscapeString(s) => {
14210 use crate::dialects::DialectType;
14214 let content = if let Some(c) = s.strip_prefix("e:") {
14215 c
14216 } else if let Some(c) = s.strip_prefix("E:") {
14217 c
14218 } else {
14219 s.as_str()
14220 };
14221
14222 if matches!(
14224 self.config.dialect,
14225 Some(DialectType::MySQL) | Some(DialectType::TiDB)
14226 ) {
14227 self.write(content);
14228 } else {
14229 let prefix = if matches!(
14231 self.config.dialect,
14232 Some(DialectType::SingleStore)
14233 | Some(DialectType::DuckDB)
14234 | Some(DialectType::PostgreSQL)
14235 | Some(DialectType::CockroachDB)
14236 | Some(DialectType::Materialize)
14237 | Some(DialectType::RisingWave)
14238 ) {
14239 "e'"
14240 } else {
14241 "E'"
14242 };
14243
14244 let normalized = content.replace("\\'", "''");
14246 self.write(prefix);
14247 self.write(&normalized);
14248 self.write("'");
14249 }
14250 }
14251 Literal::DollarString(s) => {
14252 use crate::dialects::DialectType;
14255 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
14257 let escape_backslash = matches!(self.config.dialect, Some(DialectType::Snowflake));
14259 let use_backslash_quote =
14263 matches!(self.config.dialect, Some(DialectType::Snowflake));
14264
14265 let mut escaped = String::with_capacity(content.len() + 4);
14266 for ch in content.chars() {
14267 if escape_backslash && ch == '\\' {
14268 escaped.push('\\');
14270 escaped.push('\\');
14271 } else if ch == '\'' {
14272 if use_backslash_quote {
14273 escaped.push('\\');
14274 escaped.push('\'');
14275 } else {
14276 escaped.push('\'');
14277 escaped.push('\'');
14278 }
14279 } else {
14280 escaped.push(ch);
14281 }
14282 }
14283 self.write("'");
14284 self.write(&escaped);
14285 self.write("'");
14286 }
14287 Literal::RawString(s) => {
14288 use crate::dialects::DialectType;
14294
14295 let escape_backslash = matches!(
14297 self.config.dialect,
14298 Some(DialectType::BigQuery)
14299 | Some(DialectType::MySQL)
14300 | Some(DialectType::SingleStore)
14301 | Some(DialectType::TiDB)
14302 | Some(DialectType::Hive)
14303 | Some(DialectType::Spark)
14304 | Some(DialectType::Databricks)
14305 | Some(DialectType::Drill)
14306 | Some(DialectType::Snowflake)
14307 | Some(DialectType::Redshift)
14308 | Some(DialectType::ClickHouse)
14309 );
14310
14311 let backslash_escapes_quote = matches!(
14314 self.config.dialect,
14315 Some(DialectType::BigQuery)
14316 | Some(DialectType::Hive)
14317 | Some(DialectType::Spark)
14318 | Some(DialectType::Databricks)
14319 | Some(DialectType::Drill)
14320 | Some(DialectType::Snowflake)
14321 | Some(DialectType::Redshift)
14322 );
14323
14324 let supports_escape_sequences = escape_backslash;
14327
14328 let mut escaped = String::with_capacity(s.len() + 4);
14329 for ch in s.chars() {
14330 if escape_backslash && ch == '\\' {
14331 escaped.push('\\');
14333 escaped.push('\\');
14334 } else if ch == '\'' {
14335 if backslash_escapes_quote {
14336 escaped.push('\\');
14338 escaped.push('\'');
14339 } else {
14340 escaped.push('\'');
14342 escaped.push('\'');
14343 }
14344 } else if supports_escape_sequences {
14345 match ch {
14348 '\n' => {
14349 escaped.push('\\');
14350 escaped.push('n');
14351 }
14352 '\r' => {
14353 escaped.push('\\');
14354 escaped.push('r');
14355 }
14356 '\t' => {
14357 escaped.push('\\');
14358 escaped.push('t');
14359 }
14360 '\x07' => {
14361 escaped.push('\\');
14362 escaped.push('a');
14363 }
14364 '\x08' => {
14365 escaped.push('\\');
14366 escaped.push('b');
14367 }
14368 '\x0C' => {
14369 escaped.push('\\');
14370 escaped.push('f');
14371 }
14372 '\x0B' => {
14373 escaped.push('\\');
14374 escaped.push('v');
14375 }
14376 _ => escaped.push(ch),
14377 }
14378 } else {
14379 escaped.push(ch);
14380 }
14381 }
14382 self.write("'");
14383 self.write(&escaped);
14384 self.write("'");
14385 }
14386 }
14387 Ok(())
14388 }
14389
14390 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
14392 use crate::dialects::DialectType;
14393
14394 match self.config.dialect {
14395 Some(DialectType::TSQL) => {
14397 self.write("CAST('");
14398 self.write(d);
14399 self.write("' AS DATE)");
14400 }
14401 Some(DialectType::BigQuery) => {
14404 self.write("CAST('");
14405 self.write(d);
14406 self.write("' AS DATE)");
14407 }
14408 Some(DialectType::Exasol) => {
14411 self.write("CAST('");
14412 self.write(d);
14413 self.write("' AS DATE)");
14414 }
14415 Some(DialectType::Snowflake) => {
14418 self.write("CAST('");
14419 self.write(d);
14420 self.write("' AS DATE)");
14421 }
14422 Some(DialectType::PostgreSQL)
14424 | Some(DialectType::MySQL)
14425 | Some(DialectType::SingleStore)
14426 | Some(DialectType::TiDB)
14427 | Some(DialectType::Redshift) => {
14428 self.write("CAST('");
14429 self.write(d);
14430 self.write("' AS DATE)");
14431 }
14432 Some(DialectType::DuckDB)
14434 | Some(DialectType::Presto)
14435 | Some(DialectType::Trino)
14436 | Some(DialectType::Athena)
14437 | Some(DialectType::Spark)
14438 | Some(DialectType::Databricks)
14439 | Some(DialectType::Hive) => {
14440 self.write("CAST('");
14441 self.write(d);
14442 self.write("' AS DATE)");
14443 }
14444 Some(DialectType::Oracle) => {
14446 self.write("TO_DATE('");
14447 self.write(d);
14448 self.write("', 'YYYY-MM-DD')");
14449 }
14450 _ => {
14452 self.write_keyword("DATE");
14453 self.write(" '");
14454 self.write(d);
14455 self.write("'");
14456 }
14457 }
14458 Ok(())
14459 }
14460
14461 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
14463 use crate::dialects::DialectType;
14464
14465 match self.config.dialect {
14466 Some(DialectType::TSQL) => {
14468 self.write("CAST('");
14469 self.write(t);
14470 self.write("' AS TIME)");
14471 }
14472 _ => {
14474 self.write_keyword("TIME");
14475 self.write(" '");
14476 self.write(t);
14477 self.write("'");
14478 }
14479 }
14480 Ok(())
14481 }
14482
14483 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
14485 use crate::expressions::Literal;
14486
14487 match expr {
14488 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
14489 let Literal::Date(d) = lit.as_ref() else {
14490 unreachable!()
14491 };
14492 self.write("CAST('");
14494 self.write(d);
14495 self.write("' AS DATE)");
14496 }
14497 _ => {
14498 self.generate_expression(expr)?;
14500 }
14501 }
14502 Ok(())
14503 }
14504
14505 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
14507 use crate::dialects::DialectType;
14508
14509 match self.config.dialect {
14510 Some(DialectType::TSQL) => {
14512 self.write("CAST('");
14513 self.write(ts);
14514 self.write("' AS DATETIME2)");
14515 }
14516 Some(DialectType::BigQuery) => {
14519 self.write("CAST('");
14520 self.write(ts);
14521 self.write("' AS TIMESTAMP)");
14522 }
14523 Some(DialectType::Snowflake) => {
14526 self.write("CAST('");
14527 self.write(ts);
14528 self.write("' AS TIMESTAMP)");
14529 }
14530 Some(DialectType::Dremio) => {
14533 self.write("CAST('");
14534 self.write(ts);
14535 self.write("' AS TIMESTAMP)");
14536 }
14537 Some(DialectType::Exasol) => {
14540 self.write("CAST('");
14541 self.write(ts);
14542 self.write("' AS TIMESTAMP)");
14543 }
14544 Some(DialectType::Oracle) => {
14547 self.write("TO_TIMESTAMP('");
14548 self.write(ts);
14549 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
14550 }
14551 Some(DialectType::Presto) | Some(DialectType::Trino) => {
14553 if Self::timestamp_has_timezone(ts) {
14554 self.write("CAST('");
14555 self.write(ts);
14556 self.write("' AS TIMESTAMP WITH TIME ZONE)");
14557 } else {
14558 self.write("CAST('");
14559 self.write(ts);
14560 self.write("' AS TIMESTAMP)");
14561 }
14562 }
14563 Some(DialectType::ClickHouse) => {
14565 self.write("CAST('");
14566 self.write(ts);
14567 self.write("' AS Nullable(DateTime))");
14568 }
14569 Some(DialectType::Spark) => {
14571 self.write("CAST('");
14572 self.write(ts);
14573 self.write("' AS TIMESTAMP)");
14574 }
14575 Some(DialectType::Redshift) => {
14578 if ts == "epoch" {
14579 self.write_keyword("TIMESTAMP");
14580 self.write(" '");
14581 self.write(ts);
14582 self.write("'");
14583 } else {
14584 self.write("CAST('");
14585 self.write(ts);
14586 self.write("' AS TIMESTAMP)");
14587 }
14588 }
14589 Some(DialectType::PostgreSQL)
14591 | Some(DialectType::Hive)
14592 | Some(DialectType::SQLite)
14593 | Some(DialectType::DuckDB)
14594 | Some(DialectType::Athena)
14595 | Some(DialectType::Drill)
14596 | Some(DialectType::Teradata) => {
14597 self.write("CAST('");
14598 self.write(ts);
14599 self.write("' AS TIMESTAMP)");
14600 }
14601 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
14603 self.write("CAST('");
14604 self.write(ts);
14605 self.write("' AS DATETIME)");
14606 }
14607 Some(DialectType::Databricks) => {
14609 self.write("CAST('");
14610 self.write(ts);
14611 self.write("' AS TIMESTAMP_NTZ)");
14612 }
14613 _ => {
14615 self.write_keyword("TIMESTAMP");
14616 self.write(" '");
14617 self.write(ts);
14618 self.write("'");
14619 }
14620 }
14621 Ok(())
14622 }
14623
14624 fn timestamp_has_timezone(ts: &str) -> bool {
14627 let ts_lower = ts.to_ascii_lowercase();
14631
14632 let continent_prefixes = [
14634 "africa/",
14635 "america/",
14636 "antarctica/",
14637 "arctic/",
14638 "asia/",
14639 "atlantic/",
14640 "australia/",
14641 "europe/",
14642 "indian/",
14643 "pacific/",
14644 "etc/",
14645 "brazil/",
14646 "canada/",
14647 "chile/",
14648 "mexico/",
14649 "us/",
14650 ];
14651
14652 for prefix in &continent_prefixes {
14653 if ts_lower.contains(prefix) {
14654 return true;
14655 }
14656 }
14657
14658 let tz_abbrevs = [
14661 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west", " est", " edt",
14662 " cst", " cdt", " mst", " mdt", " pst", " pdt", " ist", " bst", " jst", " kst", " hkt",
14663 " sgt", " aest", " aedt", " acst", " acdt", " awst",
14664 ];
14665
14666 for abbrev in &tz_abbrevs {
14667 if ts_lower.ends_with(abbrev) {
14668 return true;
14669 }
14670 }
14671
14672 let trimmed = ts.trim();
14676 if let Some(last_space) = trimmed.rfind(' ') {
14677 let suffix = &trimmed[last_space + 1..];
14678 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
14679 let rest = &suffix[1..];
14681 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
14682 return true;
14683 }
14684 }
14685 }
14686
14687 false
14688 }
14689
14690 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
14692 use crate::dialects::DialectType;
14693
14694 match self.config.dialect {
14695 Some(DialectType::BigQuery) => {
14698 self.write("CAST('");
14699 self.write(dt);
14700 self.write("' AS DATETIME)");
14701 }
14702 Some(DialectType::DuckDB) => {
14704 self.write("CAST('");
14705 self.write(dt);
14706 self.write("' AS TIMESTAMP)");
14707 }
14708 _ => {
14711 self.write_keyword("DATETIME");
14712 self.write(" '");
14713 self.write(dt);
14714 self.write("'");
14715 }
14716 }
14717 Ok(())
14718 }
14719
14720 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
14722 use crate::dialects::DialectType;
14723
14724 match self.config.dialect {
14725 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
14729 self.write("'");
14731 for c in s.chars() {
14732 match c {
14733 '\'' => self.write("\\'"),
14734 '\\' => self.write("\\\\"),
14735 '\n' => self.write("\\n"),
14736 '\r' => self.write("\\r"),
14737 '\t' => self.write("\\t"),
14738 '\0' => self.write("\\0"),
14739 _ => self.output.push(c),
14740 }
14741 }
14742 self.write("'");
14743 }
14744 Some(DialectType::Drill) => {
14745 self.write("'");
14748 for c in s.chars() {
14749 match c {
14750 '\'' => self.write("''"),
14751 '\\' => self.write("\\\\"),
14752 '\n' => self.write("\\n"),
14753 '\r' => self.write("\\r"),
14754 '\t' => self.write("\\t"),
14755 '\0' => self.write("\\0"),
14756 _ => self.output.push(c),
14757 }
14758 }
14759 self.write("'");
14760 }
14761 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
14762 self.write("'");
14763 for c in s.chars() {
14764 match c {
14765 '\'' => self.write("''"),
14767 '\\' => self.write("\\\\"),
14768 '\n' => self.write("\\n"),
14769 '\r' => self.write("\\r"),
14770 '\t' => self.write("\\t"),
14771 '\0' => self.output.push('\0'),
14773 _ => self.output.push(c),
14774 }
14775 }
14776 self.write("'");
14777 }
14778 Some(DialectType::BigQuery) => {
14780 self.write("'");
14781 for c in s.chars() {
14782 match c {
14783 '\'' => self.write("\\'"),
14784 '\\' => self.write("\\\\"),
14785 '\n' => self.write("\\n"),
14786 '\r' => self.write("\\r"),
14787 '\t' => self.write("\\t"),
14788 '\0' => self.write("\\0"),
14789 '\x07' => self.write("\\a"),
14790 '\x08' => self.write("\\b"),
14791 '\x0C' => self.write("\\f"),
14792 '\x0B' => self.write("\\v"),
14793 _ => self.output.push(c),
14794 }
14795 }
14796 self.write("'");
14797 }
14798 Some(DialectType::Athena) => {
14802 if self.athena_hive_context {
14803 self.write("'");
14805 for c in s.chars() {
14806 match c {
14807 '\'' => self.write("\\'"),
14808 '\\' => self.write("\\\\"),
14809 '\n' => self.write("\\n"),
14810 '\r' => self.write("\\r"),
14811 '\t' => self.write("\\t"),
14812 '\0' => self.write("\\0"),
14813 _ => self.output.push(c),
14814 }
14815 }
14816 self.write("'");
14817 } else {
14818 self.write("'");
14820 for c in s.chars() {
14821 match c {
14822 '\'' => self.write("''"),
14823 _ => self.output.push(c),
14825 }
14826 }
14827 self.write("'");
14828 }
14829 }
14830 Some(DialectType::Snowflake) => {
14835 self.write("'");
14836 for c in s.chars() {
14837 match c {
14838 '\'' => self.write("\\'"),
14839 '\n' => self.write("\\n"),
14842 '\r' => self.write("\\r"),
14843 '\t' => self.write("\\t"),
14844 _ => self.output.push(c),
14845 }
14846 }
14847 self.write("'");
14848 }
14849 Some(DialectType::PostgreSQL) => {
14851 self.write("'");
14852 for c in s.chars() {
14853 match c {
14854 '\'' => self.write("''"),
14855 _ => self.output.push(c),
14856 }
14857 }
14858 self.write("'");
14859 }
14860 Some(DialectType::Redshift) => {
14862 self.write("'");
14863 for c in s.chars() {
14864 match c {
14865 '\'' => self.write("\\'"),
14866 _ => self.output.push(c),
14867 }
14868 }
14869 self.write("'");
14870 }
14871 Some(DialectType::Oracle) => {
14873 self.write("'");
14874 for ch in s.chars() {
14875 if ch == '\'' {
14876 self.output.push_str("''");
14877 } else {
14878 self.output.push(ch);
14879 }
14880 }
14881 self.write("'");
14882 }
14883 Some(DialectType::ClickHouse) => {
14886 self.write("'");
14887 for c in s.chars() {
14888 match c {
14889 '\'' => self.write("''"),
14890 '\\' => self.write("\\\\"),
14891 '\n' => self.write("\\n"),
14892 '\r' => self.write("\\r"),
14893 '\t' => self.write("\\t"),
14894 '\0' => self.write("\\0"),
14895 '\x07' => self.write("\\a"),
14896 '\x08' => self.write("\\b"),
14897 '\x0C' => self.write("\\f"),
14898 '\x0B' => self.write("\\v"),
14899 c if c.is_control() || (c as u32) < 0x20 => {
14901 let byte = c as u32;
14902 if byte < 256 {
14903 self.write(&format!("\\x{:02X}", byte));
14904 } else {
14905 self.output.push(c);
14906 }
14907 }
14908 _ => self.output.push(c),
14909 }
14910 }
14911 self.write("'");
14912 }
14913 _ => {
14916 self.write("'");
14917 for ch in s.chars() {
14918 if ch == '\'' {
14919 self.output.push_str("''");
14920 } else {
14921 self.output.push(ch);
14922 }
14923 }
14924 self.write("'");
14925 }
14926 }
14927 Ok(())
14928 }
14929
14930 fn write_escaped_byte_string(&mut self, s: &str) {
14933 for c in s.chars() {
14934 match c {
14935 '\'' => self.write("\\'"),
14937 '\\' => self.write("\\\\"),
14939 _ if !c.is_control() => self.output.push(c),
14941 _ => {
14943 let byte = c as u32;
14944 if byte < 256 {
14945 self.write(&format!("\\x{:02x}", byte));
14946 } else {
14947 for b in c.to_string().as_bytes() {
14949 self.write(&format!("\\x{:02x}", b));
14950 }
14951 }
14952 }
14953 }
14954 }
14955 }
14956
14957 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
14958 use crate::dialects::DialectType;
14959
14960 match self.config.dialect {
14962 Some(DialectType::TSQL) => {
14965 self.write(if b.value { "1" } else { "0" });
14966 }
14967 Some(DialectType::Oracle) => {
14969 self.write(if b.value { "1" } else { "0" });
14970 }
14971 Some(DialectType::MySQL) => {
14973 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14974 }
14975 _ => {
14977 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
14978 }
14979 }
14980 Ok(())
14981 }
14982
14983 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
14986 let name = &id.name;
14987 let quote_style = &self.config.identifier_quote_style;
14988
14989 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
14993
14994 let output_name = if self.config.normalize_identifiers && !id.quoted {
14996 name.to_ascii_lowercase()
14997 } else {
14998 name.to_string()
14999 };
15000
15001 if needs_quoting {
15002 let escaped_name = if quote_style.start == quote_style.end {
15004 output_name.replace(
15005 quote_style.end,
15006 &format!("{}{}", quote_style.end, quote_style.end),
15007 )
15008 } else {
15009 output_name.replace(
15010 quote_style.end,
15011 &format!("{}{}", quote_style.end, quote_style.end),
15012 )
15013 };
15014 self.write(&format!(
15015 "{}{}{}",
15016 quote_style.start, escaped_name, quote_style.end
15017 ));
15018 } else {
15019 self.write(&output_name);
15020 }
15021
15022 for comment in &id.trailing_comments {
15024 self.write(" ");
15025 self.write_formatted_comment(comment);
15026 }
15027 Ok(())
15028 }
15029
15030 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
15031 use crate::dialects::DialectType;
15032
15033 let name = &id.name;
15034
15035 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena))
15037 && self.athena_hive_context
15038 {
15039 &IdentifierQuoteStyle::BACKTICK
15040 } else {
15041 &self.config.identifier_quote_style
15042 };
15043
15044 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
15051 let needs_digit_quoting = starts_with_digit
15052 && !self.config.identifiers_can_start_with_digit
15053 && self.config.dialect.is_some();
15054 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
15055 && name.len() > 2
15056 && (name.starts_with("0x") || name.starts_with("0X"))
15057 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
15058 let needs_quoting = id.quoted
15059 || self.is_reserved_keyword(name)
15060 || self.config.always_quote_identifiers
15061 || needs_digit_quoting
15062 || mysql_invalid_hex_identifier;
15063
15064 let (base_name, suffix) = if needs_quoting {
15067 if let Some(paren_pos) = name.find('(') {
15069 let base = &name[..paren_pos];
15070 let rest = &name[paren_pos..];
15071 if rest.starts_with('(')
15073 && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC"))
15074 {
15075 let close_paren = rest.find(')').unwrap_or(rest.len());
15077 let inside = &rest[1..close_paren];
15078 if inside.chars().all(|c| c.is_ascii_digit()) {
15079 (base.to_string(), rest.to_string())
15080 } else {
15081 (name.to_string(), String::new())
15082 }
15083 } else {
15084 (name.to_string(), String::new())
15085 }
15086 } else if name.ends_with(" ASC") {
15087 let base = &name[..name.len() - 4];
15088 (base.to_string(), " ASC".to_string())
15089 } else if name.ends_with(" DESC") {
15090 let base = &name[..name.len() - 5];
15091 (base.to_string(), " DESC".to_string())
15092 } else {
15093 (name.to_string(), String::new())
15094 }
15095 } else {
15096 (name.to_string(), String::new())
15097 };
15098
15099 let output_name = if self.config.normalize_identifiers && !id.quoted {
15103 base_name.to_ascii_lowercase()
15104 } else if matches!(self.config.dialect, Some(DialectType::Exasol))
15105 && !id.quoted
15106 && self.is_reserved_keyword(name)
15107 {
15108 base_name.to_ascii_uppercase()
15111 } else {
15112 base_name
15113 };
15114
15115 if needs_quoting {
15116 let escaped_name = if quote_style.start == quote_style.end {
15118 output_name.replace(
15120 quote_style.end,
15121 &format!("{}{}", quote_style.end, quote_style.end),
15122 )
15123 } else {
15124 output_name.replace(
15126 quote_style.end,
15127 &format!("{}{}", quote_style.end, quote_style.end),
15128 )
15129 };
15130 self.write(&format!(
15131 "{}{}{}{}",
15132 quote_style.start, escaped_name, quote_style.end, suffix
15133 ));
15134 } else {
15135 self.write(&output_name);
15136 }
15137
15138 for comment in &id.trailing_comments {
15140 self.write(" ");
15141 self.write_formatted_comment(comment);
15142 }
15143 Ok(())
15144 }
15145
15146 fn generate_column(&mut self, col: &Column) -> Result<()> {
15147 use crate::dialects::DialectType;
15148
15149 if let Some(table) = &col.table {
15150 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
15154 && !table.quoted
15155 && table.name.eq_ignore_ascii_case("LOCAL");
15156
15157 if is_exasol_local_prefix {
15158 self.write("LOCAL");
15160 } else {
15161 self.generate_identifier(table)?;
15162 }
15163 self.write(".");
15164 }
15165 self.generate_identifier(&col.name)?;
15166 if col.join_mark && self.config.supports_column_join_marks {
15169 self.write(" (+)");
15170 }
15171 for comment in &col.trailing_comments {
15173 self.write_space();
15174 self.write_formatted_comment(comment);
15175 }
15176 Ok(())
15177 }
15178
15179 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
15182 use crate::dialects::DialectType;
15183 use crate::expressions::PseudocolumnType;
15184
15185 if pc.kind == PseudocolumnType::Sysdate
15187 && !matches!(
15188 self.config.dialect,
15189 Some(DialectType::Oracle) | Some(DialectType::Redshift) | None
15190 )
15191 {
15192 self.write_keyword("CURRENT_TIMESTAMP");
15193 if matches!(
15195 self.config.dialect,
15196 Some(DialectType::MySQL)
15197 | Some(DialectType::ClickHouse)
15198 | Some(DialectType::Spark)
15199 | Some(DialectType::Databricks)
15200 | Some(DialectType::Hive)
15201 ) {
15202 self.write("()");
15203 }
15204 } else {
15205 self.write(pc.kind.as_str());
15206 }
15207 Ok(())
15208 }
15209
15210 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
15212 use crate::dialects::DialectType;
15213
15214 let supports_connect_by = matches!(
15217 self.config.dialect,
15218 Some(DialectType::Oracle) | Some(DialectType::Snowflake)
15219 );
15220
15221 if !supports_connect_by && self.config.dialect.is_some() {
15222 if self.config.pretty {
15224 self.write_newline();
15225 } else {
15226 self.write_space();
15227 }
15228 self.write_unsupported_comment(
15229 "CONNECT BY requires manual conversion to recursive CTE",
15230 )?;
15231 }
15232
15233 if let Some(start) = &connect.start {
15235 if self.config.pretty {
15236 self.write_newline();
15237 } else {
15238 self.write_space();
15239 }
15240 self.write_keyword("START WITH");
15241 self.write_space();
15242 self.generate_expression(start)?;
15243 }
15244
15245 if self.config.pretty {
15247 self.write_newline();
15248 } else {
15249 self.write_space();
15250 }
15251 self.write_keyword("CONNECT BY");
15252 if connect.nocycle {
15253 self.write_space();
15254 self.write_keyword("NOCYCLE");
15255 }
15256 self.write_space();
15257 self.generate_expression(&connect.connect)?;
15258
15259 Ok(())
15260 }
15261
15262 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
15264 self.generate_connect(connect)
15265 }
15266
15267 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
15269 self.write_keyword("PRIOR");
15270 self.write_space();
15271 self.generate_expression(&prior.this)?;
15272 Ok(())
15273 }
15274
15275 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
15278 self.write_keyword("CONNECT_BY_ROOT");
15279 self.write_space();
15280 self.generate_expression(&cbr.this)?;
15281 Ok(())
15282 }
15283
15284 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
15286 use crate::dialects::DialectType;
15287
15288 let supports_match_recognize = matches!(
15290 self.config.dialect,
15291 Some(DialectType::Oracle)
15292 | Some(DialectType::Snowflake)
15293 | Some(DialectType::Presto)
15294 | Some(DialectType::Trino)
15295 );
15296
15297 if let Some(source) = &mr.this {
15299 self.generate_expression(source)?;
15300 }
15301
15302 if !supports_match_recognize {
15303 self.write_unsupported_comment("MATCH_RECOGNIZE not supported in this dialect")?;
15304 return Ok(());
15305 }
15306
15307 if self.config.pretty {
15309 self.write_newline();
15310 } else {
15311 self.write_space();
15312 }
15313
15314 self.write_keyword("MATCH_RECOGNIZE");
15315 self.write(" (");
15316
15317 if self.config.pretty {
15318 self.indent_level += 1;
15319 }
15320
15321 let mut needs_separator = false;
15322
15323 if let Some(partition_by) = &mr.partition_by {
15325 if !partition_by.is_empty() {
15326 if self.config.pretty {
15327 self.write_newline();
15328 self.write_indent();
15329 }
15330 self.write_keyword("PARTITION BY");
15331 self.write_space();
15332 for (i, expr) in partition_by.iter().enumerate() {
15333 if i > 0 {
15334 self.write(", ");
15335 }
15336 self.generate_expression(expr)?;
15337 }
15338 needs_separator = true;
15339 }
15340 }
15341
15342 if let Some(order_by) = &mr.order_by {
15344 if !order_by.is_empty() {
15345 if needs_separator {
15346 if self.config.pretty {
15347 self.write_newline();
15348 self.write_indent();
15349 } else {
15350 self.write_space();
15351 }
15352 } else if self.config.pretty {
15353 self.write_newline();
15354 self.write_indent();
15355 }
15356 self.write_keyword("ORDER BY");
15357 if self.config.pretty {
15359 self.indent_level += 1;
15360 for (i, ordered) in order_by.iter().enumerate() {
15361 if i > 0 {
15362 self.write(",");
15363 }
15364 self.write_newline();
15365 self.write_indent();
15366 self.generate_ordered(ordered)?;
15367 }
15368 self.indent_level -= 1;
15369 } else {
15370 self.write_space();
15371 for (i, ordered) in order_by.iter().enumerate() {
15372 if i > 0 {
15373 self.write(", ");
15374 }
15375 self.generate_ordered(ordered)?;
15376 }
15377 }
15378 needs_separator = true;
15379 }
15380 }
15381
15382 if let Some(measures) = &mr.measures {
15384 if !measures.is_empty() {
15385 if needs_separator {
15386 if self.config.pretty {
15387 self.write_newline();
15388 self.write_indent();
15389 } else {
15390 self.write_space();
15391 }
15392 } else if self.config.pretty {
15393 self.write_newline();
15394 self.write_indent();
15395 }
15396 self.write_keyword("MEASURES");
15397 if self.config.pretty {
15399 self.indent_level += 1;
15400 for (i, measure) in measures.iter().enumerate() {
15401 if i > 0 {
15402 self.write(",");
15403 }
15404 self.write_newline();
15405 self.write_indent();
15406 if let Some(semantics) = &measure.window_frame {
15408 match semantics {
15409 MatchRecognizeSemantics::Running => {
15410 self.write_keyword("RUNNING");
15411 self.write_space();
15412 }
15413 MatchRecognizeSemantics::Final => {
15414 self.write_keyword("FINAL");
15415 self.write_space();
15416 }
15417 }
15418 }
15419 self.generate_expression(&measure.this)?;
15420 }
15421 self.indent_level -= 1;
15422 } else {
15423 self.write_space();
15424 for (i, measure) in measures.iter().enumerate() {
15425 if i > 0 {
15426 self.write(", ");
15427 }
15428 if let Some(semantics) = &measure.window_frame {
15430 match semantics {
15431 MatchRecognizeSemantics::Running => {
15432 self.write_keyword("RUNNING");
15433 self.write_space();
15434 }
15435 MatchRecognizeSemantics::Final => {
15436 self.write_keyword("FINAL");
15437 self.write_space();
15438 }
15439 }
15440 }
15441 self.generate_expression(&measure.this)?;
15442 }
15443 }
15444 needs_separator = true;
15445 }
15446 }
15447
15448 if let Some(rows) = &mr.rows {
15450 if needs_separator {
15451 if self.config.pretty {
15452 self.write_newline();
15453 self.write_indent();
15454 } else {
15455 self.write_space();
15456 }
15457 } else if self.config.pretty {
15458 self.write_newline();
15459 self.write_indent();
15460 }
15461 match rows {
15462 MatchRecognizeRows::OneRowPerMatch => {
15463 self.write_keyword("ONE ROW PER MATCH");
15464 }
15465 MatchRecognizeRows::AllRowsPerMatch => {
15466 self.write_keyword("ALL ROWS PER MATCH");
15467 }
15468 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
15469 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
15470 }
15471 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
15472 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
15473 }
15474 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
15475 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
15476 }
15477 }
15478 needs_separator = true;
15479 }
15480
15481 if let Some(after) = &mr.after {
15483 if needs_separator {
15484 if self.config.pretty {
15485 self.write_newline();
15486 self.write_indent();
15487 } else {
15488 self.write_space();
15489 }
15490 } else if self.config.pretty {
15491 self.write_newline();
15492 self.write_indent();
15493 }
15494 match after {
15495 MatchRecognizeAfter::PastLastRow => {
15496 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
15497 }
15498 MatchRecognizeAfter::ToNextRow => {
15499 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
15500 }
15501 MatchRecognizeAfter::ToFirst(ident) => {
15502 self.write_keyword("AFTER MATCH SKIP TO FIRST");
15503 self.write_space();
15504 self.generate_identifier(ident)?;
15505 }
15506 MatchRecognizeAfter::ToLast(ident) => {
15507 self.write_keyword("AFTER MATCH SKIP TO LAST");
15508 self.write_space();
15509 self.generate_identifier(ident)?;
15510 }
15511 }
15512 needs_separator = true;
15513 }
15514
15515 if let Some(pattern) = &mr.pattern {
15517 if needs_separator {
15518 if self.config.pretty {
15519 self.write_newline();
15520 self.write_indent();
15521 } else {
15522 self.write_space();
15523 }
15524 } else if self.config.pretty {
15525 self.write_newline();
15526 self.write_indent();
15527 }
15528 self.write_keyword("PATTERN");
15529 self.write_space();
15530 self.write("(");
15531 self.write(pattern);
15532 self.write(")");
15533 needs_separator = true;
15534 }
15535
15536 if let Some(define) = &mr.define {
15538 if !define.is_empty() {
15539 if needs_separator {
15540 if self.config.pretty {
15541 self.write_newline();
15542 self.write_indent();
15543 } else {
15544 self.write_space();
15545 }
15546 } else if self.config.pretty {
15547 self.write_newline();
15548 self.write_indent();
15549 }
15550 self.write_keyword("DEFINE");
15551 if self.config.pretty {
15553 self.indent_level += 1;
15554 for (i, (name, expr)) in define.iter().enumerate() {
15555 if i > 0 {
15556 self.write(",");
15557 }
15558 self.write_newline();
15559 self.write_indent();
15560 self.generate_identifier(name)?;
15561 self.write(" AS ");
15562 self.generate_expression(expr)?;
15563 }
15564 self.indent_level -= 1;
15565 } else {
15566 self.write_space();
15567 for (i, (name, expr)) in define.iter().enumerate() {
15568 if i > 0 {
15569 self.write(", ");
15570 }
15571 self.generate_identifier(name)?;
15572 self.write(" AS ");
15573 self.generate_expression(expr)?;
15574 }
15575 }
15576 }
15577 }
15578
15579 if self.config.pretty {
15580 self.indent_level -= 1;
15581 self.write_newline();
15582 }
15583 self.write(")");
15584
15585 if let Some(alias) = &mr.alias {
15587 self.write(" ");
15588 if mr.alias_explicit_as {
15589 self.write_keyword("AS");
15590 self.write(" ");
15591 }
15592 self.generate_identifier(alias)?;
15593 }
15594
15595 Ok(())
15596 }
15597
15598 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
15600 use crate::dialects::DialectType;
15601
15602 let supports_hints = matches!(
15604 self.config.dialect,
15605 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
15607 Some(DialectType::Spark) | Some(DialectType::Hive) |
15608 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
15609 );
15610
15611 if !supports_hints || hint.expressions.is_empty() {
15612 return Ok(());
15613 }
15614
15615 let mut hint_strings: Vec<String> = Vec::new();
15618 for expr in &hint.expressions {
15619 match expr {
15620 HintExpression::Raw(text) => {
15621 let parsed = self.parse_raw_hint_text(text);
15623 hint_strings.extend(parsed);
15624 }
15625 _ => {
15626 hint_strings.push(self.hint_expression_to_string(expr)?);
15627 }
15628 }
15629 }
15630
15631 let use_multiline = self.config.pretty && hint_strings.len() > 1;
15635
15636 if use_multiline {
15637 self.write(" /*+ ");
15639 for (i, hint_str) in hint_strings.iter().enumerate() {
15640 if i > 0 {
15641 self.write_newline();
15642 self.write(" "); }
15644 self.write(hint_str);
15645 }
15646 self.write(" */");
15647 } else {
15648 self.write(" /*+ ");
15650 let sep = match self.config.dialect {
15651 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
15652 _ => " ",
15653 };
15654 for (i, hint_str) in hint_strings.iter().enumerate() {
15655 if i > 0 {
15656 self.write(sep);
15657 }
15658 self.write(hint_str);
15659 }
15660 self.write(" */");
15661 }
15662
15663 Ok(())
15664 }
15665
15666 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
15670 let mut results = Vec::new();
15671 let mut chars = text.chars().peekable();
15672 let mut current = String::new();
15673 let mut paren_depth = 0;
15674 let mut has_unparseable_content = false;
15675 let mut position_after_last_function = 0;
15676 let mut char_position = 0;
15677
15678 while let Some(c) = chars.next() {
15679 char_position += c.len_utf8();
15680 match c {
15681 '(' => {
15682 paren_depth += 1;
15683 current.push(c);
15684 }
15685 ')' => {
15686 paren_depth -= 1;
15687 current.push(c);
15688 if paren_depth == 0 {
15690 let trimmed = current.trim().to_string();
15691 if !trimmed.is_empty() {
15692 let formatted = self.format_hint_function(&trimmed);
15694 results.push(formatted);
15695 }
15696 current.clear();
15697 position_after_last_function = char_position;
15698 }
15699 }
15700 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
15701 }
15703 _ if paren_depth == 0 => {
15704 current.push(c);
15706 }
15707 _ => {
15708 current.push(c);
15709 }
15710 }
15711 }
15712
15713 let remaining_text = text[position_after_last_function..].trim();
15715 if !remaining_text.is_empty() {
15716 let words: Vec<&str> = remaining_text.split_whitespace().collect();
15720 let looks_like_hint_functions = words.iter().all(|word| {
15721 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
15723 });
15724
15725 if !looks_like_hint_functions && words.len() > 1 {
15726 has_unparseable_content = true;
15727 }
15728 }
15729
15730 if has_unparseable_content {
15732 return vec![text.trim().to_string()];
15733 }
15734
15735 if results.is_empty() {
15737 results.push(text.trim().to_string());
15738 }
15739
15740 results
15741 }
15742
15743 fn format_hint_function(&self, hint: &str) -> String {
15746 if !self.config.pretty {
15747 return hint.to_string();
15748 }
15749
15750 if let Some(paren_pos) = hint.find('(') {
15752 if hint.ends_with(')') {
15753 let name = &hint[..paren_pos];
15754 let args_str = &hint[paren_pos + 1..hint.len() - 1];
15755
15756 let args: Vec<&str> = args_str.split_whitespace().collect();
15758
15759 let total_args_width: usize =
15761 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() {
15765 let mut result = format!("{}(\n", name);
15766 for arg in &args {
15767 result.push_str(" "); result.push_str(arg);
15769 result.push('\n');
15770 }
15771 result.push_str(" )"); return result;
15773 }
15774 }
15775 }
15776
15777 hint.to_string()
15778 }
15779
15780 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
15782 match expr {
15783 HintExpression::Function { name, args } => {
15784 let arg_strings: Vec<String> = args
15786 .iter()
15787 .map(|arg| {
15788 let mut gen = Generator::with_arc_config(self.config.clone());
15789 gen.generate_expression(arg)?;
15790 Ok(gen.output)
15791 })
15792 .collect::<Result<Vec<_>>>()?;
15793
15794 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
15796 + arg_strings.len().saturating_sub(1); let args_multiline =
15801 self.config.pretty && total_args_width > self.config.max_text_width;
15802
15803 if args_multiline && !arg_strings.is_empty() {
15804 let mut result = format!("{}(\n", name);
15806 for arg_str in &arg_strings {
15807 result.push_str(" "); result.push_str(arg_str);
15809 result.push('\n');
15810 }
15811 result.push_str(" )"); Ok(result)
15813 } else {
15814 let args_str = arg_strings.join(" ");
15816 Ok(format!("{}({})", name, args_str))
15817 }
15818 }
15819 HintExpression::Identifier(name) => Ok(name.clone()),
15820 HintExpression::Raw(text) => {
15821 if self.config.pretty {
15823 Ok(self.format_hint_function(text))
15824 } else {
15825 Ok(text.clone())
15826 }
15827 }
15828 }
15829 }
15830
15831 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
15832 if table.only {
15834 self.write_keyword("ONLY");
15835 self.write_space();
15836 }
15837
15838 if let Some(ref identifier_func) = table.identifier_func {
15840 self.generate_expression(identifier_func)?;
15841 if !table.name.name.is_empty() {
15843 if let Some(catalog) = &table.catalog {
15844 self.write(".");
15845 self.generate_identifier(catalog)?;
15846 }
15847 if let Some(schema) = &table.schema {
15848 self.write(".");
15849 self.generate_identifier(schema)?;
15850 }
15851 self.write(".");
15852 self.generate_identifier(&table.name)?;
15853 }
15854 } else {
15855 if let Some(catalog) = &table.catalog {
15856 self.generate_identifier(catalog)?;
15857 self.write(".");
15858 }
15859 if let Some(schema) = &table.schema {
15860 self.generate_identifier(schema)?;
15861 self.write(".");
15862 }
15863 self.generate_identifier(&table.name)?;
15864 }
15865
15866 if let Some(changes) = &table.changes {
15868 self.write(" ");
15869 self.generate_changes(changes)?;
15870 }
15871
15872 if !table.partitions.is_empty() {
15874 self.write_space();
15875 self.write_keyword("PARTITION");
15876 self.write("(");
15877 for (i, partition) in table.partitions.iter().enumerate() {
15878 if i > 0 {
15879 self.write(", ");
15880 }
15881 self.generate_identifier(partition)?;
15882 }
15883 self.write(")");
15884 }
15885
15886 if table.changes.is_none() {
15889 if let Some(when) = &table.when {
15890 self.write_space();
15891 self.generate_historical_data(when)?;
15892 }
15893 }
15894
15895 let system_time_post_alias = matches!(self.config.dialect, Some(DialectType::BigQuery));
15897 if !system_time_post_alias {
15898 if let Some(ref system_time) = table.system_time {
15899 self.write_space();
15900 self.write(system_time);
15901 }
15902 }
15903
15904 if let Some(ref version) = table.version {
15906 self.write_space();
15907 self.generate_version(version)?;
15908 }
15909
15910 let alias_post_tablesample = self.config.alias_post_tablesample;
15914
15915 if alias_post_tablesample {
15916 self.generate_table_sample_clause(table)?;
15918 }
15919
15920 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
15923 && table.hints.iter().any(|h| {
15924 if let Expression::Identifier(id) = h {
15925 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
15926 } else {
15927 false
15928 }
15929 });
15930 if !table.hints.is_empty() && !is_sqlite_hint {
15931 for hint in &table.hints {
15932 self.write_space();
15933 self.generate_expression(hint)?;
15934 }
15935 }
15936
15937 if let Some(alias) = &table.alias {
15938 self.write_space();
15939 let always_use_as = self.config.dialect.is_none()
15942 || matches!(
15943 self.config.dialect,
15944 Some(DialectType::Generic)
15945 | Some(DialectType::PostgreSQL)
15946 | Some(DialectType::Redshift)
15947 | Some(DialectType::Snowflake)
15948 | Some(DialectType::BigQuery)
15949 | Some(DialectType::DuckDB)
15950 | Some(DialectType::Presto)
15951 | Some(DialectType::Trino)
15952 | Some(DialectType::TSQL)
15953 | Some(DialectType::Fabric)
15954 | Some(DialectType::MySQL)
15955 | Some(DialectType::Spark)
15956 | Some(DialectType::Hive)
15957 | Some(DialectType::SQLite)
15958 | Some(DialectType::Drill)
15959 );
15960 let is_stage_ref = table.name.name.starts_with('@');
15961 let suppress_as = matches!(self.config.dialect, Some(DialectType::Oracle));
15963 if !suppress_as && (table.alias_explicit_as || always_use_as || is_stage_ref) {
15964 self.write_keyword("AS");
15965 self.write_space();
15966 }
15967 self.generate_identifier(alias)?;
15968
15969 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
15972 self.write("(");
15973 for (i, col_alias) in table.column_aliases.iter().enumerate() {
15974 if i > 0 {
15975 self.write(", ");
15976 }
15977 self.generate_identifier(col_alias)?;
15978 }
15979 self.write(")");
15980 }
15981 }
15982
15983 if system_time_post_alias {
15985 if let Some(ref system_time) = table.system_time {
15986 self.write_space();
15987 self.write(system_time);
15988 }
15989 }
15990
15991 if !alias_post_tablesample {
15993 self.generate_table_sample_clause(table)?;
15994 }
15995
15996 if is_sqlite_hint {
15998 for hint in &table.hints {
15999 self.write_space();
16000 self.generate_expression(hint)?;
16001 }
16002 }
16003
16004 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
16006 self.write_space();
16007 self.write_keyword("FINAL");
16008 }
16009
16010 for comment in &table.trailing_comments {
16012 self.write_space();
16013 self.write_formatted_comment(comment);
16014 }
16015 Ok(())
16019 }
16020
16021 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
16023 if let Some(ref ts) = table.table_sample {
16024 self.write_space();
16025 if ts.is_using_sample {
16026 self.write_keyword("USING SAMPLE");
16027 } else {
16028 self.write_keyword(self.config.tablesample_keywords);
16030 }
16031 self.generate_sample_body(ts)?;
16032 if let Some(ref seed) = ts.seed {
16034 self.write_space();
16035 self.write_keyword(self.config.tablesample_seed_keyword);
16036 self.write(" (");
16037 self.generate_expression(seed)?;
16038 self.write(")");
16039 }
16040 }
16041 Ok(())
16042 }
16043
16044 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
16045 if sr.quoted {
16049 self.write("'");
16050 }
16051
16052 self.write(&sr.name);
16053 if let Some(path) = &sr.path {
16054 self.write(path);
16055 }
16056
16057 if sr.quoted {
16058 self.write("'");
16059 }
16060
16061 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
16063 if has_options {
16064 self.write(" (");
16065 let mut first = true;
16066
16067 if let Some(file_format) = &sr.file_format {
16068 if !first {
16069 self.write(", ");
16070 }
16071 self.write_keyword("FILE_FORMAT");
16072 self.write(" => ");
16073 self.generate_expression(file_format)?;
16074 first = false;
16075 }
16076
16077 if let Some(pattern) = &sr.pattern {
16078 if !first {
16079 self.write(", ");
16080 }
16081 self.write_keyword("PATTERN");
16082 self.write(" => '");
16083 self.write(pattern);
16084 self.write("'");
16085 }
16086
16087 self.write(")");
16088 }
16089 Ok(())
16090 }
16091
16092 fn generate_star(&mut self, star: &Star) -> Result<()> {
16093 use crate::dialects::DialectType;
16094
16095 if let Some(table) = &star.table {
16096 self.generate_identifier(table)?;
16097 self.write(".");
16098 }
16099 self.write("*");
16100
16101 if let Some(except) = &star.except {
16103 if !except.is_empty() {
16104 self.write_space();
16105 match self.config.dialect {
16107 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
16108 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
16109 self.write_keyword("EXCLUDE")
16110 }
16111 _ => self.write_keyword("EXCEPT"), }
16113 self.write(" (");
16114 for (i, col) in except.iter().enumerate() {
16115 if i > 0 {
16116 self.write(", ");
16117 }
16118 self.generate_identifier(col)?;
16119 }
16120 self.write(")");
16121 }
16122 }
16123
16124 if let Some(replace) = &star.replace {
16126 if !replace.is_empty() {
16127 self.write_space();
16128 self.write_keyword("REPLACE");
16129 self.write(" (");
16130 for (i, alias) in replace.iter().enumerate() {
16131 if i > 0 {
16132 self.write(", ");
16133 }
16134 self.generate_expression(&alias.this)?;
16135 self.write_space();
16136 self.write_keyword("AS");
16137 self.write_space();
16138 self.generate_identifier(&alias.alias)?;
16139 }
16140 self.write(")");
16141 }
16142 }
16143
16144 if let Some(rename) = &star.rename {
16146 if !rename.is_empty() {
16147 self.write_space();
16148 self.write_keyword("RENAME");
16149 self.write(" (");
16150 for (i, (old_name, new_name)) in rename.iter().enumerate() {
16151 if i > 0 {
16152 self.write(", ");
16153 }
16154 self.generate_identifier(old_name)?;
16155 self.write_space();
16156 self.write_keyword("AS");
16157 self.write_space();
16158 self.generate_identifier(new_name)?;
16159 }
16160 self.write(")");
16161 }
16162 }
16163
16164 for comment in &star.trailing_comments {
16166 self.write_space();
16167 self.write_formatted_comment(comment);
16168 }
16169
16170 Ok(())
16171 }
16172
16173 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
16175 self.write("{");
16176 match expr {
16177 Expression::Star(star) => {
16178 self.generate_star(star)?;
16180 }
16181 Expression::ILike(ilike) => {
16182 self.generate_expression(&ilike.left)?;
16184 self.write_space();
16185 self.write_keyword("ILIKE");
16186 self.write_space();
16187 self.generate_expression(&ilike.right)?;
16188 }
16189 _ => {
16190 self.generate_expression(expr)?;
16191 }
16192 }
16193 self.write("}");
16194 Ok(())
16195 }
16196
16197 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
16198 match &alias.this {
16202 Expression::Column(col) => {
16203 if let Some(table) = &col.table {
16205 self.generate_identifier(table)?;
16206 self.write(".");
16207 }
16208 self.generate_identifier(&col.name)?;
16209 }
16210 _ => {
16211 self.generate_expression(&alias.this)?;
16212 }
16213 }
16214
16215 if !alias.pre_alias_comments.is_empty() && !alias.trailing_comments.is_empty() {
16219 for comment in &alias.pre_alias_comments {
16220 self.write_space();
16221 self.write_formatted_comment(comment);
16222 }
16223 }
16224
16225 use crate::dialects::DialectType;
16226
16227 let is_table_source = matches!(
16233 &alias.this,
16234 Expression::JSONTable(_)
16235 | Expression::XMLTable(_)
16236 | Expression::TableFromRows(_)
16237 | Expression::Unnest(_)
16238 | Expression::MatchRecognize(_)
16239 | Expression::Select(_)
16240 | Expression::Subquery(_)
16241 | Expression::Paren(_)
16242 );
16243 let dialect_skips_table_alias_as = matches!(self.config.dialect, Some(DialectType::Oracle));
16244 let skip_as = is_table_source && dialect_skips_table_alias_as;
16245
16246 self.write_space();
16247 if !skip_as {
16248 self.write_keyword("AS");
16249 self.write_space();
16250 }
16251
16252 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
16254
16255 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
16257 self.write("(");
16259 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16260 if i > 0 {
16261 self.write(", ");
16262 }
16263 self.generate_alias_identifier(col_alias)?;
16264 }
16265 self.write(")");
16266 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
16267 self.generate_alias_identifier(&alias.alias)?;
16269 self.write("(");
16270 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
16271 if i > 0 {
16272 self.write(", ");
16273 }
16274 self.generate_alias_identifier(col_alias)?;
16275 }
16276 self.write(")");
16277 } else {
16278 self.generate_alias_identifier(&alias.alias)?;
16280 }
16281
16282 for comment in &alias.trailing_comments {
16284 self.write_space();
16285 self.write_formatted_comment(comment);
16286 }
16287
16288 if alias.trailing_comments.is_empty() {
16293 for comment in &alias.pre_alias_comments {
16294 self.write_space();
16295 self.write_formatted_comment(comment);
16296 }
16297 }
16298
16299 Ok(())
16300 }
16301
16302 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
16303 use crate::dialects::DialectType;
16304
16305 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
16307 self.generate_expression(&cast.this)?;
16308 self.write(" :> ");
16309 self.generate_data_type(&cast.to)?;
16310 return Ok(());
16311 }
16312
16313 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
16315 let is_unknown_type = matches!(cast.to, DataType::Unknown)
16316 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
16317 if is_unknown_type {
16318 if let Some(format) = &cast.format {
16319 self.write_keyword("CAST");
16320 self.write("(");
16321 self.generate_expression(&cast.this)?;
16322 self.write_space();
16323 self.write_keyword("AS");
16324 self.write_space();
16325 self.write_keyword("FORMAT");
16326 self.write_space();
16327 self.generate_expression(format)?;
16328 self.write(")");
16329 return Ok(());
16330 }
16331 }
16332 }
16333
16334 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
16337 if let Some(format) = &cast.format {
16338 let is_date = matches!(cast.to, DataType::Date);
16340 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
16341
16342 if is_date || is_timestamp {
16343 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
16344 self.write_keyword(func_name);
16345 self.write("(");
16346 self.generate_expression(&cast.this)?;
16347 self.write(", ");
16348
16349 if let Expression::Literal(lit) = format.as_ref() {
16352 if let Literal::String(fmt_str) = lit.as_ref() {
16353 let normalized = self.normalize_oracle_format(fmt_str);
16354 self.write("'");
16355 self.write(&normalized);
16356 self.write("'");
16357 }
16358 } else {
16359 self.generate_expression(format)?;
16360 }
16361
16362 self.write(")");
16363 return Ok(());
16364 }
16365 }
16366 }
16367
16368 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
16371 if let Expression::Array(arr) = &cast.this {
16372 self.generate_data_type(&cast.to)?;
16373 self.write("[");
16375 for (i, expr) in arr.expressions.iter().enumerate() {
16376 if i > 0 {
16377 self.write(", ");
16378 }
16379 self.generate_expression(expr)?;
16380 }
16381 self.write("]");
16382 return Ok(());
16383 }
16384 if matches!(&cast.this, Expression::ArrayFunc(_)) {
16385 self.generate_data_type(&cast.to)?;
16386 self.generate_expression(&cast.this)?;
16387 return Ok(());
16388 }
16389 }
16390
16391 if matches!(
16394 self.config.dialect,
16395 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
16396 ) {
16397 if let Expression::Struct(ref s) = cast.this {
16398 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
16399 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
16400 self.write_keyword("CAST");
16401 self.write("(");
16402 self.generate_struct_as_row(s)?;
16403 self.write_space();
16404 self.write_keyword("AS");
16405 self.write_space();
16406 self.generate_data_type(&cast.to)?;
16407 self.write(")");
16408 return Ok(());
16409 }
16410 }
16411 }
16412
16413 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
16416
16417 if use_double_colon {
16418 self.generate_expression(&cast.this)?;
16420 self.write("::");
16421 self.generate_data_type(&cast.to)?;
16422 } else {
16423 self.write_keyword("CAST");
16425 self.write("(");
16426 self.generate_expression(&cast.this)?;
16427 self.write_space();
16428 self.write_keyword("AS");
16429 self.write_space();
16430 if matches!(
16433 self.config.dialect,
16434 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
16435 ) {
16436 match &cast.to {
16437 DataType::Custom { ref name } => {
16438 if name.eq_ignore_ascii_case("LONGTEXT")
16439 || name.eq_ignore_ascii_case("MEDIUMTEXT")
16440 || name.eq_ignore_ascii_case("TINYTEXT")
16441 || name.eq_ignore_ascii_case("LONGBLOB")
16442 || name.eq_ignore_ascii_case("MEDIUMBLOB")
16443 || name.eq_ignore_ascii_case("TINYBLOB")
16444 {
16445 self.write_keyword("CHAR");
16446 } else {
16447 self.generate_data_type(&cast.to)?;
16448 }
16449 }
16450 DataType::VarChar { length, .. } => {
16451 self.write_keyword("CHAR");
16453 if let Some(n) = length {
16454 self.write(&format!("({})", n));
16455 }
16456 }
16457 DataType::Text => {
16458 self.write_keyword("CHAR");
16460 }
16461 DataType::Timestamp {
16462 precision,
16463 timezone: false,
16464 } => {
16465 self.write_keyword("DATETIME");
16467 if let Some(p) = precision {
16468 self.write(&format!("({})", p));
16469 }
16470 }
16471 _ => {
16472 self.generate_data_type(&cast.to)?;
16473 }
16474 }
16475 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
16476 match &cast.to {
16478 DataType::String { length } => {
16479 self.write_keyword("VARCHAR");
16480 if let Some(n) = length {
16481 self.write(&format!("({})", n));
16482 }
16483 }
16484 _ => {
16485 self.generate_data_type(&cast.to)?;
16486 }
16487 }
16488 } else {
16489 self.generate_data_type(&cast.to)?;
16490 }
16491
16492 if let Some(default) = &cast.default {
16494 self.write_space();
16495 self.write_keyword("DEFAULT");
16496 self.write_space();
16497 self.generate_expression(default)?;
16498 self.write_space();
16499 self.write_keyword("ON");
16500 self.write_space();
16501 self.write_keyword("CONVERSION");
16502 self.write_space();
16503 self.write_keyword("ERROR");
16504 }
16505
16506 if let Some(format) = &cast.format {
16509 if matches!(
16511 self.config.dialect,
16512 Some(crate::dialects::DialectType::Oracle)
16513 ) {
16514 self.write(", ");
16515 } else {
16516 self.write_space();
16517 self.write_keyword("FORMAT");
16518 self.write_space();
16519 }
16520 self.generate_expression(format)?;
16521 }
16522
16523 self.write(")");
16524 for comment in &cast.trailing_comments {
16526 self.write_space();
16527 self.write_formatted_comment(comment);
16528 }
16529 }
16530 Ok(())
16531 }
16532
16533 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
16536 self.write_keyword("ROW");
16537 self.write("(");
16538 for (i, (_, expr)) in s.fields.iter().enumerate() {
16539 if i > 0 {
16540 self.write(", ");
16541 }
16542 if let Expression::Struct(ref inner_s) = expr {
16544 self.generate_struct_as_row(inner_s)?;
16545 } else {
16546 self.generate_expression(expr)?;
16547 }
16548 }
16549 self.write(")");
16550 Ok(())
16551 }
16552
16553 fn normalize_oracle_format(&self, format: &str) -> String {
16556 let mut result = String::new();
16559 let chars: Vec<char> = format.chars().collect();
16560 let mut i = 0;
16561
16562 while i < chars.len() {
16563 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
16564 if i + 2 < chars.len() {
16566 let next = chars[i + 2];
16567 if next == '1' || next == '2' {
16568 result.push('H');
16570 result.push('H');
16571 i += 2;
16572 continue;
16573 }
16574 }
16575 result.push_str("HH12");
16577 i += 2;
16578 } else {
16579 result.push(chars[i]);
16580 i += 1;
16581 }
16582 }
16583
16584 result
16585 }
16586
16587 fn dialect_prefers_double_colon(&self) -> bool {
16591 false
16594 }
16595
16596 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16598 use crate::dialects::DialectType;
16599
16600 let use_percent_operator = matches!(
16602 self.config.dialect,
16603 Some(DialectType::Snowflake)
16604 | Some(DialectType::MySQL)
16605 | Some(DialectType::Presto)
16606 | Some(DialectType::Trino)
16607 | Some(DialectType::PostgreSQL)
16608 | Some(DialectType::DuckDB)
16609 | Some(DialectType::Hive)
16610 | Some(DialectType::Spark)
16611 | Some(DialectType::Databricks)
16612 | Some(DialectType::Athena)
16613 );
16614
16615 if use_percent_operator {
16616 let needs_paren = |e: &Expression| matches!(e, Expression::Add(_) | Expression::Sub(_));
16619 if needs_paren(&f.this) {
16620 self.write("(");
16621 self.generate_expression(&f.this)?;
16622 self.write(")");
16623 } else {
16624 self.generate_expression(&f.this)?;
16625 }
16626 self.write(" % ");
16627 if needs_paren(&f.expression) {
16628 self.write("(");
16629 self.generate_expression(&f.expression)?;
16630 self.write(")");
16631 } else {
16632 self.generate_expression(&f.expression)?;
16633 }
16634 Ok(())
16635 } else {
16636 self.generate_binary_func("MOD", &f.this, &f.expression)
16637 }
16638 }
16639
16640 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16642 use crate::dialects::DialectType;
16643
16644 let func_name = match self.config.dialect {
16646 Some(DialectType::Snowflake) => "COALESCE",
16647 _ => "IFNULL",
16648 };
16649
16650 self.generate_binary_func(func_name, &f.this, &f.expression)
16651 }
16652
16653 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
16655 if let Some(ref original_name) = f.original_name {
16657 return self.generate_binary_func(original_name, &f.this, &f.expression);
16658 }
16659
16660 use crate::dialects::DialectType;
16662 let func_name = match self.config.dialect {
16663 Some(DialectType::Snowflake)
16664 | Some(DialectType::ClickHouse)
16665 | Some(DialectType::PostgreSQL)
16666 | Some(DialectType::Presto)
16667 | Some(DialectType::Trino)
16668 | Some(DialectType::Athena)
16669 | Some(DialectType::DuckDB)
16670 | Some(DialectType::BigQuery)
16671 | Some(DialectType::Spark)
16672 | Some(DialectType::Databricks)
16673 | Some(DialectType::Hive) => "COALESCE",
16674 Some(DialectType::MySQL)
16675 | Some(DialectType::Doris)
16676 | Some(DialectType::StarRocks)
16677 | Some(DialectType::SingleStore)
16678 | Some(DialectType::TiDB) => "IFNULL",
16679 _ => "NVL",
16680 };
16681
16682 self.generate_binary_func(func_name, &f.this, &f.expression)
16683 }
16684
16685 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
16687 use crate::dialects::DialectType;
16688
16689 let func_name = match self.config.dialect {
16691 Some(DialectType::Snowflake) => "STDDEV",
16692 _ => "STDDEV_SAMP",
16693 };
16694
16695 self.generate_agg_func(func_name, f)
16696 }
16697
16698 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
16699 self.generate_expression(&coll.this)?;
16700 self.write_space();
16701 self.write_keyword("COLLATE");
16702 self.write_space();
16703 if coll.quoted {
16704 self.write("'");
16706 self.write(&coll.collation);
16707 self.write("'");
16708 } else if coll.double_quoted {
16709 self.write("\"");
16711 self.write(&coll.collation);
16712 self.write("\"");
16713 } else {
16714 self.write(&coll.collation);
16716 }
16717 Ok(())
16718 }
16719
16720 fn generate_case(&mut self, case: &Case) -> Result<()> {
16721 let multiline_case = if self.config.pretty {
16723 let mut statements: Vec<String> = Vec::new();
16725 let operand_str = if let Some(operand) = &case.operand {
16726 let s = self.generate_to_string(operand)?;
16727 statements.push(format!("CASE {}", s));
16728 s
16729 } else {
16730 statements.push("CASE".to_string());
16731 String::new()
16732 };
16733 let _ = operand_str;
16734 for (condition, result) in &case.whens {
16735 statements.push(format!("WHEN {}", self.generate_to_string(condition)?));
16736 statements.push(format!("THEN {}", self.generate_to_string(result)?));
16737 }
16738 if let Some(else_) = &case.else_ {
16739 statements.push(format!("ELSE {}", self.generate_to_string(else_)?));
16740 }
16741 statements.push("END".to_string());
16742 self.too_wide(&statements)
16743 } else {
16744 false
16745 };
16746
16747 self.write_keyword("CASE");
16748 if let Some(operand) = &case.operand {
16749 self.write_space();
16750 self.generate_expression(operand)?;
16751 }
16752 if multiline_case {
16753 self.indent_level += 1;
16754 }
16755 for (condition, result) in &case.whens {
16756 if multiline_case {
16757 self.write_newline();
16758 self.write_indent();
16759 } else {
16760 self.write_space();
16761 }
16762 self.write_keyword("WHEN");
16763 self.write_space();
16764 self.generate_expression(condition)?;
16765 if multiline_case {
16766 self.write_newline();
16767 self.write_indent();
16768 } else {
16769 self.write_space();
16770 }
16771 self.write_keyword("THEN");
16772 self.write_space();
16773 self.generate_expression(result)?;
16774 }
16775 if let Some(else_) = &case.else_ {
16776 if multiline_case {
16777 self.write_newline();
16778 self.write_indent();
16779 } else {
16780 self.write_space();
16781 }
16782 self.write_keyword("ELSE");
16783 self.write_space();
16784 self.generate_expression(else_)?;
16785 }
16786 if multiline_case {
16787 self.indent_level -= 1;
16788 self.write_newline();
16789 self.write_indent();
16790 } else {
16791 self.write_space();
16792 }
16793 self.write_keyword("END");
16794 for comment in &case.comments {
16796 self.write(" ");
16797 self.write_formatted_comment(comment);
16798 }
16799 Ok(())
16800 }
16801
16802 fn generate_function(&mut self, func: &Function) -> Result<()> {
16803 let normalized_name = self.normalize_func_name(&func.name);
16805
16806 if matches!(self.config.dialect, Some(DialectType::DuckDB))
16808 && func.name.eq_ignore_ascii_case("ARRAY_CONSTRUCT_COMPACT")
16809 {
16810 self.write("LIST_FILTER(");
16811 self.write("[");
16812 for (i, arg) in func.args.iter().enumerate() {
16813 if i > 0 {
16814 self.write(", ");
16815 }
16816 self.generate_expression(arg)?;
16817 }
16818 self.write("], _u -> NOT _u IS NULL)");
16819 return Ok(());
16820 }
16821
16822 if func.name.eq_ignore_ascii_case("STRUCT")
16824 && !matches!(
16825 self.config.dialect,
16826 Some(DialectType::BigQuery)
16827 | Some(DialectType::Spark)
16828 | Some(DialectType::Databricks)
16829 | Some(DialectType::Hive)
16830 | None
16831 )
16832 {
16833 return self.generate_struct_function_cross_dialect(func);
16834 }
16835
16836 if func.name.eq_ignore_ascii_case("__SS_JSON_PATH_QMARK__") && func.args.len() == 2 {
16839 self.generate_expression(&func.args[0])?;
16840 self.write("::?");
16841 if let Expression::Literal(lit) = &func.args[1] {
16843 if let crate::expressions::Literal::String(key) = lit.as_ref() {
16844 self.write(key);
16845 }
16846 } else {
16847 self.generate_expression(&func.args[1])?;
16848 }
16849 return Ok(());
16850 }
16851
16852 if func.name.eq_ignore_ascii_case("__PG_BITWISE_XOR__") && func.args.len() == 2 {
16854 self.generate_expression(&func.args[0])?;
16855 self.write(" # ");
16856 self.generate_expression(&func.args[1])?;
16857 return Ok(());
16858 }
16859
16860 if matches!(
16862 self.config.dialect,
16863 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
16864 ) && func.name.eq_ignore_ascii_case("TRY")
16865 && func.args.len() == 1
16866 {
16867 self.generate_expression(&func.args[0])?;
16868 return Ok(());
16869 }
16870
16871 if self.config.dialect == Some(DialectType::ClickHouse)
16873 && func.name.eq_ignore_ascii_case("TOSTARTOFDAY")
16874 && func.args.len() == 1
16875 {
16876 self.write("dateTrunc('DAY', ");
16877 self.generate_expression(&func.args[0])?;
16878 self.write(")");
16879 return Ok(());
16880 }
16881
16882 if self.config.dialect == Some(DialectType::Redshift)
16884 && func.name.eq_ignore_ascii_case("CONCAT")
16885 && func.args.len() >= 2
16886 {
16887 for (i, arg) in func.args.iter().enumerate() {
16888 if i > 0 {
16889 self.write(" || ");
16890 }
16891 self.generate_expression(arg)?;
16892 }
16893 return Ok(());
16894 }
16895
16896 if self.config.dialect == Some(DialectType::Redshift)
16898 && func.name.eq_ignore_ascii_case("CONCAT_WS")
16899 && func.args.len() >= 2
16900 {
16901 let sep = &func.args[0];
16902 for (i, arg) in func.args.iter().skip(1).enumerate() {
16903 if i > 0 {
16904 self.write(" || ");
16905 self.generate_expression(sep)?;
16906 self.write(" || ");
16907 }
16908 self.generate_expression(arg)?;
16909 }
16910 return Ok(());
16911 }
16912
16913 if self.config.dialect == Some(DialectType::Redshift)
16916 && (func.name.eq_ignore_ascii_case("DATEDIFF")
16917 || func.name.eq_ignore_ascii_case("DATE_DIFF"))
16918 && func.args.len() == 3
16919 {
16920 self.write_keyword("DATEDIFF");
16921 self.write("(");
16922 self.write_redshift_date_part(&func.args[0]);
16924 self.write(", ");
16925 self.generate_expression(&func.args[1])?;
16926 self.write(", ");
16927 self.generate_expression(&func.args[2])?;
16928 self.write(")");
16929 return Ok(());
16930 }
16931
16932 if self.config.dialect == Some(DialectType::Redshift)
16935 && (func.name.eq_ignore_ascii_case("DATEADD")
16936 || func.name.eq_ignore_ascii_case("DATE_ADD"))
16937 && func.args.len() == 3
16938 {
16939 self.write_keyword("DATEADD");
16940 self.write("(");
16941 self.write_redshift_date_part(&func.args[0]);
16943 self.write(", ");
16944 self.generate_expression(&func.args[1])?;
16945 self.write(", ");
16946 self.generate_expression(&func.args[2])?;
16947 self.write(")");
16948 return Ok(());
16949 }
16950
16951 if func.name.eq_ignore_ascii_case("UUID_STRING")
16953 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None)
16954 {
16955 let func_name = match self.config.dialect {
16956 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
16957 Some(DialectType::BigQuery) => "GENERATE_UUID",
16958 _ => "UUID",
16959 };
16960 self.write_keyword(func_name);
16961 self.write("()");
16962 return Ok(());
16963 }
16964
16965 if matches!(self.config.dialect, Some(DialectType::Snowflake))
16969 && func.name.eq_ignore_ascii_case("GENERATOR")
16970 {
16971 let has_positional_args =
16972 !func.args.is_empty() && !matches!(&func.args[0], Expression::NamedArgument(_));
16973 if has_positional_args {
16974 let param_names = ["ROWCOUNT", "TIMELIMIT"];
16975 self.write_keyword("GENERATOR");
16976 self.write("(");
16977 for (i, arg) in func.args.iter().enumerate() {
16978 if i > 0 {
16979 self.write(", ");
16980 }
16981 if i < param_names.len() {
16982 self.write_keyword(param_names[i]);
16983 self.write(" => ");
16984 self.generate_expression(arg)?;
16985 } else {
16986 self.generate_expression(arg)?;
16987 }
16988 }
16989 self.write(")");
16990 return Ok(());
16991 }
16992 }
16993
16994 if self.config.dialect == Some(DialectType::Redshift)
16997 && func.name.eq_ignore_ascii_case("DATE_TRUNC")
16998 && func.args.len() == 2
16999 {
17000 self.write_keyword("DATE_TRUNC");
17001 self.write("(");
17002 self.write_redshift_date_part_quoted(&func.args[0]);
17004 self.write(", ");
17005 self.generate_expression(&func.args[1])?;
17006 self.write(")");
17007 return Ok(());
17008 }
17009
17010 if matches!(
17012 self.config.dialect,
17013 Some(DialectType::TSQL) | Some(DialectType::Fabric)
17014 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17015 || func.name.eq_ignore_ascii_case("DATEPART"))
17016 && func.args.len() == 2
17017 {
17018 self.write_keyword("DATEPART");
17019 self.write("(");
17020 self.generate_expression(&func.args[0])?;
17021 self.write(", ");
17022 self.generate_expression(&func.args[1])?;
17023 self.write(")");
17024 return Ok(());
17025 }
17026
17027 if matches!(
17029 self.config.dialect,
17030 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
17031 ) && (func.name.eq_ignore_ascii_case("DATE_PART")
17032 || func.name.eq_ignore_ascii_case("DATEPART"))
17033 && func.args.len() == 2
17034 {
17035 self.write_keyword("EXTRACT");
17036 self.write("(");
17037 match &func.args[0] {
17039 Expression::Literal(lit)
17040 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
17041 {
17042 let crate::expressions::Literal::String(s) = lit.as_ref() else {
17043 unreachable!()
17044 };
17045 self.write(&s.to_ascii_lowercase());
17046 }
17047 _ => self.generate_expression(&func.args[0])?,
17048 }
17049 self.write_space();
17050 self.write_keyword("FROM");
17051 self.write_space();
17052 self.generate_expression(&func.args[1])?;
17053 self.write(")");
17054 return Ok(());
17055 }
17056
17057 if self.config.dialect == Some(DialectType::Dremio)
17060 && (func.name.eq_ignore_ascii_case("DATE_PART")
17061 || func.name.eq_ignore_ascii_case("DATEPART"))
17062 && func.args.len() == 2
17063 {
17064 self.write_keyword("EXTRACT");
17065 self.write("(");
17066 self.generate_expression(&func.args[0])?;
17067 self.write_space();
17068 self.write_keyword("FROM");
17069 self.write_space();
17070 self.generate_dremio_date_expression(&func.args[1])?;
17072 self.write(")");
17073 return Ok(());
17074 }
17075
17076 if self.config.dialect == Some(DialectType::Dremio)
17078 && func.name.eq_ignore_ascii_case("CURRENT_DATE_UTC")
17079 && func.args.is_empty()
17080 {
17081 self.write_keyword("CURRENT_DATE_UTC");
17082 return Ok(());
17083 }
17084
17085 if self.config.dialect == Some(DialectType::Dremio)
17089 && func.name.eq_ignore_ascii_case("DATETYPE")
17090 && func.args.len() == 3
17091 {
17092 fn get_int_literal(expr: &Expression) -> Option<i64> {
17094 if let Expression::Literal(lit) = expr {
17095 if let crate::expressions::Literal::Number(s) = lit.as_ref() {
17096 s.parse::<i64>().ok()
17097 } else {
17098 None
17099 }
17100 } else {
17101 None
17102 }
17103 }
17104
17105 if let (Some(year), Some(month), Some(day)) = (
17107 get_int_literal(&func.args[0]),
17108 get_int_literal(&func.args[1]),
17109 get_int_literal(&func.args[2]),
17110 ) {
17111 self.write_keyword("DATE");
17113 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
17114 return Ok(());
17115 }
17116
17117 self.write_keyword("CAST");
17119 self.write("(");
17120 self.write_keyword("CONCAT");
17121 self.write("(");
17122 self.generate_expression(&func.args[0])?;
17123 self.write(", '-', ");
17124 self.generate_expression(&func.args[1])?;
17125 self.write(", '-', ");
17126 self.generate_expression(&func.args[2])?;
17127 self.write(")");
17128 self.write_space();
17129 self.write_keyword("AS");
17130 self.write_space();
17131 self.write_keyword("DATE");
17132 self.write(")");
17133 return Ok(());
17134 }
17135
17136 let is_presto_like = matches!(
17139 self.config.dialect,
17140 Some(DialectType::Presto) | Some(DialectType::Trino)
17141 );
17142 if is_presto_like && func.name.eq_ignore_ascii_case("DATE_ADD") && func.args.len() == 3 {
17143 self.write_keyword("DATE_ADD");
17144 self.write("(");
17145 self.generate_expression(&func.args[0])?;
17147 self.write(", ");
17148 let interval = &func.args[1];
17150 let needs_cast = !self.returns_integer_type(interval);
17151 if needs_cast {
17152 self.write_keyword("CAST");
17153 self.write("(");
17154 }
17155 self.generate_expression(interval)?;
17156 if needs_cast {
17157 self.write_space();
17158 self.write_keyword("AS");
17159 self.write_space();
17160 self.write_keyword("BIGINT");
17161 self.write(")");
17162 }
17163 self.write(", ");
17164 self.generate_expression(&func.args[2])?;
17166 self.write(")");
17167 return Ok(());
17168 }
17169
17170 let use_brackets = func.use_bracket_syntax;
17172
17173 let has_ordinality = func.name.len() >= 16
17178 && func.name[func.name.len() - 16..].eq_ignore_ascii_case(" WITH ORDINALITY");
17179 let output_name = if has_ordinality {
17180 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
17181 self.normalize_func_name(base_name)
17182 } else {
17183 normalized_name.clone()
17184 };
17185
17186 if func.name.contains('.') && !has_ordinality {
17189 if func.quoted {
17192 self.write("`");
17193 self.write(&func.name);
17194 self.write("`");
17195 } else {
17196 self.write(&func.name);
17197 }
17198 } else {
17199 self.write(&output_name);
17200 }
17201
17202 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
17205 let needs_parens = if func.name.eq_ignore_ascii_case("CURRENT_USER")
17206 || func.name.eq_ignore_ascii_case("SESSION_USER")
17207 || func.name.eq_ignore_ascii_case("SYSTEM_USER")
17208 {
17209 matches!(
17210 self.config.dialect,
17211 Some(DialectType::Snowflake)
17212 | Some(DialectType::Spark)
17213 | Some(DialectType::Databricks)
17214 | Some(DialectType::Hive)
17215 )
17216 } else {
17217 false
17218 };
17219 !needs_parens
17220 };
17221 if force_parens {
17222 for comment in &func.trailing_comments {
17224 self.write_space();
17225 self.write_formatted_comment(comment);
17226 }
17227 return Ok(());
17228 }
17229
17230 if func.name.eq_ignore_ascii_case("CUBE")
17232 || func.name.eq_ignore_ascii_case("ROLLUP")
17233 || func.name.eq_ignore_ascii_case("GROUPING SETS")
17234 {
17235 self.write(" (");
17236 } else if use_brackets {
17237 self.write("[");
17238 } else {
17239 self.write("(");
17240 }
17241 if func.distinct {
17242 self.write_keyword("DISTINCT");
17243 self.write_space();
17244 }
17245
17246 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
17248 && (func.name.eq_ignore_ascii_case("TABLE")
17249 || func.name.eq_ignore_ascii_case("FLATTEN"));
17250 let is_grouping_func = func.name.eq_ignore_ascii_case("GROUPING SETS")
17252 || func.name.eq_ignore_ascii_case("CUBE")
17253 || func.name.eq_ignore_ascii_case("ROLLUP");
17254 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
17255 if is_grouping_func {
17256 true
17257 } else {
17258 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
17260 for arg in &func.args {
17261 let mut temp_gen = Generator::with_arc_config(self.config.clone());
17262 Arc::make_mut(&mut temp_gen.config).pretty = false; temp_gen.generate_expression(arg)?;
17264 expr_strings.push(temp_gen.output);
17265 }
17266 self.too_wide(&expr_strings)
17267 }
17268 } else {
17269 false
17270 };
17271
17272 if should_split {
17273 self.write_newline();
17275 self.indent_level += 1;
17276 for (i, arg) in func.args.iter().enumerate() {
17277 self.write_indent();
17278 self.generate_expression(arg)?;
17279 if i + 1 < func.args.len() {
17280 self.write(",");
17281 }
17282 self.write_newline();
17283 }
17284 self.indent_level -= 1;
17285 self.write_indent();
17286 } else {
17287 for (i, arg) in func.args.iter().enumerate() {
17289 if i > 0 {
17290 self.write(", ");
17291 }
17292 self.generate_expression(arg)?;
17293 }
17294 }
17295
17296 if use_brackets {
17297 self.write("]");
17298 } else {
17299 self.write(")");
17300 }
17301 if has_ordinality {
17303 self.write_space();
17304 self.write_keyword("WITH ORDINALITY");
17305 }
17306 for comment in &func.trailing_comments {
17308 self.write_space();
17309 self.write_formatted_comment(comment);
17310 }
17311 Ok(())
17312 }
17313
17314 fn generate_function_emits(&mut self, fe: &FunctionEmits) -> Result<()> {
17315 self.generate_expression(&fe.this)?;
17316 self.write_keyword(" EMITS ");
17317 self.generate_expression(&fe.emits)?;
17318 Ok(())
17319 }
17320
17321 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
17322 let mut normalized_name = self.normalize_func_name(&func.name);
17324
17325 if func.name.eq_ignore_ascii_case("MAX_BY") || func.name.eq_ignore_ascii_case("MIN_BY") {
17327 let is_max = func.name.eq_ignore_ascii_case("MAX_BY");
17328 match self.config.dialect {
17329 Some(DialectType::ClickHouse) => {
17330 normalized_name = if is_max {
17331 Cow::Borrowed("argMax")
17332 } else {
17333 Cow::Borrowed("argMin")
17334 };
17335 }
17336 Some(DialectType::DuckDB) => {
17337 normalized_name = if is_max {
17338 Cow::Borrowed("ARG_MAX")
17339 } else {
17340 Cow::Borrowed("ARG_MIN")
17341 };
17342 }
17343 _ => {}
17344 }
17345 }
17346 self.write(normalized_name.as_ref());
17347 self.write("(");
17348 if func.distinct {
17349 self.write_keyword("DISTINCT");
17350 self.write_space();
17351 }
17352
17353 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
17357 let needs_multi_arg_transform =
17358 func.distinct && is_count && func.args.len() > 1 && !self.config.multi_arg_distinct;
17359
17360 if needs_multi_arg_transform {
17361 self.write_keyword("CASE");
17363 for arg in &func.args {
17364 self.write_space();
17365 self.write_keyword("WHEN");
17366 self.write_space();
17367 self.generate_expression(arg)?;
17368 self.write_space();
17369 self.write_keyword("IS NULL THEN NULL");
17370 }
17371 self.write_space();
17372 self.write_keyword("ELSE");
17373 self.write(" (");
17374 for (i, arg) in func.args.iter().enumerate() {
17375 if i > 0 {
17376 self.write(", ");
17377 }
17378 self.generate_expression(arg)?;
17379 }
17380 self.write(")");
17381 self.write_space();
17382 self.write_keyword("END");
17383 } else {
17384 for (i, arg) in func.args.iter().enumerate() {
17385 if i > 0 {
17386 self.write(", ");
17387 }
17388 self.generate_expression(arg)?;
17389 }
17390 }
17391
17392 if self.config.ignore_nulls_in_func
17394 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17395 {
17396 if let Some(ignore) = func.ignore_nulls {
17397 self.write_space();
17398 if ignore {
17399 self.write_keyword("IGNORE NULLS");
17400 } else {
17401 self.write_keyword("RESPECT NULLS");
17402 }
17403 }
17404 }
17405
17406 if !func.order_by.is_empty() {
17408 self.write_space();
17409 self.write_keyword("ORDER BY");
17410 self.write_space();
17411 for (i, ord) in func.order_by.iter().enumerate() {
17412 if i > 0 {
17413 self.write(", ");
17414 }
17415 self.generate_ordered(ord)?;
17416 }
17417 }
17418
17419 if let Some(limit) = &func.limit {
17421 self.write_space();
17422 self.write_keyword("LIMIT");
17423 self.write_space();
17424 if let Expression::Tuple(t) = limit.as_ref() {
17426 if t.expressions.len() == 2 {
17427 self.generate_expression(&t.expressions[0])?;
17428 self.write(", ");
17429 self.generate_expression(&t.expressions[1])?;
17430 } else {
17431 self.generate_expression(limit)?;
17432 }
17433 } else {
17434 self.generate_expression(limit)?;
17435 }
17436 }
17437
17438 self.write(")");
17439
17440 if !self.config.ignore_nulls_in_func
17442 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
17443 {
17444 if let Some(ignore) = func.ignore_nulls {
17445 self.write_space();
17446 if ignore {
17447 self.write_keyword("IGNORE NULLS");
17448 } else {
17449 self.write_keyword("RESPECT NULLS");
17450 }
17451 }
17452 }
17453
17454 if let Some(filter) = &func.filter {
17455 self.write_space();
17456 self.write_keyword("FILTER");
17457 self.write("(");
17458 self.write_keyword("WHERE");
17459 self.write_space();
17460 self.generate_expression(filter)?;
17461 self.write(")");
17462 }
17463
17464 Ok(())
17465 }
17466
17467 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
17468 self.generate_expression(&wf.this)?;
17469
17470 if let Some(keep) = &wf.keep {
17472 self.write_space();
17473 self.write_keyword("KEEP");
17474 self.write(" (");
17475 self.write_keyword("DENSE_RANK");
17476 self.write_space();
17477 if keep.first {
17478 self.write_keyword("FIRST");
17479 } else {
17480 self.write_keyword("LAST");
17481 }
17482 self.write_space();
17483 self.write_keyword("ORDER BY");
17484 self.write_space();
17485 for (i, ord) in keep.order_by.iter().enumerate() {
17486 if i > 0 {
17487 self.write(", ");
17488 }
17489 self.generate_ordered(ord)?;
17490 }
17491 self.write(")");
17492 }
17493
17494 let has_over = !wf.over.partition_by.is_empty()
17496 || !wf.over.order_by.is_empty()
17497 || wf.over.frame.is_some()
17498 || wf.over.window_name.is_some();
17499
17500 if has_over {
17502 self.write_space();
17503 self.write_keyword("OVER");
17504
17505 let has_specs = !wf.over.partition_by.is_empty()
17507 || !wf.over.order_by.is_empty()
17508 || wf.over.frame.is_some();
17509
17510 if wf.over.window_name.is_some() && !has_specs {
17511 self.write_space();
17513 self.write(&wf.over.window_name.as_ref().unwrap().name);
17514 } else {
17515 self.write(" (");
17517 self.generate_over(&wf.over)?;
17518 self.write(")");
17519 }
17520 } else if wf.keep.is_none() {
17521 self.write_space();
17523 self.write_keyword("OVER");
17524 self.write(" ()");
17525 }
17526
17527 Ok(())
17528 }
17529
17530 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
17532 self.generate_expression(&wg.this)?;
17533 self.write_space();
17534 self.write_keyword("WITHIN GROUP");
17535 self.write(" (");
17536 self.write_keyword("ORDER BY");
17537 self.write_space();
17538 for (i, ord) in wg.order_by.iter().enumerate() {
17539 if i > 0 {
17540 self.write(", ");
17541 }
17542 self.generate_ordered(ord)?;
17543 }
17544 self.write(")");
17545 Ok(())
17546 }
17547
17548 fn generate_over(&mut self, over: &Over) -> Result<()> {
17550 let mut has_content = false;
17551
17552 if let Some(name) = &over.window_name {
17554 self.write(&name.name);
17555 has_content = true;
17556 }
17557
17558 if !over.partition_by.is_empty() {
17560 if has_content {
17561 self.write_space();
17562 }
17563 self.write_keyword("PARTITION BY");
17564 self.write_space();
17565 for (i, expr) in over.partition_by.iter().enumerate() {
17566 if i > 0 {
17567 self.write(", ");
17568 }
17569 self.generate_expression(expr)?;
17570 }
17571 has_content = true;
17572 }
17573
17574 if !over.order_by.is_empty() {
17576 if has_content {
17577 self.write_space();
17578 }
17579 self.write_keyword("ORDER BY");
17580 self.write_space();
17581 for (i, ordered) in over.order_by.iter().enumerate() {
17582 if i > 0 {
17583 self.write(", ");
17584 }
17585 self.generate_ordered(ordered)?;
17586 }
17587 has_content = true;
17588 }
17589
17590 if let Some(frame) = &over.frame {
17592 if has_content {
17593 self.write_space();
17594 }
17595 self.generate_window_frame(frame)?;
17596 }
17597
17598 Ok(())
17599 }
17600
17601 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
17602 let lowercase_frame = self.config.lowercase_window_frame_keywords;
17604
17605 if !lowercase_frame {
17607 if let Some(kind_text) = &frame.kind_text {
17608 self.write(kind_text);
17609 } else {
17610 match frame.kind {
17611 WindowFrameKind::Rows => self.write_keyword("ROWS"),
17612 WindowFrameKind::Range => self.write_keyword("RANGE"),
17613 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
17614 }
17615 }
17616 } else {
17617 match frame.kind {
17618 WindowFrameKind::Rows => self.write("rows"),
17619 WindowFrameKind::Range => self.write("range"),
17620 WindowFrameKind::Groups => self.write("groups"),
17621 }
17622 }
17623
17624 self.write_space();
17627 let should_normalize = self.config.normalize_window_frame_between
17628 && frame.end.is_none()
17629 && matches!(
17630 frame.start,
17631 WindowFrameBound::Preceding(_)
17632 | WindowFrameBound::Following(_)
17633 | WindowFrameBound::UnboundedPreceding
17634 | WindowFrameBound::UnboundedFollowing
17635 );
17636
17637 if let Some(end) = &frame.end {
17638 self.write_keyword("BETWEEN");
17640 self.write_space();
17641 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17642 self.write_space();
17643 self.write_keyword("AND");
17644 self.write_space();
17645 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
17646 } else if should_normalize {
17647 self.write_keyword("BETWEEN");
17649 self.write_space();
17650 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17651 self.write_space();
17652 self.write_keyword("AND");
17653 self.write_space();
17654 self.write_keyword("CURRENT ROW");
17655 } else {
17656 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
17658 }
17659
17660 if let Some(exclude) = &frame.exclude {
17662 self.write_space();
17663 self.write_keyword("EXCLUDE");
17664 self.write_space();
17665 match exclude {
17666 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
17667 WindowFrameExclude::Group => self.write_keyword("GROUP"),
17668 WindowFrameExclude::Ties => self.write_keyword("TIES"),
17669 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
17670 }
17671 }
17672
17673 Ok(())
17674 }
17675
17676 fn generate_window_frame_bound(
17677 &mut self,
17678 bound: &WindowFrameBound,
17679 side_text: Option<&str>,
17680 ) -> Result<()> {
17681 let lowercase_frame = self.config.lowercase_window_frame_keywords;
17683
17684 match bound {
17685 WindowFrameBound::CurrentRow => {
17686 self.write_keyword("CURRENT ROW");
17687 }
17688 WindowFrameBound::UnboundedPreceding => {
17689 self.write_keyword("UNBOUNDED");
17690 self.write_space();
17691 if lowercase_frame {
17692 self.write("preceding");
17693 } else if let Some(text) = side_text {
17694 self.write(text);
17695 } else {
17696 self.write_keyword("PRECEDING");
17697 }
17698 }
17699 WindowFrameBound::UnboundedFollowing => {
17700 self.write_keyword("UNBOUNDED");
17701 self.write_space();
17702 if lowercase_frame {
17703 self.write("following");
17704 } else if let Some(text) = side_text {
17705 self.write(text);
17706 } else {
17707 self.write_keyword("FOLLOWING");
17708 }
17709 }
17710 WindowFrameBound::Preceding(expr) => {
17711 self.generate_expression(expr)?;
17712 self.write_space();
17713 if lowercase_frame {
17714 self.write("preceding");
17715 } else if let Some(text) = side_text {
17716 self.write(text);
17717 } else {
17718 self.write_keyword("PRECEDING");
17719 }
17720 }
17721 WindowFrameBound::Following(expr) => {
17722 self.generate_expression(expr)?;
17723 self.write_space();
17724 if lowercase_frame {
17725 self.write("following");
17726 } else if let Some(text) = side_text {
17727 self.write(text);
17728 } else {
17729 self.write_keyword("FOLLOWING");
17730 }
17731 }
17732 WindowFrameBound::BarePreceding => {
17733 if lowercase_frame {
17734 self.write("preceding");
17735 } else if let Some(text) = side_text {
17736 self.write(text);
17737 } else {
17738 self.write_keyword("PRECEDING");
17739 }
17740 }
17741 WindowFrameBound::BareFollowing => {
17742 if lowercase_frame {
17743 self.write("following");
17744 } else if let Some(text) = side_text {
17745 self.write(text);
17746 } else {
17747 self.write_keyword("FOLLOWING");
17748 }
17749 }
17750 WindowFrameBound::Value(expr) => {
17751 self.generate_expression(expr)?;
17753 }
17754 }
17755 Ok(())
17756 }
17757
17758 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
17759 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
17762 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
17763 && !matches!(&interval.this, Some(Expression::Literal(_)));
17764
17765 if self.config.single_string_interval {
17768 if let (
17769 Some(Expression::Literal(lit)),
17770 Some(IntervalUnitSpec::Simple {
17771 ref unit,
17772 ref use_plural,
17773 }),
17774 ) = (&interval.this, &interval.unit)
17775 {
17776 if let Literal::String(ref val) = lit.as_ref() {
17777 self.write_keyword("INTERVAL");
17778 self.write_space();
17779 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17780 let unit_str = self.interval_unit_str(unit, effective_plural);
17781 self.write("'");
17782 self.write(val);
17783 self.write(" ");
17784 self.write(&unit_str);
17785 self.write("'");
17786 return Ok(());
17787 }
17788 }
17789 }
17790
17791 if !skip_interval_keyword {
17792 self.write_keyword("INTERVAL");
17793 }
17794
17795 if let Some(ref value) = interval.this {
17797 if !skip_interval_keyword {
17798 self.write_space();
17799 }
17800 let needs_parens = interval.unit.is_some()
17804 && matches!(
17805 value,
17806 Expression::Add(_)
17807 | Expression::Sub(_)
17808 | Expression::Mul(_)
17809 | Expression::Div(_)
17810 | Expression::Mod(_)
17811 | Expression::BitwiseAnd(_)
17812 | Expression::BitwiseOr(_)
17813 | Expression::BitwiseXor(_)
17814 );
17815 if needs_parens {
17816 self.write("(");
17817 }
17818 self.generate_expression(value)?;
17819 if needs_parens {
17820 self.write(")");
17821 }
17822 }
17823
17824 if let Some(ref unit_spec) = interval.unit {
17826 self.write_space();
17827 self.write_interval_unit_spec(unit_spec)?;
17828 }
17829
17830 Ok(())
17831 }
17832
17833 fn interval_unit_str(&self, unit: &IntervalUnit, use_plural: bool) -> &'static str {
17835 match (unit, use_plural) {
17836 (IntervalUnit::Year, false) => "YEAR",
17837 (IntervalUnit::Year, true) => "YEARS",
17838 (IntervalUnit::Quarter, false) => "QUARTER",
17839 (IntervalUnit::Quarter, true) => "QUARTERS",
17840 (IntervalUnit::Month, false) => "MONTH",
17841 (IntervalUnit::Month, true) => "MONTHS",
17842 (IntervalUnit::Week, false) => "WEEK",
17843 (IntervalUnit::Week, true) => "WEEKS",
17844 (IntervalUnit::Day, false) => "DAY",
17845 (IntervalUnit::Day, true) => "DAYS",
17846 (IntervalUnit::Hour, false) => "HOUR",
17847 (IntervalUnit::Hour, true) => "HOURS",
17848 (IntervalUnit::Minute, false) => "MINUTE",
17849 (IntervalUnit::Minute, true) => "MINUTES",
17850 (IntervalUnit::Second, false) => "SECOND",
17851 (IntervalUnit::Second, true) => "SECONDS",
17852 (IntervalUnit::Millisecond, false) => "MILLISECOND",
17853 (IntervalUnit::Millisecond, true) => "MILLISECONDS",
17854 (IntervalUnit::Microsecond, false) => "MICROSECOND",
17855 (IntervalUnit::Microsecond, true) => "MICROSECONDS",
17856 (IntervalUnit::Nanosecond, false) => "NANOSECOND",
17857 (IntervalUnit::Nanosecond, true) => "NANOSECONDS",
17858 }
17859 }
17860
17861 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
17862 match unit_spec {
17863 IntervalUnitSpec::Simple { unit, use_plural } => {
17864 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
17866 self.write_simple_interval_unit(unit, effective_plural);
17867 }
17868 IntervalUnitSpec::Span(span) => {
17869 self.write_simple_interval_unit(&span.this, false);
17870 self.write_space();
17871 self.write_keyword("TO");
17872 self.write_space();
17873 self.write_simple_interval_unit(&span.expression, false);
17874 }
17875 IntervalUnitSpec::ExprSpan(span) => {
17876 self.generate_expression(&span.this)?;
17878 self.write_space();
17879 self.write_keyword("TO");
17880 self.write_space();
17881 self.generate_expression(&span.expression)?;
17882 }
17883 IntervalUnitSpec::Expr(expr) => {
17884 self.generate_expression(expr)?;
17885 }
17886 }
17887 Ok(())
17888 }
17889
17890 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
17891 match (unit, use_plural) {
17893 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
17894 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
17895 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
17896 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
17897 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
17898 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
17899 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
17900 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
17901 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
17902 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
17903 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
17904 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
17905 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
17906 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
17907 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
17908 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
17909 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
17910 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
17911 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
17912 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
17913 (IntervalUnit::Nanosecond, false) => self.write_keyword("NANOSECOND"),
17914 (IntervalUnit::Nanosecond, true) => self.write_keyword("NANOSECONDS"),
17915 }
17916 }
17917
17918 fn write_redshift_date_part(&mut self, expr: &Expression) {
17921 let part_str = self.extract_date_part_string(expr);
17922 if let Some(part) = part_str {
17923 let normalized = self.normalize_date_part(&part);
17924 self.write_keyword(&normalized);
17925 } else {
17926 let _ = self.generate_expression(expr);
17928 }
17929 }
17930
17931 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
17934 let part_str = self.extract_date_part_string(expr);
17935 if let Some(part) = part_str {
17936 let normalized = self.normalize_date_part(&part);
17937 self.write("'");
17938 self.write(&normalized);
17939 self.write("'");
17940 } else {
17941 let _ = self.generate_expression(expr);
17943 }
17944 }
17945
17946 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
17948 match expr {
17949 Expression::Literal(lit)
17950 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
17951 {
17952 let crate::expressions::Literal::String(s) = lit.as_ref() else {
17953 unreachable!()
17954 };
17955 Some(s.clone())
17956 }
17957 Expression::Identifier(id) => Some(id.name.clone()),
17958 Expression::Column(col) if col.table.is_none() => {
17959 Some(col.name.name.clone())
17961 }
17962 _ => None,
17963 }
17964 }
17965
17966 fn normalize_date_part(&self, part: &str) -> String {
17969 let mut buf = [0u8; 64];
17970 let lower: &str = if part.len() <= 64 {
17971 for (i, b) in part.bytes().enumerate() {
17972 buf[i] = b.to_ascii_lowercase();
17973 }
17974 std::str::from_utf8(&buf[..part.len()]).unwrap_or(part)
17975 } else {
17976 return part.to_ascii_uppercase();
17977 };
17978 match lower {
17979 "day" | "days" | "d" => "DAY".to_string(),
17980 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
17981 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
17982 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
17983 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
17984 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
17985 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
17986 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
17987 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
17988 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
17989 _ => part.to_ascii_uppercase(),
17990 }
17991 }
17992
17993 fn write_datetime_field(&mut self, field: &DateTimeField) {
17994 match field {
17995 DateTimeField::Year => self.write_keyword("YEAR"),
17996 DateTimeField::Month => self.write_keyword("MONTH"),
17997 DateTimeField::Day => self.write_keyword("DAY"),
17998 DateTimeField::Hour => self.write_keyword("HOUR"),
17999 DateTimeField::Minute => self.write_keyword("MINUTE"),
18000 DateTimeField::Second => self.write_keyword("SECOND"),
18001 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
18002 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
18003 DateTimeField::DayOfWeek => {
18004 let name = match self.config.dialect {
18005 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
18006 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "WEEKDAY",
18007 _ => "DOW",
18008 };
18009 self.write_keyword(name);
18010 }
18011 DateTimeField::DayOfYear => {
18012 let name = match self.config.dialect {
18013 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
18014 _ => "DOY",
18015 };
18016 self.write_keyword(name);
18017 }
18018 DateTimeField::Week => self.write_keyword("WEEK"),
18019 DateTimeField::WeekWithModifier(modifier) => {
18020 self.write_keyword("WEEK");
18021 self.write("(");
18022 self.write(modifier);
18023 self.write(")");
18024 }
18025 DateTimeField::Quarter => self.write_keyword("QUARTER"),
18026 DateTimeField::Epoch => self.write_keyword("EPOCH"),
18027 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
18028 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
18029 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
18030 DateTimeField::Date => self.write_keyword("DATE"),
18031 DateTimeField::Time => self.write_keyword("TIME"),
18032 DateTimeField::Custom(name) => self.write(name),
18033 }
18034 }
18035
18036 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
18038 match field {
18039 DateTimeField::Year => self.write("year"),
18040 DateTimeField::Month => self.write("month"),
18041 DateTimeField::Day => self.write("day"),
18042 DateTimeField::Hour => self.write("hour"),
18043 DateTimeField::Minute => self.write("minute"),
18044 DateTimeField::Second => self.write("second"),
18045 DateTimeField::Millisecond => self.write("millisecond"),
18046 DateTimeField::Microsecond => self.write("microsecond"),
18047 DateTimeField::DayOfWeek => self.write("dow"),
18048 DateTimeField::DayOfYear => self.write("doy"),
18049 DateTimeField::Week => self.write("week"),
18050 DateTimeField::WeekWithModifier(modifier) => {
18051 self.write("week(");
18052 self.write(modifier);
18053 self.write(")");
18054 }
18055 DateTimeField::Quarter => self.write("quarter"),
18056 DateTimeField::Epoch => self.write("epoch"),
18057 DateTimeField::Timezone => self.write("timezone"),
18058 DateTimeField::TimezoneHour => self.write("timezone_hour"),
18059 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
18060 DateTimeField::Date => self.write("date"),
18061 DateTimeField::Time => self.write("time"),
18062 DateTimeField::Custom(name) => self.write(name),
18063 }
18064 }
18065
18066 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
18069 self.write_keyword(name);
18070 self.write("(");
18071 self.generate_expression(arg)?;
18072 self.write(")");
18073 Ok(())
18074 }
18075
18076 fn generate_unary_func(
18078 &mut self,
18079 default_name: &str,
18080 f: &crate::expressions::UnaryFunc,
18081 ) -> Result<()> {
18082 let name = f.original_name.as_deref().unwrap_or(default_name);
18083 self.write_keyword(name);
18084 self.write("(");
18085 self.generate_expression(&f.this)?;
18086 self.write(")");
18087 Ok(())
18088 }
18089
18090 fn generate_sqrt_cbrt(
18092 &mut self,
18093 f: &crate::expressions::UnaryFunc,
18094 func_name: &str,
18095 _op: &str,
18096 ) -> Result<()> {
18097 self.write_keyword(func_name);
18100 self.write("(");
18101 self.generate_expression(&f.this)?;
18102 self.write(")");
18103 Ok(())
18104 }
18105
18106 fn generate_binary_func(
18107 &mut self,
18108 name: &str,
18109 arg1: &Expression,
18110 arg2: &Expression,
18111 ) -> Result<()> {
18112 self.write_keyword(name);
18113 self.write("(");
18114 self.generate_expression(arg1)?;
18115 self.write(", ");
18116 self.generate_expression(arg2)?;
18117 self.write(")");
18118 Ok(())
18119 }
18120
18121 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
18125 let func_name = f.name.as_deref().unwrap_or("CHAR");
18127 self.write_keyword(func_name);
18128 self.write("(");
18129 for (i, arg) in f.args.iter().enumerate() {
18130 if i > 0 {
18131 self.write(", ");
18132 }
18133 self.generate_expression(arg)?;
18134 }
18135 if let Some(ref charset) = f.charset {
18136 self.write(" ");
18137 self.write_keyword("USING");
18138 self.write(" ");
18139 self.write(charset);
18140 }
18141 self.write(")");
18142 Ok(())
18143 }
18144
18145 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
18146 use crate::dialects::DialectType;
18147
18148 match self.config.dialect {
18149 Some(DialectType::Teradata) => {
18150 self.generate_expression(&f.this)?;
18152 self.write(" ** ");
18153 self.generate_expression(&f.expression)?;
18154 Ok(())
18155 }
18156 _ => {
18157 self.generate_binary_func("POWER", &f.this, &f.expression)
18159 }
18160 }
18161 }
18162
18163 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
18164 self.write_func_name(name);
18165 self.write("(");
18166 for (i, arg) in args.iter().enumerate() {
18167 if i > 0 {
18168 self.write(", ");
18169 }
18170 self.generate_expression(arg)?;
18171 }
18172 self.write(")");
18173 Ok(())
18174 }
18175
18176 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
18179 self.write_keyword("CONCAT_WS");
18180 self.write("(");
18181 self.generate_expression(&f.separator)?;
18182 for expr in &f.expressions {
18183 self.write(", ");
18184 self.generate_expression(expr)?;
18185 }
18186 self.write(")");
18187 Ok(())
18188 }
18189
18190 fn collect_concat_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18191 if let Expression::Concat(op) = expr {
18192 Self::collect_concat_operands(&op.left, out);
18193 Self::collect_concat_operands(&op.right, out);
18194 } else {
18195 out.push(expr);
18196 }
18197 }
18198
18199 fn generate_mysql_concat_from_concat(&mut self, op: &BinaryOp) -> Result<()> {
18200 let mut operands = Vec::new();
18201 Self::collect_concat_operands(&op.left, &mut operands);
18202 Self::collect_concat_operands(&op.right, &mut operands);
18203
18204 self.write_keyword("CONCAT");
18205 self.write("(");
18206 for (i, operand) in operands.iter().enumerate() {
18207 if i > 0 {
18208 self.write(", ");
18209 }
18210 self.generate_expression(operand)?;
18211 }
18212 self.write(")");
18213 Ok(())
18214 }
18215
18216 fn collect_dpipe_operands<'a>(expr: &'a Expression, out: &mut Vec<&'a Expression>) {
18217 if let Expression::DPipe(dpipe) = expr {
18218 Self::collect_dpipe_operands(&dpipe.this, out);
18219 Self::collect_dpipe_operands(&dpipe.expression, out);
18220 } else {
18221 out.push(expr);
18222 }
18223 }
18224
18225 fn generate_mysql_concat_from_dpipe(&mut self, e: &DPipe) -> Result<()> {
18226 let mut operands = Vec::new();
18227 Self::collect_dpipe_operands(&e.this, &mut operands);
18228 Self::collect_dpipe_operands(&e.expression, &mut operands);
18229
18230 self.write_keyword("CONCAT");
18231 self.write("(");
18232 for (i, operand) in operands.iter().enumerate() {
18233 if i > 0 {
18234 self.write(", ");
18235 }
18236 self.generate_expression(operand)?;
18237 }
18238 self.write(")");
18239 Ok(())
18240 }
18241
18242 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
18243 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
18245 if is_oracle {
18246 self.write_keyword("SUBSTR");
18247 } else {
18248 self.write_keyword("SUBSTRING");
18249 }
18250 self.write("(");
18251 self.generate_expression(&f.this)?;
18252 let force_from_for = matches!(self.config.dialect, Some(DialectType::PostgreSQL));
18254 let use_comma_syntax = matches!(
18256 self.config.dialect,
18257 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
18258 );
18259 if (f.from_for_syntax || force_from_for) && !use_comma_syntax {
18260 self.write_space();
18262 self.write_keyword("FROM");
18263 self.write_space();
18264 self.generate_expression(&f.start)?;
18265 if let Some(length) = &f.length {
18266 self.write_space();
18267 self.write_keyword("FOR");
18268 self.write_space();
18269 self.generate_expression(length)?;
18270 }
18271 } else {
18272 self.write(", ");
18274 self.generate_expression(&f.start)?;
18275 if let Some(length) = &f.length {
18276 self.write(", ");
18277 self.generate_expression(length)?;
18278 }
18279 }
18280 self.write(")");
18281 Ok(())
18282 }
18283
18284 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
18285 self.write_keyword("OVERLAY");
18286 self.write("(");
18287 self.generate_expression(&f.this)?;
18288 self.write_space();
18289 self.write_keyword("PLACING");
18290 self.write_space();
18291 self.generate_expression(&f.replacement)?;
18292 self.write_space();
18293 self.write_keyword("FROM");
18294 self.write_space();
18295 self.generate_expression(&f.from)?;
18296 if let Some(length) = &f.length {
18297 self.write_space();
18298 self.write_keyword("FOR");
18299 self.write_space();
18300 self.generate_expression(length)?;
18301 }
18302 self.write(")");
18303 Ok(())
18304 }
18305
18306 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
18307 if f.position_explicit && f.characters.is_none() {
18310 match f.position {
18311 TrimPosition::Leading => {
18312 self.write_keyword("LTRIM");
18313 self.write("(");
18314 self.generate_expression(&f.this)?;
18315 self.write(")");
18316 return Ok(());
18317 }
18318 TrimPosition::Trailing => {
18319 self.write_keyword("RTRIM");
18320 self.write("(");
18321 self.generate_expression(&f.this)?;
18322 self.write(")");
18323 return Ok(());
18324 }
18325 TrimPosition::Both => {
18326 }
18329 }
18330 }
18331
18332 self.write_keyword("TRIM");
18333 self.write("(");
18334 let force_standard = f.characters.is_some()
18337 && !f.sql_standard_syntax
18338 && matches!(
18339 self.config.dialect,
18340 Some(DialectType::Hive)
18341 | Some(DialectType::Spark)
18342 | Some(DialectType::Databricks)
18343 | Some(DialectType::ClickHouse)
18344 );
18345 let use_standard = (f.sql_standard_syntax || force_standard)
18346 && !(f.position_explicit
18347 && f.characters.is_none()
18348 && matches!(f.position, TrimPosition::Both));
18349 if use_standard {
18350 if f.position_explicit {
18353 match f.position {
18354 TrimPosition::Both => self.write_keyword("BOTH"),
18355 TrimPosition::Leading => self.write_keyword("LEADING"),
18356 TrimPosition::Trailing => self.write_keyword("TRAILING"),
18357 }
18358 self.write_space();
18359 }
18360 if let Some(chars) = &f.characters {
18361 self.generate_expression(chars)?;
18362 self.write_space();
18363 }
18364 self.write_keyword("FROM");
18365 self.write_space();
18366 self.generate_expression(&f.this)?;
18367 } else {
18368 self.generate_expression(&f.this)?;
18370 if let Some(chars) = &f.characters {
18371 self.write(", ");
18372 self.generate_expression(chars)?;
18373 }
18374 }
18375 self.write(")");
18376 Ok(())
18377 }
18378
18379 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
18380 self.write_keyword("REPLACE");
18381 self.write("(");
18382 self.generate_expression(&f.this)?;
18383 self.write(", ");
18384 self.generate_expression(&f.old)?;
18385 self.write(", ");
18386 self.generate_expression(&f.new)?;
18387 self.write(")");
18388 Ok(())
18389 }
18390
18391 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
18392 self.write_keyword(name);
18393 self.write("(");
18394 self.generate_expression(&f.this)?;
18395 self.write(", ");
18396 self.generate_expression(&f.length)?;
18397 self.write(")");
18398 Ok(())
18399 }
18400
18401 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
18402 self.write_keyword("REPEAT");
18403 self.write("(");
18404 self.generate_expression(&f.this)?;
18405 self.write(", ");
18406 self.generate_expression(&f.times)?;
18407 self.write(")");
18408 Ok(())
18409 }
18410
18411 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
18412 self.write_keyword(name);
18413 self.write("(");
18414 self.generate_expression(&f.this)?;
18415 self.write(", ");
18416 self.generate_expression(&f.length)?;
18417 if let Some(fill) = &f.fill {
18418 self.write(", ");
18419 self.generate_expression(fill)?;
18420 }
18421 self.write(")");
18422 Ok(())
18423 }
18424
18425 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
18426 self.write_keyword("SPLIT");
18427 self.write("(");
18428 self.generate_expression(&f.this)?;
18429 self.write(", ");
18430 self.generate_expression(&f.delimiter)?;
18431 self.write(")");
18432 Ok(())
18433 }
18434
18435 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
18436 use crate::dialects::DialectType;
18437 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
18439 self.generate_expression(&f.this)?;
18440 self.write(" ~ ");
18441 self.generate_expression(&f.pattern)?;
18442 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && f.flags.is_none() {
18443 self.generate_expression(&f.this)?;
18445 self.write_keyword(" REGEXP_LIKE ");
18446 self.generate_expression(&f.pattern)?;
18447 } else if matches!(
18448 self.config.dialect,
18449 Some(DialectType::SingleStore)
18450 | Some(DialectType::Spark)
18451 | Some(DialectType::Hive)
18452 | Some(DialectType::Databricks)
18453 ) && f.flags.is_none()
18454 {
18455 self.generate_expression(&f.this)?;
18457 self.write_keyword(" RLIKE ");
18458 self.generate_expression(&f.pattern)?;
18459 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
18460 self.write_keyword("REGEXP");
18462 self.write("(");
18463 self.generate_expression(&f.this)?;
18464 self.write(", ");
18465 self.generate_expression(&f.pattern)?;
18466 if let Some(flags) = &f.flags {
18467 self.write(", ");
18468 self.generate_expression(flags)?;
18469 }
18470 self.write(")");
18471 } else {
18472 self.write_keyword("REGEXP_LIKE");
18473 self.write("(");
18474 self.generate_expression(&f.this)?;
18475 self.write(", ");
18476 self.generate_expression(&f.pattern)?;
18477 if let Some(flags) = &f.flags {
18478 self.write(", ");
18479 self.generate_expression(flags)?;
18480 }
18481 self.write(")");
18482 }
18483 Ok(())
18484 }
18485
18486 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
18487 self.write_keyword("REGEXP_REPLACE");
18488 self.write("(");
18489 self.generate_expression(&f.this)?;
18490 self.write(", ");
18491 self.generate_expression(&f.pattern)?;
18492 self.write(", ");
18493 self.generate_expression(&f.replacement)?;
18494 if let Some(flags) = &f.flags {
18495 self.write(", ");
18496 self.generate_expression(flags)?;
18497 }
18498 self.write(")");
18499 Ok(())
18500 }
18501
18502 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
18503 self.write_keyword("REGEXP_EXTRACT");
18504 self.write("(");
18505 self.generate_expression(&f.this)?;
18506 self.write(", ");
18507 self.generate_expression(&f.pattern)?;
18508 if let Some(group) = &f.group {
18509 self.write(", ");
18510 self.generate_expression(group)?;
18511 }
18512 self.write(")");
18513 Ok(())
18514 }
18515
18516 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
18519 self.write_keyword("ROUND");
18520 self.write("(");
18521 self.generate_expression(&f.this)?;
18522 if let Some(decimals) = &f.decimals {
18523 self.write(", ");
18524 self.generate_expression(decimals)?;
18525 }
18526 self.write(")");
18527 Ok(())
18528 }
18529
18530 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
18531 self.write_keyword("FLOOR");
18532 self.write("(");
18533 self.generate_expression(&f.this)?;
18534 if let Some(to) = &f.to {
18536 self.write(" ");
18537 self.write_keyword("TO");
18538 self.write(" ");
18539 self.generate_expression(to)?;
18540 } else if let Some(scale) = &f.scale {
18541 self.write(", ");
18542 self.generate_expression(scale)?;
18543 }
18544 self.write(")");
18545 Ok(())
18546 }
18547
18548 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
18549 self.write_keyword("CEIL");
18550 self.write("(");
18551 self.generate_expression(&f.this)?;
18552 if let Some(to) = &f.to {
18554 self.write(" ");
18555 self.write_keyword("TO");
18556 self.write(" ");
18557 self.generate_expression(to)?;
18558 } else if let Some(decimals) = &f.decimals {
18559 self.write(", ");
18560 self.generate_expression(decimals)?;
18561 }
18562 self.write(")");
18563 Ok(())
18564 }
18565
18566 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
18567 use crate::expressions::Literal;
18568
18569 if let Some(base) = &f.base {
18570 if self.is_log_base_none() {
18573 if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "2"))
18574 {
18575 self.write_func_name("LOG2");
18576 self.write("(");
18577 self.generate_expression(&f.this)?;
18578 self.write(")");
18579 return Ok(());
18580 } else if matches!(base, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(s) if s == "10"))
18581 {
18582 self.write_func_name("LOG10");
18583 self.write("(");
18584 self.generate_expression(&f.this)?;
18585 self.write(")");
18586 return Ok(());
18587 }
18588 }
18590
18591 self.write_func_name("LOG");
18592 self.write("(");
18593 if self.is_log_value_first() {
18594 self.generate_expression(&f.this)?;
18596 self.write(", ");
18597 self.generate_expression(base)?;
18598 } else {
18599 self.generate_expression(base)?;
18601 self.write(", ");
18602 self.generate_expression(&f.this)?;
18603 }
18604 self.write(")");
18605 } else {
18606 self.write_func_name("LOG");
18608 self.write("(");
18609 self.generate_expression(&f.this)?;
18610 self.write(")");
18611 }
18612 Ok(())
18613 }
18614
18615 fn is_log_value_first(&self) -> bool {
18618 use crate::dialects::DialectType;
18619 matches!(
18620 self.config.dialect,
18621 Some(DialectType::BigQuery)
18622 | Some(DialectType::TSQL)
18623 | Some(DialectType::Tableau)
18624 | Some(DialectType::Fabric)
18625 )
18626 }
18627
18628 fn is_log_base_none(&self) -> bool {
18631 use crate::dialects::DialectType;
18632 matches!(
18633 self.config.dialect,
18634 Some(DialectType::Presto)
18635 | Some(DialectType::Trino)
18636 | Some(DialectType::ClickHouse)
18637 | Some(DialectType::Athena)
18638 )
18639 }
18640
18641 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
18644 self.write_keyword("CURRENT_TIME");
18645 if let Some(precision) = f.precision {
18646 self.write(&format!("({})", precision));
18647 } else if matches!(
18648 self.config.dialect,
18649 Some(crate::dialects::DialectType::MySQL)
18650 | Some(crate::dialects::DialectType::SingleStore)
18651 | Some(crate::dialects::DialectType::TiDB)
18652 ) {
18653 self.write("()");
18654 }
18655 Ok(())
18656 }
18657
18658 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
18659 use crate::dialects::DialectType;
18660
18661 if f.sysdate {
18663 match self.config.dialect {
18664 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
18665 self.write_keyword("SYSDATE");
18666 return Ok(());
18667 }
18668 Some(DialectType::Snowflake) => {
18669 self.write_keyword("SYSDATE");
18671 self.write("()");
18672 return Ok(());
18673 }
18674 _ => {
18675 }
18677 }
18678 }
18679
18680 self.write_keyword("CURRENT_TIMESTAMP");
18681 if let Some(precision) = f.precision {
18683 self.write(&format!("({})", precision));
18684 } else if matches!(
18685 self.config.dialect,
18686 Some(crate::dialects::DialectType::MySQL)
18687 | Some(crate::dialects::DialectType::SingleStore)
18688 | Some(crate::dialects::DialectType::TiDB)
18689 | Some(crate::dialects::DialectType::Spark)
18690 | Some(crate::dialects::DialectType::Hive)
18691 | Some(crate::dialects::DialectType::Databricks)
18692 | Some(crate::dialects::DialectType::ClickHouse)
18693 | Some(crate::dialects::DialectType::BigQuery)
18694 | Some(crate::dialects::DialectType::Snowflake)
18695 | Some(crate::dialects::DialectType::Exasol)
18696 ) {
18697 self.write("()");
18698 }
18699 Ok(())
18700 }
18701
18702 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
18703 if self.config.dialect == Some(DialectType::Exasol) {
18705 self.write_keyword("CONVERT_TZ");
18706 self.write("(");
18707 self.generate_expression(&f.this)?;
18708 self.write(", 'UTC', ");
18709 self.generate_expression(&f.zone)?;
18710 self.write(")");
18711 return Ok(());
18712 }
18713
18714 self.generate_expression(&f.this)?;
18715 self.write_space();
18716 self.write_keyword("AT TIME ZONE");
18717 self.write_space();
18718 self.generate_expression(&f.zone)?;
18719 Ok(())
18720 }
18721
18722 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
18723 use crate::dialects::DialectType;
18724
18725 let is_presto_like = matches!(
18728 self.config.dialect,
18729 Some(DialectType::Presto) | Some(DialectType::Trino)
18730 );
18731
18732 if is_presto_like {
18733 self.write_keyword(name);
18734 self.write("(");
18735 self.write("'");
18737 self.write_simple_interval_unit(&f.unit, false);
18738 self.write("'");
18739 self.write(", ");
18740 let needs_cast = !self.returns_integer_type(&f.interval);
18742 if needs_cast {
18743 self.write_keyword("CAST");
18744 self.write("(");
18745 }
18746 self.generate_expression(&f.interval)?;
18747 if needs_cast {
18748 self.write_space();
18749 self.write_keyword("AS");
18750 self.write_space();
18751 self.write_keyword("BIGINT");
18752 self.write(")");
18753 }
18754 self.write(", ");
18755 self.generate_expression(&f.this)?;
18756 self.write(")");
18757 } else {
18758 self.write_keyword(name);
18759 self.write("(");
18760 self.generate_expression(&f.this)?;
18761 self.write(", ");
18762 self.write_keyword("INTERVAL");
18763 self.write_space();
18764 self.generate_expression(&f.interval)?;
18765 self.write_space();
18766 self.write_simple_interval_unit(&f.unit, false); self.write(")");
18768 }
18769 Ok(())
18770 }
18771
18772 fn returns_integer_type(&self, expr: &Expression) -> bool {
18775 use crate::expressions::{DataType, Literal};
18776 match expr {
18777 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
18779 let Literal::Number(n) = lit.as_ref() else {
18780 unreachable!()
18781 };
18782 !n.contains('.')
18783 }
18784
18785 Expression::Floor(f) => self.returns_integer_type(&f.this),
18787
18788 Expression::Round(f) => {
18790 f.decimals.is_none() && self.returns_integer_type(&f.this)
18792 }
18793
18794 Expression::Sign(f) => self.returns_integer_type(&f.this),
18796
18797 Expression::Abs(f) => self.returns_integer_type(&f.this),
18799
18800 Expression::Mul(op) => {
18802 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18803 }
18804 Expression::Add(op) => {
18805 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18806 }
18807 Expression::Sub(op) => {
18808 self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right)
18809 }
18810 Expression::Mod(op) => self.returns_integer_type(&op.left),
18811
18812 Expression::Cast(c) => matches!(
18814 &c.to,
18815 DataType::BigInt { .. }
18816 | DataType::Int { .. }
18817 | DataType::SmallInt { .. }
18818 | DataType::TinyInt { .. }
18819 ),
18820
18821 Expression::Neg(op) => self.returns_integer_type(&op.this),
18823
18824 Expression::Paren(p) => self.returns_integer_type(&p.this),
18826
18827 _ => false,
18830 }
18831 }
18832
18833 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
18834 self.write_keyword("DATEDIFF");
18835 self.write("(");
18836 if let Some(unit) = &f.unit {
18837 self.write_simple_interval_unit(unit, false); self.write(", ");
18839 }
18840 self.generate_expression(&f.this)?;
18841 self.write(", ");
18842 self.generate_expression(&f.expression)?;
18843 self.write(")");
18844 Ok(())
18845 }
18846
18847 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
18848 self.write_keyword("DATE_TRUNC");
18849 self.write("('");
18850 self.write_datetime_field(&f.unit);
18851 self.write("', ");
18852 self.generate_expression(&f.this)?;
18853 self.write(")");
18854 Ok(())
18855 }
18856
18857 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
18858 use crate::dialects::DialectType;
18859 use crate::expressions::DateTimeField;
18860
18861 self.write_keyword("LAST_DAY");
18862 self.write("(");
18863 self.generate_expression(&f.this)?;
18864 if let Some(unit) = &f.unit {
18865 self.write(", ");
18866 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
18869 if let DateTimeField::WeekWithModifier(_) = unit {
18870 self.write_keyword("WEEK");
18871 } else {
18872 self.write_datetime_field(unit);
18873 }
18874 } else {
18875 self.write_datetime_field(unit);
18876 }
18877 }
18878 self.write(")");
18879 Ok(())
18880 }
18881
18882 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
18883 if matches!(
18885 self.config.dialect,
18886 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18887 ) {
18888 self.write_keyword("DATEPART");
18889 self.write("(");
18890 self.write_datetime_field(&f.field);
18891 self.write(", ");
18892 self.generate_expression(&f.this)?;
18893 self.write(")");
18894 return Ok(());
18895 }
18896 self.write_keyword("EXTRACT");
18897 self.write("(");
18898 if matches!(
18900 self.config.dialect,
18901 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
18902 ) {
18903 self.write_datetime_field_lower(&f.field);
18904 } else {
18905 self.write_datetime_field(&f.field);
18906 }
18907 self.write_space();
18908 self.write_keyword("FROM");
18909 self.write_space();
18910 self.generate_expression(&f.this)?;
18911 self.write(")");
18912 Ok(())
18913 }
18914
18915 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
18916 self.write_keyword("TO_DATE");
18917 self.write("(");
18918 self.generate_expression(&f.this)?;
18919 if let Some(format) = &f.format {
18920 self.write(", ");
18921 self.generate_expression(format)?;
18922 }
18923 self.write(")");
18924 Ok(())
18925 }
18926
18927 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
18928 self.write_keyword("TO_TIMESTAMP");
18929 self.write("(");
18930 self.generate_expression(&f.this)?;
18931 if let Some(format) = &f.format {
18932 self.write(", ");
18933 self.generate_expression(format)?;
18934 }
18935 self.write(")");
18936 Ok(())
18937 }
18938
18939 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
18942 use crate::dialects::DialectType;
18943
18944 if self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic) {
18946 self.write_keyword("CASE WHEN");
18947 self.write_space();
18948 self.generate_expression(&f.condition)?;
18949 self.write_space();
18950 self.write_keyword("THEN");
18951 self.write_space();
18952 self.generate_expression(&f.true_value)?;
18953 if let Some(false_val) = &f.false_value {
18954 self.write_space();
18955 self.write_keyword("ELSE");
18956 self.write_space();
18957 self.generate_expression(false_val)?;
18958 }
18959 self.write_space();
18960 self.write_keyword("END");
18961 return Ok(());
18962 }
18963
18964 if self.config.dialect == Some(DialectType::Exasol) {
18966 self.write_keyword("IF");
18967 self.write_space();
18968 self.generate_expression(&f.condition)?;
18969 self.write_space();
18970 self.write_keyword("THEN");
18971 self.write_space();
18972 self.generate_expression(&f.true_value)?;
18973 if let Some(false_val) = &f.false_value {
18974 self.write_space();
18975 self.write_keyword("ELSE");
18976 self.write_space();
18977 self.generate_expression(false_val)?;
18978 }
18979 self.write_space();
18980 self.write_keyword("ENDIF");
18981 return Ok(());
18982 }
18983
18984 let func_name = match self.config.dialect {
18986 Some(DialectType::Snowflake) => "IFF",
18987 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
18988 Some(DialectType::Drill) => "`IF`",
18989 _ => "IF",
18990 };
18991 self.write(func_name);
18992 self.write("(");
18993 self.generate_expression(&f.condition)?;
18994 self.write(", ");
18995 self.generate_expression(&f.true_value)?;
18996 if let Some(false_val) = &f.false_value {
18997 self.write(", ");
18998 self.generate_expression(false_val)?;
18999 }
19000 self.write(")");
19001 Ok(())
19002 }
19003
19004 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
19005 self.write_keyword("NVL2");
19006 self.write("(");
19007 self.generate_expression(&f.this)?;
19008 self.write(", ");
19009 self.generate_expression(&f.true_value)?;
19010 self.write(", ");
19011 self.generate_expression(&f.false_value)?;
19012 self.write(")");
19013 Ok(())
19014 }
19015
19016 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
19019 let count_name = match self.config.normalize_functions {
19021 NormalizeFunctions::Upper => "COUNT".to_string(),
19022 NormalizeFunctions::Lower => "count".to_string(),
19023 NormalizeFunctions::None => f
19024 .original_name
19025 .clone()
19026 .unwrap_or_else(|| "COUNT".to_string()),
19027 };
19028 self.write(&count_name);
19029 self.write("(");
19030 if f.distinct {
19031 self.write_keyword("DISTINCT");
19032 self.write_space();
19033 }
19034 if f.star {
19035 self.write("*");
19036 } else if let Some(ref expr) = f.this {
19037 if let Expression::Tuple(tuple) = expr {
19039 let needs_transform =
19043 f.distinct && tuple.expressions.len() > 1 && !self.config.multi_arg_distinct;
19044
19045 if needs_transform {
19046 self.write_keyword("CASE");
19048 for e in &tuple.expressions {
19049 self.write_space();
19050 self.write_keyword("WHEN");
19051 self.write_space();
19052 self.generate_expression(e)?;
19053 self.write_space();
19054 self.write_keyword("IS NULL THEN NULL");
19055 }
19056 self.write_space();
19057 self.write_keyword("ELSE");
19058 self.write(" (");
19059 for (i, e) in tuple.expressions.iter().enumerate() {
19060 if i > 0 {
19061 self.write(", ");
19062 }
19063 self.generate_expression(e)?;
19064 }
19065 self.write(")");
19066 self.write_space();
19067 self.write_keyword("END");
19068 } else {
19069 for (i, e) in tuple.expressions.iter().enumerate() {
19070 if i > 0 {
19071 self.write(", ");
19072 }
19073 self.generate_expression(e)?;
19074 }
19075 }
19076 } else {
19077 self.generate_expression(expr)?;
19078 }
19079 }
19080 if let Some(ignore) = f.ignore_nulls {
19082 self.write_space();
19083 if ignore {
19084 self.write_keyword("IGNORE NULLS");
19085 } else {
19086 self.write_keyword("RESPECT NULLS");
19087 }
19088 }
19089 self.write(")");
19090 if let Some(ref filter) = f.filter {
19091 self.write_space();
19092 self.write_keyword("FILTER");
19093 self.write("(");
19094 self.write_keyword("WHERE");
19095 self.write_space();
19096 self.generate_expression(filter)?;
19097 self.write(")");
19098 }
19099 Ok(())
19100 }
19101
19102 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19103 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19105 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19106 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19107 NormalizeFunctions::None => {
19108 if let Some(ref original) = f.name {
19111 Cow::Owned(original.clone())
19112 } else {
19113 Cow::Owned(name.to_ascii_lowercase())
19114 }
19115 }
19116 };
19117 self.write(func_name.as_ref());
19118 self.write("(");
19119 if f.distinct {
19120 self.write_keyword("DISTINCT");
19121 self.write_space();
19122 }
19123 if !matches!(f.this, Expression::Null(_)) {
19125 self.generate_expression(&f.this)?;
19126 }
19127 if self.config.ignore_nulls_in_func
19130 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19131 {
19132 match f.ignore_nulls {
19133 Some(true) => {
19134 self.write_space();
19135 self.write_keyword("IGNORE NULLS");
19136 }
19137 Some(false) => {
19138 self.write_space();
19139 self.write_keyword("RESPECT NULLS");
19140 }
19141 None => {}
19142 }
19143 }
19144 if let Some((ref expr, is_max)) = f.having_max {
19147 self.write_space();
19148 self.write_keyword("HAVING");
19149 self.write_space();
19150 if is_max {
19151 self.write_keyword("MAX");
19152 } else {
19153 self.write_keyword("MIN");
19154 }
19155 self.write_space();
19156 self.generate_expression(expr)?;
19157 }
19158 if !f.order_by.is_empty() {
19160 self.write_space();
19161 self.write_keyword("ORDER BY");
19162 self.write_space();
19163 for (i, ord) in f.order_by.iter().enumerate() {
19164 if i > 0 {
19165 self.write(", ");
19166 }
19167 self.generate_ordered(ord)?;
19168 }
19169 }
19170 if let Some(ref limit) = f.limit {
19172 self.write_space();
19173 self.write_keyword("LIMIT");
19174 self.write_space();
19175 if let Expression::Tuple(t) = limit.as_ref() {
19177 if t.expressions.len() == 2 {
19178 self.generate_expression(&t.expressions[0])?;
19179 self.write(", ");
19180 self.generate_expression(&t.expressions[1])?;
19181 } else {
19182 self.generate_expression(limit)?;
19183 }
19184 } else {
19185 self.generate_expression(limit)?;
19186 }
19187 }
19188 self.write(")");
19189 if !self.config.ignore_nulls_in_func
19192 && !matches!(self.config.dialect, Some(DialectType::DuckDB))
19193 {
19194 match f.ignore_nulls {
19195 Some(true) => {
19196 self.write_space();
19197 self.write_keyword("IGNORE NULLS");
19198 }
19199 Some(false) => {
19200 self.write_space();
19201 self.write_keyword("RESPECT NULLS");
19202 }
19203 None => {}
19204 }
19205 }
19206 if let Some(ref filter) = f.filter {
19207 self.write_space();
19208 self.write_keyword("FILTER");
19209 self.write("(");
19210 self.write_keyword("WHERE");
19211 self.write_space();
19212 self.generate_expression(filter)?;
19213 self.write(")");
19214 }
19215 Ok(())
19216 }
19217
19218 fn generate_agg_func_with_ignore_nulls_bool(&mut self, name: &str, f: &AggFunc) -> Result<()> {
19221 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19223 let func_name: Cow<'_, str> = match self.config.normalize_functions {
19225 NormalizeFunctions::Upper => Cow::Owned(name.to_ascii_uppercase()),
19226 NormalizeFunctions::Lower => Cow::Owned(name.to_ascii_lowercase()),
19227 NormalizeFunctions::None => {
19228 if let Some(ref original) = f.name {
19229 Cow::Owned(original.clone())
19230 } else {
19231 Cow::Owned(name.to_ascii_lowercase())
19232 }
19233 }
19234 };
19235 self.write(func_name.as_ref());
19236 self.write("(");
19237 if f.distinct {
19238 self.write_keyword("DISTINCT");
19239 self.write_space();
19240 }
19241 if !matches!(f.this, Expression::Null(_)) {
19242 self.generate_expression(&f.this)?;
19243 }
19244 self.write(", ");
19245 self.write_keyword("TRUE");
19246 self.write(")");
19247 return Ok(());
19248 }
19249 self.generate_agg_func(name, f)
19250 }
19251
19252 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
19253 self.write_keyword("GROUP_CONCAT");
19254 self.write("(");
19255 if f.distinct {
19256 self.write_keyword("DISTINCT");
19257 self.write_space();
19258 }
19259 self.generate_expression(&f.this)?;
19260 if let Some(ref order_by) = f.order_by {
19261 self.write_space();
19262 self.write_keyword("ORDER BY");
19263 self.write_space();
19264 for (i, ord) in order_by.iter().enumerate() {
19265 if i > 0 {
19266 self.write(", ");
19267 }
19268 self.generate_ordered(ord)?;
19269 }
19270 }
19271 if let Some(ref sep) = f.separator {
19272 if matches!(
19275 self.config.dialect,
19276 Some(crate::dialects::DialectType::SQLite)
19277 ) {
19278 self.write(", ");
19279 self.generate_expression(sep)?;
19280 } else {
19281 self.write_space();
19282 self.write_keyword("SEPARATOR");
19283 self.write_space();
19284 self.generate_expression(sep)?;
19285 }
19286 }
19287 self.write(")");
19288 if let Some(ref filter) = f.filter {
19289 self.write_space();
19290 self.write_keyword("FILTER");
19291 self.write("(");
19292 self.write_keyword("WHERE");
19293 self.write_space();
19294 self.generate_expression(filter)?;
19295 self.write(")");
19296 }
19297 Ok(())
19298 }
19299
19300 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
19301 let is_tsql = matches!(
19302 self.config.dialect,
19303 Some(crate::dialects::DialectType::TSQL)
19304 );
19305 self.write_keyword("STRING_AGG");
19306 self.write("(");
19307 if f.distinct {
19308 self.write_keyword("DISTINCT");
19309 self.write_space();
19310 }
19311 self.generate_expression(&f.this)?;
19312 if let Some(ref separator) = f.separator {
19313 self.write(", ");
19314 self.generate_expression(separator)?;
19315 }
19316 if !is_tsql {
19318 if let Some(ref order_by) = f.order_by {
19319 self.write_space();
19320 self.write_keyword("ORDER BY");
19321 self.write_space();
19322 for (i, ord) in order_by.iter().enumerate() {
19323 if i > 0 {
19324 self.write(", ");
19325 }
19326 self.generate_ordered(ord)?;
19327 }
19328 }
19329 }
19330 if let Some(ref limit) = f.limit {
19331 self.write_space();
19332 self.write_keyword("LIMIT");
19333 self.write_space();
19334 self.generate_expression(limit)?;
19335 }
19336 self.write(")");
19337 if is_tsql {
19339 if let Some(ref order_by) = f.order_by {
19340 self.write_space();
19341 self.write_keyword("WITHIN GROUP");
19342 self.write(" (");
19343 self.write_keyword("ORDER BY");
19344 self.write_space();
19345 for (i, ord) in order_by.iter().enumerate() {
19346 if i > 0 {
19347 self.write(", ");
19348 }
19349 self.generate_ordered(ord)?;
19350 }
19351 self.write(")");
19352 }
19353 }
19354 if let Some(ref filter) = f.filter {
19355 self.write_space();
19356 self.write_keyword("FILTER");
19357 self.write("(");
19358 self.write_keyword("WHERE");
19359 self.write_space();
19360 self.generate_expression(filter)?;
19361 self.write(")");
19362 }
19363 Ok(())
19364 }
19365
19366 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
19367 use crate::dialects::DialectType;
19368 self.write_keyword("LISTAGG");
19369 self.write("(");
19370 if f.distinct {
19371 self.write_keyword("DISTINCT");
19372 self.write_space();
19373 }
19374 self.generate_expression(&f.this)?;
19375 if let Some(ref sep) = f.separator {
19376 self.write(", ");
19377 self.generate_expression(sep)?;
19378 } else if matches!(
19379 self.config.dialect,
19380 Some(DialectType::Trino) | Some(DialectType::Presto)
19381 ) {
19382 self.write(", ','");
19384 }
19385 if let Some(ref overflow) = f.on_overflow {
19386 self.write_space();
19387 self.write_keyword("ON OVERFLOW");
19388 self.write_space();
19389 match overflow {
19390 ListAggOverflow::Error => self.write_keyword("ERROR"),
19391 ListAggOverflow::Truncate { filler, with_count } => {
19392 self.write_keyword("TRUNCATE");
19393 if let Some(ref fill) = filler {
19394 self.write_space();
19395 self.generate_expression(fill)?;
19396 }
19397 if *with_count {
19398 self.write_space();
19399 self.write_keyword("WITH COUNT");
19400 } else {
19401 self.write_space();
19402 self.write_keyword("WITHOUT COUNT");
19403 }
19404 }
19405 }
19406 }
19407 self.write(")");
19408 if let Some(ref order_by) = f.order_by {
19409 self.write_space();
19410 self.write_keyword("WITHIN GROUP");
19411 self.write(" (");
19412 self.write_keyword("ORDER BY");
19413 self.write_space();
19414 for (i, ord) in order_by.iter().enumerate() {
19415 if i > 0 {
19416 self.write(", ");
19417 }
19418 self.generate_ordered(ord)?;
19419 }
19420 self.write(")");
19421 }
19422 if let Some(ref filter) = f.filter {
19423 self.write_space();
19424 self.write_keyword("FILTER");
19425 self.write("(");
19426 self.write_keyword("WHERE");
19427 self.write_space();
19428 self.generate_expression(filter)?;
19429 self.write(")");
19430 }
19431 Ok(())
19432 }
19433
19434 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
19435 self.write_keyword("SUM_IF");
19436 self.write("(");
19437 self.generate_expression(&f.this)?;
19438 self.write(", ");
19439 self.generate_expression(&f.condition)?;
19440 self.write(")");
19441 if let Some(ref filter) = f.filter {
19442 self.write_space();
19443 self.write_keyword("FILTER");
19444 self.write("(");
19445 self.write_keyword("WHERE");
19446 self.write_space();
19447 self.generate_expression(filter)?;
19448 self.write(")");
19449 }
19450 Ok(())
19451 }
19452
19453 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
19454 self.write_keyword("APPROX_PERCENTILE");
19455 self.write("(");
19456 self.generate_expression(&f.this)?;
19457 self.write(", ");
19458 self.generate_expression(&f.percentile)?;
19459 if let Some(ref acc) = f.accuracy {
19460 self.write(", ");
19461 self.generate_expression(acc)?;
19462 }
19463 self.write(")");
19464 if let Some(ref filter) = f.filter {
19465 self.write_space();
19466 self.write_keyword("FILTER");
19467 self.write("(");
19468 self.write_keyword("WHERE");
19469 self.write_space();
19470 self.generate_expression(filter)?;
19471 self.write(")");
19472 }
19473 Ok(())
19474 }
19475
19476 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
19477 self.write_keyword(name);
19478 self.write("(");
19479 self.generate_expression(&f.percentile)?;
19480 self.write(")");
19481 if let Some(ref order_by) = f.order_by {
19482 self.write_space();
19483 self.write_keyword("WITHIN GROUP");
19484 self.write(" (");
19485 self.write_keyword("ORDER BY");
19486 self.write_space();
19487 self.generate_expression(&f.this)?;
19488 for ord in order_by.iter() {
19489 if ord.desc {
19490 self.write_space();
19491 self.write_keyword("DESC");
19492 }
19493 }
19494 self.write(")");
19495 }
19496 if let Some(ref filter) = f.filter {
19497 self.write_space();
19498 self.write_keyword("FILTER");
19499 self.write("(");
19500 self.write_keyword("WHERE");
19501 self.write_space();
19502 self.generate_expression(filter)?;
19503 self.write(")");
19504 }
19505 Ok(())
19506 }
19507
19508 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
19511 self.write_keyword("NTILE");
19512 self.write("(");
19513 if let Some(num_buckets) = &f.num_buckets {
19514 self.generate_expression(num_buckets)?;
19515 }
19516 if let Some(order_by) = &f.order_by {
19517 self.write_keyword(" ORDER BY ");
19518 for (i, ob) in order_by.iter().enumerate() {
19519 if i > 0 {
19520 self.write(", ");
19521 }
19522 self.generate_ordered(ob)?;
19523 }
19524 }
19525 self.write(")");
19526 Ok(())
19527 }
19528
19529 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
19530 self.write_keyword(name);
19531 self.write("(");
19532 self.generate_expression(&f.this)?;
19533 if let Some(ref offset) = f.offset {
19534 self.write(", ");
19535 self.generate_expression(offset)?;
19536 if let Some(ref default) = f.default {
19537 self.write(", ");
19538 self.generate_expression(default)?;
19539 }
19540 }
19541 if self.config.ignore_nulls_in_func {
19543 match f.ignore_nulls {
19544 Some(true) => {
19545 self.write_space();
19546 self.write_keyword("IGNORE NULLS");
19547 }
19548 Some(false) => {
19549 self.write_space();
19550 self.write_keyword("RESPECT NULLS");
19551 }
19552 None => {}
19553 }
19554 }
19555 self.write(")");
19556 if !self.config.ignore_nulls_in_func {
19558 match f.ignore_nulls {
19559 Some(true) => {
19560 self.write_space();
19561 self.write_keyword("IGNORE NULLS");
19562 }
19563 Some(false) => {
19564 self.write_space();
19565 self.write_keyword("RESPECT NULLS");
19566 }
19567 None => {}
19568 }
19569 }
19570 Ok(())
19571 }
19572
19573 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
19574 self.write_keyword(name);
19575 self.write("(");
19576 self.generate_expression(&f.this)?;
19577 if !f.order_by.is_empty() {
19579 self.write_space();
19580 self.write_keyword("ORDER BY");
19581 self.write_space();
19582 for (i, ordered) in f.order_by.iter().enumerate() {
19583 if i > 0 {
19584 self.write(", ");
19585 }
19586 self.generate_ordered(ordered)?;
19587 }
19588 }
19589 if self.config.ignore_nulls_in_func {
19591 match f.ignore_nulls {
19592 Some(true) => {
19593 self.write_space();
19594 self.write_keyword("IGNORE NULLS");
19595 }
19596 Some(false) => {
19597 self.write_space();
19598 self.write_keyword("RESPECT NULLS");
19599 }
19600 None => {}
19601 }
19602 }
19603 self.write(")");
19604 if !self.config.ignore_nulls_in_func {
19606 match f.ignore_nulls {
19607 Some(true) => {
19608 self.write_space();
19609 self.write_keyword("IGNORE NULLS");
19610 }
19611 Some(false) => {
19612 self.write_space();
19613 self.write_keyword("RESPECT NULLS");
19614 }
19615 None => {}
19616 }
19617 }
19618 Ok(())
19619 }
19620
19621 fn generate_value_func_with_ignore_nulls_bool(
19624 &mut self,
19625 name: &str,
19626 f: &ValueFunc,
19627 ) -> Result<()> {
19628 if matches!(self.config.dialect, Some(DialectType::Hive)) && f.ignore_nulls == Some(true) {
19629 self.write_keyword(name);
19630 self.write("(");
19631 self.generate_expression(&f.this)?;
19632 self.write(", ");
19633 self.write_keyword("TRUE");
19634 self.write(")");
19635 return Ok(());
19636 }
19637 self.generate_value_func(name, f)
19638 }
19639
19640 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
19641 self.write_keyword("NTH_VALUE");
19642 self.write("(");
19643 self.generate_expression(&f.this)?;
19644 self.write(", ");
19645 self.generate_expression(&f.offset)?;
19646 if self.config.ignore_nulls_in_func {
19648 match f.ignore_nulls {
19649 Some(true) => {
19650 self.write_space();
19651 self.write_keyword("IGNORE NULLS");
19652 }
19653 Some(false) => {
19654 self.write_space();
19655 self.write_keyword("RESPECT NULLS");
19656 }
19657 None => {}
19658 }
19659 }
19660 self.write(")");
19661 if matches!(
19663 self.config.dialect,
19664 Some(crate::dialects::DialectType::Snowflake)
19665 ) {
19666 match f.from_first {
19667 Some(true) => {
19668 self.write_space();
19669 self.write_keyword("FROM FIRST");
19670 }
19671 Some(false) => {
19672 self.write_space();
19673 self.write_keyword("FROM LAST");
19674 }
19675 None => {}
19676 }
19677 }
19678 if !self.config.ignore_nulls_in_func {
19680 match f.ignore_nulls {
19681 Some(true) => {
19682 self.write_space();
19683 self.write_keyword("IGNORE NULLS");
19684 }
19685 Some(false) => {
19686 self.write_space();
19687 self.write_keyword("RESPECT NULLS");
19688 }
19689 None => {}
19690 }
19691 }
19692 Ok(())
19693 }
19694
19695 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
19698 if matches!(
19701 self.config.dialect,
19702 Some(crate::dialects::DialectType::ClickHouse)
19703 ) {
19704 self.write_keyword("POSITION");
19705 self.write("(");
19706 self.generate_expression(&f.string)?;
19707 self.write(", ");
19708 self.generate_expression(&f.substring)?;
19709 if let Some(ref start) = f.start {
19710 self.write(", ");
19711 self.generate_expression(start)?;
19712 }
19713 self.write(")");
19714 return Ok(());
19715 }
19716
19717 self.write_keyword("POSITION");
19718 self.write("(");
19719 self.generate_expression(&f.substring)?;
19720 self.write_space();
19721 self.write_keyword("IN");
19722 self.write_space();
19723 self.generate_expression(&f.string)?;
19724 if let Some(ref start) = f.start {
19725 self.write(", ");
19726 self.generate_expression(start)?;
19727 }
19728 self.write(")");
19729 Ok(())
19730 }
19731
19732 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
19735 if f.lower.is_some() || f.upper.is_some() {
19737 self.write_keyword("RANDOM");
19738 self.write("(");
19739 if let Some(ref lower) = f.lower {
19740 self.generate_expression(lower)?;
19741 }
19742 if let Some(ref upper) = f.upper {
19743 self.write(", ");
19744 self.generate_expression(upper)?;
19745 }
19746 self.write(")");
19747 return Ok(());
19748 }
19749 let func_name = match self.config.dialect {
19751 Some(crate::dialects::DialectType::Snowflake)
19752 | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
19753 _ => "RAND",
19754 };
19755 self.write_keyword(func_name);
19756 self.write("(");
19757 if !matches!(
19759 self.config.dialect,
19760 Some(crate::dialects::DialectType::DuckDB)
19761 ) {
19762 if let Some(ref seed) = f.seed {
19763 self.generate_expression(seed)?;
19764 }
19765 }
19766 self.write(")");
19767 Ok(())
19768 }
19769
19770 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
19771 self.write_keyword("TRUNCATE");
19772 self.write("(");
19773 self.generate_expression(&f.this)?;
19774 if let Some(ref decimals) = f.decimals {
19775 self.write(", ");
19776 self.generate_expression(decimals)?;
19777 }
19778 self.write(")");
19779 Ok(())
19780 }
19781
19782 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
19785 self.write_keyword("DECODE");
19786 self.write("(");
19787 self.generate_expression(&f.this)?;
19788 for (search, result) in &f.search_results {
19789 self.write(", ");
19790 self.generate_expression(search)?;
19791 self.write(", ");
19792 self.generate_expression(result)?;
19793 }
19794 if let Some(ref default) = f.default {
19795 self.write(", ");
19796 self.generate_expression(default)?;
19797 }
19798 self.write(")");
19799 Ok(())
19800 }
19801
19802 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
19805 self.write_keyword(name);
19806 self.write("(");
19807 self.generate_expression(&f.this)?;
19808 self.write(", ");
19809 self.generate_expression(&f.format)?;
19810 self.write(")");
19811 Ok(())
19812 }
19813
19814 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
19815 self.write_keyword("FROM_UNIXTIME");
19816 self.write("(");
19817 self.generate_expression(&f.this)?;
19818 if let Some(ref format) = f.format {
19819 self.write(", ");
19820 self.generate_expression(format)?;
19821 }
19822 self.write(")");
19823 Ok(())
19824 }
19825
19826 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
19827 self.write_keyword("UNIX_TIMESTAMP");
19828 self.write("(");
19829 if let Some(ref expr) = f.this {
19830 self.generate_expression(expr)?;
19831 if let Some(ref format) = f.format {
19832 self.write(", ");
19833 self.generate_expression(format)?;
19834 }
19835 } else if matches!(
19836 self.config.dialect,
19837 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
19838 ) {
19839 self.write_keyword("CURRENT_TIMESTAMP");
19841 self.write("()");
19842 }
19843 self.write(")");
19844 Ok(())
19845 }
19846
19847 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
19848 self.write_keyword("MAKE_DATE");
19849 self.write("(");
19850 self.generate_expression(&f.year)?;
19851 self.write(", ");
19852 self.generate_expression(&f.month)?;
19853 self.write(", ");
19854 self.generate_expression(&f.day)?;
19855 self.write(")");
19856 Ok(())
19857 }
19858
19859 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
19860 self.write_keyword("MAKE_TIMESTAMP");
19861 self.write("(");
19862 self.generate_expression(&f.year)?;
19863 self.write(", ");
19864 self.generate_expression(&f.month)?;
19865 self.write(", ");
19866 self.generate_expression(&f.day)?;
19867 self.write(", ");
19868 self.generate_expression(&f.hour)?;
19869 self.write(", ");
19870 self.generate_expression(&f.minute)?;
19871 self.write(", ");
19872 self.generate_expression(&f.second)?;
19873 if let Some(ref tz) = f.timezone {
19874 self.write(", ");
19875 self.generate_expression(tz)?;
19876 }
19877 self.write(")");
19878 Ok(())
19879 }
19880
19881 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
19883 match expr {
19884 Expression::Struct(s) => {
19885 if s.fields.iter().all(|(name, _)| name.is_some()) {
19886 Some(
19887 s.fields
19888 .iter()
19889 .map(|(name, _)| name.as_deref().unwrap_or("").to_string())
19890 .collect(),
19891 )
19892 } else {
19893 None
19894 }
19895 }
19896 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
19897 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
19899 Some(
19900 f.args
19901 .iter()
19902 .filter_map(|a| {
19903 if let Expression::Alias(alias) = a {
19904 Some(alias.alias.name.clone())
19905 } else {
19906 None
19907 }
19908 })
19909 .collect(),
19910 )
19911 } else {
19912 None
19913 }
19914 }
19915 _ => None,
19916 }
19917 }
19918
19919 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
19921 match expr {
19922 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
19923 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
19924 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
19925 }
19926 _ => false,
19927 }
19928 }
19929
19930 fn struct_field_count(expr: &Expression) -> usize {
19932 match expr {
19933 Expression::Struct(s) => s.fields.len(),
19934 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => f.args.len(),
19935 _ => 0,
19936 }
19937 }
19938
19939 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
19941 match expr {
19942 Expression::Struct(s) => {
19943 let mut new_fields = Vec::with_capacity(s.fields.len());
19944 for (i, (name, value)) in s.fields.iter().enumerate() {
19945 if name.is_none() && i < field_names.len() {
19946 new_fields.push((Some(field_names[i].clone()), value.clone()));
19947 } else {
19948 new_fields.push((name.clone(), value.clone()));
19949 }
19950 }
19951 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
19952 }
19953 Expression::Function(f) if f.name.eq_ignore_ascii_case("STRUCT") => {
19954 let mut new_args = Vec::with_capacity(f.args.len());
19955 for (i, arg) in f.args.iter().enumerate() {
19956 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
19957 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
19959 this: arg.clone(),
19960 alias: crate::expressions::Identifier::new(field_names[i].clone()),
19961 column_aliases: Vec::new(),
19962 pre_alias_comments: Vec::new(),
19963 trailing_comments: Vec::new(),
19964 inferred_type: None,
19965 })));
19966 } else {
19967 new_args.push(arg.clone());
19968 }
19969 }
19970 Expression::Function(Box::new(crate::expressions::Function {
19971 name: f.name.clone(),
19972 args: new_args,
19973 distinct: f.distinct,
19974 trailing_comments: f.trailing_comments.clone(),
19975 use_bracket_syntax: f.use_bracket_syntax,
19976 no_parens: f.no_parens,
19977 quoted: f.quoted,
19978 span: None,
19979 inferred_type: None,
19980 }))
19981 }
19982 _ => expr.clone(),
19983 }
19984 }
19985
19986 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
19990 let first = match expressions.first() {
19991 Some(e) => e,
19992 None => return expressions.to_vec(),
19993 };
19994
19995 let field_names = match Self::extract_struct_field_names(first) {
19996 Some(names) if !names.is_empty() => names,
19997 _ => return expressions.to_vec(),
19998 };
19999
20000 let mut result = Vec::with_capacity(expressions.len());
20001 for (idx, expr) in expressions.iter().enumerate() {
20002 if idx == 0 {
20003 result.push(expr.clone());
20004 continue;
20005 }
20006 if Self::struct_field_count(expr) == field_names.len()
20008 && Self::struct_has_unnamed_fields(expr)
20009 {
20010 result.push(Self::apply_struct_field_names(expr, &field_names));
20011 } else {
20012 result.push(expr.clone());
20013 }
20014 }
20015 result
20016 }
20017
20018 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
20021 let needs_inheritance = matches!(
20024 self.config.dialect,
20025 Some(DialectType::DuckDB)
20026 | Some(DialectType::Spark)
20027 | Some(DialectType::Databricks)
20028 | Some(DialectType::Hive)
20029 | Some(DialectType::Snowflake)
20030 | Some(DialectType::Presto)
20031 | Some(DialectType::Trino)
20032 );
20033 let propagated: Vec<Expression>;
20034 let expressions = if needs_inheritance && f.expressions.len() > 1 {
20035 propagated = Self::inherit_struct_field_names(&f.expressions);
20036 &propagated
20037 } else {
20038 &f.expressions
20039 };
20040
20041 let should_split = if self.config.pretty && !expressions.is_empty() {
20043 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
20044 for expr in expressions {
20045 let mut temp_gen = Generator::with_arc_config(self.config.clone());
20046 Arc::make_mut(&mut temp_gen.config).pretty = false;
20047 temp_gen.generate_expression(expr)?;
20048 expr_strings.push(temp_gen.output);
20049 }
20050 self.too_wide(&expr_strings)
20051 } else {
20052 false
20053 };
20054
20055 if f.bracket_notation {
20056 let (open, close) = match self.config.dialect {
20060 None
20061 | Some(DialectType::Generic)
20062 | Some(DialectType::Spark)
20063 | Some(DialectType::Databricks)
20064 | Some(DialectType::Hive) => {
20065 self.write_keyword("ARRAY");
20066 ("(", ")")
20067 }
20068 Some(DialectType::Presto)
20069 | Some(DialectType::Trino)
20070 | Some(DialectType::PostgreSQL)
20071 | Some(DialectType::Redshift)
20072 | Some(DialectType::Materialize)
20073 | Some(DialectType::RisingWave)
20074 | Some(DialectType::CockroachDB) => {
20075 self.write_keyword("ARRAY");
20076 ("[", "]")
20077 }
20078 _ => ("[", "]"),
20079 };
20080 self.write(open);
20081 if should_split {
20082 self.write_newline();
20083 self.indent_level += 1;
20084 for (i, expr) in expressions.iter().enumerate() {
20085 self.write_indent();
20086 self.generate_expression(expr)?;
20087 if i + 1 < expressions.len() {
20088 self.write(",");
20089 }
20090 self.write_newline();
20091 }
20092 self.indent_level -= 1;
20093 self.write_indent();
20094 } else {
20095 for (i, expr) in expressions.iter().enumerate() {
20096 if i > 0 {
20097 self.write(", ");
20098 }
20099 self.generate_expression(expr)?;
20100 }
20101 }
20102 self.write(close);
20103 } else {
20104 if f.use_list_keyword {
20106 self.write_keyword("LIST");
20107 } else {
20108 self.write_keyword("ARRAY");
20109 }
20110 let has_subquery = expressions
20113 .iter()
20114 .any(|e| matches!(e, Expression::Select(_)));
20115 let (open, close) = if matches!(
20116 self.config.dialect,
20117 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
20118 ) || (matches!(self.config.dialect, Some(DialectType::BigQuery))
20119 && has_subquery)
20120 {
20121 ("(", ")")
20122 } else {
20123 ("[", "]")
20124 };
20125 self.write(open);
20126 if should_split {
20127 self.write_newline();
20128 self.indent_level += 1;
20129 for (i, expr) in expressions.iter().enumerate() {
20130 self.write_indent();
20131 self.generate_expression(expr)?;
20132 if i + 1 < expressions.len() {
20133 self.write(",");
20134 }
20135 self.write_newline();
20136 }
20137 self.indent_level -= 1;
20138 self.write_indent();
20139 } else {
20140 for (i, expr) in expressions.iter().enumerate() {
20141 if i > 0 {
20142 self.write(", ");
20143 }
20144 self.generate_expression(expr)?;
20145 }
20146 }
20147 self.write(close);
20148 }
20149 Ok(())
20150 }
20151
20152 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
20153 self.write_keyword("ARRAY_SORT");
20154 self.write("(");
20155 self.generate_expression(&f.this)?;
20156 if let Some(ref comp) = f.comparator {
20157 self.write(", ");
20158 self.generate_expression(comp)?;
20159 }
20160 self.write(")");
20161 Ok(())
20162 }
20163
20164 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
20165 self.write_keyword(name);
20166 self.write("(");
20167 self.generate_expression(&f.this)?;
20168 self.write(", ");
20169 self.generate_expression(&f.separator)?;
20170 if let Some(ref null_rep) = f.null_replacement {
20171 self.write(", ");
20172 self.generate_expression(null_rep)?;
20173 }
20174 self.write(")");
20175 Ok(())
20176 }
20177
20178 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
20179 self.write_keyword("UNNEST");
20180 self.write("(");
20181 self.generate_expression(&f.this)?;
20182 for extra in &f.expressions {
20183 self.write(", ");
20184 self.generate_expression(extra)?;
20185 }
20186 self.write(")");
20187 if f.with_ordinality {
20188 self.write_space();
20189 if self.config.unnest_with_ordinality {
20190 self.write_keyword("WITH ORDINALITY");
20192 } else if f.offset_alias.is_some() {
20193 if let Some(ref alias) = f.alias {
20196 self.write_keyword("AS");
20197 self.write_space();
20198 self.generate_identifier(alias)?;
20199 self.write_space();
20200 }
20201 self.write_keyword("WITH OFFSET");
20202 if let Some(ref offset_alias) = f.offset_alias {
20203 self.write_space();
20204 self.write_keyword("AS");
20205 self.write_space();
20206 self.generate_identifier(offset_alias)?;
20207 }
20208 } else {
20209 self.write_keyword("WITH OFFSET");
20211 if f.alias.is_none() {
20212 self.write(" AS offset");
20213 }
20214 }
20215 }
20216 if let Some(ref alias) = f.alias {
20217 let should_add_alias = if !f.with_ordinality {
20219 true
20220 } else if self.config.unnest_with_ordinality {
20221 true
20223 } else if f.offset_alias.is_some() {
20224 false
20226 } else {
20227 true
20229 };
20230 if should_add_alias {
20231 self.write_space();
20232 self.write_keyword("AS");
20233 self.write_space();
20234 self.generate_identifier(alias)?;
20235 }
20236 }
20237 Ok(())
20238 }
20239
20240 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
20241 self.write_keyword("FILTER");
20242 self.write("(");
20243 self.generate_expression(&f.this)?;
20244 self.write(", ");
20245 self.generate_expression(&f.filter)?;
20246 self.write(")");
20247 Ok(())
20248 }
20249
20250 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
20251 self.write_keyword("TRANSFORM");
20252 self.write("(");
20253 self.generate_expression(&f.this)?;
20254 self.write(", ");
20255 self.generate_expression(&f.transform)?;
20256 self.write(")");
20257 Ok(())
20258 }
20259
20260 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
20261 self.write_keyword(name);
20262 self.write("(");
20263 self.generate_expression(&f.start)?;
20264 self.write(", ");
20265 self.generate_expression(&f.stop)?;
20266 if let Some(ref step) = f.step {
20267 self.write(", ");
20268 self.generate_expression(step)?;
20269 }
20270 self.write(")");
20271 Ok(())
20272 }
20273
20274 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
20277 self.write_keyword("STRUCT");
20278 self.write("(");
20279 for (i, (name, expr)) in f.fields.iter().enumerate() {
20280 if i > 0 {
20281 self.write(", ");
20282 }
20283 if let Some(ref id) = name {
20284 self.generate_identifier(id)?;
20285 self.write(" ");
20286 self.write_keyword("AS");
20287 self.write(" ");
20288 }
20289 self.generate_expression(expr)?;
20290 }
20291 self.write(")");
20292 Ok(())
20293 }
20294
20295 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
20297 let mut names: Vec<Option<String>> = Vec::new();
20300 let mut values: Vec<&Expression> = Vec::new();
20301 let mut all_named = true;
20302
20303 for arg in &func.args {
20304 match arg {
20305 Expression::Alias(a) => {
20306 names.push(Some(a.alias.name.clone()));
20307 values.push(&a.this);
20308 }
20309 _ => {
20310 names.push(None);
20311 values.push(arg);
20312 all_named = false;
20313 }
20314 }
20315 }
20316
20317 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20318 self.write("{");
20320 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20321 if i > 0 {
20322 self.write(", ");
20323 }
20324 if let Some(n) = name {
20325 self.write("'");
20326 self.write(n);
20327 self.write("'");
20328 } else {
20329 self.write("'_");
20330 self.write(&i.to_string());
20331 self.write("'");
20332 }
20333 self.write(": ");
20334 self.generate_expression(value)?;
20335 }
20336 self.write("}");
20337 return Ok(());
20338 }
20339
20340 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
20341 self.write_keyword("OBJECT_CONSTRUCT");
20343 self.write("(");
20344 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20345 if i > 0 {
20346 self.write(", ");
20347 }
20348 if let Some(n) = name {
20349 self.write("'");
20350 self.write(n);
20351 self.write("'");
20352 } else {
20353 self.write("'_");
20354 self.write(&i.to_string());
20355 self.write("'");
20356 }
20357 self.write(", ");
20358 self.generate_expression(value)?;
20359 }
20360 self.write(")");
20361 return Ok(());
20362 }
20363
20364 if matches!(
20365 self.config.dialect,
20366 Some(DialectType::Presto) | Some(DialectType::Trino)
20367 ) {
20368 if all_named && !names.is_empty() {
20369 self.write_keyword("CAST");
20372 self.write("(");
20373 self.write_keyword("ROW");
20374 self.write("(");
20375 for (i, value) in values.iter().enumerate() {
20376 if i > 0 {
20377 self.write(", ");
20378 }
20379 self.generate_expression(value)?;
20380 }
20381 self.write(")");
20382 self.write(" ");
20383 self.write_keyword("AS");
20384 self.write(" ");
20385 self.write_keyword("ROW");
20386 self.write("(");
20387 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
20388 if i > 0 {
20389 self.write(", ");
20390 }
20391 if let Some(n) = name {
20392 self.write(n);
20393 }
20394 self.write(" ");
20395 let type_str = Self::infer_sql_type_for_presto(value);
20396 self.write_keyword(&type_str);
20397 }
20398 self.write(")");
20399 self.write(")");
20400 } else {
20401 self.write_keyword("ROW");
20403 self.write("(");
20404 for (i, value) in values.iter().enumerate() {
20405 if i > 0 {
20406 self.write(", ");
20407 }
20408 self.generate_expression(value)?;
20409 }
20410 self.write(")");
20411 }
20412 return Ok(());
20413 }
20414
20415 self.write_keyword("ROW");
20417 self.write("(");
20418 for (i, value) in values.iter().enumerate() {
20419 if i > 0 {
20420 self.write(", ");
20421 }
20422 self.generate_expression(value)?;
20423 }
20424 self.write(")");
20425 Ok(())
20426 }
20427
20428 fn infer_sql_type_for_presto(expr: &Expression) -> String {
20430 match expr {
20431 Expression::Literal(lit)
20432 if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
20433 {
20434 "VARCHAR".to_string()
20435 }
20436 Expression::Literal(lit)
20437 if matches!(lit.as_ref(), crate::expressions::Literal::Number(_)) =>
20438 {
20439 let crate::expressions::Literal::Number(n) = lit.as_ref() else {
20440 unreachable!()
20441 };
20442 if n.contains('.') {
20443 "DOUBLE".to_string()
20444 } else {
20445 "INTEGER".to_string()
20446 }
20447 }
20448 Expression::Boolean(_) => "BOOLEAN".to_string(),
20449 Expression::Literal(lit)
20450 if matches!(lit.as_ref(), crate::expressions::Literal::Date(_)) =>
20451 {
20452 "DATE".to_string()
20453 }
20454 Expression::Literal(lit)
20455 if matches!(lit.as_ref(), crate::expressions::Literal::Timestamp(_)) =>
20456 {
20457 "TIMESTAMP".to_string()
20458 }
20459 Expression::Literal(lit)
20460 if matches!(lit.as_ref(), crate::expressions::Literal::Datetime(_)) =>
20461 {
20462 "TIMESTAMP".to_string()
20463 }
20464 Expression::Array(_) | Expression::ArrayFunc(_) => {
20465 "ARRAY(VARCHAR)".to_string()
20467 }
20468 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
20470 Expression::Function(f) => {
20471 if f.name.eq_ignore_ascii_case("STRUCT") {
20472 "ROW".to_string()
20473 } else if f.name.eq_ignore_ascii_case("CURRENT_DATE") {
20474 "DATE".to_string()
20475 } else if f.name.eq_ignore_ascii_case("CURRENT_TIMESTAMP")
20476 || f.name.eq_ignore_ascii_case("NOW")
20477 {
20478 "TIMESTAMP".to_string()
20479 } else {
20480 "VARCHAR".to_string()
20481 }
20482 }
20483 _ => "VARCHAR".to_string(),
20484 }
20485 }
20486
20487 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
20488 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
20490 self.write_keyword("STRUCT_EXTRACT");
20491 self.write("(");
20492 self.generate_expression(&f.this)?;
20493 self.write(", ");
20494 self.write("'");
20496 self.write(&f.field.name);
20497 self.write("'");
20498 self.write(")");
20499 return Ok(());
20500 }
20501 self.generate_expression(&f.this)?;
20502 self.write(".");
20503 self.generate_identifier(&f.field)
20504 }
20505
20506 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
20507 self.write_keyword("NAMED_STRUCT");
20508 self.write("(");
20509 for (i, (name, value)) in f.pairs.iter().enumerate() {
20510 if i > 0 {
20511 self.write(", ");
20512 }
20513 self.generate_expression(name)?;
20514 self.write(", ");
20515 self.generate_expression(value)?;
20516 }
20517 self.write(")");
20518 Ok(())
20519 }
20520
20521 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
20524 if f.curly_brace_syntax {
20525 if f.with_map_keyword {
20527 self.write_keyword("MAP");
20528 self.write(" ");
20529 }
20530 self.write("{");
20531 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
20532 if i > 0 {
20533 self.write(", ");
20534 }
20535 self.generate_expression(key)?;
20536 self.write(": ");
20537 self.generate_expression(val)?;
20538 }
20539 self.write("}");
20540 } else {
20541 self.write_keyword("MAP");
20543 self.write("(");
20544 self.write_keyword("ARRAY");
20545 self.write("[");
20546 for (i, key) in f.keys.iter().enumerate() {
20547 if i > 0 {
20548 self.write(", ");
20549 }
20550 self.generate_expression(key)?;
20551 }
20552 self.write("], ");
20553 self.write_keyword("ARRAY");
20554 self.write("[");
20555 for (i, val) in f.values.iter().enumerate() {
20556 if i > 0 {
20557 self.write(", ");
20558 }
20559 self.generate_expression(val)?;
20560 }
20561 self.write("])");
20562 }
20563 Ok(())
20564 }
20565
20566 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
20567 self.write_keyword(name);
20568 self.write("(");
20569 self.generate_expression(&f.this)?;
20570 self.write(", ");
20571 self.generate_expression(&f.transform)?;
20572 self.write(")");
20573 Ok(())
20574 }
20575
20576 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
20579 use crate::dialects::DialectType;
20580
20581 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
20583
20584 if use_arrow {
20585 self.generate_expression(&f.this)?;
20587 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
20588 self.write(" ->> ");
20589 } else {
20590 self.write(" -> ");
20591 }
20592 self.generate_expression(&f.path)?;
20593 return Ok(());
20594 }
20595
20596 if f.hash_arrow_syntax
20598 && matches!(
20599 self.config.dialect,
20600 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20601 )
20602 {
20603 self.generate_expression(&f.this)?;
20604 self.write(" #>> ");
20605 self.generate_expression(&f.path)?;
20606 return Ok(());
20607 }
20608
20609 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20612 match name {
20613 "JSON_EXTRACT_SCALAR"
20614 | "JSON_EXTRACT_PATH_TEXT"
20615 | "JSON_EXTRACT"
20616 | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
20617 _ => name,
20618 }
20619 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20620 match name {
20621 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
20622 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
20623 _ => name,
20624 }
20625 } else {
20626 name
20627 };
20628
20629 self.write_keyword(func_name);
20630 self.write("(");
20631 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20633 if let Expression::Cast(ref cast) = f.this {
20634 if matches!(cast.to, crate::expressions::DataType::Json) {
20635 self.generate_expression(&cast.this)?;
20636 } else {
20637 self.generate_expression(&f.this)?;
20638 }
20639 } else {
20640 self.generate_expression(&f.this)?;
20641 }
20642 } else {
20643 self.generate_expression(&f.this)?;
20644 }
20645 if matches!(
20648 self.config.dialect,
20649 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20650 ) && (func_name == "JSON_EXTRACT_PATH" || func_name == "JSON_EXTRACT_PATH_TEXT")
20651 {
20652 if let Expression::Literal(ref lit) = f.path {
20653 if let Literal::String(ref s) = lit.as_ref() {
20654 let parts = Self::decompose_json_path(s);
20655 for part in &parts {
20656 self.write(", '");
20657 self.write(part);
20658 self.write("'");
20659 }
20660 }
20661 } else {
20662 self.write(", ");
20663 self.generate_expression(&f.path)?;
20664 }
20665 } else {
20666 self.write(", ");
20667 self.generate_expression(&f.path)?;
20668 }
20669
20670 if let Some(ref wrapper) = f.wrapper_option {
20673 self.write_space();
20674 self.write_keyword(wrapper);
20675 }
20676 if let Some(ref quotes) = f.quotes_option {
20677 self.write_space();
20678 self.write_keyword(quotes);
20679 if f.on_scalar_string {
20680 self.write_space();
20681 self.write_keyword("ON SCALAR STRING");
20682 }
20683 }
20684 if let Some(ref on_err) = f.on_error {
20685 self.write_space();
20686 self.write_keyword(on_err);
20687 }
20688 if let Some(ref ret_type) = f.returning {
20689 self.write_space();
20690 self.write_keyword("RETURNING");
20691 self.write_space();
20692 self.generate_data_type(ret_type)?;
20693 }
20694
20695 self.write(")");
20696 Ok(())
20697 }
20698
20699 fn dialect_supports_json_arrow(&self) -> bool {
20701 use crate::dialects::DialectType;
20702 match self.config.dialect {
20703 Some(DialectType::PostgreSQL) => true,
20705 Some(DialectType::MySQL) => true,
20706 Some(DialectType::DuckDB) => true,
20707 Some(DialectType::CockroachDB) => true,
20708 Some(DialectType::StarRocks) => true,
20709 Some(DialectType::SQLite) => true,
20710 _ => false,
20712 }
20713 }
20714
20715 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
20716 use crate::dialects::DialectType;
20717
20718 if matches!(
20720 self.config.dialect,
20721 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
20722 ) && name == "JSON_EXTRACT_PATH"
20723 {
20724 self.generate_expression(&f.this)?;
20725 self.write(" #> ");
20726 if f.paths.len() == 1 {
20727 self.generate_expression(&f.paths[0])?;
20728 } else {
20729 self.write_keyword("ARRAY");
20731 self.write("[");
20732 for (i, path) in f.paths.iter().enumerate() {
20733 if i > 0 {
20734 self.write(", ");
20735 }
20736 self.generate_expression(path)?;
20737 }
20738 self.write("]");
20739 }
20740 return Ok(());
20741 }
20742
20743 self.write_keyword(name);
20744 self.write("(");
20745 self.generate_expression(&f.this)?;
20746 for path in &f.paths {
20747 self.write(", ");
20748 self.generate_expression(path)?;
20749 }
20750 self.write(")");
20751 Ok(())
20752 }
20753
20754 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
20755 use crate::dialects::DialectType;
20756
20757 self.write_keyword("JSON_OBJECT");
20758 self.write("(");
20759 if f.star {
20760 self.write("*");
20761 } else {
20762 let use_comma_syntax = self.config.json_key_value_pair_sep == ","
20766 || matches!(
20767 self.config.dialect,
20768 Some(DialectType::BigQuery)
20769 | Some(DialectType::MySQL)
20770 | Some(DialectType::SQLite)
20771 );
20772
20773 for (i, (key, value)) in f.pairs.iter().enumerate() {
20774 if i > 0 {
20775 self.write(", ");
20776 }
20777 self.generate_expression(key)?;
20778 if use_comma_syntax {
20779 self.write(", ");
20780 } else {
20781 self.write(": ");
20782 }
20783 self.generate_expression(value)?;
20784 }
20785 }
20786 if let Some(null_handling) = f.null_handling {
20787 self.write_space();
20788 match null_handling {
20789 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20790 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20791 }
20792 }
20793 if f.with_unique_keys {
20794 self.write_space();
20795 self.write_keyword("WITH UNIQUE KEYS");
20796 }
20797 if let Some(ref ret_type) = f.returning_type {
20798 self.write_space();
20799 self.write_keyword("RETURNING");
20800 self.write_space();
20801 self.generate_data_type(ret_type)?;
20802 if f.format_json {
20803 self.write_space();
20804 self.write_keyword("FORMAT JSON");
20805 }
20806 if let Some(ref enc) = f.encoding {
20807 self.write_space();
20808 self.write_keyword("ENCODING");
20809 self.write_space();
20810 self.write(enc);
20811 }
20812 }
20813 self.write(")");
20814 Ok(())
20815 }
20816
20817 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
20818 self.write_keyword(name);
20819 self.write("(");
20820 self.generate_expression(&f.this)?;
20821 for (path, value) in &f.path_values {
20822 self.write(", ");
20823 self.generate_expression(path)?;
20824 self.write(", ");
20825 self.generate_expression(value)?;
20826 }
20827 self.write(")");
20828 Ok(())
20829 }
20830
20831 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
20832 self.write_keyword("JSON_ARRAYAGG");
20833 self.write("(");
20834 self.generate_expression(&f.this)?;
20835 if let Some(ref order_by) = f.order_by {
20836 self.write_space();
20837 self.write_keyword("ORDER BY");
20838 self.write_space();
20839 for (i, ord) in order_by.iter().enumerate() {
20840 if i > 0 {
20841 self.write(", ");
20842 }
20843 self.generate_ordered(ord)?;
20844 }
20845 }
20846 if let Some(null_handling) = f.null_handling {
20847 self.write_space();
20848 match null_handling {
20849 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20850 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20851 }
20852 }
20853 self.write(")");
20854 if let Some(ref filter) = f.filter {
20855 self.write_space();
20856 self.write_keyword("FILTER");
20857 self.write("(");
20858 self.write_keyword("WHERE");
20859 self.write_space();
20860 self.generate_expression(filter)?;
20861 self.write(")");
20862 }
20863 Ok(())
20864 }
20865
20866 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
20867 self.write_keyword("JSON_OBJECTAGG");
20868 self.write("(");
20869 self.generate_expression(&f.key)?;
20870 self.write(": ");
20871 self.generate_expression(&f.value)?;
20872 if let Some(null_handling) = f.null_handling {
20873 self.write_space();
20874 match null_handling {
20875 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
20876 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
20877 }
20878 }
20879 self.write(")");
20880 if let Some(ref filter) = f.filter {
20881 self.write_space();
20882 self.write_keyword("FILTER");
20883 self.write("(");
20884 self.write_keyword("WHERE");
20885 self.write_space();
20886 self.generate_expression(filter)?;
20887 self.write(")");
20888 }
20889 Ok(())
20890 }
20891
20892 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
20895 use crate::dialects::DialectType;
20896
20897 if self.config.dialect == Some(DialectType::Redshift) {
20899 self.write_keyword("CAST");
20900 self.write("(");
20901 self.generate_expression(&f.this)?;
20902 self.write_space();
20903 self.write_keyword("AS");
20904 self.write_space();
20905 self.generate_data_type(&f.to)?;
20906 self.write(")");
20907 return Ok(());
20908 }
20909
20910 self.write_keyword("CONVERT");
20911 self.write("(");
20912 self.generate_data_type(&f.to)?;
20913 self.write(", ");
20914 self.generate_expression(&f.this)?;
20915 if let Some(ref style) = f.style {
20916 self.write(", ");
20917 self.generate_expression(style)?;
20918 }
20919 self.write(")");
20920 Ok(())
20921 }
20922
20923 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
20926 if f.colon {
20927 self.write_keyword("LAMBDA");
20929 self.write_space();
20930 for (i, param) in f.parameters.iter().enumerate() {
20931 if i > 0 {
20932 self.write(", ");
20933 }
20934 self.generate_identifier(param)?;
20935 }
20936 self.write(" : ");
20937 } else {
20938 if f.parameters.len() == 1 {
20940 self.generate_identifier(&f.parameters[0])?;
20941 } else {
20942 self.write("(");
20943 for (i, param) in f.parameters.iter().enumerate() {
20944 if i > 0 {
20945 self.write(", ");
20946 }
20947 self.generate_identifier(param)?;
20948 }
20949 self.write(")");
20950 }
20951 self.write(" -> ");
20952 }
20953 self.generate_expression(&f.body)
20954 }
20955
20956 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
20957 self.generate_identifier(&f.name)?;
20958 match f.separator {
20959 NamedArgSeparator::DArrow => self.write(" => "),
20960 NamedArgSeparator::ColonEq => self.write(" := "),
20961 NamedArgSeparator::Eq => self.write(" = "),
20962 }
20963 self.generate_expression(&f.value)
20964 }
20965
20966 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
20967 self.write_keyword(&f.prefix);
20968 self.write(" ");
20969 self.generate_expression(&f.this)
20970 }
20971
20972 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
20973 match f.style {
20974 ParameterStyle::Question => self.write("?"),
20975 ParameterStyle::Dollar => {
20976 self.write("$");
20977 if let Some(idx) = f.index {
20978 self.write(&idx.to_string());
20979 } else if let Some(ref name) = f.name {
20980 self.write(name);
20982 }
20983 }
20984 ParameterStyle::DollarBrace => {
20985 self.write("${");
20987 if let Some(ref name) = f.name {
20988 self.write(name);
20989 }
20990 if let Some(ref expr) = f.expression {
20991 self.write(":");
20992 self.write(expr);
20993 }
20994 self.write("}");
20995 }
20996 ParameterStyle::Colon => {
20997 self.write(":");
20998 if let Some(idx) = f.index {
20999 self.write(&idx.to_string());
21000 } else if let Some(ref name) = f.name {
21001 self.write(name);
21002 }
21003 }
21004 ParameterStyle::At => {
21005 self.write("@");
21006 if let Some(ref name) = f.name {
21007 if f.string_quoted {
21008 self.write("'");
21009 self.write(name);
21010 self.write("'");
21011 } else if f.quoted {
21012 self.write("\"");
21013 self.write(name);
21014 self.write("\"");
21015 } else {
21016 self.write(name);
21017 }
21018 }
21019 }
21020 ParameterStyle::DoubleAt => {
21021 self.write("@@");
21022 if let Some(ref name) = f.name {
21023 self.write(name);
21024 }
21025 }
21026 ParameterStyle::DoubleDollar => {
21027 self.write("$$");
21028 if let Some(ref name) = f.name {
21029 self.write(name);
21030 }
21031 }
21032 ParameterStyle::Percent => {
21033 if let Some(ref name) = f.name {
21034 self.write("%(");
21036 self.write(name);
21037 self.write(")s");
21038 } else {
21039 self.write("%s");
21041 }
21042 }
21043 ParameterStyle::Brace => {
21044 self.write("{");
21047 if let Some(ref name) = f.name {
21048 self.write(name);
21049 }
21050 if let Some(ref expr) = f.expression {
21051 self.write(": ");
21052 self.write(expr);
21053 }
21054 self.write("}");
21055 }
21056 }
21057 Ok(())
21058 }
21059
21060 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
21061 self.write("?");
21062 if let Some(idx) = f.index {
21063 self.write(&idx.to_string());
21064 }
21065 Ok(())
21066 }
21067
21068 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
21069 if f.is_block {
21070 self.write("/*");
21071 self.write(&f.text);
21072 self.write("*/");
21073 } else {
21074 self.write("--");
21075 self.write(&f.text);
21076 }
21077 Ok(())
21078 }
21079
21080 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
21083 self.generate_expression(&f.this)?;
21084 if f.not {
21085 self.write_space();
21086 self.write_keyword("NOT");
21087 }
21088 self.write_space();
21089 self.write_keyword("SIMILAR TO");
21090 self.write_space();
21091 self.generate_expression(&f.pattern)?;
21092 if let Some(ref escape) = f.escape {
21093 self.write_space();
21094 self.write_keyword("ESCAPE");
21095 self.write_space();
21096 self.generate_expression(escape)?;
21097 }
21098 Ok(())
21099 }
21100
21101 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
21102 self.generate_expression(&f.this)?;
21103 self.write_space();
21104 if let Some(op) = &f.op {
21106 match op {
21107 QuantifiedOp::Eq => self.write("="),
21108 QuantifiedOp::Neq => self.write("<>"),
21109 QuantifiedOp::Lt => self.write("<"),
21110 QuantifiedOp::Lte => self.write("<="),
21111 QuantifiedOp::Gt => self.write(">"),
21112 QuantifiedOp::Gte => self.write(">="),
21113 }
21114 self.write_space();
21115 }
21116 self.write_keyword(name);
21117
21118 if matches!(&f.subquery, Expression::Subquery(_)) {
21120 self.write_space();
21121 self.generate_expression(&f.subquery)?;
21122 } else {
21123 self.write("(");
21124
21125 let is_statement = matches!(
21126 &f.subquery,
21127 Expression::Select(_)
21128 | Expression::Union(_)
21129 | Expression::Intersect(_)
21130 | Expression::Except(_)
21131 );
21132
21133 if self.config.pretty && is_statement {
21134 self.write_newline();
21135 self.indent_level += 1;
21136 self.write_indent();
21137 }
21138 self.generate_expression(&f.subquery)?;
21139 if self.config.pretty && is_statement {
21140 self.write_newline();
21141 self.indent_level -= 1;
21142 self.write_indent();
21143 }
21144 self.write(")");
21145 }
21146 Ok(())
21147 }
21148
21149 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
21150 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
21152 self.generate_expression(this)?;
21153 self.write_space();
21154 self.write_keyword("OVERLAPS");
21155 self.write_space();
21156 self.generate_expression(expr)?;
21157 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
21158 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
21159 {
21160 self.write("(");
21162 self.generate_expression(ls)?;
21163 self.write(", ");
21164 self.generate_expression(le)?;
21165 self.write(")");
21166 self.write_space();
21167 self.write_keyword("OVERLAPS");
21168 self.write_space();
21169 self.write("(");
21170 self.generate_expression(rs)?;
21171 self.write(", ");
21172 self.generate_expression(re)?;
21173 self.write(")");
21174 }
21175 Ok(())
21176 }
21177
21178 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
21181 use crate::dialects::DialectType;
21182
21183 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
21185 self.generate_expression(&cast.this)?;
21186 self.write(" !:> ");
21187 self.generate_data_type(&cast.to)?;
21188 return Ok(());
21189 }
21190
21191 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
21193 self.write_keyword("TRYCAST");
21194 self.write("(");
21195 self.generate_expression(&cast.this)?;
21196 self.write_space();
21197 self.write_keyword("AS");
21198 self.write_space();
21199 self.generate_data_type(&cast.to)?;
21200 self.write(")");
21201 return Ok(());
21202 }
21203
21204 let keyword = if matches!(
21206 self.config.dialect,
21207 Some(DialectType::Hive)
21208 | Some(DialectType::MySQL)
21209 | Some(DialectType::SQLite)
21210 | Some(DialectType::Oracle)
21211 | Some(DialectType::ClickHouse)
21212 | Some(DialectType::Redshift)
21213 | Some(DialectType::PostgreSQL)
21214 | Some(DialectType::StarRocks)
21215 | Some(DialectType::Doris)
21216 ) {
21217 "CAST"
21218 } else {
21219 "TRY_CAST"
21220 };
21221
21222 self.write_keyword(keyword);
21223 self.write("(");
21224 self.generate_expression(&cast.this)?;
21225 self.write_space();
21226 self.write_keyword("AS");
21227 self.write_space();
21228 self.generate_data_type(&cast.to)?;
21229
21230 if let Some(format) = &cast.format {
21232 self.write_space();
21233 self.write_keyword("FORMAT");
21234 self.write_space();
21235 self.generate_expression(format)?;
21236 }
21237
21238 self.write(")");
21239 Ok(())
21240 }
21241
21242 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
21243 self.write_keyword("SAFE_CAST");
21244 self.write("(");
21245 self.generate_expression(&cast.this)?;
21246 self.write_space();
21247 self.write_keyword("AS");
21248 self.write_space();
21249 self.generate_data_type(&cast.to)?;
21250
21251 if let Some(format) = &cast.format {
21253 self.write_space();
21254 self.write_keyword("FORMAT");
21255 self.write_space();
21256 self.generate_expression(format)?;
21257 }
21258
21259 self.write(")");
21260 Ok(())
21261 }
21262
21263 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
21266 let needs_parens = matches!(&s.this, Expression::JsonExtract(ref f) if f.arrow_syntax);
21270 if needs_parens {
21271 self.write("(");
21272 }
21273 self.generate_expression(&s.this)?;
21274 if needs_parens {
21275 self.write(")");
21276 }
21277 self.write("[");
21278 self.generate_expression(&s.index)?;
21279 self.write("]");
21280 Ok(())
21281 }
21282
21283 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
21284 self.generate_expression(&d.this)?;
21285 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
21288 && matches!(
21289 &d.this,
21290 Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_)
21291 );
21292 if use_colon {
21293 self.write(":");
21294 } else {
21295 self.write(".");
21296 }
21297 self.generate_identifier(&d.field)
21298 }
21299
21300 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
21301 self.generate_expression(&m.this)?;
21302 self.write(".");
21303 if m.method.quoted {
21306 let q = self.config.identifier_quote;
21307 self.write(&format!("{}{}{}", q, m.method.name, q));
21308 } else {
21309 self.write(&m.method.name);
21310 }
21311 self.write("(");
21312 for (i, arg) in m.args.iter().enumerate() {
21313 if i > 0 {
21314 self.write(", ");
21315 }
21316 self.generate_expression(arg)?;
21317 }
21318 self.write(")");
21319 Ok(())
21320 }
21321
21322 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
21323 let needs_parens = matches!(
21326 &s.this,
21327 Expression::JsonExtract(f) if f.arrow_syntax
21328 ) || matches!(
21329 &s.this,
21330 Expression::JsonExtractScalar(f) if f.arrow_syntax
21331 );
21332
21333 if needs_parens {
21334 self.write("(");
21335 }
21336 self.generate_expression(&s.this)?;
21337 if needs_parens {
21338 self.write(")");
21339 }
21340 self.write("[");
21341 if let Some(start) = &s.start {
21342 self.generate_expression(start)?;
21343 }
21344 self.write(":");
21345 if let Some(end) = &s.end {
21346 self.generate_expression(end)?;
21347 }
21348 self.write("]");
21349 Ok(())
21350 }
21351
21352 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
21353 match &op.left {
21357 Expression::Column(col) => {
21358 if let Some(table) = &col.table {
21361 self.generate_identifier(table)?;
21362 self.write(".");
21363 }
21364 self.generate_identifier(&col.name)?;
21365 if col.join_mark && self.config.supports_column_join_marks {
21367 self.write(" (+)");
21368 }
21369 if op.left_comments.is_empty() {
21371 for comment in &col.trailing_comments {
21372 self.write_space();
21373 self.write_formatted_comment(comment);
21374 }
21375 }
21376 }
21377 Expression::Add(inner_op)
21378 | Expression::Sub(inner_op)
21379 | Expression::Mul(inner_op)
21380 | Expression::Div(inner_op)
21381 | Expression::Concat(inner_op) => {
21382 self.generate_binary_op_no_trailing(inner_op, match &op.left {
21384 Expression::Add(_) => "+",
21385 Expression::Sub(_) => "-",
21386 Expression::Mul(_) => "*",
21387 Expression::Div(_) => "/",
21388 Expression::Concat(_) => "||",
21389 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
21390 })?;
21391 }
21392 _ => {
21393 self.generate_expression(&op.left)?;
21394 }
21395 }
21396 for comment in &op.left_comments {
21398 self.write_space();
21399 self.write_formatted_comment(comment);
21400 }
21401 if self.config.pretty
21402 && matches!(self.config.dialect, Some(DialectType::Snowflake))
21403 && (operator == "AND" || operator == "OR")
21404 {
21405 self.write_newline();
21406 self.write_indent();
21407 self.write_keyword(operator);
21408 } else {
21409 self.write_space();
21410 if operator.chars().all(|c| c.is_alphabetic()) {
21411 self.write_keyword(operator);
21412 } else {
21413 self.write(operator);
21414 }
21415 }
21416 for comment in &op.operator_comments {
21418 self.write_space();
21419 self.write_formatted_comment(comment);
21420 }
21421 self.write_space();
21422 self.generate_expression(&op.right)?;
21423 for comment in &op.trailing_comments {
21425 self.write_space();
21426 self.write_formatted_comment(comment);
21427 }
21428 Ok(())
21429 }
21430
21431 fn generate_connector_op(&mut self, op: &BinaryOp, connector: ConnectorOperator) -> Result<()> {
21432 let keyword = connector.keyword();
21433 let Some(terms) = self.flatten_connector_terms(op, connector) else {
21434 return self.generate_binary_op(op, keyword);
21435 };
21436
21437 self.generate_expression(terms[0])?;
21438 for term in terms.iter().skip(1) {
21439 if self.config.pretty && matches!(self.config.dialect, Some(DialectType::Snowflake)) {
21440 self.write_newline();
21441 self.write_indent();
21442 self.write_keyword(keyword);
21443 } else {
21444 self.write_space();
21445 self.write_keyword(keyword);
21446 }
21447 self.write_space();
21448 self.generate_expression(term)?;
21449 }
21450
21451 Ok(())
21452 }
21453
21454 fn flatten_connector_terms<'a>(
21455 &self,
21456 root: &'a BinaryOp,
21457 connector: ConnectorOperator,
21458 ) -> Option<Vec<&'a Expression>> {
21459 if !root.left_comments.is_empty()
21460 || !root.operator_comments.is_empty()
21461 || !root.trailing_comments.is_empty()
21462 {
21463 return None;
21464 }
21465
21466 let mut terms = Vec::new();
21467 let mut stack: Vec<&Expression> = vec![&root.right, &root.left];
21468
21469 while let Some(expr) = stack.pop() {
21470 match (connector, expr) {
21471 (ConnectorOperator::And, Expression::And(inner))
21472 if inner.left_comments.is_empty()
21473 && inner.operator_comments.is_empty()
21474 && inner.trailing_comments.is_empty() =>
21475 {
21476 stack.push(&inner.right);
21477 stack.push(&inner.left);
21478 }
21479 (ConnectorOperator::Or, Expression::Or(inner))
21480 if inner.left_comments.is_empty()
21481 && inner.operator_comments.is_empty()
21482 && inner.trailing_comments.is_empty() =>
21483 {
21484 stack.push(&inner.right);
21485 stack.push(&inner.left);
21486 }
21487 _ => terms.push(expr),
21488 }
21489 }
21490
21491 if terms.len() > 1 {
21492 Some(terms)
21493 } else {
21494 None
21495 }
21496 }
21497
21498 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
21500 self.generate_expression(&op.left)?;
21501 self.write_space();
21502 if operator == "ILIKE" && matches!(self.config.dialect, Some(DialectType::Drill)) {
21504 self.write("`ILIKE`");
21505 } else {
21506 self.write_keyword(operator);
21507 }
21508 if let Some(quantifier) = &op.quantifier {
21509 self.write_space();
21510 self.write_keyword(quantifier);
21511 let is_any =
21516 quantifier.eq_ignore_ascii_case("ANY") || quantifier.eq_ignore_ascii_case("SOME");
21517 if !(is_any && matches!(&op.right, Expression::Paren(_))) {
21518 self.write_space();
21519 }
21520 } else {
21521 self.write_space();
21522 }
21523 self.generate_expression(&op.right)?;
21524 if let Some(escape) = &op.escape {
21525 self.write_space();
21526 self.write_keyword("ESCAPE");
21527 self.write_space();
21528 self.generate_expression(escape)?;
21529 }
21530 Ok(())
21531 }
21532
21533 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
21536 use crate::dialects::DialectType;
21537 self.generate_expression(&op.left)?;
21538 self.write_space();
21539 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
21540 self.write("<=>");
21541 } else {
21542 self.write_keyword("IS NOT DISTINCT FROM");
21543 }
21544 self.write_space();
21545 self.generate_expression(&op.right)?;
21546 Ok(())
21547 }
21548
21549 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
21551 self.generate_expression(&op.left)?;
21552 self.write_space();
21553 self.write_keyword("IS DISTINCT FROM");
21554 self.write_space();
21555 self.generate_expression(&op.right)?;
21556 Ok(())
21557 }
21558
21559 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
21561 match &op.left {
21563 Expression::Column(col) => {
21564 if let Some(table) = &col.table {
21565 self.generate_identifier(table)?;
21566 self.write(".");
21567 }
21568 self.generate_identifier(&col.name)?;
21569 if col.join_mark && self.config.supports_column_join_marks {
21571 self.write(" (+)");
21572 }
21573 }
21574 Expression::Add(inner_op)
21575 | Expression::Sub(inner_op)
21576 | Expression::Mul(inner_op)
21577 | Expression::Div(inner_op)
21578 | Expression::Concat(inner_op) => {
21579 self.generate_binary_op_no_trailing(inner_op, match &op.left {
21580 Expression::Add(_) => "+",
21581 Expression::Sub(_) => "-",
21582 Expression::Mul(_) => "*",
21583 Expression::Div(_) => "/",
21584 Expression::Concat(_) => "||",
21585 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
21586 })?;
21587 }
21588 _ => {
21589 self.generate_expression(&op.left)?;
21590 }
21591 }
21592 for comment in &op.left_comments {
21594 self.write_space();
21595 self.write_formatted_comment(comment);
21596 }
21597 self.write_space();
21598 if operator.chars().all(|c| c.is_alphabetic()) {
21599 self.write_keyword(operator);
21600 } else {
21601 self.write(operator);
21602 }
21603 for comment in &op.operator_comments {
21605 self.write_space();
21606 self.write_formatted_comment(comment);
21607 }
21608 self.write_space();
21609 match &op.right {
21612 Expression::Column(col) => {
21613 if let Some(table) = &col.table {
21614 self.generate_identifier(table)?;
21615 self.write(".");
21616 }
21617 self.generate_identifier(&col.name)?;
21618 if col.join_mark && self.config.supports_column_join_marks {
21620 self.write(" (+)");
21621 }
21622 }
21623 _ => {
21624 self.generate_expression(&op.right)?;
21625 }
21626 }
21627 Ok(())
21629 }
21630
21631 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
21632 if operator.chars().all(|c| c.is_alphabetic()) {
21633 self.write_keyword(operator);
21634 self.write_space();
21635 } else {
21636 self.write(operator);
21637 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
21639 self.write_space();
21640 }
21641 }
21642 self.generate_expression(&op.this)
21643 }
21644
21645 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
21646 let is_generic =
21650 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
21651 let use_prefix_not =
21652 in_expr.not && is_generic && self.config.not_in_style == NotInStyle::Prefix;
21653 if use_prefix_not {
21654 self.write_keyword("NOT");
21655 self.write_space();
21656 }
21657 self.generate_expression(&in_expr.this)?;
21658 if in_expr.global {
21659 self.write_space();
21660 self.write_keyword("GLOBAL");
21661 }
21662 if in_expr.not && !use_prefix_not {
21663 self.write_space();
21664 self.write_keyword("NOT");
21665 }
21666 self.write_space();
21667 self.write_keyword("IN");
21668
21669 if let Some(unnest_expr) = &in_expr.unnest {
21671 self.write_space();
21672 self.write_keyword("UNNEST");
21673 self.write("(");
21674 self.generate_expression(unnest_expr)?;
21675 self.write(")");
21676 return Ok(());
21677 }
21678
21679 if let Some(query) = &in_expr.query {
21680 let is_bare = in_expr.expressions.is_empty()
21683 && !matches!(
21684 query,
21685 Expression::Select(_)
21686 | Expression::Union(_)
21687 | Expression::Intersect(_)
21688 | Expression::Except(_)
21689 | Expression::Subquery(_)
21690 );
21691 if is_bare {
21692 self.write_space();
21694 self.generate_expression(query)?;
21695 } else {
21696 self.write(" (");
21698 let is_statement = matches!(
21699 query,
21700 Expression::Select(_)
21701 | Expression::Union(_)
21702 | Expression::Intersect(_)
21703 | Expression::Except(_)
21704 | Expression::Subquery(_)
21705 );
21706 if self.config.pretty && is_statement {
21707 self.write_newline();
21708 self.indent_level += 1;
21709 self.write_indent();
21710 }
21711 self.generate_expression(query)?;
21712 if self.config.pretty && is_statement {
21713 self.write_newline();
21714 self.indent_level -= 1;
21715 self.write_indent();
21716 }
21717 self.write(")");
21718 }
21719 } else {
21720 let is_duckdb = matches!(
21724 self.config.dialect,
21725 Some(crate::dialects::DialectType::DuckDB)
21726 );
21727 let is_clickhouse = matches!(
21728 self.config.dialect,
21729 Some(crate::dialects::DialectType::ClickHouse)
21730 );
21731 let single_expr = in_expr.expressions.len() == 1;
21732 if is_clickhouse && single_expr {
21733 if let Expression::Array(arr) = &in_expr.expressions[0] {
21734 self.write(" (");
21736 for (i, expr) in arr.expressions.iter().enumerate() {
21737 if i > 0 {
21738 self.write(", ");
21739 }
21740 self.generate_expression(expr)?;
21741 }
21742 self.write(")");
21743 } else {
21744 self.write_space();
21745 self.generate_expression(&in_expr.expressions[0])?;
21746 }
21747 } else {
21748 let is_bare_ref = single_expr
21749 && matches!(
21750 &in_expr.expressions[0],
21751 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
21752 );
21753 if (is_duckdb && is_bare_ref) || (in_expr.is_field && single_expr) {
21754 self.write_space();
21757 self.generate_expression(&in_expr.expressions[0])?;
21758 } else {
21759 self.write(" (");
21761 for (i, expr) in in_expr.expressions.iter().enumerate() {
21762 if i > 0 {
21763 self.write(", ");
21764 }
21765 self.generate_expression(expr)?;
21766 }
21767 self.write(")");
21768 }
21769 }
21770 }
21771
21772 Ok(())
21773 }
21774
21775 fn generate_between(&mut self, between: &Between) -> Result<()> {
21776 let use_prefix_not = between.not
21778 && (self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic));
21779 if use_prefix_not {
21780 self.write_keyword("NOT");
21781 self.write_space();
21782 }
21783 self.generate_expression(&between.this)?;
21784 if between.not && !use_prefix_not {
21785 self.write_space();
21786 self.write_keyword("NOT");
21787 }
21788 self.write_space();
21789 self.write_keyword("BETWEEN");
21790 if let Some(sym) = between.symmetric {
21792 if sym {
21793 self.write(" SYMMETRIC");
21794 } else {
21795 self.write(" ASYMMETRIC");
21796 }
21797 }
21798 self.write_space();
21799 self.generate_expression(&between.low)?;
21800 self.write_space();
21801 self.write_keyword("AND");
21802 self.write_space();
21803 self.generate_expression(&between.high)
21804 }
21805
21806 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
21807 let use_prefix_not = is_null.not
21809 && (self.config.dialect.is_none()
21810 || self.config.dialect == Some(DialectType::Generic)
21811 || is_null.postfix_form);
21812 if use_prefix_not {
21813 self.write_keyword("NOT");
21815 self.write_space();
21816 self.generate_expression(&is_null.this)?;
21817 self.write_space();
21818 self.write_keyword("IS");
21819 self.write_space();
21820 self.write_keyword("NULL");
21821 } else {
21822 self.generate_expression(&is_null.this)?;
21823 self.write_space();
21824 self.write_keyword("IS");
21825 if is_null.not {
21826 self.write_space();
21827 self.write_keyword("NOT");
21828 }
21829 self.write_space();
21830 self.write_keyword("NULL");
21831 }
21832 Ok(())
21833 }
21834
21835 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
21836 self.generate_expression(&is_true.this)?;
21837 self.write_space();
21838 self.write_keyword("IS");
21839 if is_true.not {
21840 self.write_space();
21841 self.write_keyword("NOT");
21842 }
21843 self.write_space();
21844 self.write_keyword("TRUE");
21845 Ok(())
21846 }
21847
21848 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
21849 self.generate_expression(&is_false.this)?;
21850 self.write_space();
21851 self.write_keyword("IS");
21852 if is_false.not {
21853 self.write_space();
21854 self.write_keyword("NOT");
21855 }
21856 self.write_space();
21857 self.write_keyword("FALSE");
21858 Ok(())
21859 }
21860
21861 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
21862 self.generate_expression(&is_json.this)?;
21863 self.write_space();
21864 self.write_keyword("IS");
21865 if is_json.negated {
21866 self.write_space();
21867 self.write_keyword("NOT");
21868 }
21869 self.write_space();
21870 self.write_keyword("JSON");
21871
21872 if let Some(ref json_type) = is_json.json_type {
21874 self.write_space();
21875 self.write_keyword(json_type);
21876 }
21877
21878 match &is_json.unique_keys {
21880 Some(JsonUniqueKeys::With) => {
21881 self.write_space();
21882 self.write_keyword("WITH UNIQUE KEYS");
21883 }
21884 Some(JsonUniqueKeys::Without) => {
21885 self.write_space();
21886 self.write_keyword("WITHOUT UNIQUE KEYS");
21887 }
21888 Some(JsonUniqueKeys::Shorthand) => {
21889 self.write_space();
21890 self.write_keyword("UNIQUE KEYS");
21891 }
21892 None => {}
21893 }
21894
21895 Ok(())
21896 }
21897
21898 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
21899 self.generate_expression(&is_expr.left)?;
21900 self.write_space();
21901 self.write_keyword("IS");
21902 self.write_space();
21903 self.generate_expression(&is_expr.right)
21904 }
21905
21906 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
21907 if exists.not {
21908 self.write_keyword("NOT");
21909 self.write_space();
21910 }
21911 self.write_keyword("EXISTS");
21912 self.write("(");
21913 let is_statement = matches!(
21914 &exists.this,
21915 Expression::Select(_)
21916 | Expression::Union(_)
21917 | Expression::Intersect(_)
21918 | Expression::Except(_)
21919 );
21920 if self.config.pretty && is_statement {
21921 self.write_newline();
21922 self.indent_level += 1;
21923 self.write_indent();
21924 self.generate_expression(&exists.this)?;
21925 self.write_newline();
21926 self.indent_level -= 1;
21927 self.write_indent();
21928 self.write(")");
21929 } else {
21930 self.generate_expression(&exists.this)?;
21931 self.write(")");
21932 }
21933 Ok(())
21934 }
21935
21936 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
21937 self.generate_expression(&op.left)?;
21938 self.write_space();
21939 self.write_keyword("MEMBER OF");
21940 self.write("(");
21941 self.generate_expression(&op.right)?;
21942 self.write(")");
21943 Ok(())
21944 }
21945
21946 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
21947 if subquery.lateral {
21948 self.write_keyword("LATERAL");
21949 self.write_space();
21950 }
21951
21952 let skip_outer_parens = if let Expression::Paren(ref p) = &subquery.this {
21956 matches!(
21957 &p.this,
21958 Expression::Select(_)
21959 | Expression::Union(_)
21960 | Expression::Intersect(_)
21961 | Expression::Except(_)
21962 | Expression::Subquery(_)
21963 )
21964 } else {
21965 false
21966 };
21967
21968 let is_statement = matches!(
21970 &subquery.this,
21971 Expression::Select(_)
21972 | Expression::Union(_)
21973 | Expression::Intersect(_)
21974 | Expression::Except(_)
21975 | Expression::Merge(_)
21976 );
21977
21978 if !skip_outer_parens {
21979 self.write("(");
21980 if self.config.pretty && is_statement {
21981 self.write_newline();
21982 self.indent_level += 1;
21983 self.write_indent();
21984 }
21985 }
21986 self.generate_expression(&subquery.this)?;
21987
21988 if subquery.modifiers_inside {
21990 if let Some(order_by) = &subquery.order_by {
21992 self.write_space();
21993 self.write_keyword("ORDER BY");
21994 self.write_space();
21995 for (i, ord) in order_by.expressions.iter().enumerate() {
21996 if i > 0 {
21997 self.write(", ");
21998 }
21999 self.generate_ordered(ord)?;
22000 }
22001 }
22002
22003 if let Some(limit) = &subquery.limit {
22004 self.write_space();
22005 self.write_keyword("LIMIT");
22006 self.write_space();
22007 self.generate_expression(&limit.this)?;
22008 if limit.percent {
22009 self.write_space();
22010 self.write_keyword("PERCENT");
22011 }
22012 }
22013
22014 if let Some(offset) = &subquery.offset {
22015 self.write_space();
22016 self.write_keyword("OFFSET");
22017 self.write_space();
22018 self.generate_expression(&offset.this)?;
22019 }
22020 }
22021
22022 if !skip_outer_parens {
22023 if self.config.pretty && is_statement {
22024 self.write_newline();
22025 self.indent_level -= 1;
22026 self.write_indent();
22027 }
22028 self.write(")");
22029 }
22030
22031 if !subquery.modifiers_inside {
22033 if let Some(order_by) = &subquery.order_by {
22034 self.write_space();
22035 self.write_keyword("ORDER BY");
22036 self.write_space();
22037 for (i, ord) in order_by.expressions.iter().enumerate() {
22038 if i > 0 {
22039 self.write(", ");
22040 }
22041 self.generate_ordered(ord)?;
22042 }
22043 }
22044
22045 if let Some(limit) = &subquery.limit {
22046 self.write_space();
22047 self.write_keyword("LIMIT");
22048 self.write_space();
22049 self.generate_expression(&limit.this)?;
22050 if limit.percent {
22051 self.write_space();
22052 self.write_keyword("PERCENT");
22053 }
22054 }
22055
22056 if let Some(offset) = &subquery.offset {
22057 self.write_space();
22058 self.write_keyword("OFFSET");
22059 self.write_space();
22060 self.generate_expression(&offset.this)?;
22061 }
22062
22063 if let Some(distribute_by) = &subquery.distribute_by {
22065 self.write_space();
22066 self.write_keyword("DISTRIBUTE BY");
22067 self.write_space();
22068 for (i, expr) in distribute_by.expressions.iter().enumerate() {
22069 if i > 0 {
22070 self.write(", ");
22071 }
22072 self.generate_expression(expr)?;
22073 }
22074 }
22075
22076 if let Some(sort_by) = &subquery.sort_by {
22078 self.write_space();
22079 self.write_keyword("SORT BY");
22080 self.write_space();
22081 for (i, ord) in sort_by.expressions.iter().enumerate() {
22082 if i > 0 {
22083 self.write(", ");
22084 }
22085 self.generate_ordered(ord)?;
22086 }
22087 }
22088
22089 if let Some(cluster_by) = &subquery.cluster_by {
22091 self.write_space();
22092 self.write_keyword("CLUSTER BY");
22093 self.write_space();
22094 for (i, ord) in cluster_by.expressions.iter().enumerate() {
22095 if i > 0 {
22096 self.write(", ");
22097 }
22098 self.generate_ordered(ord)?;
22099 }
22100 }
22101 }
22102
22103 if let Some(alias) = &subquery.alias {
22104 self.write_space();
22105 let skip_as = matches!(
22107 self.config.dialect,
22108 Some(crate::dialects::DialectType::Oracle)
22109 );
22110 if !skip_as {
22111 self.write_keyword("AS");
22112 self.write_space();
22113 }
22114 self.generate_identifier(alias)?;
22115 if !subquery.column_aliases.is_empty() {
22116 self.write("(");
22117 for (i, col) in subquery.column_aliases.iter().enumerate() {
22118 if i > 0 {
22119 self.write(", ");
22120 }
22121 self.generate_identifier(col)?;
22122 }
22123 self.write(")");
22124 }
22125 }
22126 for comment in &subquery.trailing_comments {
22128 self.write(" ");
22129 self.write_formatted_comment(comment);
22130 }
22131 Ok(())
22132 }
22133
22134 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
22135 if let Some(ref with) = pivot.with {
22137 self.generate_with(with)?;
22138 self.write_space();
22139 }
22140
22141 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
22142
22143 let is_redshift_unpivot = pivot.unpivot
22147 && pivot.expressions.is_empty()
22148 && pivot.fields.is_empty()
22149 && pivot.using.is_empty()
22150 && pivot.into.is_none()
22151 && !matches!(&pivot.this, Expression::Null(_));
22152
22153 if is_redshift_unpivot {
22154 self.write_keyword("UNPIVOT");
22156 self.write_space();
22157 self.generate_expression(&pivot.this)?;
22158 if let Some(alias) = &pivot.alias {
22160 self.write_space();
22161 self.write_keyword("AS");
22162 self.write_space();
22163 self.write(&alias.name);
22165 }
22166 return Ok(());
22167 }
22168
22169 let is_simplified = !pivot.using.is_empty()
22171 || pivot.into.is_some()
22172 || (pivot.fields.is_empty()
22173 && !pivot.expressions.is_empty()
22174 && !matches!(&pivot.this, Expression::Null(_)));
22175
22176 if is_simplified {
22177 self.write_keyword(direction);
22181 self.write_space();
22182 self.generate_expression(&pivot.this)?;
22183
22184 if !pivot.expressions.is_empty() {
22185 self.write_space();
22186 self.write_keyword("ON");
22187 self.write_space();
22188 for (i, expr) in pivot.expressions.iter().enumerate() {
22189 if i > 0 {
22190 self.write(", ");
22191 }
22192 self.generate_expression(expr)?;
22193 }
22194 }
22195
22196 if let Some(into) = &pivot.into {
22198 self.write_space();
22199 self.write_keyword("INTO");
22200 self.write_space();
22201 self.generate_expression(into)?;
22202 }
22203
22204 if !pivot.using.is_empty() {
22206 self.write_space();
22207 self.write_keyword("USING");
22208 self.write_space();
22209 for (i, expr) in pivot.using.iter().enumerate() {
22210 if i > 0 {
22211 self.write(", ");
22212 }
22213 self.generate_expression(expr)?;
22214 }
22215 }
22216
22217 if let Some(group) = &pivot.group {
22219 self.write_space();
22220 self.generate_expression(group)?;
22221 }
22222 } else {
22223 if !matches!(&pivot.this, Expression::Null(_)) {
22228 self.generate_expression(&pivot.this)?;
22229 self.write_space();
22230 }
22231 self.write_keyword(direction);
22232 self.write("(");
22233
22234 for (i, expr) in pivot.expressions.iter().enumerate() {
22236 if i > 0 {
22237 self.write(", ");
22238 }
22239 self.generate_expression(expr)?;
22240 }
22241
22242 if !pivot.fields.is_empty() {
22244 if !pivot.expressions.is_empty() {
22245 self.write_space();
22246 }
22247 self.write_keyword("FOR");
22248 self.write_space();
22249 for (i, field) in pivot.fields.iter().enumerate() {
22250 if i > 0 {
22251 self.write_space();
22252 }
22253 self.generate_expression(field)?;
22255 }
22256 }
22257
22258 if let Some(default_val) = &pivot.default_on_null {
22260 self.write_space();
22261 self.write_keyword("DEFAULT ON NULL");
22262 self.write(" (");
22263 self.generate_expression(default_val)?;
22264 self.write(")");
22265 }
22266
22267 if let Some(group) = &pivot.group {
22269 self.write_space();
22270 self.generate_expression(group)?;
22271 }
22272
22273 self.write(")");
22274 }
22275
22276 if let Some(alias) = &pivot.alias {
22278 self.write_space();
22279 self.write_keyword("AS");
22280 self.write_space();
22281 self.generate_identifier(alias)?;
22282 }
22283
22284 Ok(())
22285 }
22286
22287 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
22288 self.generate_expression(&unpivot.this)?;
22289 self.write_space();
22290 self.write_keyword("UNPIVOT");
22291 if let Some(include) = unpivot.include_nulls {
22293 self.write_space();
22294 if include {
22295 self.write_keyword("INCLUDE NULLS");
22296 } else {
22297 self.write_keyword("EXCLUDE NULLS");
22298 }
22299 self.write_space();
22300 }
22301 self.write("(");
22302 if unpivot.value_column_parenthesized {
22303 self.write("(");
22304 }
22305 self.generate_identifier(&unpivot.value_column)?;
22306 for extra_col in &unpivot.extra_value_columns {
22308 self.write(", ");
22309 self.generate_identifier(extra_col)?;
22310 }
22311 if unpivot.value_column_parenthesized {
22312 self.write(")");
22313 }
22314 self.write_space();
22315 self.write_keyword("FOR");
22316 self.write_space();
22317 self.generate_identifier(&unpivot.name_column)?;
22318 self.write_space();
22319 self.write_keyword("IN");
22320 self.write(" (");
22321 for (i, col) in unpivot.columns.iter().enumerate() {
22322 if i > 0 {
22323 self.write(", ");
22324 }
22325 self.generate_expression(col)?;
22326 }
22327 self.write("))");
22328 if let Some(alias) = &unpivot.alias {
22329 self.write_space();
22330 self.write_keyword("AS");
22331 self.write_space();
22332 self.generate_identifier(alias)?;
22333 }
22334 Ok(())
22335 }
22336
22337 fn generate_values(&mut self, values: &Values) -> Result<()> {
22338 self.write_keyword("VALUES");
22339 for (i, row) in values.expressions.iter().enumerate() {
22340 if i > 0 {
22341 self.write(",");
22342 }
22343 self.write(" (");
22344 for (j, expr) in row.expressions.iter().enumerate() {
22345 if j > 0 {
22346 self.write(", ");
22347 }
22348 self.generate_expression(expr)?;
22349 }
22350 self.write(")");
22351 }
22352 if let Some(alias) = &values.alias {
22353 self.write_space();
22354 self.write_keyword("AS");
22355 self.write_space();
22356 self.generate_identifier(alias)?;
22357 if !values.column_aliases.is_empty() {
22358 self.write("(");
22359 for (i, col) in values.column_aliases.iter().enumerate() {
22360 if i > 0 {
22361 self.write(", ");
22362 }
22363 self.generate_identifier(col)?;
22364 }
22365 self.write(")");
22366 }
22367 }
22368 Ok(())
22369 }
22370
22371 fn generate_array(&mut self, arr: &Array) -> Result<()> {
22372 let needs_inheritance = matches!(
22374 self.config.dialect,
22375 Some(DialectType::DuckDB)
22376 | Some(DialectType::Spark)
22377 | Some(DialectType::Databricks)
22378 | Some(DialectType::Hive)
22379 | Some(DialectType::Snowflake)
22380 | Some(DialectType::Presto)
22381 | Some(DialectType::Trino)
22382 );
22383 let propagated: Vec<Expression>;
22384 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
22385 propagated = Self::inherit_struct_field_names(&arr.expressions);
22386 &propagated
22387 } else {
22388 &arr.expressions
22389 };
22390
22391 let use_parens =
22394 self.config.dialect.is_none() || self.config.dialect == Some(DialectType::Generic);
22395 if !self.config.array_bracket_only {
22396 self.write_keyword("ARRAY");
22397 }
22398 if use_parens {
22399 self.write("(");
22400 } else {
22401 self.write("[");
22402 }
22403 for (i, expr) in expressions.iter().enumerate() {
22404 if i > 0 {
22405 self.write(", ");
22406 }
22407 self.generate_expression(expr)?;
22408 }
22409 if use_parens {
22410 self.write(")");
22411 } else {
22412 self.write("]");
22413 }
22414 Ok(())
22415 }
22416
22417 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
22418 if tuple.expressions.len() == 2 {
22421 if let Expression::TableAlias(_) = &tuple.expressions[1] {
22422 self.generate_expression(&tuple.expressions[0])?;
22424 self.write_space();
22425 self.write_keyword("AS");
22426 self.write_space();
22427 self.generate_expression(&tuple.expressions[1])?;
22428 return Ok(());
22429 }
22430 }
22431
22432 let expand_tuple = if self.config.pretty && tuple.expressions.len() > 1 {
22435 let mut expr_strings: Vec<String> = Vec::with_capacity(tuple.expressions.len());
22436 for expr in &tuple.expressions {
22437 expr_strings.push(self.generate_to_string(expr)?);
22438 }
22439 self.too_wide(&expr_strings)
22440 } else {
22441 false
22442 };
22443
22444 if expand_tuple {
22445 self.write("(");
22446 self.write_newline();
22447 self.indent_level += 1;
22448 for (i, expr) in tuple.expressions.iter().enumerate() {
22449 if i > 0 {
22450 self.write(",");
22451 self.write_newline();
22452 }
22453 self.write_indent();
22454 self.generate_expression(expr)?;
22455 }
22456 self.indent_level -= 1;
22457 self.write_newline();
22458 self.write_indent();
22459 self.write(")");
22460 } else {
22461 self.write("(");
22462 for (i, expr) in tuple.expressions.iter().enumerate() {
22463 if i > 0 {
22464 self.write(", ");
22465 }
22466 self.generate_expression(expr)?;
22467 }
22468 self.write(")");
22469 }
22470 Ok(())
22471 }
22472
22473 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
22474 self.generate_expression(&pipe.this)?;
22475 self.write(" |> ");
22476 self.generate_expression(&pipe.expression)?;
22477 Ok(())
22478 }
22479
22480 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
22481 self.generate_expression(&ordered.this)?;
22482 if ordered.desc {
22483 self.write_space();
22484 self.write_keyword("DESC");
22485 } else if ordered.explicit_asc {
22486 self.write_space();
22487 self.write_keyword("ASC");
22488 }
22489 if let Some(nulls_first) = ordered.nulls_first {
22490 let is_asc = !ordered.desc;
22504 let is_nulls_are_large = matches!(
22505 self.config.dialect,
22506 Some(DialectType::Oracle)
22507 | Some(DialectType::PostgreSQL)
22508 | Some(DialectType::Redshift)
22509 | Some(DialectType::Snowflake)
22510 );
22511 let is_nulls_are_last = matches!(
22512 self.config.dialect,
22513 Some(DialectType::Dremio)
22514 | Some(DialectType::DuckDB)
22515 | Some(DialectType::Presto)
22516 | Some(DialectType::Trino)
22517 | Some(DialectType::Athena)
22518 | Some(DialectType::ClickHouse)
22519 | Some(DialectType::Drill)
22520 | Some(DialectType::Exasol)
22521 );
22522
22523 let is_default_nulls = if is_nulls_are_large {
22525 (is_asc && !nulls_first) || (!is_asc && nulls_first)
22527 } else if is_nulls_are_last {
22528 !nulls_first
22530 } else {
22531 false
22532 };
22533
22534 if !is_default_nulls {
22535 self.write_space();
22536 self.write_keyword("NULLS");
22537 self.write_space();
22538 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
22539 }
22540 }
22541 if let Some(ref with_fill) = ordered.with_fill {
22543 self.write_space();
22544 self.generate_with_fill(with_fill)?;
22545 }
22546 Ok(())
22547 }
22548
22549 fn write_clickhouse_type(&mut self, type_str: &str) {
22551 if self.clickhouse_nullable_depth < 0 {
22552 self.write(type_str);
22554 } else {
22555 self.write(&format!("Nullable({})", type_str));
22556 }
22557 }
22558
22559 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
22560 use crate::dialects::DialectType;
22561
22562 match dt {
22563 DataType::Boolean => {
22564 match self.config.dialect {
22566 Some(DialectType::TSQL) => self.write_keyword("BIT"),
22567 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
22569 self.write_keyword("NUMBER(1)")
22571 }
22572 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
22574 }
22575 }
22576 DataType::TinyInt { length } => {
22577 match self.config.dialect {
22581 Some(DialectType::PostgreSQL)
22582 | Some(DialectType::Redshift)
22583 | Some(DialectType::Oracle)
22584 | Some(DialectType::Exasol) => {
22585 self.write_keyword("SMALLINT");
22586 }
22587 Some(DialectType::Teradata) => {
22588 self.write_keyword("BYTEINT");
22590 }
22591 Some(DialectType::Dremio) => {
22592 self.write_keyword("INT");
22594 }
22595 Some(DialectType::ClickHouse) => {
22596 self.write_clickhouse_type("Int8");
22597 }
22598 _ => {
22599 self.write_keyword("TINYINT");
22600 }
22601 }
22602 if let Some(n) = length {
22603 if !matches!(
22604 self.config.dialect,
22605 Some(DialectType::Dremio) | Some(DialectType::ClickHouse)
22606 ) {
22607 self.write(&format!("({})", n));
22608 }
22609 }
22610 }
22611 DataType::SmallInt { length } => {
22612 match self.config.dialect {
22614 Some(DialectType::Dremio) => {
22615 self.write_keyword("INT");
22616 }
22617 Some(DialectType::SQLite) | Some(DialectType::Drill) => {
22618 self.write_keyword("INTEGER");
22619 }
22620 Some(DialectType::BigQuery) => {
22621 self.write_keyword("INT64");
22622 }
22623 Some(DialectType::ClickHouse) => {
22624 self.write_clickhouse_type("Int16");
22625 }
22626 _ => {
22627 self.write_keyword("SMALLINT");
22628 if let Some(n) = length {
22629 self.write(&format!("({})", n));
22630 }
22631 }
22632 }
22633 }
22634 DataType::Int {
22635 length,
22636 integer_spelling: _,
22637 } => {
22638 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
22640 self.write_keyword("INT64");
22641 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22642 self.write_clickhouse_type("Int32");
22643 } else {
22644 let use_integer = match self.config.dialect {
22646 Some(DialectType::TSQL)
22647 | Some(DialectType::Fabric)
22648 | Some(DialectType::Presto)
22649 | Some(DialectType::Trino)
22650 | Some(DialectType::SQLite)
22651 | Some(DialectType::Redshift) => true,
22652 _ => false,
22653 };
22654 if use_integer {
22655 self.write_keyword("INTEGER");
22656 } else {
22657 self.write_keyword("INT");
22658 }
22659 if let Some(n) = length {
22660 self.write(&format!("({})", n));
22661 }
22662 }
22663 }
22664 DataType::BigInt { length } => {
22665 match self.config.dialect {
22667 Some(DialectType::Oracle) => {
22668 self.write_keyword("INT");
22670 }
22671 Some(DialectType::ClickHouse) => {
22672 self.write_clickhouse_type("Int64");
22673 }
22674 _ => {
22675 self.write_keyword("BIGINT");
22676 if let Some(n) = length {
22677 self.write(&format!("({})", n));
22678 }
22679 }
22680 }
22681 }
22682 DataType::Float {
22683 precision,
22684 scale,
22685 real_spelling,
22686 } => {
22687 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
22691 self.write_clickhouse_type("Float32");
22692 } else if *real_spelling
22693 && !matches!(
22694 self.config.dialect,
22695 Some(DialectType::Spark)
22696 | Some(DialectType::Databricks)
22697 | Some(DialectType::Hive)
22698 | Some(DialectType::Snowflake)
22699 | Some(DialectType::MySQL)
22700 | Some(DialectType::BigQuery)
22701 )
22702 {
22703 self.write_keyword("REAL")
22704 } else {
22705 match self.config.dialect {
22706 Some(DialectType::PostgreSQL) => self.write_keyword("REAL"),
22707 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
22708 _ => self.write_keyword("FLOAT"),
22709 }
22710 }
22711 if !matches!(
22714 self.config.dialect,
22715 Some(DialectType::Spark)
22716 | Some(DialectType::Databricks)
22717 | Some(DialectType::Hive)
22718 | Some(DialectType::Presto)
22719 | Some(DialectType::Trino)
22720 ) {
22721 if let Some(p) = precision {
22722 self.write(&format!("({}", p));
22723 if let Some(s) = scale {
22724 self.write(&format!(", {})", s));
22725 } else {
22726 self.write(")");
22727 }
22728 }
22729 }
22730 }
22731 DataType::Double { precision, scale } => {
22732 match self.config.dialect {
22734 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22735 self.write_keyword("FLOAT")
22736 } Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
22738 Some(DialectType::ClickHouse) => self.write_clickhouse_type("Float64"),
22739 Some(DialectType::BigQuery) => self.write_keyword("FLOAT64"),
22740 Some(DialectType::SQLite) => self.write_keyword("REAL"),
22741 Some(DialectType::PostgreSQL)
22742 | Some(DialectType::Redshift)
22743 | Some(DialectType::Teradata)
22744 | Some(DialectType::Materialize) => self.write_keyword("DOUBLE PRECISION"),
22745 _ => self.write_keyword("DOUBLE"),
22746 }
22747 if let Some(p) = precision {
22749 self.write(&format!("({}", p));
22750 if let Some(s) = scale {
22751 self.write(&format!(", {})", s));
22752 } else {
22753 self.write(")");
22754 }
22755 }
22756 }
22757 DataType::Decimal { precision, scale } => {
22758 match self.config.dialect {
22760 Some(DialectType::ClickHouse) => {
22761 self.write("Decimal");
22762 if let Some(p) = precision {
22763 self.write(&format!("({}", p));
22764 if let Some(s) = scale {
22765 self.write(&format!(", {}", s));
22766 }
22767 self.write(")");
22768 }
22769 }
22770 Some(DialectType::Oracle) => {
22771 self.write_keyword("NUMBER");
22773 if let Some(p) = precision {
22774 self.write(&format!("({}", p));
22775 if let Some(s) = scale {
22776 self.write(&format!(", {}", s));
22777 }
22778 self.write(")");
22779 }
22780 }
22781 Some(DialectType::BigQuery) => {
22782 self.write_keyword("NUMERIC");
22784 if let Some(p) = precision {
22785 self.write(&format!("({}", p));
22786 if let Some(s) = scale {
22787 self.write(&format!(", {}", s));
22788 }
22789 self.write(")");
22790 }
22791 }
22792 _ => {
22793 self.write_keyword("DECIMAL");
22794 if let Some(p) = precision {
22795 self.write(&format!("({}", p));
22796 if let Some(s) = scale {
22797 self.write(&format!(", {}", s));
22798 }
22799 self.write(")");
22800 }
22801 }
22802 }
22803 }
22804 DataType::Char { length } => {
22805 match self.config.dialect {
22807 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
22808 self.write_keyword("TEXT");
22810 }
22811 Some(DialectType::Hive)
22812 | Some(DialectType::Spark)
22813 | Some(DialectType::Databricks) => {
22814 if length.is_some()
22817 && !matches!(self.config.dialect, Some(DialectType::Hive))
22818 {
22819 self.write_keyword("CHAR");
22820 if let Some(n) = length {
22821 self.write(&format!("({})", n));
22822 }
22823 } else {
22824 self.write_keyword("STRING");
22825 }
22826 }
22827 Some(DialectType::Dremio) => {
22828 self.write_keyword("VARCHAR");
22830 if let Some(n) = length {
22831 self.write(&format!("({})", n));
22832 }
22833 }
22834 _ => {
22835 self.write_keyword("CHAR");
22836 if let Some(n) = length {
22837 self.write(&format!("({})", n));
22838 }
22839 }
22840 }
22841 }
22842 DataType::VarChar {
22843 length,
22844 parenthesized_length,
22845 } => {
22846 match self.config.dialect {
22848 Some(DialectType::Oracle) => {
22849 self.write_keyword("VARCHAR2");
22850 if let Some(n) = length {
22851 self.write(&format!("({})", n));
22852 }
22853 }
22854 Some(DialectType::DuckDB) => {
22855 self.write_keyword("TEXT");
22857 if let Some(n) = length {
22858 self.write(&format!("({})", n));
22859 }
22860 }
22861 Some(DialectType::SQLite) => {
22862 self.write_keyword("TEXT");
22864 if let Some(n) = length {
22865 self.write(&format!("({})", n));
22866 }
22867 }
22868 Some(DialectType::MySQL) if length.is_none() => {
22869 self.write_keyword("TEXT");
22871 }
22872 Some(DialectType::Hive)
22873 | Some(DialectType::Spark)
22874 | Some(DialectType::Databricks)
22875 if length.is_none() =>
22876 {
22877 self.write_keyword("STRING");
22879 }
22880 _ => {
22881 self.write_keyword("VARCHAR");
22882 if let Some(n) = length {
22883 if *parenthesized_length {
22885 self.write(&format!("(({}))", n));
22886 } else {
22887 self.write(&format!("({})", n));
22888 }
22889 }
22890 }
22891 }
22892 }
22893 DataType::Text => {
22894 match self.config.dialect {
22896 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
22897 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22898 self.write_keyword("VARCHAR(MAX)")
22899 }
22900 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
22901 Some(DialectType::Snowflake)
22902 | Some(DialectType::Dremio)
22903 | Some(DialectType::Drill) => self.write_keyword("VARCHAR"),
22904 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
22905 Some(DialectType::Presto)
22906 | Some(DialectType::Trino)
22907 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
22908 Some(DialectType::Spark)
22909 | Some(DialectType::Databricks)
22910 | Some(DialectType::Hive) => self.write_keyword("STRING"),
22911 Some(DialectType::Redshift) => self.write_keyword("VARCHAR(MAX)"),
22912 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
22913 self.write_keyword("STRING")
22914 }
22915 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
22916 _ => self.write_keyword("TEXT"),
22917 }
22918 }
22919 DataType::TextWithLength { length } => {
22920 match self.config.dialect {
22922 Some(DialectType::Oracle) => self.write(&format!("CLOB({})", length)),
22923 Some(DialectType::Hive)
22924 | Some(DialectType::Spark)
22925 | Some(DialectType::Databricks) => {
22926 self.write(&format!("VARCHAR({})", length));
22927 }
22928 Some(DialectType::Redshift) => self.write(&format!("VARCHAR({})", length)),
22929 Some(DialectType::BigQuery) => self.write(&format!("STRING({})", length)),
22930 Some(DialectType::Snowflake)
22931 | Some(DialectType::Presto)
22932 | Some(DialectType::Trino)
22933 | Some(DialectType::Athena)
22934 | Some(DialectType::Drill)
22935 | Some(DialectType::Dremio) => {
22936 self.write(&format!("VARCHAR({})", length));
22937 }
22938 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22939 self.write(&format!("VARCHAR({})", length))
22940 }
22941 Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
22942 self.write(&format!("STRING({})", length))
22943 }
22944 Some(DialectType::ClickHouse) => self.write_clickhouse_type("String"),
22945 _ => self.write(&format!("TEXT({})", length)),
22946 }
22947 }
22948 DataType::String { length } => {
22949 match self.config.dialect {
22951 Some(DialectType::ClickHouse) => {
22952 self.write("String");
22954 if let Some(n) = length {
22955 self.write(&format!("({})", n));
22956 }
22957 }
22958 Some(DialectType::BigQuery)
22959 | Some(DialectType::Hive)
22960 | Some(DialectType::Spark)
22961 | Some(DialectType::Databricks)
22962 | Some(DialectType::StarRocks)
22963 | Some(DialectType::Doris) => {
22964 self.write_keyword("STRING");
22965 if let Some(n) = length {
22966 self.write(&format!("({})", n));
22967 }
22968 }
22969 Some(DialectType::PostgreSQL) => {
22970 if let Some(n) = length {
22972 self.write_keyword("VARCHAR");
22973 self.write(&format!("({})", n));
22974 } else {
22975 self.write_keyword("TEXT");
22976 }
22977 }
22978 Some(DialectType::Redshift) => {
22979 if let Some(n) = length {
22981 self.write_keyword("VARCHAR");
22982 self.write(&format!("({})", n));
22983 } else {
22984 self.write_keyword("VARCHAR(MAX)");
22985 }
22986 }
22987 Some(DialectType::MySQL) => {
22988 if let Some(n) = length {
22990 self.write_keyword("VARCHAR");
22991 self.write(&format!("({})", n));
22992 } else {
22993 self.write_keyword("TEXT");
22994 }
22995 }
22996 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
22997 if let Some(n) = length {
22999 self.write_keyword("VARCHAR");
23000 self.write(&format!("({})", n));
23001 } else {
23002 self.write_keyword("VARCHAR(MAX)");
23003 }
23004 }
23005 Some(DialectType::Oracle) => {
23006 self.write_keyword("CLOB");
23008 }
23009 Some(DialectType::DuckDB) | Some(DialectType::Materialize) => {
23010 self.write_keyword("TEXT");
23012 if let Some(n) = length {
23013 self.write(&format!("({})", n));
23014 }
23015 }
23016 Some(DialectType::Presto)
23017 | Some(DialectType::Trino)
23018 | Some(DialectType::Drill)
23019 | Some(DialectType::Dremio) => {
23020 self.write_keyword("VARCHAR");
23022 if let Some(n) = length {
23023 self.write(&format!("({})", n));
23024 }
23025 }
23026 Some(DialectType::Snowflake) => {
23027 self.write_keyword("STRING");
23030 if let Some(n) = length {
23031 self.write(&format!("({})", n));
23032 }
23033 }
23034 _ => {
23035 self.write_keyword("STRING");
23037 if let Some(n) = length {
23038 self.write(&format!("({})", n));
23039 }
23040 }
23041 }
23042 }
23043 DataType::Binary { length } => {
23044 match self.config.dialect {
23046 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23047 self.write_keyword("BYTEA");
23048 if let Some(n) = length {
23049 self.write(&format!("({})", n));
23050 }
23051 }
23052 Some(DialectType::Redshift) => {
23053 self.write_keyword("VARBYTE");
23054 if let Some(n) = length {
23055 self.write(&format!("({})", n));
23056 }
23057 }
23058 Some(DialectType::DuckDB)
23059 | Some(DialectType::SQLite)
23060 | Some(DialectType::Oracle) => {
23061 self.write_keyword("BLOB");
23063 if let Some(n) = length {
23064 self.write(&format!("({})", n));
23065 }
23066 }
23067 Some(DialectType::Presto)
23068 | Some(DialectType::Trino)
23069 | Some(DialectType::Athena)
23070 | Some(DialectType::Drill)
23071 | Some(DialectType::Dremio) => {
23072 self.write_keyword("VARBINARY");
23074 if let Some(n) = length {
23075 self.write(&format!("({})", n));
23076 }
23077 }
23078 Some(DialectType::ClickHouse) => {
23079 if self.clickhouse_nullable_depth < 0 {
23081 self.write("BINARY");
23082 } else {
23083 self.write("Nullable(BINARY");
23084 }
23085 if let Some(n) = length {
23086 self.write(&format!("({})", n));
23087 }
23088 if self.clickhouse_nullable_depth >= 0 {
23089 self.write(")");
23090 }
23091 }
23092 _ => {
23093 self.write_keyword("BINARY");
23094 if let Some(n) = length {
23095 self.write(&format!("({})", n));
23096 }
23097 }
23098 }
23099 }
23100 DataType::VarBinary { length } => {
23101 match self.config.dialect {
23103 Some(DialectType::PostgreSQL) | Some(DialectType::Materialize) => {
23104 self.write_keyword("BYTEA");
23105 if let Some(n) = length {
23106 self.write(&format!("({})", n));
23107 }
23108 }
23109 Some(DialectType::Redshift) => {
23110 self.write_keyword("VARBYTE");
23111 if let Some(n) = length {
23112 self.write(&format!("({})", n));
23113 }
23114 }
23115 Some(DialectType::DuckDB)
23116 | Some(DialectType::SQLite)
23117 | Some(DialectType::Oracle) => {
23118 self.write_keyword("BLOB");
23120 if let Some(n) = length {
23121 self.write(&format!("({})", n));
23122 }
23123 }
23124 Some(DialectType::Exasol) => {
23125 self.write_keyword("VARCHAR");
23127 }
23128 Some(DialectType::Spark)
23129 | Some(DialectType::Hive)
23130 | Some(DialectType::Databricks) => {
23131 self.write_keyword("BINARY");
23133 if let Some(n) = length {
23134 self.write(&format!("({})", n));
23135 }
23136 }
23137 Some(DialectType::ClickHouse) => {
23138 self.write_clickhouse_type("String");
23140 }
23141 _ => {
23142 self.write_keyword("VARBINARY");
23143 if let Some(n) = length {
23144 self.write(&format!("({})", n));
23145 }
23146 }
23147 }
23148 }
23149 DataType::Blob => {
23150 match self.config.dialect {
23152 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
23153 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
23154 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
23155 self.write_keyword("VARBINARY")
23156 }
23157 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
23158 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
23159 Some(DialectType::Presto)
23160 | Some(DialectType::Trino)
23161 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
23162 Some(DialectType::DuckDB) => {
23163 self.write_keyword("VARBINARY");
23166 }
23167 Some(DialectType::Spark)
23168 | Some(DialectType::Databricks)
23169 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
23170 Some(DialectType::ClickHouse) => {
23171 self.write("Nullable(String)");
23175 }
23176 _ => self.write_keyword("BLOB"),
23177 }
23178 }
23179 DataType::Bit { length } => {
23180 match self.config.dialect {
23182 Some(DialectType::Dremio)
23183 | Some(DialectType::Spark)
23184 | Some(DialectType::Databricks)
23185 | Some(DialectType::Hive)
23186 | Some(DialectType::Snowflake)
23187 | Some(DialectType::BigQuery)
23188 | Some(DialectType::Presto)
23189 | Some(DialectType::Trino)
23190 | Some(DialectType::ClickHouse)
23191 | Some(DialectType::Redshift) => {
23192 self.write_keyword("BOOLEAN");
23194 }
23195 _ => {
23196 self.write_keyword("BIT");
23197 if let Some(n) = length {
23198 self.write(&format!("({})", n));
23199 }
23200 }
23201 }
23202 }
23203 DataType::VarBit { length } => {
23204 self.write_keyword("VARBIT");
23205 if let Some(n) = length {
23206 self.write(&format!("({})", n));
23207 }
23208 }
23209 DataType::Date => self.write_keyword("DATE"),
23210 DataType::Time {
23211 precision,
23212 timezone,
23213 } => {
23214 if *timezone {
23215 match self.config.dialect {
23217 Some(DialectType::DuckDB) => {
23218 self.write_keyword("TIMETZ");
23220 }
23221 Some(DialectType::PostgreSQL) => {
23222 self.write_keyword("TIMETZ");
23224 if let Some(p) = precision {
23225 self.write(&format!("({})", p));
23226 }
23227 }
23228 _ => {
23229 self.write_keyword("TIME");
23231 if let Some(p) = precision {
23232 self.write(&format!("({})", p));
23233 }
23234 self.write_keyword(" WITH TIME ZONE");
23235 }
23236 }
23237 } else {
23238 if matches!(
23240 self.config.dialect,
23241 Some(DialectType::Spark)
23242 | Some(DialectType::Databricks)
23243 | Some(DialectType::Hive)
23244 ) {
23245 self.write_keyword("TIMESTAMP");
23246 } else {
23247 self.write_keyword("TIME");
23248 if let Some(p) = precision {
23249 self.write(&format!("({})", p));
23250 }
23251 }
23252 }
23253 }
23254 DataType::Timestamp {
23255 precision,
23256 timezone,
23257 } => {
23258 match self.config.dialect {
23260 Some(DialectType::ClickHouse) => {
23261 self.write("DateTime");
23262 if let Some(p) = precision {
23263 self.write(&format!("({})", p));
23264 }
23265 }
23266 Some(DialectType::TSQL) => {
23267 if *timezone {
23268 self.write_keyword("DATETIMEOFFSET");
23269 } else {
23270 self.write_keyword("DATETIME2");
23271 }
23272 if let Some(p) = precision {
23273 self.write(&format!("({})", p));
23274 }
23275 }
23276 Some(DialectType::MySQL) => {
23277 self.write_keyword("TIMESTAMP");
23279 if let Some(p) = precision {
23280 self.write(&format!("({})", p));
23281 }
23282 }
23283 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
23284 self.write_keyword("DATETIME");
23286 if let Some(p) = precision {
23287 self.write(&format!("({})", p));
23288 }
23289 }
23290 Some(DialectType::BigQuery) => {
23291 if *timezone {
23293 self.write_keyword("TIMESTAMP");
23294 } else {
23295 self.write_keyword("DATETIME");
23296 }
23297 }
23298 Some(DialectType::DuckDB) => {
23299 if *timezone {
23301 self.write_keyword("TIMESTAMPTZ");
23302 } else {
23303 self.write_keyword("TIMESTAMP");
23304 if let Some(p) = precision {
23305 self.write(&format!("({})", p));
23306 }
23307 }
23308 }
23309 _ => {
23310 if *timezone && !self.config.tz_to_with_time_zone {
23311 self.write_keyword("TIMESTAMPTZ");
23313 if let Some(p) = precision {
23314 self.write(&format!("({})", p));
23315 }
23316 } else {
23317 self.write_keyword("TIMESTAMP");
23318 if let Some(p) = precision {
23319 self.write(&format!("({})", p));
23320 }
23321 if *timezone {
23322 self.write_space();
23323 self.write_keyword("WITH TIME ZONE");
23324 }
23325 }
23326 }
23327 }
23328 }
23329 DataType::Interval { unit, to } => {
23330 self.write_keyword("INTERVAL");
23331 if let Some(u) = unit {
23332 self.write_space();
23333 self.write_keyword(u);
23334 }
23335 if let Some(t) = to {
23337 self.write_space();
23338 self.write_keyword("TO");
23339 self.write_space();
23340 self.write_keyword(t);
23341 }
23342 }
23343 DataType::Json => {
23344 match self.config.dialect {
23346 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
23349 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23350 _ => self.write_keyword("JSON"),
23351 }
23352 }
23353 DataType::JsonB => {
23354 match self.config.dialect {
23356 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
23357 Some(DialectType::Doris) => self.write_keyword("JSONB"),
23358 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
23359 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23360 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
23363 }
23364 DataType::Uuid => {
23365 match self.config.dialect {
23367 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
23368 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
23369 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
23370 Some(DialectType::BigQuery)
23371 | Some(DialectType::Spark)
23372 | Some(DialectType::Databricks) => self.write_keyword("STRING"),
23373 _ => self.write_keyword("UUID"),
23374 }
23375 }
23376 DataType::Array {
23377 element_type,
23378 dimension,
23379 } => {
23380 match self.config.dialect {
23382 Some(DialectType::PostgreSQL)
23383 | Some(DialectType::Redshift)
23384 | Some(DialectType::DuckDB) => {
23385 self.generate_data_type(element_type)?;
23387 if let Some(dim) = dimension {
23388 self.write(&format!("[{}]", dim));
23389 } else {
23390 self.write("[]");
23391 }
23392 }
23393 Some(DialectType::BigQuery) => {
23394 self.write_keyword("ARRAY<");
23395 self.generate_data_type(element_type)?;
23396 self.write(">");
23397 }
23398 Some(DialectType::Snowflake)
23399 | Some(DialectType::Presto)
23400 | Some(DialectType::Trino)
23401 | Some(DialectType::ClickHouse) => {
23402 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23404 self.write("Array(");
23405 } else {
23406 self.write_keyword("ARRAY(");
23407 }
23408 self.generate_data_type(element_type)?;
23409 self.write(")");
23410 }
23411 Some(DialectType::TSQL)
23412 | Some(DialectType::MySQL)
23413 | Some(DialectType::Oracle) => {
23414 match self.config.dialect {
23417 Some(DialectType::MySQL) => self.write_keyword("JSON"),
23418 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
23419 _ => self.write_keyword("JSON"),
23420 }
23421 }
23422 _ => {
23423 self.write_keyword("ARRAY<");
23425 self.generate_data_type(element_type)?;
23426 self.write(">");
23427 }
23428 }
23429 }
23430 DataType::List { element_type } => {
23431 self.generate_data_type(element_type)?;
23433 self.write_keyword(" LIST");
23434 }
23435 DataType::Map {
23436 key_type,
23437 value_type,
23438 } => {
23439 match self.config.dialect {
23441 Some(DialectType::Materialize) => {
23442 self.write_keyword("MAP[");
23444 self.generate_data_type(key_type)?;
23445 self.write(" => ");
23446 self.generate_data_type(value_type)?;
23447 self.write("]");
23448 }
23449 Some(DialectType::Snowflake)
23450 | Some(DialectType::RisingWave)
23451 | Some(DialectType::DuckDB)
23452 | Some(DialectType::Presto)
23453 | Some(DialectType::Trino)
23454 | Some(DialectType::Athena) => {
23455 self.write_keyword("MAP(");
23456 self.generate_data_type(key_type)?;
23457 self.write(", ");
23458 self.generate_data_type(value_type)?;
23459 self.write(")");
23460 }
23461 Some(DialectType::ClickHouse) => {
23462 self.write("Map(");
23465 self.clickhouse_nullable_depth = -1; self.generate_data_type(key_type)?;
23467 self.clickhouse_nullable_depth = 0;
23468 self.write(", ");
23469 self.generate_data_type(value_type)?;
23470 self.write(")");
23471 }
23472 _ => {
23473 self.write_keyword("MAP<");
23474 self.generate_data_type(key_type)?;
23475 self.write(", ");
23476 self.generate_data_type(value_type)?;
23477 self.write(">");
23478 }
23479 }
23480 }
23481 DataType::Vector {
23482 element_type,
23483 dimension,
23484 } => {
23485 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
23486 self.write_keyword("VECTOR(");
23488 if let Some(dim) = dimension {
23489 self.write(&dim.to_string());
23490 }
23491 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
23493 DataType::TinyInt { .. } => Some("I8"),
23494 DataType::SmallInt { .. } => Some("I16"),
23495 DataType::Int { .. } => Some("I32"),
23496 DataType::BigInt { .. } => Some("I64"),
23497 DataType::Float { .. } => Some("F32"),
23498 DataType::Double { .. } => Some("F64"),
23499 _ => None,
23500 });
23501 if let Some(alias) = type_alias {
23502 if dimension.is_some() {
23503 self.write(", ");
23504 }
23505 self.write(alias);
23506 }
23507 self.write(")");
23508 } else {
23509 self.write_keyword("VECTOR(");
23511 if let Some(ref et) = element_type {
23512 self.generate_data_type(et)?;
23513 if dimension.is_some() {
23514 self.write(", ");
23515 }
23516 }
23517 if let Some(dim) = dimension {
23518 self.write(&dim.to_string());
23519 }
23520 self.write(")");
23521 }
23522 }
23523 DataType::Object { fields, modifier } => {
23524 self.write_keyword("OBJECT(");
23525 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
23526 if i > 0 {
23527 self.write(", ");
23528 }
23529 self.write(name);
23530 self.write(" ");
23531 self.generate_data_type(dt)?;
23532 if *not_null {
23533 self.write_keyword(" NOT NULL");
23534 }
23535 }
23536 self.write(")");
23537 if let Some(mod_str) = modifier {
23538 self.write(" ");
23539 self.write_keyword(mod_str);
23540 }
23541 }
23542 DataType::Struct { fields, nested } => {
23543 match self.config.dialect {
23545 Some(DialectType::Snowflake) => {
23546 self.write_keyword("OBJECT(");
23548 for (i, field) in fields.iter().enumerate() {
23549 if i > 0 {
23550 self.write(", ");
23551 }
23552 if !field.name.is_empty() {
23553 self.write(&field.name);
23554 self.write(" ");
23555 }
23556 self.generate_data_type(&field.data_type)?;
23557 }
23558 self.write(")");
23559 }
23560 Some(DialectType::Presto) | Some(DialectType::Trino) => {
23561 self.write_keyword("ROW(");
23563 for (i, field) in fields.iter().enumerate() {
23564 if i > 0 {
23565 self.write(", ");
23566 }
23567 if !field.name.is_empty() {
23568 self.write(&field.name);
23569 self.write(" ");
23570 }
23571 self.generate_data_type(&field.data_type)?;
23572 }
23573 self.write(")");
23574 }
23575 Some(DialectType::DuckDB) => {
23576 self.write_keyword("STRUCT(");
23578 for (i, field) in fields.iter().enumerate() {
23579 if i > 0 {
23580 self.write(", ");
23581 }
23582 if !field.name.is_empty() {
23583 self.write(&field.name);
23584 self.write(" ");
23585 }
23586 self.generate_data_type(&field.data_type)?;
23587 }
23588 self.write(")");
23589 }
23590 Some(DialectType::ClickHouse) => {
23591 self.write("Tuple(");
23593 for (i, field) in fields.iter().enumerate() {
23594 if i > 0 {
23595 self.write(", ");
23596 }
23597 if !field.name.is_empty() {
23598 self.write(&field.name);
23599 self.write(" ");
23600 }
23601 self.generate_data_type(&field.data_type)?;
23602 }
23603 self.write(")");
23604 }
23605 Some(DialectType::SingleStore) => {
23606 self.write_keyword("RECORD(");
23608 for (i, field) in fields.iter().enumerate() {
23609 if i > 0 {
23610 self.write(", ");
23611 }
23612 if !field.name.is_empty() {
23613 self.write(&field.name);
23614 self.write(" ");
23615 }
23616 self.generate_data_type(&field.data_type)?;
23617 }
23618 self.write(")");
23619 }
23620 _ => {
23621 let force_angle_brackets = matches!(
23623 self.config.dialect,
23624 Some(DialectType::Hive)
23625 | Some(DialectType::Spark)
23626 | Some(DialectType::Databricks)
23627 );
23628 if *nested && !force_angle_brackets {
23629 self.write_keyword("STRUCT(");
23630 for (i, field) in fields.iter().enumerate() {
23631 if i > 0 {
23632 self.write(", ");
23633 }
23634 if !field.name.is_empty() {
23635 self.write(&field.name);
23636 self.write(" ");
23637 }
23638 self.generate_data_type(&field.data_type)?;
23639 }
23640 self.write(")");
23641 } else {
23642 self.write_keyword("STRUCT<");
23643 for (i, field) in fields.iter().enumerate() {
23644 if i > 0 {
23645 self.write(", ");
23646 }
23647 if !field.name.is_empty() {
23648 self.write(&field.name);
23650 self.write(self.config.struct_field_sep);
23651 }
23652 self.generate_data_type(&field.data_type)?;
23654 if let Some(comment) = &field.comment {
23656 self.write(" COMMENT '");
23657 self.write(comment);
23658 self.write("'");
23659 }
23660 if !field.options.is_empty() {
23662 self.write(" ");
23663 self.generate_options_clause(&field.options)?;
23664 }
23665 }
23666 self.write(">");
23667 }
23668 }
23669 }
23670 }
23671 DataType::Enum {
23672 values,
23673 assignments,
23674 } => {
23675 if self.config.dialect == Some(DialectType::ClickHouse) {
23678 self.write("Enum(");
23679 } else {
23680 self.write_keyword("ENUM(");
23681 }
23682 for (i, val) in values.iter().enumerate() {
23683 if i > 0 {
23684 self.write(", ");
23685 }
23686 self.write("'");
23687 self.write(val);
23688 self.write("'");
23689 if let Some(Some(assignment)) = assignments.get(i) {
23690 self.write(" = ");
23691 self.write(assignment);
23692 }
23693 }
23694 self.write(")");
23695 }
23696 DataType::Set { values } => {
23697 self.write_keyword("SET(");
23699 for (i, val) in values.iter().enumerate() {
23700 if i > 0 {
23701 self.write(", ");
23702 }
23703 self.write("'");
23704 self.write(val);
23705 self.write("'");
23706 }
23707 self.write(")");
23708 }
23709 DataType::Union { fields } => {
23710 self.write_keyword("UNION(");
23712 for (i, (name, dt)) in fields.iter().enumerate() {
23713 if i > 0 {
23714 self.write(", ");
23715 }
23716 if !name.is_empty() {
23717 self.write(name);
23718 self.write(" ");
23719 }
23720 self.generate_data_type(dt)?;
23721 }
23722 self.write(")");
23723 }
23724 DataType::Nullable { inner } => {
23725 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23727 self.write("Nullable(");
23728 let saved_depth = self.clickhouse_nullable_depth;
23730 self.clickhouse_nullable_depth = -1;
23731 self.generate_data_type(inner)?;
23732 self.clickhouse_nullable_depth = saved_depth;
23733 self.write(")");
23734 } else {
23735 match inner.as_ref() {
23737 DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
23738 self.generate_data_type(&DataType::Timestamp {
23739 precision: None,
23740 timezone: false,
23741 })?;
23742 }
23743 _ => {
23744 self.generate_data_type(inner)?;
23745 }
23746 }
23747 }
23748 }
23749 DataType::Custom { name } => {
23750 let name_upper = name.to_ascii_uppercase();
23752 match self.config.dialect {
23753 Some(DialectType::ClickHouse) => {
23754 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
23755 (name_upper[..idx].to_string(), &name[idx..])
23756 } else {
23757 (name_upper.clone(), "")
23758 };
23759 let mapped = match base_upper.as_str() {
23760 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ"
23761 | "SMALLDATETIME" | "DATETIME2" => "DateTime",
23762 "DATETIME64" => "DateTime64",
23763 "DATE32" => "Date32",
23764 "INT" => "Int32",
23765 "MEDIUMINT" => "Int32",
23766 "INT8" => "Int8",
23767 "INT16" => "Int16",
23768 "INT32" => "Int32",
23769 "INT64" => "Int64",
23770 "INT128" => "Int128",
23771 "INT256" => "Int256",
23772 "UINT8" => "UInt8",
23773 "UINT16" => "UInt16",
23774 "UINT32" => "UInt32",
23775 "UINT64" => "UInt64",
23776 "UINT128" => "UInt128",
23777 "UINT256" => "UInt256",
23778 "FLOAT32" => "Float32",
23779 "FLOAT64" => "Float64",
23780 "DECIMAL32" => "Decimal32",
23781 "DECIMAL64" => "Decimal64",
23782 "DECIMAL128" => "Decimal128",
23783 "DECIMAL256" => "Decimal256",
23784 "ENUM" => "Enum",
23785 "ENUM8" => "Enum8",
23786 "ENUM16" => "Enum16",
23787 "FIXEDSTRING" => "FixedString",
23788 "NESTED" => "Nested",
23789 "LOWCARDINALITY" => "LowCardinality",
23790 "NULLABLE" => "Nullable",
23791 "IPV4" => "IPv4",
23792 "IPV6" => "IPv6",
23793 "POINT" => "Point",
23794 "RING" => "Ring",
23795 "LINESTRING" => "LineString",
23796 "MULTILINESTRING" => "MultiLineString",
23797 "POLYGON" => "Polygon",
23798 "MULTIPOLYGON" => "MultiPolygon",
23799 "AGGREGATEFUNCTION" => "AggregateFunction",
23800 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
23801 "DYNAMIC" => "Dynamic",
23802 _ => "",
23803 };
23804 if mapped.is_empty() {
23805 self.write(name);
23806 } else {
23807 self.write(mapped);
23808 self.write(suffix);
23809 }
23810 }
23811 Some(DialectType::MySQL)
23812 if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" =>
23813 {
23814 self.write_keyword("TIMESTAMP");
23816 }
23817 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
23818 self.write_keyword("SQL_VARIANT");
23819 }
23820 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
23821 self.write_keyword("DECIMAL(38, 5)");
23822 }
23823 Some(DialectType::Exasol) => {
23824 match name_upper.as_str() {
23826 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
23828 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
23830 "MEDIUMINT" => self.write_keyword("INT"),
23832 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => {
23834 self.write_keyword("DECIMAL")
23835 }
23836 "DATETIME" => self.write_keyword("TIMESTAMP"),
23838 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
23839 _ => self.write(name),
23840 }
23841 }
23842 Some(DialectType::Dremio) => {
23843 match name_upper.as_str() {
23845 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
23846 "ARRAY" => self.write_keyword("LIST"),
23847 "NCHAR" => self.write_keyword("VARCHAR"),
23848 _ => self.write(name),
23849 }
23850 }
23851 _ => {
23853 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
23855 (name_upper[..idx].to_string(), Some(&name[idx..]))
23856 } else {
23857 (name_upper.clone(), None)
23858 };
23859
23860 match base_upper.as_str() {
23861 "INT64"
23862 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23863 {
23864 self.write_keyword("BIGINT");
23865 }
23866 "FLOAT64"
23867 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23868 {
23869 self.write_keyword("DOUBLE");
23870 }
23871 "BOOL"
23872 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23873 {
23874 self.write_keyword("BOOLEAN");
23875 }
23876 "BYTES"
23877 if matches!(
23878 self.config.dialect,
23879 Some(DialectType::Spark)
23880 | Some(DialectType::Hive)
23881 | Some(DialectType::Databricks)
23882 ) =>
23883 {
23884 self.write_keyword("BINARY");
23885 }
23886 "BYTES"
23887 if !matches!(self.config.dialect, Some(DialectType::BigQuery)) =>
23888 {
23889 self.write_keyword("VARBINARY");
23890 }
23891 "DATETIME2" | "SMALLDATETIME"
23893 if !matches!(
23894 self.config.dialect,
23895 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23896 ) =>
23897 {
23898 if matches!(
23900 self.config.dialect,
23901 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
23902 ) {
23903 self.write_keyword("TIMESTAMP");
23904 if let Some(args) = _args_str {
23905 self.write(args);
23906 }
23907 } else {
23908 self.write_keyword("TIMESTAMP");
23909 }
23910 }
23911 "DATETIMEOFFSET"
23913 if !matches!(
23914 self.config.dialect,
23915 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23916 ) =>
23917 {
23918 if matches!(
23919 self.config.dialect,
23920 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
23921 ) {
23922 self.write_keyword("TIMESTAMPTZ");
23923 if let Some(args) = _args_str {
23924 self.write(args);
23925 }
23926 } else {
23927 self.write_keyword("TIMESTAMPTZ");
23928 }
23929 }
23930 "UNIQUEIDENTIFIER"
23932 if !matches!(
23933 self.config.dialect,
23934 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23935 ) =>
23936 {
23937 match self.config.dialect {
23938 Some(DialectType::Spark)
23939 | Some(DialectType::Databricks)
23940 | Some(DialectType::Hive) => self.write_keyword("STRING"),
23941 _ => self.write_keyword("UUID"),
23942 }
23943 }
23944 "BIT"
23946 if !matches!(
23947 self.config.dialect,
23948 Some(DialectType::TSQL)
23949 | Some(DialectType::Fabric)
23950 | Some(DialectType::PostgreSQL)
23951 | Some(DialectType::MySQL)
23952 | Some(DialectType::DuckDB)
23953 ) =>
23954 {
23955 self.write_keyword("BOOLEAN");
23956 }
23957 "NVARCHAR"
23959 if !matches!(
23960 self.config.dialect,
23961 Some(DialectType::TSQL) | Some(DialectType::Fabric)
23962 ) =>
23963 {
23964 match self.config.dialect {
23965 Some(DialectType::Oracle) => {
23966 self.write_keyword("NVARCHAR2");
23968 if let Some(args) = _args_str {
23969 self.write(args);
23970 }
23971 }
23972 Some(DialectType::BigQuery) => {
23973 self.write_keyword("STRING");
23975 }
23976 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
23977 self.write_keyword("TEXT");
23978 if let Some(args) = _args_str {
23979 self.write(args);
23980 }
23981 }
23982 Some(DialectType::Hive) => {
23983 self.write_keyword("STRING");
23985 }
23986 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
23987 if _args_str.is_some() {
23988 self.write_keyword("VARCHAR");
23989 self.write(_args_str.unwrap());
23990 } else {
23991 self.write_keyword("STRING");
23992 }
23993 }
23994 _ => {
23995 self.write_keyword("VARCHAR");
23996 if let Some(args) = _args_str {
23997 self.write(args);
23998 }
23999 }
24000 }
24001 }
24002 "NCHAR"
24004 if !matches!(
24005 self.config.dialect,
24006 Some(DialectType::TSQL) | Some(DialectType::Fabric)
24007 ) =>
24008 {
24009 match self.config.dialect {
24010 Some(DialectType::Oracle) => {
24011 self.write_keyword("NCHAR");
24013 if let Some(args) = _args_str {
24014 self.write(args);
24015 }
24016 }
24017 Some(DialectType::BigQuery) => {
24018 self.write_keyword("STRING");
24020 }
24021 Some(DialectType::Hive) => {
24022 self.write_keyword("STRING");
24024 }
24025 Some(DialectType::SQLite) | Some(DialectType::DuckDB) => {
24026 self.write_keyword("TEXT");
24027 if let Some(args) = _args_str {
24028 self.write(args);
24029 }
24030 }
24031 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
24032 if _args_str.is_some() {
24033 self.write_keyword("CHAR");
24034 self.write(_args_str.unwrap());
24035 } else {
24036 self.write_keyword("STRING");
24037 }
24038 }
24039 _ => {
24040 self.write_keyword("CHAR");
24041 if let Some(args) = _args_str {
24042 self.write(args);
24043 }
24044 }
24045 }
24046 }
24047 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => match self.config.dialect {
24050 Some(DialectType::MySQL)
24051 | Some(DialectType::SingleStore)
24052 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24053 Some(DialectType::Spark)
24054 | Some(DialectType::Databricks)
24055 | Some(DialectType::Hive) => self.write_keyword("TEXT"),
24056 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
24057 Some(DialectType::Presto)
24058 | Some(DialectType::Trino)
24059 | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
24060 Some(DialectType::Snowflake)
24061 | Some(DialectType::Redshift)
24062 | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
24063 _ => self.write_keyword("TEXT"),
24064 },
24065 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => match self.config.dialect {
24068 Some(DialectType::MySQL)
24069 | Some(DialectType::SingleStore)
24070 | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
24071 Some(DialectType::Spark)
24072 | Some(DialectType::Databricks)
24073 | Some(DialectType::Hive) => self.write_keyword("BLOB"),
24074 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
24075 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
24076 Some(DialectType::Presto)
24077 | Some(DialectType::Trino)
24078 | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
24079 Some(DialectType::Snowflake)
24080 | Some(DialectType::Redshift)
24081 | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
24082 _ => self.write_keyword("BLOB"),
24083 },
24084 "LONGVARCHAR" => match self.config.dialect {
24086 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
24087 _ => self.write_keyword("VARCHAR"),
24088 },
24089 "DATETIME" => {
24091 match self.config.dialect {
24092 Some(DialectType::MySQL)
24093 | Some(DialectType::Doris)
24094 | Some(DialectType::StarRocks)
24095 | Some(DialectType::TSQL)
24096 | Some(DialectType::Fabric)
24097 | Some(DialectType::BigQuery)
24098 | Some(DialectType::SQLite)
24099 | Some(DialectType::Snowflake) => {
24100 self.write_keyword("DATETIME");
24101 if let Some(args) = _args_str {
24102 self.write(args);
24103 }
24104 }
24105 Some(_) => {
24106 self.write_keyword("TIMESTAMP");
24108 if let Some(args) = _args_str {
24109 self.write(args);
24110 }
24111 }
24112 None => {
24113 self.write(name);
24115 }
24116 }
24117 }
24118 "VARCHAR2"
24120 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24121 {
24122 match self.config.dialect {
24123 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24124 self.write_keyword("TEXT");
24125 }
24126 Some(DialectType::Hive)
24127 | Some(DialectType::Spark)
24128 | Some(DialectType::Databricks)
24129 | Some(DialectType::BigQuery)
24130 | Some(DialectType::ClickHouse)
24131 | Some(DialectType::StarRocks)
24132 | Some(DialectType::Doris) => {
24133 self.write_keyword("STRING");
24134 }
24135 _ => {
24136 self.write_keyword("VARCHAR");
24137 if let Some(args) = _args_str {
24138 self.write(args);
24139 }
24140 }
24141 }
24142 }
24143 "NVARCHAR2"
24144 if !matches!(self.config.dialect, Some(DialectType::Oracle)) =>
24145 {
24146 match self.config.dialect {
24147 Some(DialectType::DuckDB) | Some(DialectType::SQLite) => {
24148 self.write_keyword("TEXT");
24149 }
24150 Some(DialectType::Hive)
24151 | Some(DialectType::Spark)
24152 | Some(DialectType::Databricks)
24153 | Some(DialectType::BigQuery)
24154 | Some(DialectType::ClickHouse)
24155 | Some(DialectType::StarRocks)
24156 | Some(DialectType::Doris) => {
24157 self.write_keyword("STRING");
24158 }
24159 _ => {
24160 self.write_keyword("VARCHAR");
24161 if let Some(args) = _args_str {
24162 self.write(args);
24163 }
24164 }
24165 }
24166 }
24167 _ => self.write(name),
24168 }
24169 }
24170 }
24171 }
24172 DataType::Geometry { subtype, srid } => {
24173 match self.config.dialect {
24175 Some(DialectType::MySQL) => {
24176 if let Some(sub) = subtype {
24178 self.write_keyword(sub);
24179 if let Some(s) = srid {
24180 self.write(" SRID ");
24181 self.write(&s.to_string());
24182 }
24183 } else {
24184 self.write_keyword("GEOMETRY");
24185 }
24186 }
24187 Some(DialectType::BigQuery) => {
24188 self.write_keyword("GEOGRAPHY");
24190 }
24191 Some(DialectType::Teradata) => {
24192 self.write_keyword("ST_GEOMETRY");
24194 if subtype.is_some() || srid.is_some() {
24195 self.write("(");
24196 if let Some(sub) = subtype {
24197 self.write_keyword(sub);
24198 }
24199 if let Some(s) = srid {
24200 if subtype.is_some() {
24201 self.write(", ");
24202 }
24203 self.write(&s.to_string());
24204 }
24205 self.write(")");
24206 }
24207 }
24208 _ => {
24209 self.write_keyword("GEOMETRY");
24211 if subtype.is_some() || srid.is_some() {
24212 self.write("(");
24213 if let Some(sub) = subtype {
24214 self.write_keyword(sub);
24215 }
24216 if let Some(s) = srid {
24217 if subtype.is_some() {
24218 self.write(", ");
24219 }
24220 self.write(&s.to_string());
24221 }
24222 self.write(")");
24223 }
24224 }
24225 }
24226 }
24227 DataType::Geography { subtype, srid } => {
24228 match self.config.dialect {
24230 Some(DialectType::MySQL) => {
24231 if let Some(sub) = subtype {
24233 self.write_keyword(sub);
24234 } else {
24235 self.write_keyword("GEOMETRY");
24236 }
24237 let effective_srid = srid.unwrap_or(4326);
24239 self.write(" SRID ");
24240 self.write(&effective_srid.to_string());
24241 }
24242 Some(DialectType::BigQuery) => {
24243 self.write_keyword("GEOGRAPHY");
24245 }
24246 Some(DialectType::Snowflake) => {
24247 self.write_keyword("GEOGRAPHY");
24249 }
24250 _ => {
24251 self.write_keyword("GEOGRAPHY");
24253 if subtype.is_some() || srid.is_some() {
24254 self.write("(");
24255 if let Some(sub) = subtype {
24256 self.write_keyword(sub);
24257 }
24258 if let Some(s) = srid {
24259 if subtype.is_some() {
24260 self.write(", ");
24261 }
24262 self.write(&s.to_string());
24263 }
24264 self.write(")");
24265 }
24266 }
24267 }
24268 }
24269 DataType::CharacterSet { name } => {
24270 self.write_keyword("CHAR CHARACTER SET ");
24272 self.write(name);
24273 }
24274 _ => self.write("UNKNOWN"),
24275 }
24276 Ok(())
24277 }
24278
24279 #[inline]
24282 fn write(&mut self, s: &str) {
24283 self.output.push_str(s);
24284 }
24285
24286 #[inline]
24287 fn write_space(&mut self) {
24288 self.output.push(' ');
24289 }
24290
24291 #[inline]
24292 fn write_keyword(&mut self, keyword: &str) {
24293 if self.config.uppercase_keywords {
24294 self.output.push_str(keyword);
24295 } else {
24296 for b in keyword.bytes() {
24297 self.output.push(b.to_ascii_lowercase() as char);
24298 }
24299 }
24300 }
24301
24302 fn write_func_name(&mut self, name: &str) {
24304 let normalized = self.normalize_func_name(name);
24305 self.output.push_str(normalized.as_ref());
24306 }
24307
24308 fn convert_strptime_to_exasol_format(format: &str) -> String {
24312 let mut result = String::new();
24313 let chars: Vec<char> = format.chars().collect();
24314 let mut i = 0;
24315 while i < chars.len() {
24316 if chars[i] == '%' && i + 1 < chars.len() {
24317 let spec = chars[i + 1];
24318 let exasol_spec = match spec {
24319 'Y' => "YYYY",
24320 'y' => "YY",
24321 'm' => "MM",
24322 'd' => "DD",
24323 'H' => "HH",
24324 'M' => "MI",
24325 'S' => "SS",
24326 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
24338 result.push('%');
24340 result.push(spec);
24341 i += 2;
24342 continue;
24343 }
24344 };
24345 result.push_str(exasol_spec);
24346 i += 2;
24347 } else {
24348 result.push(chars[i]);
24349 i += 1;
24350 }
24351 }
24352 result
24353 }
24354
24355 fn convert_strptime_to_postgres_format(format: &str) -> String {
24359 let mut result = String::new();
24360 let chars: Vec<char> = format.chars().collect();
24361 let mut i = 0;
24362 while i < chars.len() {
24363 if chars[i] == '%' && i + 1 < chars.len() {
24364 if chars[i + 1] == '-' && i + 2 < chars.len() {
24366 let spec = chars[i + 2];
24367 let pg_spec = match spec {
24368 'd' => "FMDD",
24369 'm' => "FMMM",
24370 'H' => "FMHH24",
24371 'M' => "FMMI",
24372 'S' => "FMSS",
24373 _ => {
24374 result.push('%');
24375 result.push('-');
24376 result.push(spec);
24377 i += 3;
24378 continue;
24379 }
24380 };
24381 result.push_str(pg_spec);
24382 i += 3;
24383 continue;
24384 }
24385 let spec = chars[i + 1];
24386 let pg_spec = match spec {
24387 'Y' => "YYYY",
24388 'y' => "YY",
24389 'm' => "MM",
24390 'd' => "DD",
24391 'H' => "HH24",
24392 'I' => "HH12",
24393 'M' => "MI",
24394 'S' => "SS",
24395 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
24406 result.push('%');
24408 result.push(spec);
24409 i += 2;
24410 continue;
24411 }
24412 };
24413 result.push_str(pg_spec);
24414 i += 2;
24415 } else {
24416 result.push(chars[i]);
24417 i += 1;
24418 }
24419 }
24420 result
24421 }
24422
24423 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
24425 if self.config.limit_only_literals {
24426 if let Some(value) = Self::try_evaluate_constant(expr) {
24427 self.write(&value.to_string());
24428 return Ok(());
24429 }
24430 }
24431 self.generate_expression(expr)
24432 }
24433
24434 fn write_formatted_comment(&mut self, comment: &str) {
24438 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
24441 &comment[2..comment.len() - 2]
24444 } else if comment.starts_with("--") {
24445 &comment[2..]
24448 } else {
24449 comment
24451 };
24452 if content.trim().is_empty() {
24454 return;
24455 }
24456 let sanitized = content.replace("*/", "* /").replace("/*", "/ *");
24459 let content = &sanitized;
24460 self.output.push_str("/*");
24462 if !content.starts_with(' ') {
24463 self.output.push(' ');
24464 }
24465 self.output.push_str(content);
24466 if !content.ends_with(' ') {
24467 self.output.push(' ');
24468 }
24469 self.output.push_str("*/");
24470 }
24471
24472 fn escape_block_for_single_quote(&self, block: &str) -> String {
24475 let escape_backslash = matches!(
24476 self.config.dialect,
24477 Some(crate::dialects::DialectType::Snowflake)
24478 );
24479 let mut escaped = String::with_capacity(block.len() + 4);
24480 for ch in block.chars() {
24481 if ch == '\'' {
24482 escaped.push('\\');
24483 escaped.push('\'');
24484 } else if escape_backslash && ch == '\\' {
24485 escaped.push('\\');
24486 escaped.push('\\');
24487 } else {
24488 escaped.push(ch);
24489 }
24490 }
24491 escaped
24492 }
24493
24494 fn write_newline(&mut self) {
24495 self.output.push('\n');
24496 }
24497
24498 fn write_indent(&mut self) {
24499 for _ in 0..self.indent_level {
24500 self.output.push_str(self.config.indent);
24501 }
24502 }
24503
24504 fn too_wide(&self, args: &[String]) -> bool {
24510 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
24511 }
24512
24513 fn generate_to_string(&self, expr: &Expression) -> Result<String> {
24516 let config = GeneratorConfig {
24517 pretty: false,
24518 dialect: self.config.dialect,
24519 ..Default::default()
24520 };
24521 let mut gen = Generator::with_config(config);
24522 gen.generate_expression(expr)?;
24523 Ok(gen.output)
24524 }
24525
24526 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
24529 if self.config.pretty {
24530 self.write_newline();
24531 self.write_indent();
24532 self.write_keyword(keyword);
24533 self.write_newline();
24534 self.indent_level += 1;
24535 self.write_indent();
24536 self.generate_expression(condition)?;
24537 self.indent_level -= 1;
24538 } else {
24539 self.write_space();
24540 self.write_keyword(keyword);
24541 self.write_space();
24542 self.generate_expression(condition)?;
24543 }
24544 Ok(())
24545 }
24546
24547 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
24550 if exprs.is_empty() {
24551 return Ok(());
24552 }
24553
24554 if self.config.pretty {
24555 self.write_newline();
24556 self.write_indent();
24557 self.write_keyword(keyword);
24558 self.write_newline();
24559 self.indent_level += 1;
24560 for (i, expr) in exprs.iter().enumerate() {
24561 if i > 0 {
24562 self.write(",");
24563 self.write_newline();
24564 }
24565 self.write_indent();
24566 self.generate_expression(expr)?;
24567 }
24568 self.indent_level -= 1;
24569 } else {
24570 self.write_space();
24571 self.write_keyword(keyword);
24572 self.write_space();
24573 for (i, expr) in exprs.iter().enumerate() {
24574 if i > 0 {
24575 self.write(", ");
24576 }
24577 self.generate_expression(expr)?;
24578 }
24579 }
24580 Ok(())
24581 }
24582
24583 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
24585 if orderings.is_empty() {
24586 return Ok(());
24587 }
24588
24589 if self.config.pretty {
24590 self.write_newline();
24591 self.write_indent();
24592 self.write_keyword(keyword);
24593 self.write_newline();
24594 self.indent_level += 1;
24595 for (i, ordered) in orderings.iter().enumerate() {
24596 if i > 0 {
24597 self.write(",");
24598 self.write_newline();
24599 }
24600 self.write_indent();
24601 self.generate_ordered(ordered)?;
24602 }
24603 self.indent_level -= 1;
24604 } else {
24605 self.write_space();
24606 self.write_keyword(keyword);
24607 self.write_space();
24608 for (i, ordered) in orderings.iter().enumerate() {
24609 if i > 0 {
24610 self.write(", ");
24611 }
24612 self.generate_ordered(ordered)?;
24613 }
24614 }
24615 Ok(())
24616 }
24617
24618 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
24620 if windows.is_empty() {
24621 return Ok(());
24622 }
24623
24624 if self.config.pretty {
24625 self.write_newline();
24626 self.write_indent();
24627 self.write_keyword("WINDOW");
24628 self.write_newline();
24629 self.indent_level += 1;
24630 for (i, named_window) in windows.iter().enumerate() {
24631 if i > 0 {
24632 self.write(",");
24633 self.write_newline();
24634 }
24635 self.write_indent();
24636 self.generate_identifier(&named_window.name)?;
24637 self.write_space();
24638 self.write_keyword("AS");
24639 self.write(" (");
24640 self.generate_over(&named_window.spec)?;
24641 self.write(")");
24642 }
24643 self.indent_level -= 1;
24644 } else {
24645 self.write_space();
24646 self.write_keyword("WINDOW");
24647 self.write_space();
24648 for (i, named_window) in windows.iter().enumerate() {
24649 if i > 0 {
24650 self.write(", ");
24651 }
24652 self.generate_identifier(&named_window.name)?;
24653 self.write_space();
24654 self.write_keyword("AS");
24655 self.write(" (");
24656 self.generate_over(&named_window.spec)?;
24657 self.write(")");
24658 }
24659 }
24660 Ok(())
24661 }
24662
24663 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
24665 self.write_keyword("AI_AGG");
24667 self.write("(");
24668 self.generate_expression(&e.this)?;
24669 self.write(", ");
24670 self.generate_expression(&e.expression)?;
24671 self.write(")");
24672 Ok(())
24673 }
24674
24675 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
24676 self.write_keyword("AI_CLASSIFY");
24678 self.write("(");
24679 self.generate_expression(&e.this)?;
24680 if let Some(categories) = &e.categories {
24681 self.write(", ");
24682 self.generate_expression(categories)?;
24683 }
24684 if let Some(config) = &e.config {
24685 self.write(", ");
24686 self.generate_expression(config)?;
24687 }
24688 self.write(")");
24689 Ok(())
24690 }
24691
24692 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
24693 self.write_keyword("ADD");
24695 self.write_space();
24696 if e.exists {
24697 self.write_keyword("IF NOT EXISTS");
24698 self.write_space();
24699 }
24700 self.generate_expression(&e.this)?;
24701 if let Some(location) = &e.location {
24702 self.write_space();
24703 self.generate_expression(location)?;
24704 }
24705 Ok(())
24706 }
24707
24708 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
24709 self.write_keyword("ALGORITHM");
24711 self.write("=");
24712 self.generate_expression(&e.this)?;
24713 Ok(())
24714 }
24715
24716 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
24717 self.generate_expression(&e.this)?;
24719 self.write_space();
24720 self.write_keyword("AS");
24721 self.write(" (");
24722 for (i, expr) in e.expressions.iter().enumerate() {
24723 if i > 0 {
24724 self.write(", ");
24725 }
24726 self.generate_expression(expr)?;
24727 }
24728 self.write(")");
24729 Ok(())
24730 }
24731
24732 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
24733 self.write_keyword("ALLOWED_VALUES");
24735 self.write_space();
24736 for (i, expr) in e.expressions.iter().enumerate() {
24737 if i > 0 {
24738 self.write(", ");
24739 }
24740 self.generate_expression(expr)?;
24741 }
24742 Ok(())
24743 }
24744
24745 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
24746 self.write_keyword("ALTER COLUMN");
24748 self.write_space();
24749 self.generate_expression(&e.this)?;
24750
24751 if let Some(dtype) = &e.dtype {
24752 self.write_space();
24753 self.write_keyword("SET DATA TYPE");
24754 self.write_space();
24755 self.generate_expression(dtype)?;
24756 if let Some(collate) = &e.collate {
24757 self.write_space();
24758 self.write_keyword("COLLATE");
24759 self.write_space();
24760 self.generate_expression(collate)?;
24761 }
24762 if let Some(using) = &e.using {
24763 self.write_space();
24764 self.write_keyword("USING");
24765 self.write_space();
24766 self.generate_expression(using)?;
24767 }
24768 } else if let Some(default) = &e.default {
24769 self.write_space();
24770 self.write_keyword("SET DEFAULT");
24771 self.write_space();
24772 self.generate_expression(default)?;
24773 } else if let Some(comment) = &e.comment {
24774 self.write_space();
24775 self.write_keyword("COMMENT");
24776 self.write_space();
24777 self.generate_expression(comment)?;
24778 } else if let Some(drop) = &e.drop {
24779 self.write_space();
24780 self.write_keyword("DROP");
24781 self.write_space();
24782 self.generate_expression(drop)?;
24783 } else if let Some(visible) = &e.visible {
24784 self.write_space();
24785 self.generate_expression(visible)?;
24786 } else if let Some(rename_to) = &e.rename_to {
24787 self.write_space();
24788 self.write_keyword("RENAME TO");
24789 self.write_space();
24790 self.generate_expression(rename_to)?;
24791 } else if let Some(allow_null) = &e.allow_null {
24792 self.write_space();
24793 self.generate_expression(allow_null)?;
24794 }
24795 Ok(())
24796 }
24797
24798 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
24799 self.write_keyword("ALTER SESSION");
24801 self.write_space();
24802 if e.unset.is_some() {
24803 self.write_keyword("UNSET");
24804 } else {
24805 self.write_keyword("SET");
24806 }
24807 self.write_space();
24808 for (i, expr) in e.expressions.iter().enumerate() {
24809 if i > 0 {
24810 self.write(", ");
24811 }
24812 self.generate_expression(expr)?;
24813 }
24814 Ok(())
24815 }
24816
24817 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
24818 self.write_keyword("SET");
24820
24821 if let Some(opt) = &e.option {
24823 self.write_space();
24824 self.generate_expression(opt)?;
24825 }
24826
24827 if !e.expressions.is_empty() {
24830 let is_properties = e
24832 .expressions
24833 .iter()
24834 .any(|expr| matches!(expr, Expression::Eq(_)));
24835 if is_properties && e.option.is_none() {
24836 self.write_space();
24837 self.write_keyword("PROPERTIES");
24838 }
24839 self.write_space();
24840 for (i, expr) in e.expressions.iter().enumerate() {
24841 if i > 0 {
24842 self.write(", ");
24843 }
24844 self.generate_expression(expr)?;
24845 }
24846 }
24847
24848 if let Some(file_format) = &e.file_format {
24850 self.write(" ");
24851 self.write_keyword("STAGE_FILE_FORMAT");
24852 self.write(" = (");
24853 self.generate_space_separated_properties(file_format)?;
24854 self.write(")");
24855 }
24856
24857 if let Some(copy_options) = &e.copy_options {
24859 self.write(" ");
24860 self.write_keyword("STAGE_COPY_OPTIONS");
24861 self.write(" = (");
24862 self.generate_space_separated_properties(copy_options)?;
24863 self.write(")");
24864 }
24865
24866 if let Some(tag) = &e.tag {
24868 self.write(" ");
24869 self.write_keyword("TAG");
24870 self.write(" ");
24871 self.generate_expression(tag)?;
24872 }
24873
24874 Ok(())
24875 }
24876
24877 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
24879 match expr {
24880 Expression::Tuple(t) => {
24881 for (i, prop) in t.expressions.iter().enumerate() {
24882 if i > 0 {
24883 self.write(" ");
24884 }
24885 self.generate_expression(prop)?;
24886 }
24887 }
24888 _ => {
24889 self.generate_expression(expr)?;
24890 }
24891 }
24892 Ok(())
24893 }
24894
24895 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
24896 self.write_keyword("ALTER");
24898 if e.compound.is_some() {
24899 self.write_space();
24900 self.write_keyword("COMPOUND");
24901 }
24902 self.write_space();
24903 self.write_keyword("SORTKEY");
24904 self.write_space();
24905 if let Some(this) = &e.this {
24906 self.generate_expression(this)?;
24907 } else if !e.expressions.is_empty() {
24908 self.write("(");
24909 for (i, expr) in e.expressions.iter().enumerate() {
24910 if i > 0 {
24911 self.write(", ");
24912 }
24913 self.generate_expression(expr)?;
24914 }
24915 self.write(")");
24916 }
24917 Ok(())
24918 }
24919
24920 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
24921 self.write_keyword("ANALYZE");
24923 if !e.options.is_empty() {
24924 self.write_space();
24925 for (i, opt) in e.options.iter().enumerate() {
24926 if i > 0 {
24927 self.write_space();
24928 }
24929 if let Expression::Identifier(id) = opt {
24931 self.write_keyword(&id.name);
24932 } else {
24933 self.generate_expression(opt)?;
24934 }
24935 }
24936 }
24937 if let Some(kind) = &e.kind {
24938 self.write_space();
24939 self.write_keyword(kind);
24940 }
24941 if let Some(this) = &e.this {
24942 self.write_space();
24943 self.generate_expression(this)?;
24944 }
24945 if !e.columns.is_empty() {
24947 self.write("(");
24948 for (i, col) in e.columns.iter().enumerate() {
24949 if i > 0 {
24950 self.write(", ");
24951 }
24952 self.write(col);
24953 }
24954 self.write(")");
24955 }
24956 if let Some(partition) = &e.partition {
24957 self.write_space();
24958 self.generate_expression(partition)?;
24959 }
24960 if let Some(mode) = &e.mode {
24961 self.write_space();
24962 self.generate_expression(mode)?;
24963 }
24964 if let Some(expression) = &e.expression {
24965 self.write_space();
24966 self.generate_expression(expression)?;
24967 }
24968 if !e.properties.is_empty() {
24969 self.write_space();
24970 self.write_keyword(self.config.with_properties_prefix);
24971 self.write(" (");
24972 for (i, prop) in e.properties.iter().enumerate() {
24973 if i > 0 {
24974 self.write(", ");
24975 }
24976 self.generate_expression(prop)?;
24977 }
24978 self.write(")");
24979 }
24980 Ok(())
24981 }
24982
24983 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
24984 self.write_keyword("DELETE");
24986 if let Some(kind) = &e.kind {
24987 self.write_space();
24988 self.write_keyword(kind);
24989 }
24990 self.write_space();
24991 self.write_keyword("STATISTICS");
24992 Ok(())
24993 }
24994
24995 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
24996 if let Expression::Identifier(id) = e.this.as_ref() {
24999 self.write_keyword(&id.name);
25000 } else {
25001 self.generate_expression(&e.this)?;
25002 }
25003 self.write_space();
25004 self.write_keyword("HISTOGRAM ON");
25005 self.write_space();
25006 for (i, expr) in e.expressions.iter().enumerate() {
25007 if i > 0 {
25008 self.write(", ");
25009 }
25010 self.generate_expression(expr)?;
25011 }
25012 if let Some(expression) = &e.expression {
25013 self.write_space();
25014 self.generate_expression(expression)?;
25015 }
25016 if let Some(update_options) = &e.update_options {
25017 self.write_space();
25018 self.generate_expression(update_options)?;
25019 self.write_space();
25020 self.write_keyword("UPDATE");
25021 }
25022 Ok(())
25023 }
25024
25025 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
25026 self.write_keyword("LIST CHAINED ROWS");
25028 if let Some(expression) = &e.expression {
25029 self.write_space();
25030 self.write_keyword("INTO");
25031 self.write_space();
25032 self.generate_expression(expression)?;
25033 }
25034 Ok(())
25035 }
25036
25037 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
25038 self.write_keyword("SAMPLE");
25040 self.write_space();
25041 if let Some(sample) = &e.sample {
25042 self.generate_expression(sample)?;
25043 self.write_space();
25044 }
25045 self.write_keyword(&e.kind);
25046 Ok(())
25047 }
25048
25049 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
25050 self.write_keyword(&e.kind);
25052 if let Some(option) = &e.option {
25053 self.write_space();
25054 self.generate_expression(option)?;
25055 }
25056 self.write_space();
25057 self.write_keyword("STATISTICS");
25058 if let Some(this) = &e.this {
25059 self.write_space();
25060 self.generate_expression(this)?;
25061 }
25062 if !e.expressions.is_empty() {
25063 self.write_space();
25064 for (i, expr) in e.expressions.iter().enumerate() {
25065 if i > 0 {
25066 self.write(", ");
25067 }
25068 self.generate_expression(expr)?;
25069 }
25070 }
25071 Ok(())
25072 }
25073
25074 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
25075 self.write_keyword("VALIDATE");
25077 self.write_space();
25078 self.write_keyword(&e.kind);
25079 if let Some(this) = &e.this {
25080 self.write_space();
25081 if let Expression::Identifier(id) = this.as_ref() {
25083 self.write_keyword(&id.name);
25084 } else {
25085 self.generate_expression(this)?;
25086 }
25087 }
25088 if let Some(expression) = &e.expression {
25089 self.write_space();
25090 self.write_keyword("INTO");
25091 self.write_space();
25092 self.generate_expression(expression)?;
25093 }
25094 Ok(())
25095 }
25096
25097 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
25098 self.write_keyword("WITH");
25100 self.write_space();
25101 for (i, expr) in e.expressions.iter().enumerate() {
25102 if i > 0 {
25103 self.write(", ");
25104 }
25105 self.generate_expression(expr)?;
25106 }
25107 Ok(())
25108 }
25109
25110 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
25111 self.generate_expression(&e.this)?;
25114 self.write("(");
25115 for (i, arg) in e.expressions.iter().enumerate() {
25116 if i > 0 {
25117 self.write(", ");
25118 }
25119 self.generate_expression(arg)?;
25120 }
25121 self.write(")");
25122 Ok(())
25123 }
25124
25125 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
25126 self.generate_expression(&e.this)?;
25128 self.write("(");
25129 for (i, arg) in e.expressions.iter().enumerate() {
25130 if i > 0 {
25131 self.write(", ");
25132 }
25133 self.generate_expression(arg)?;
25134 }
25135 self.write(")");
25136 Ok(())
25137 }
25138
25139 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
25140 self.generate_expression(&e.this)?;
25142 self.write_space();
25143 self.write_keyword("APPLY");
25144 self.write("(");
25145 self.generate_expression(&e.expression)?;
25146 self.write(")");
25147 Ok(())
25148 }
25149
25150 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
25151 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
25153 self.write("(");
25154 self.generate_expression(&e.this)?;
25155 if let Some(percentile) = &e.percentile {
25156 self.write(", ");
25157 self.generate_expression(percentile)?;
25158 }
25159 self.write(")");
25160 Ok(())
25161 }
25162
25163 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
25164 self.write_keyword("APPROX_QUANTILE");
25166 self.write("(");
25167 self.generate_expression(&e.this)?;
25168 if let Some(quantile) = &e.quantile {
25169 self.write(", ");
25170 self.generate_expression(quantile)?;
25171 }
25172 if let Some(accuracy) = &e.accuracy {
25173 self.write(", ");
25174 self.generate_expression(accuracy)?;
25175 }
25176 if let Some(weight) = &e.weight {
25177 self.write(", ");
25178 self.generate_expression(weight)?;
25179 }
25180 self.write(")");
25181 Ok(())
25182 }
25183
25184 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
25185 self.write_keyword("APPROX_QUANTILES");
25187 self.write("(");
25188 self.generate_expression(&e.this)?;
25189 if let Some(expression) = &e.expression {
25190 self.write(", ");
25191 self.generate_expression(expression)?;
25192 }
25193 self.write(")");
25194 Ok(())
25195 }
25196
25197 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
25198 self.write_keyword("APPROX_TOP_K");
25200 self.write("(");
25201 self.generate_expression(&e.this)?;
25202 if let Some(expression) = &e.expression {
25203 self.write(", ");
25204 self.generate_expression(expression)?;
25205 }
25206 if let Some(counters) = &e.counters {
25207 self.write(", ");
25208 self.generate_expression(counters)?;
25209 }
25210 self.write(")");
25211 Ok(())
25212 }
25213
25214 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
25215 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
25217 self.write("(");
25218 self.generate_expression(&e.this)?;
25219 if let Some(expression) = &e.expression {
25220 self.write(", ");
25221 self.generate_expression(expression)?;
25222 }
25223 self.write(")");
25224 Ok(())
25225 }
25226
25227 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
25228 self.write_keyword("APPROX_TOP_K_COMBINE");
25230 self.write("(");
25231 self.generate_expression(&e.this)?;
25232 if let Some(expression) = &e.expression {
25233 self.write(", ");
25234 self.generate_expression(expression)?;
25235 }
25236 self.write(")");
25237 Ok(())
25238 }
25239
25240 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
25241 self.write_keyword("APPROX_TOP_K_ESTIMATE");
25243 self.write("(");
25244 self.generate_expression(&e.this)?;
25245 if let Some(expression) = &e.expression {
25246 self.write(", ");
25247 self.generate_expression(expression)?;
25248 }
25249 self.write(")");
25250 Ok(())
25251 }
25252
25253 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
25254 self.write_keyword("APPROX_TOP_SUM");
25256 self.write("(");
25257 self.generate_expression(&e.this)?;
25258 self.write(", ");
25259 self.generate_expression(&e.expression)?;
25260 if let Some(count) = &e.count {
25261 self.write(", ");
25262 self.generate_expression(count)?;
25263 }
25264 self.write(")");
25265 Ok(())
25266 }
25267
25268 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
25269 self.write_keyword("ARG_MAX");
25271 self.write("(");
25272 self.generate_expression(&e.this)?;
25273 self.write(", ");
25274 self.generate_expression(&e.expression)?;
25275 if let Some(count) = &e.count {
25276 self.write(", ");
25277 self.generate_expression(count)?;
25278 }
25279 self.write(")");
25280 Ok(())
25281 }
25282
25283 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
25284 self.write_keyword("ARG_MIN");
25286 self.write("(");
25287 self.generate_expression(&e.this)?;
25288 self.write(", ");
25289 self.generate_expression(&e.expression)?;
25290 if let Some(count) = &e.count {
25291 self.write(", ");
25292 self.generate_expression(count)?;
25293 }
25294 self.write(")");
25295 Ok(())
25296 }
25297
25298 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
25299 self.write_keyword("ARRAY_ALL");
25301 self.write("(");
25302 self.generate_expression(&e.this)?;
25303 self.write(", ");
25304 self.generate_expression(&e.expression)?;
25305 self.write(")");
25306 Ok(())
25307 }
25308
25309 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
25310 self.write_keyword("ARRAY_ANY");
25312 self.write("(");
25313 self.generate_expression(&e.this)?;
25314 self.write(", ");
25315 self.generate_expression(&e.expression)?;
25316 self.write(")");
25317 Ok(())
25318 }
25319
25320 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
25321 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
25323 self.write("(");
25324 for (i, expr) in e.expressions.iter().enumerate() {
25325 if i > 0 {
25326 self.write(", ");
25327 }
25328 self.generate_expression(expr)?;
25329 }
25330 self.write(")");
25331 Ok(())
25332 }
25333
25334 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
25335 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
25337 self.write("arraySum");
25338 } else {
25339 self.write_keyword("ARRAY_SUM");
25340 }
25341 self.write("(");
25342 self.generate_expression(&e.this)?;
25343 if let Some(expression) = &e.expression {
25344 self.write(", ");
25345 self.generate_expression(expression)?;
25346 }
25347 self.write(")");
25348 Ok(())
25349 }
25350
25351 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
25352 self.generate_expression(&e.this)?;
25354 self.write_space();
25355 self.write_keyword("AT");
25356 self.write_space();
25357 self.generate_expression(&e.expression)?;
25358 Ok(())
25359 }
25360
25361 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
25362 self.write_keyword("ATTACH");
25364 if e.exists {
25365 self.write_space();
25366 self.write_keyword("IF NOT EXISTS");
25367 }
25368 self.write_space();
25369 self.generate_expression(&e.this)?;
25370 if !e.expressions.is_empty() {
25371 self.write(" (");
25372 for (i, expr) in e.expressions.iter().enumerate() {
25373 if i > 0 {
25374 self.write(", ");
25375 }
25376 self.generate_expression(expr)?;
25377 }
25378 self.write(")");
25379 }
25380 Ok(())
25381 }
25382
25383 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
25384 self.generate_expression(&e.this)?;
25387 if let Some(expression) = &e.expression {
25388 self.write_space();
25389 self.generate_expression(expression)?;
25390 }
25391 Ok(())
25392 }
25393
25394 fn generate_auto_increment_keyword(
25398 &mut self,
25399 col: &crate::expressions::ColumnDef,
25400 ) -> Result<()> {
25401 use crate::dialects::DialectType;
25402 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
25403 self.write_keyword("IDENTITY");
25404 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25405 self.write("(");
25406 if let Some(ref start) = col.auto_increment_start {
25407 self.generate_expression(start)?;
25408 } else {
25409 self.write("0");
25410 }
25411 self.write(", ");
25412 if let Some(ref inc) = col.auto_increment_increment {
25413 self.generate_expression(inc)?;
25414 } else {
25415 self.write("1");
25416 }
25417 self.write(")");
25418 }
25419 } else if matches!(
25420 self.config.dialect,
25421 Some(DialectType::Snowflake) | Some(DialectType::SQLite)
25422 ) {
25423 self.write_keyword("AUTOINCREMENT");
25424 if let Some(ref start) = col.auto_increment_start {
25425 self.write_space();
25426 self.write_keyword("START");
25427 self.write_space();
25428 self.generate_expression(start)?;
25429 }
25430 if let Some(ref inc) = col.auto_increment_increment {
25431 self.write_space();
25432 self.write_keyword("INCREMENT");
25433 self.write_space();
25434 self.generate_expression(inc)?;
25435 }
25436 if let Some(order) = col.auto_increment_order {
25437 self.write_space();
25438 if order {
25439 self.write_keyword("ORDER");
25440 } else {
25441 self.write_keyword("NOORDER");
25442 }
25443 }
25444 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
25445 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25446 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25447 self.write(" (");
25448 let mut first = true;
25449 if let Some(ref start) = col.auto_increment_start {
25450 self.write_keyword("START WITH");
25451 self.write_space();
25452 self.generate_expression(start)?;
25453 first = false;
25454 }
25455 if let Some(ref inc) = col.auto_increment_increment {
25456 if !first {
25457 self.write_space();
25458 }
25459 self.write_keyword("INCREMENT BY");
25460 self.write_space();
25461 self.generate_expression(inc)?;
25462 }
25463 self.write(")");
25464 }
25465 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
25466 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25469 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
25470 } else {
25471 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
25472 }
25473 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25474 self.write(" (");
25475 let mut first = true;
25476 if let Some(ref start) = col.auto_increment_start {
25477 self.write_keyword("START WITH");
25478 self.write_space();
25479 self.generate_expression(start)?;
25480 first = false;
25481 }
25482 if let Some(ref inc) = col.auto_increment_increment {
25483 if !first {
25484 self.write_space();
25485 }
25486 self.write_keyword("INCREMENT BY");
25487 self.write_space();
25488 self.generate_expression(inc)?;
25489 }
25490 self.write(")");
25491 }
25492 } else if matches!(
25493 self.config.dialect,
25494 Some(DialectType::TSQL) | Some(DialectType::Fabric)
25495 ) {
25496 self.write_keyword("IDENTITY");
25497 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
25498 self.write("(");
25499 if let Some(ref start) = col.auto_increment_start {
25500 self.generate_expression(start)?;
25501 } else {
25502 self.write("0");
25503 }
25504 self.write(", ");
25505 if let Some(ref inc) = col.auto_increment_increment {
25506 self.generate_expression(inc)?;
25507 } else {
25508 self.write("1");
25509 }
25510 self.write(")");
25511 }
25512 } else {
25513 self.write_keyword("AUTO_INCREMENT");
25514 if let Some(ref start) = col.auto_increment_start {
25515 self.write_space();
25516 self.write_keyword("START");
25517 self.write_space();
25518 self.generate_expression(start)?;
25519 }
25520 if let Some(ref inc) = col.auto_increment_increment {
25521 self.write_space();
25522 self.write_keyword("INCREMENT");
25523 self.write_space();
25524 self.generate_expression(inc)?;
25525 }
25526 if let Some(order) = col.auto_increment_order {
25527 self.write_space();
25528 if order {
25529 self.write_keyword("ORDER");
25530 } else {
25531 self.write_keyword("NOORDER");
25532 }
25533 }
25534 }
25535 Ok(())
25536 }
25537
25538 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
25539 self.write_keyword("AUTO_INCREMENT");
25541 self.write("=");
25542 self.generate_expression(&e.this)?;
25543 Ok(())
25544 }
25545
25546 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
25547 self.write_keyword("AUTO_REFRESH");
25549 self.write("=");
25550 self.generate_expression(&e.this)?;
25551 Ok(())
25552 }
25553
25554 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
25555 self.write_keyword("BACKUP");
25557 self.write_space();
25558 self.generate_expression(&e.this)?;
25559 Ok(())
25560 }
25561
25562 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
25563 self.write_keyword("BASE64_DECODE_BINARY");
25565 self.write("(");
25566 self.generate_expression(&e.this)?;
25567 if let Some(alphabet) = &e.alphabet {
25568 self.write(", ");
25569 self.generate_expression(alphabet)?;
25570 }
25571 self.write(")");
25572 Ok(())
25573 }
25574
25575 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
25576 self.write_keyword("BASE64_DECODE_STRING");
25578 self.write("(");
25579 self.generate_expression(&e.this)?;
25580 if let Some(alphabet) = &e.alphabet {
25581 self.write(", ");
25582 self.generate_expression(alphabet)?;
25583 }
25584 self.write(")");
25585 Ok(())
25586 }
25587
25588 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
25589 self.write_keyword("BASE64_ENCODE");
25591 self.write("(");
25592 self.generate_expression(&e.this)?;
25593 if let Some(max_line_length) = &e.max_line_length {
25594 self.write(", ");
25595 self.generate_expression(max_line_length)?;
25596 }
25597 if let Some(alphabet) = &e.alphabet {
25598 self.write(", ");
25599 self.generate_expression(alphabet)?;
25600 }
25601 self.write(")");
25602 Ok(())
25603 }
25604
25605 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
25606 self.write_keyword("BLOCKCOMPRESSION");
25608 self.write("=");
25609 if let Some(autotemp) = &e.autotemp {
25610 self.write_keyword("AUTOTEMP");
25611 self.write("(");
25612 self.generate_expression(autotemp)?;
25613 self.write(")");
25614 }
25615 if let Some(always) = &e.always {
25616 self.generate_expression(always)?;
25617 }
25618 if let Some(default) = &e.default {
25619 self.generate_expression(default)?;
25620 }
25621 if let Some(manual) = &e.manual {
25622 self.generate_expression(manual)?;
25623 }
25624 if let Some(never) = &e.never {
25625 self.generate_expression(never)?;
25626 }
25627 Ok(())
25628 }
25629
25630 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
25631 self.write("((");
25633 self.generate_expression(&e.this)?;
25634 self.write(") ");
25635 self.write_keyword("AND");
25636 self.write(" (");
25637 self.generate_expression(&e.expression)?;
25638 self.write("))");
25639 Ok(())
25640 }
25641
25642 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
25643 self.write("((");
25645 self.generate_expression(&e.this)?;
25646 self.write(") ");
25647 self.write_keyword("OR");
25648 self.write(" (");
25649 self.generate_expression(&e.expression)?;
25650 self.write("))");
25651 Ok(())
25652 }
25653
25654 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
25655 self.write_keyword("BUILD");
25657 self.write_space();
25658 self.generate_expression(&e.this)?;
25659 Ok(())
25660 }
25661
25662 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
25663 self.generate_expression(&e.this)?;
25665 Ok(())
25666 }
25667
25668 fn generate_case_specific_column_constraint(
25669 &mut self,
25670 e: &CaseSpecificColumnConstraint,
25671 ) -> Result<()> {
25672 if e.not_.is_some() {
25674 self.write_keyword("NOT");
25675 self.write_space();
25676 }
25677 self.write_keyword("CASESPECIFIC");
25678 Ok(())
25679 }
25680
25681 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
25682 self.write_keyword("CAST");
25684 self.write("(");
25685 self.generate_expression(&e.this)?;
25686 if self.config.dialect == Some(DialectType::ClickHouse) {
25687 self.write(", ");
25689 } else {
25690 self.write_space();
25691 self.write_keyword("AS");
25692 self.write_space();
25693 }
25694 if let Some(to) = &e.to {
25695 self.generate_expression(to)?;
25696 }
25697 self.write(")");
25698 Ok(())
25699 }
25700
25701 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
25702 self.write_keyword("CHANGES");
25705 self.write(" (");
25706 if let Some(information) = &e.information {
25707 self.write_keyword("INFORMATION");
25708 self.write(" => ");
25709 self.generate_expression(information)?;
25710 }
25711 self.write(")");
25712 if let Some(at_before) = &e.at_before {
25714 self.write(" ");
25715 self.generate_expression(at_before)?;
25716 }
25717 if let Some(end) = &e.end {
25718 self.write(" ");
25719 self.generate_expression(end)?;
25720 }
25721 Ok(())
25722 }
25723
25724 fn generate_character_set_column_constraint(
25725 &mut self,
25726 e: &CharacterSetColumnConstraint,
25727 ) -> Result<()> {
25728 self.write_keyword("CHARACTER SET");
25730 self.write_space();
25731 self.generate_expression(&e.this)?;
25732 Ok(())
25733 }
25734
25735 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
25736 if e.default.is_some() {
25738 self.write_keyword("DEFAULT");
25739 self.write_space();
25740 }
25741 self.write_keyword("CHARACTER SET");
25742 self.write("=");
25743 self.generate_expression(&e.this)?;
25744 Ok(())
25745 }
25746
25747 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
25748 self.write_keyword("CHECK");
25750 self.write(" (");
25751 self.generate_expression(&e.this)?;
25752 self.write(")");
25753 if e.enforced.is_some() {
25754 self.write_space();
25755 self.write_keyword("ENFORCED");
25756 }
25757 Ok(())
25758 }
25759
25760 fn generate_assume_column_constraint(&mut self, e: &AssumeColumnConstraint) -> Result<()> {
25761 self.write_keyword("ASSUME");
25763 self.write(" (");
25764 self.generate_expression(&e.this)?;
25765 self.write(")");
25766 Ok(())
25767 }
25768
25769 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
25770 self.write_keyword("CHECK_JSON");
25772 self.write("(");
25773 self.generate_expression(&e.this)?;
25774 self.write(")");
25775 Ok(())
25776 }
25777
25778 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
25779 self.write_keyword("CHECK_XML");
25781 self.write("(");
25782 self.generate_expression(&e.this)?;
25783 self.write(")");
25784 Ok(())
25785 }
25786
25787 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
25788 self.write_keyword("CHECKSUM");
25790 self.write("=");
25791 if e.on.is_some() {
25792 self.write_keyword("ON");
25793 } else if e.default.is_some() {
25794 self.write_keyword("DEFAULT");
25795 } else {
25796 self.write_keyword("OFF");
25797 }
25798 Ok(())
25799 }
25800
25801 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
25802 if e.shallow.is_some() {
25804 self.write_keyword("SHALLOW");
25805 self.write_space();
25806 }
25807 if e.copy.is_some() {
25808 self.write_keyword("COPY");
25809 } else {
25810 self.write_keyword("CLONE");
25811 }
25812 self.write_space();
25813 self.generate_expression(&e.this)?;
25814 Ok(())
25815 }
25816
25817 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
25818 self.write_keyword("CLUSTER BY");
25820 self.write(" (");
25821 for (i, ord) in e.expressions.iter().enumerate() {
25822 if i > 0 {
25823 self.write(", ");
25824 }
25825 self.generate_ordered(ord)?;
25826 }
25827 self.write(")");
25828 Ok(())
25829 }
25830
25831 fn generate_cluster_by_columns_property(&mut self, e: &ClusterByColumnsProperty) -> Result<()> {
25832 self.write_keyword("CLUSTER BY");
25834 self.write_space();
25835 for (i, col) in e.columns.iter().enumerate() {
25836 if i > 0 {
25837 self.write(", ");
25838 }
25839 self.generate_identifier(col)?;
25840 }
25841 Ok(())
25842 }
25843
25844 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
25845 self.write_keyword("CLUSTERED BY");
25847 self.write(" (");
25848 for (i, expr) in e.expressions.iter().enumerate() {
25849 if i > 0 {
25850 self.write(", ");
25851 }
25852 self.generate_expression(expr)?;
25853 }
25854 self.write(")");
25855 if let Some(sorted_by) = &e.sorted_by {
25856 self.write_space();
25857 self.write_keyword("SORTED BY");
25858 self.write(" (");
25859 if let Expression::Tuple(t) = sorted_by.as_ref() {
25861 for (i, expr) in t.expressions.iter().enumerate() {
25862 if i > 0 {
25863 self.write(", ");
25864 }
25865 self.generate_expression(expr)?;
25866 }
25867 } else {
25868 self.generate_expression(sorted_by)?;
25869 }
25870 self.write(")");
25871 }
25872 if let Some(buckets) = &e.buckets {
25873 self.write_space();
25874 self.write_keyword("INTO");
25875 self.write_space();
25876 self.generate_expression(buckets)?;
25877 self.write_space();
25878 self.write_keyword("BUCKETS");
25879 }
25880 Ok(())
25881 }
25882
25883 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
25884 if e.default.is_some() {
25888 self.write_keyword("DEFAULT");
25889 self.write_space();
25890 }
25891 self.write_keyword("COLLATE");
25892 match self.config.dialect {
25894 Some(DialectType::BigQuery) => self.write_space(),
25895 _ => self.write("="),
25896 }
25897 self.generate_expression(&e.this)?;
25898 Ok(())
25899 }
25900
25901 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
25902 match e {
25904 ColumnConstraint::NotNull => {
25905 self.write_keyword("NOT NULL");
25906 }
25907 ColumnConstraint::Null => {
25908 self.write_keyword("NULL");
25909 }
25910 ColumnConstraint::Unique => {
25911 self.write_keyword("UNIQUE");
25912 }
25913 ColumnConstraint::PrimaryKey => {
25914 self.write_keyword("PRIMARY KEY");
25915 }
25916 ColumnConstraint::Default(expr) => {
25917 self.write_keyword("DEFAULT");
25918 self.write_space();
25919 self.generate_expression(expr)?;
25920 }
25921 ColumnConstraint::Check(expr) => {
25922 self.write_keyword("CHECK");
25923 self.write(" (");
25924 self.generate_expression(expr)?;
25925 self.write(")");
25926 }
25927 ColumnConstraint::References(fk_ref) => {
25928 if fk_ref.has_foreign_key_keywords {
25929 self.write_keyword("FOREIGN KEY");
25930 self.write_space();
25931 }
25932 self.write_keyword("REFERENCES");
25933 self.write_space();
25934 self.generate_table(&fk_ref.table)?;
25935 if !fk_ref.columns.is_empty() {
25936 self.write(" (");
25937 for (i, col) in fk_ref.columns.iter().enumerate() {
25938 if i > 0 {
25939 self.write(", ");
25940 }
25941 self.generate_identifier(col)?;
25942 }
25943 self.write(")");
25944 }
25945 }
25946 ColumnConstraint::GeneratedAsIdentity(gen) => {
25947 self.write_keyword("GENERATED");
25948 self.write_space();
25949 if gen.always {
25950 self.write_keyword("ALWAYS");
25951 } else {
25952 self.write_keyword("BY DEFAULT");
25953 if gen.on_null {
25954 self.write_space();
25955 self.write_keyword("ON NULL");
25956 }
25957 }
25958 self.write_space();
25959 self.write_keyword("AS IDENTITY");
25960 }
25961 ColumnConstraint::Collate(collation) => {
25962 self.write_keyword("COLLATE");
25963 self.write_space();
25964 self.generate_identifier(collation)?;
25965 }
25966 ColumnConstraint::Comment(comment) => {
25967 self.write_keyword("COMMENT");
25968 self.write(" '");
25969 self.write(comment);
25970 self.write("'");
25971 }
25972 ColumnConstraint::ComputedColumn(cc) => {
25973 self.generate_computed_column_inline(cc)?;
25974 }
25975 ColumnConstraint::GeneratedAsRow(gar) => {
25976 self.generate_generated_as_row_inline(gar)?;
25977 }
25978 ColumnConstraint::Tags(tags) => {
25979 self.write_keyword("TAG");
25980 self.write(" (");
25981 for (i, expr) in tags.expressions.iter().enumerate() {
25982 if i > 0 {
25983 self.write(", ");
25984 }
25985 self.generate_expression(expr)?;
25986 }
25987 self.write(")");
25988 }
25989 ColumnConstraint::Path(path_expr) => {
25990 self.write_keyword("PATH");
25991 self.write_space();
25992 self.generate_expression(path_expr)?;
25993 }
25994 }
25995 Ok(())
25996 }
25997
25998 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
25999 match e {
26001 ColumnPosition::First => {
26002 self.write_keyword("FIRST");
26003 }
26004 ColumnPosition::After(ident) => {
26005 self.write_keyword("AFTER");
26006 self.write_space();
26007 self.generate_identifier(ident)?;
26008 }
26009 }
26010 Ok(())
26011 }
26012
26013 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
26014 self.generate_expression(&e.this)?;
26016 self.write("(");
26017 self.generate_expression(&e.expression)?;
26018 self.write(")");
26019 Ok(())
26020 }
26021
26022 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
26023 if let Some(ref unpack) = e.unpack {
26026 if let Expression::Boolean(b) = unpack.as_ref() {
26027 if b.value {
26028 self.write("*");
26029 }
26030 }
26031 }
26032 self.write_keyword("COLUMNS");
26033 self.write("(");
26034 self.generate_expression(&e.this)?;
26035 self.write(")");
26036 Ok(())
26037 }
26038
26039 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
26040 self.generate_expression(&e.this)?;
26042 self.write("(");
26043 for (i, expr) in e.expressions.iter().enumerate() {
26044 if i > 0 {
26045 self.write(", ");
26046 }
26047 self.generate_expression(expr)?;
26048 }
26049 self.write(")");
26050 Ok(())
26051 }
26052
26053 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
26054 self.generate_expression(&e.this)?;
26056 self.write("(");
26057 for (i, param) in e.params.iter().enumerate() {
26058 if i > 0 {
26059 self.write(", ");
26060 }
26061 self.generate_expression(param)?;
26062 }
26063 self.write(")(");
26064 for (i, expr) in e.expressions.iter().enumerate() {
26065 if i > 0 {
26066 self.write(", ");
26067 }
26068 self.generate_expression(expr)?;
26069 }
26070 self.write(")");
26071 Ok(())
26072 }
26073
26074 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
26075 self.write_keyword("COMMIT");
26077
26078 if e.this.is_none()
26080 && matches!(
26081 self.config.dialect,
26082 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26083 )
26084 {
26085 self.write_space();
26086 self.write_keyword("TRANSACTION");
26087 }
26088
26089 if let Some(this) = &e.this {
26091 let is_transaction_marker = matches!(
26093 this.as_ref(),
26094 Expression::Identifier(id) if id.name == "TRANSACTION"
26095 );
26096
26097 self.write_space();
26098 self.write_keyword("TRANSACTION");
26099
26100 if !is_transaction_marker {
26102 self.write_space();
26103 self.generate_expression(this)?;
26104 }
26105 }
26106
26107 if let Some(durability) = &e.durability {
26109 self.write_space();
26110 self.write_keyword("WITH");
26111 self.write(" (");
26112 self.write_keyword("DELAYED_DURABILITY");
26113 self.write(" = ");
26114 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
26115 self.write_keyword("ON");
26116 } else {
26117 self.write_keyword("OFF");
26118 }
26119 self.write(")");
26120 }
26121
26122 if let Some(chain) = &e.chain {
26124 self.write_space();
26125 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
26126 self.write_keyword("AND NO CHAIN");
26127 } else {
26128 self.write_keyword("AND CHAIN");
26129 }
26130 }
26131 Ok(())
26132 }
26133
26134 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
26135 self.write("[");
26137 self.generate_expression(&e.this)?;
26138 self.write_space();
26139 self.write_keyword("FOR");
26140 self.write_space();
26141 self.generate_expression(&e.expression)?;
26142 if let Some(pos) = &e.position {
26144 self.write(", ");
26145 self.generate_expression(pos)?;
26146 }
26147 if let Some(iterator) = &e.iterator {
26148 self.write_space();
26149 self.write_keyword("IN");
26150 self.write_space();
26151 self.generate_expression(iterator)?;
26152 }
26153 if let Some(condition) = &e.condition {
26154 self.write_space();
26155 self.write_keyword("IF");
26156 self.write_space();
26157 self.generate_expression(condition)?;
26158 }
26159 self.write("]");
26160 Ok(())
26161 }
26162
26163 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
26164 self.write_keyword("COMPRESS");
26166 self.write("(");
26167 self.generate_expression(&e.this)?;
26168 if let Some(method) = &e.method {
26169 self.write(", '");
26170 self.write(method);
26171 self.write("'");
26172 }
26173 self.write(")");
26174 Ok(())
26175 }
26176
26177 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
26178 self.write_keyword("COMPRESS");
26180 if let Some(this) = &e.this {
26181 self.write_space();
26182 self.generate_expression(this)?;
26183 }
26184 Ok(())
26185 }
26186
26187 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
26188 self.write_keyword("AS");
26190 self.write_space();
26191 self.generate_expression(&e.this)?;
26192 if e.not_null.is_some() {
26193 self.write_space();
26194 self.write_keyword("PERSISTED NOT NULL");
26195 } else if e.persisted.is_some() {
26196 self.write_space();
26197 self.write_keyword("PERSISTED");
26198 }
26199 Ok(())
26200 }
26201
26202 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
26206 let computed_expr = if matches!(
26207 self.config.dialect,
26208 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26209 ) {
26210 match &*cc.expression {
26211 Expression::Year(y) if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26212 {
26213 let wrapped = Expression::Cast(Box::new(Cast {
26214 this: y.this.clone(),
26215 to: DataType::Date,
26216 trailing_comments: Vec::new(),
26217 double_colon_syntax: false,
26218 format: None,
26219 default: None,
26220 inferred_type: None,
26221 }));
26222 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
26223 }
26224 Expression::Function(f)
26225 if f.name.eq_ignore_ascii_case("YEAR")
26226 && f.args.len() == 1
26227 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
26228 {
26229 let wrapped = Expression::Cast(Box::new(Cast {
26230 this: f.args[0].clone(),
26231 to: DataType::Date,
26232 trailing_comments: Vec::new(),
26233 double_colon_syntax: false,
26234 format: None,
26235 default: None,
26236 inferred_type: None,
26237 }));
26238 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
26239 }
26240 _ => *cc.expression.clone(),
26241 }
26242 } else {
26243 *cc.expression.clone()
26244 };
26245
26246 match cc.persistence_kind.as_deref() {
26247 Some("STORED") | Some("VIRTUAL") => {
26248 self.write_keyword("GENERATED ALWAYS AS");
26250 self.write(" (");
26251 self.generate_expression(&computed_expr)?;
26252 self.write(")");
26253 self.write_space();
26254 if cc.persisted {
26255 self.write_keyword("STORED");
26256 } else {
26257 self.write_keyword("VIRTUAL");
26258 }
26259 }
26260 Some("PERSISTED") => {
26261 self.write_keyword("AS");
26263 self.write(" (");
26264 self.generate_expression(&computed_expr)?;
26265 self.write(")");
26266 self.write_space();
26267 self.write_keyword("PERSISTED");
26268 if let Some(ref dt) = cc.data_type {
26270 self.write_space();
26271 self.generate_data_type(dt)?;
26272 }
26273 if cc.not_null {
26274 self.write_space();
26275 self.write_keyword("NOT NULL");
26276 }
26277 }
26278 _ => {
26279 if matches!(
26282 self.config.dialect,
26283 Some(DialectType::Spark)
26284 | Some(DialectType::Databricks)
26285 | Some(DialectType::Hive)
26286 ) {
26287 self.write_keyword("GENERATED ALWAYS AS");
26288 self.write(" (");
26289 self.generate_expression(&computed_expr)?;
26290 self.write(")");
26291 } else if matches!(
26292 self.config.dialect,
26293 Some(DialectType::TSQL) | Some(DialectType::Fabric)
26294 ) {
26295 self.write_keyword("AS");
26296 let omit_parens = matches!(computed_expr, Expression::Year(_))
26297 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
26298 if omit_parens {
26299 self.write_space();
26300 self.generate_expression(&computed_expr)?;
26301 } else {
26302 self.write(" (");
26303 self.generate_expression(&computed_expr)?;
26304 self.write(")");
26305 }
26306 } else {
26307 self.write_keyword("AS");
26308 self.write(" (");
26309 self.generate_expression(&computed_expr)?;
26310 self.write(")");
26311 }
26312 }
26313 }
26314 Ok(())
26315 }
26316
26317 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
26320 self.write_keyword("GENERATED ALWAYS AS ROW ");
26321 if gar.start {
26322 self.write_keyword("START");
26323 } else {
26324 self.write_keyword("END");
26325 }
26326 if gar.hidden {
26327 self.write_space();
26328 self.write_keyword("HIDDEN");
26329 }
26330 Ok(())
26331 }
26332
26333 fn generate_system_versioning_content(
26335 &mut self,
26336 e: &WithSystemVersioningProperty,
26337 ) -> Result<()> {
26338 let mut parts = Vec::new();
26339
26340 if let Some(this) = &e.this {
26341 let mut s = String::from("HISTORY_TABLE=");
26342 let mut gen = Generator::with_arc_config(self.config.clone());
26343 gen.generate_expression(this)?;
26344 s.push_str(&gen.output);
26345 parts.push(s);
26346 }
26347
26348 if let Some(data_consistency) = &e.data_consistency {
26349 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
26350 let mut gen = Generator::with_arc_config(self.config.clone());
26351 gen.generate_expression(data_consistency)?;
26352 s.push_str(&gen.output);
26353 parts.push(s);
26354 }
26355
26356 if let Some(retention_period) = &e.retention_period {
26357 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
26358 let mut gen = Generator::with_arc_config(self.config.clone());
26359 gen.generate_expression(retention_period)?;
26360 s.push_str(&gen.output);
26361 parts.push(s);
26362 }
26363
26364 self.write_keyword("SYSTEM_VERSIONING");
26365 self.write("=");
26366
26367 if !parts.is_empty() {
26368 self.write_keyword("ON");
26369 self.write("(");
26370 self.write(&parts.join(", "));
26371 self.write(")");
26372 } else if e.on.is_some() {
26373 self.write_keyword("ON");
26374 } else {
26375 self.write_keyword("OFF");
26376 }
26377
26378 Ok(())
26379 }
26380
26381 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
26382 if e.else_.is_some() {
26385 self.write_keyword("ELSE");
26386 self.write_space();
26387 } else if let Some(expression) = &e.expression {
26388 self.write_keyword("WHEN");
26389 self.write_space();
26390 self.generate_expression(expression)?;
26391 self.write_space();
26392 self.write_keyword("THEN");
26393 self.write_space();
26394 }
26395
26396 if let Expression::Insert(insert) = e.this.as_ref() {
26399 self.write_keyword("INTO");
26400 self.write_space();
26401 self.generate_table(&insert.table)?;
26402
26403 if !insert.columns.is_empty() {
26405 self.write(" (");
26406 for (i, col) in insert.columns.iter().enumerate() {
26407 if i > 0 {
26408 self.write(", ");
26409 }
26410 self.generate_identifier(col)?;
26411 }
26412 self.write(")");
26413 }
26414
26415 if !insert.values.is_empty() {
26417 self.write_space();
26418 self.write_keyword("VALUES");
26419 for (row_idx, row) in insert.values.iter().enumerate() {
26420 if row_idx > 0 {
26421 self.write(", ");
26422 }
26423 self.write(" (");
26424 for (i, val) in row.iter().enumerate() {
26425 if i > 0 {
26426 self.write(", ");
26427 }
26428 self.generate_expression(val)?;
26429 }
26430 self.write(")");
26431 }
26432 }
26433 } else {
26434 self.generate_expression(&e.this)?;
26436 }
26437 Ok(())
26438 }
26439
26440 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
26441 self.write_keyword("CONSTRAINT");
26443 self.write_space();
26444 self.generate_expression(&e.this)?;
26445 if !e.expressions.is_empty() {
26446 self.write_space();
26447 for (i, expr) in e.expressions.iter().enumerate() {
26448 if i > 0 {
26449 self.write_space();
26450 }
26451 self.generate_expression(expr)?;
26452 }
26453 }
26454 Ok(())
26455 }
26456
26457 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
26458 self.write_keyword("CONVERT_TIMEZONE");
26460 self.write("(");
26461 let mut first = true;
26462 if let Some(source_tz) = &e.source_tz {
26463 self.generate_expression(source_tz)?;
26464 first = false;
26465 }
26466 if let Some(target_tz) = &e.target_tz {
26467 if !first {
26468 self.write(", ");
26469 }
26470 self.generate_expression(target_tz)?;
26471 first = false;
26472 }
26473 if let Some(timestamp) = &e.timestamp {
26474 if !first {
26475 self.write(", ");
26476 }
26477 self.generate_expression(timestamp)?;
26478 }
26479 self.write(")");
26480 Ok(())
26481 }
26482
26483 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
26484 self.write_keyword("CONVERT");
26486 self.write("(");
26487 self.generate_expression(&e.this)?;
26488 if let Some(dest) = &e.dest {
26489 self.write_space();
26490 self.write_keyword("USING");
26491 self.write_space();
26492 self.generate_expression(dest)?;
26493 }
26494 self.write(")");
26495 Ok(())
26496 }
26497
26498 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
26499 self.write_keyword("COPY");
26500 if e.is_into {
26501 self.write_space();
26502 self.write_keyword("INTO");
26503 }
26504 self.write_space();
26505
26506 if let Expression::Literal(lit) = &e.this {
26508 if let Literal::String(s) = lit.as_ref() {
26509 if s.starts_with('@') {
26510 self.write(s);
26511 } else {
26512 self.generate_expression(&e.this)?;
26513 }
26514 }
26515 } else {
26516 self.generate_expression(&e.this)?;
26517 }
26518
26519 if e.kind {
26521 if self.config.pretty {
26523 self.write_newline();
26524 } else {
26525 self.write_space();
26526 }
26527 self.write_keyword("FROM");
26528 self.write_space();
26529 } else if !e.files.is_empty() {
26530 if self.config.pretty {
26532 self.write_newline();
26533 } else {
26534 self.write_space();
26535 }
26536 self.write_keyword("TO");
26537 self.write_space();
26538 }
26539
26540 for (i, file) in e.files.iter().enumerate() {
26542 if i > 0 {
26543 self.write_space();
26544 }
26545 if let Expression::Literal(lit) = file {
26547 if let Literal::String(s) = lit.as_ref() {
26548 if s.starts_with('@') {
26549 self.write(s);
26550 } else {
26551 self.generate_expression(file)?;
26552 }
26553 }
26554 } else if let Expression::Identifier(id) = file {
26555 if id.quoted {
26557 self.write("`");
26558 self.write(&id.name);
26559 self.write("`");
26560 } else {
26561 self.generate_expression(file)?;
26562 }
26563 } else {
26564 self.generate_expression(file)?;
26565 }
26566 }
26567
26568 if !e.with_wrapped {
26570 if let Some(ref creds) = e.credentials {
26571 if let Some(ref storage) = creds.storage {
26572 if self.config.pretty {
26573 self.write_newline();
26574 } else {
26575 self.write_space();
26576 }
26577 self.write_keyword("STORAGE_INTEGRATION");
26578 self.write(" = ");
26579 self.write(storage);
26580 }
26581 if creds.credentials.is_empty() {
26582 if self.config.pretty {
26584 self.write_newline();
26585 } else {
26586 self.write_space();
26587 }
26588 self.write_keyword("CREDENTIALS");
26589 self.write(" = ()");
26590 } else {
26591 if self.config.pretty {
26592 self.write_newline();
26593 } else {
26594 self.write_space();
26595 }
26596 self.write_keyword("CREDENTIALS");
26597 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
26600 self.write(" '");
26602 self.write(&creds.credentials[0].1);
26603 self.write("'");
26604 } else {
26605 self.write(" = (");
26607 for (i, (k, v)) in creds.credentials.iter().enumerate() {
26608 if i > 0 {
26609 self.write_space();
26610 }
26611 self.write(k);
26612 self.write("='");
26613 self.write(v);
26614 self.write("'");
26615 }
26616 self.write(")");
26617 }
26618 }
26619 if let Some(ref encryption) = creds.encryption {
26620 self.write_space();
26621 self.write_keyword("ENCRYPTION");
26622 self.write(" = ");
26623 self.write(encryption);
26624 }
26625 }
26626 }
26627
26628 if !e.params.is_empty() {
26630 if e.with_wrapped {
26631 self.write_space();
26633 self.write_keyword("WITH");
26634 self.write(" (");
26635 for (i, param) in e.params.iter().enumerate() {
26636 if i > 0 {
26637 self.write(", ");
26638 }
26639 self.generate_copy_param_with_format(param)?;
26640 }
26641 self.write(")");
26642 } else {
26643 for param in &e.params {
26647 if self.config.pretty {
26648 self.write_newline();
26649 } else {
26650 self.write_space();
26651 }
26652 self.write(¶m.name);
26654 if let Some(ref value) = param.value {
26655 if param.eq {
26657 self.write(" = ");
26658 } else {
26659 self.write(" ");
26660 }
26661 if !param.values.is_empty() {
26662 self.write("(");
26663 for (i, v) in param.values.iter().enumerate() {
26664 if i > 0 {
26665 self.write_space();
26666 }
26667 self.generate_copy_nested_param(v)?;
26668 }
26669 self.write(")");
26670 } else {
26671 self.generate_copy_param_value(value)?;
26673 }
26674 } else if !param.values.is_empty() {
26675 if param.eq {
26677 self.write(" = (");
26678 } else {
26679 self.write(" (");
26680 }
26681 let is_key_value_pairs = param
26686 .values
26687 .first()
26688 .map_or(false, |v| matches!(v, Expression::Eq(_)));
26689 let sep = if is_key_value_pairs && param.eq {
26690 " "
26691 } else {
26692 ", "
26693 };
26694 for (i, v) in param.values.iter().enumerate() {
26695 if i > 0 {
26696 self.write(sep);
26697 }
26698 self.generate_copy_nested_param(v)?;
26699 }
26700 self.write(")");
26701 }
26702 }
26703 }
26704 }
26705
26706 Ok(())
26707 }
26708
26709 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
26712 self.write_keyword(¶m.name);
26713 if !param.values.is_empty() {
26714 self.write(" = (");
26716 for (i, v) in param.values.iter().enumerate() {
26717 if i > 0 {
26718 self.write(", ");
26719 }
26720 self.generate_copy_nested_param(v)?;
26721 }
26722 self.write(")");
26723 } else if let Some(ref value) = param.value {
26724 if param.eq {
26725 self.write(" = ");
26726 } else {
26727 self.write(" ");
26728 }
26729 self.generate_expression(value)?;
26730 }
26731 Ok(())
26732 }
26733
26734 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
26736 match expr {
26737 Expression::Eq(eq) => {
26738 match &eq.left {
26740 Expression::Column(c) => self.write(&c.name.name),
26741 _ => self.generate_expression(&eq.left)?,
26742 }
26743 self.write("=");
26744 match &eq.right {
26746 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
26747 let Literal::String(s) = lit.as_ref() else {
26748 unreachable!()
26749 };
26750 self.write("'");
26751 self.write(s);
26752 self.write("'");
26753 }
26754 Expression::Tuple(t) => {
26755 self.write("(");
26757 if self.config.pretty {
26758 self.write_newline();
26759 self.indent_level += 1;
26760 for (i, item) in t.expressions.iter().enumerate() {
26761 if i > 0 {
26762 self.write(", ");
26763 }
26764 self.write_indent();
26765 self.generate_expression(item)?;
26766 }
26767 self.write_newline();
26768 self.indent_level -= 1;
26769 } else {
26770 for (i, item) in t.expressions.iter().enumerate() {
26771 if i > 0 {
26772 self.write(", ");
26773 }
26774 self.generate_expression(item)?;
26775 }
26776 }
26777 self.write(")");
26778 }
26779 _ => self.generate_expression(&eq.right)?,
26780 }
26781 Ok(())
26782 }
26783 Expression::Column(c) => {
26784 self.write(&c.name.name);
26786 Ok(())
26787 }
26788 _ => self.generate_expression(expr),
26789 }
26790 }
26791
26792 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
26795 match expr {
26796 Expression::Column(c) => {
26797 if c.name.quoted {
26799 self.write("\"");
26800 self.write(&c.name.name);
26801 self.write("\"");
26802 } else {
26803 self.write(&c.name.name);
26804 }
26805 Ok(())
26806 }
26807 Expression::Identifier(id) => {
26808 if id.quoted {
26810 self.write("\"");
26811 self.write(&id.name);
26812 self.write("\"");
26813 } else {
26814 self.write(&id.name);
26815 }
26816 Ok(())
26817 }
26818 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
26819 let Literal::String(s) = lit.as_ref() else {
26820 unreachable!()
26821 };
26822 self.write("'");
26824 self.write(s);
26825 self.write("'");
26826 Ok(())
26827 }
26828 _ => self.generate_expression(expr),
26829 }
26830 }
26831
26832 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
26833 self.write_keyword(&e.name);
26834 if let Some(ref value) = e.value {
26835 if e.eq {
26836 self.write(" = ");
26837 } else {
26838 self.write(" ");
26839 }
26840 self.generate_expression(value)?;
26841 }
26842 if !e.values.is_empty() {
26843 if e.eq {
26844 self.write(" = ");
26845 } else {
26846 self.write(" ");
26847 }
26848 self.write("(");
26849 for (i, v) in e.values.iter().enumerate() {
26850 if i > 0 {
26851 self.write(", ");
26852 }
26853 self.generate_expression(v)?;
26854 }
26855 self.write(")");
26856 }
26857 Ok(())
26858 }
26859
26860 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
26861 self.write_keyword("CORR");
26863 self.write("(");
26864 self.generate_expression(&e.this)?;
26865 self.write(", ");
26866 self.generate_expression(&e.expression)?;
26867 self.write(")");
26868 Ok(())
26869 }
26870
26871 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
26872 self.write_keyword("COSINE_DISTANCE");
26874 self.write("(");
26875 self.generate_expression(&e.this)?;
26876 self.write(", ");
26877 self.generate_expression(&e.expression)?;
26878 self.write(")");
26879 Ok(())
26880 }
26881
26882 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
26883 self.write_keyword("COVAR_POP");
26885 self.write("(");
26886 self.generate_expression(&e.this)?;
26887 self.write(", ");
26888 self.generate_expression(&e.expression)?;
26889 self.write(")");
26890 Ok(())
26891 }
26892
26893 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
26894 self.write_keyword("COVAR_SAMP");
26896 self.write("(");
26897 self.generate_expression(&e.this)?;
26898 self.write(", ");
26899 self.generate_expression(&e.expression)?;
26900 self.write(")");
26901 Ok(())
26902 }
26903
26904 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
26905 self.write_keyword("CREDENTIALS");
26907 self.write(" (");
26908 for (i, (key, value)) in e.credentials.iter().enumerate() {
26909 if i > 0 {
26910 self.write(", ");
26911 }
26912 self.write(key);
26913 self.write("='");
26914 self.write(value);
26915 self.write("'");
26916 }
26917 self.write(")");
26918 Ok(())
26919 }
26920
26921 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
26922 self.write_keyword("CREDENTIALS");
26924 self.write("=(");
26925 for (i, expr) in e.expressions.iter().enumerate() {
26926 if i > 0 {
26927 self.write(", ");
26928 }
26929 self.generate_expression(expr)?;
26930 }
26931 self.write(")");
26932 Ok(())
26933 }
26934
26935 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
26936 use crate::dialects::DialectType;
26937
26938 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
26941 self.generate_expression(&e.this)?;
26942 self.write_space();
26943 self.write_keyword("AS");
26944 self.write_space();
26945 self.generate_identifier(&e.alias)?;
26946 return Ok(());
26947 }
26948 self.write(&e.alias.name);
26949
26950 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
26952
26953 if !e.columns.is_empty() && !skip_cte_columns {
26954 self.write("(");
26955 for (i, col) in e.columns.iter().enumerate() {
26956 if i > 0 {
26957 self.write(", ");
26958 }
26959 self.write(&col.name);
26960 }
26961 self.write(")");
26962 }
26963 if !e.key_expressions.is_empty() {
26965 self.write_space();
26966 self.write_keyword("USING KEY");
26967 self.write(" (");
26968 for (i, key) in e.key_expressions.iter().enumerate() {
26969 if i > 0 {
26970 self.write(", ");
26971 }
26972 self.write(&key.name);
26973 }
26974 self.write(")");
26975 }
26976 self.write_space();
26977 self.write_keyword("AS");
26978 self.write_space();
26979 if let Some(materialized) = e.materialized {
26980 if materialized {
26981 self.write_keyword("MATERIALIZED");
26982 } else {
26983 self.write_keyword("NOT MATERIALIZED");
26984 }
26985 self.write_space();
26986 }
26987 self.write("(");
26988 self.generate_expression(&e.this)?;
26989 self.write(")");
26990 Ok(())
26991 }
26992
26993 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
26994 if e.expressions.is_empty() {
26996 self.write_keyword("WITH CUBE");
26997 } else {
26998 self.write_keyword("CUBE");
26999 self.write("(");
27000 for (i, expr) in e.expressions.iter().enumerate() {
27001 if i > 0 {
27002 self.write(", ");
27003 }
27004 self.generate_expression(expr)?;
27005 }
27006 self.write(")");
27007 }
27008 Ok(())
27009 }
27010
27011 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
27012 self.write_keyword("CURRENT_DATETIME");
27014 if let Some(this) = &e.this {
27015 self.write("(");
27016 self.generate_expression(this)?;
27017 self.write(")");
27018 }
27019 Ok(())
27020 }
27021
27022 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
27023 self.write_keyword("CURRENT_SCHEMA");
27025 Ok(())
27026 }
27027
27028 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
27029 self.write_keyword("CURRENT_SCHEMAS");
27031 self.write("(");
27032 if !matches!(
27034 self.config.dialect,
27035 Some(crate::dialects::DialectType::Snowflake)
27036 ) {
27037 if let Some(this) = &e.this {
27038 self.generate_expression(this)?;
27039 }
27040 }
27041 self.write(")");
27042 Ok(())
27043 }
27044
27045 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
27046 self.write_keyword("CURRENT_USER");
27048 let needs_parens = e.this.is_some()
27050 || matches!(
27051 self.config.dialect,
27052 Some(DialectType::Snowflake)
27053 | Some(DialectType::Spark)
27054 | Some(DialectType::Hive)
27055 | Some(DialectType::DuckDB)
27056 | Some(DialectType::BigQuery)
27057 | Some(DialectType::MySQL)
27058 | Some(DialectType::Databricks)
27059 );
27060 if needs_parens {
27061 self.write("()");
27062 }
27063 Ok(())
27064 }
27065
27066 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
27067 if self.config.dialect == Some(DialectType::Solr) {
27069 self.generate_expression(&e.this)?;
27070 self.write(" ");
27071 self.write_keyword("OR");
27072 self.write(" ");
27073 self.generate_expression(&e.expression)?;
27074 } else if self.config.dialect == Some(DialectType::MySQL) {
27075 self.generate_mysql_concat_from_dpipe(e)?;
27076 } else {
27077 self.generate_expression(&e.this)?;
27079 self.write(" || ");
27080 self.generate_expression(&e.expression)?;
27081 }
27082 Ok(())
27083 }
27084
27085 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
27086 self.write_keyword("DATABLOCKSIZE");
27088 self.write("=");
27089 if let Some(size) = e.size {
27090 self.write(&size.to_string());
27091 if let Some(units) = &e.units {
27092 self.write_space();
27093 self.generate_expression(units)?;
27094 }
27095 } else if e.minimum.is_some() {
27096 self.write_keyword("MINIMUM");
27097 } else if e.maximum.is_some() {
27098 self.write_keyword("MAXIMUM");
27099 } else if e.default.is_some() {
27100 self.write_keyword("DEFAULT");
27101 }
27102 Ok(())
27103 }
27104
27105 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
27106 self.write_keyword("DATA_DELETION");
27108 self.write("=");
27109
27110 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
27111 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
27112
27113 if is_on {
27114 self.write_keyword("ON");
27115 if has_options {
27116 self.write("(");
27117 let mut first = true;
27118 if let Some(filter_column) = &e.filter_column {
27119 self.write_keyword("FILTER_COLUMN");
27120 self.write("=");
27121 self.generate_expression(filter_column)?;
27122 first = false;
27123 }
27124 if let Some(retention_period) = &e.retention_period {
27125 if !first {
27126 self.write(", ");
27127 }
27128 self.write_keyword("RETENTION_PERIOD");
27129 self.write("=");
27130 self.generate_expression(retention_period)?;
27131 }
27132 self.write(")");
27133 }
27134 } else {
27135 self.write_keyword("OFF");
27136 }
27137 Ok(())
27138 }
27139
27140 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
27144 use crate::dialects::DialectType;
27145 use crate::expressions::Literal;
27146
27147 match self.config.dialect {
27148 Some(DialectType::Exasol) => {
27150 self.write_keyword("TO_DATE");
27151 self.write("(");
27152 match &e.this {
27154 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
27155 let Literal::String(s) = lit.as_ref() else {
27156 unreachable!()
27157 };
27158 self.write("'");
27159 self.write(s);
27160 self.write("'");
27161 }
27162 _ => {
27163 self.generate_expression(&e.this)?;
27164 }
27165 }
27166 self.write(")");
27167 }
27168 _ => {
27170 self.write_keyword("DATE");
27171 self.write("(");
27172 self.generate_expression(&e.this)?;
27173 self.write(")");
27174 }
27175 }
27176 Ok(())
27177 }
27178
27179 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
27180 self.write_keyword("DATE_BIN");
27182 self.write("(");
27183 self.generate_expression(&e.this)?;
27184 self.write(", ");
27185 self.generate_expression(&e.expression)?;
27186 if let Some(origin) = &e.origin {
27187 self.write(", ");
27188 self.generate_expression(origin)?;
27189 }
27190 self.write(")");
27191 Ok(())
27192 }
27193
27194 fn generate_date_format_column_constraint(
27195 &mut self,
27196 e: &DateFormatColumnConstraint,
27197 ) -> Result<()> {
27198 self.write_keyword("FORMAT");
27200 self.write_space();
27201 self.generate_expression(&e.this)?;
27202 Ok(())
27203 }
27204
27205 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
27206 self.write_keyword("DATE_FROM_PARTS");
27208 self.write("(");
27209 let mut first = true;
27210 if let Some(year) = &e.year {
27211 self.generate_expression(year)?;
27212 first = false;
27213 }
27214 if let Some(month) = &e.month {
27215 if !first {
27216 self.write(", ");
27217 }
27218 self.generate_expression(month)?;
27219 first = false;
27220 }
27221 if let Some(day) = &e.day {
27222 if !first {
27223 self.write(", ");
27224 }
27225 self.generate_expression(day)?;
27226 }
27227 self.write(")");
27228 Ok(())
27229 }
27230
27231 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
27232 self.write_keyword("DATETIME");
27234 self.write("(");
27235 self.generate_expression(&e.this)?;
27236 if let Some(expr) = &e.expression {
27237 self.write(", ");
27238 self.generate_expression(expr)?;
27239 }
27240 self.write(")");
27241 Ok(())
27242 }
27243
27244 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
27245 self.write_keyword("DATETIME_ADD");
27247 self.write("(");
27248 self.generate_expression(&e.this)?;
27249 self.write(", ");
27250 self.generate_expression(&e.expression)?;
27251 if let Some(unit) = &e.unit {
27252 self.write(", ");
27253 self.write_keyword(unit);
27254 }
27255 self.write(")");
27256 Ok(())
27257 }
27258
27259 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
27260 self.write_keyword("DATETIME_DIFF");
27262 self.write("(");
27263 self.generate_expression(&e.this)?;
27264 self.write(", ");
27265 self.generate_expression(&e.expression)?;
27266 if let Some(unit) = &e.unit {
27267 self.write(", ");
27268 self.write_keyword(unit);
27269 }
27270 self.write(")");
27271 Ok(())
27272 }
27273
27274 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
27275 self.write_keyword("DATETIME_SUB");
27277 self.write("(");
27278 self.generate_expression(&e.this)?;
27279 self.write(", ");
27280 self.generate_expression(&e.expression)?;
27281 if let Some(unit) = &e.unit {
27282 self.write(", ");
27283 self.write_keyword(unit);
27284 }
27285 self.write(")");
27286 Ok(())
27287 }
27288
27289 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
27290 self.write_keyword("DATETIME_TRUNC");
27292 self.write("(");
27293 self.generate_expression(&e.this)?;
27294 self.write(", ");
27295 self.write_keyword(&e.unit);
27296 if let Some(zone) = &e.zone {
27297 self.write(", ");
27298 self.generate_expression(zone)?;
27299 }
27300 self.write(")");
27301 Ok(())
27302 }
27303
27304 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
27305 self.write_keyword("DAYNAME");
27307 self.write("(");
27308 self.generate_expression(&e.this)?;
27309 self.write(")");
27310 Ok(())
27311 }
27312
27313 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
27314 self.write_keyword("DECLARE");
27316 self.write_space();
27317 if e.replace {
27318 self.write_keyword("OR");
27319 self.write_space();
27320 self.write_keyword("REPLACE");
27321 self.write_space();
27322 }
27323 for (i, expr) in e.expressions.iter().enumerate() {
27324 if i > 0 {
27325 self.write(", ");
27326 }
27327 self.generate_expression(expr)?;
27328 }
27329 Ok(())
27330 }
27331
27332 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
27333 use crate::dialects::DialectType;
27334
27335 self.generate_expression(&e.this)?;
27337 for name in &e.additional_names {
27339 self.write(", ");
27340 self.generate_expression(name)?;
27341 }
27342 if let Some(kind) = &e.kind {
27343 self.write_space();
27344 match self.config.dialect {
27348 Some(DialectType::BigQuery) => {
27349 self.write(kind);
27350 }
27351 Some(DialectType::TSQL) => {
27352 let is_complex_table = kind.starts_with("TABLE")
27356 && (kind.contains("CLUSTERED") || kind.contains("INDEX"));
27357 if is_complex_table {
27358 self.write(kind);
27359 } else if kind == "INT" {
27360 self.write("INTEGER");
27361 } else if kind.starts_with("TABLE") {
27362 let normalized = kind
27364 .replace(" INT ", " INTEGER ")
27365 .replace(" INT,", " INTEGER,")
27366 .replace(" INT)", " INTEGER)")
27367 .replace("(INT ", "(INTEGER ");
27368 self.write(&normalized);
27369 } else {
27370 self.write(kind);
27371 }
27372 }
27373 _ => {
27374 if e.has_as {
27375 self.write_keyword("AS");
27376 self.write_space();
27377 }
27378 self.write(kind);
27379 }
27380 }
27381 }
27382 if let Some(default) = &e.default {
27383 match self.config.dialect {
27385 Some(DialectType::BigQuery) => {
27386 self.write_space();
27387 self.write_keyword("DEFAULT");
27388 self.write_space();
27389 }
27390 _ => {
27391 self.write(" = ");
27392 }
27393 }
27394 self.generate_expression(default)?;
27395 }
27396 Ok(())
27397 }
27398
27399 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
27400 self.write_keyword("DECODE");
27402 self.write("(");
27403 for (i, expr) in e.expressions.iter().enumerate() {
27404 if i > 0 {
27405 self.write(", ");
27406 }
27407 self.generate_expression(expr)?;
27408 }
27409 self.write(")");
27410 Ok(())
27411 }
27412
27413 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
27414 self.write_keyword("DECOMPRESS");
27416 self.write("(");
27417 self.generate_expression(&e.this)?;
27418 self.write(", '");
27419 self.write(&e.method);
27420 self.write("')");
27421 Ok(())
27422 }
27423
27424 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
27425 self.write_keyword("DECOMPRESS");
27427 self.write("(");
27428 self.generate_expression(&e.this)?;
27429 self.write(", '");
27430 self.write(&e.method);
27431 self.write("')");
27432 Ok(())
27433 }
27434
27435 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
27436 self.write_keyword("DECRYPT");
27438 self.write("(");
27439 self.generate_expression(&e.this)?;
27440 if let Some(passphrase) = &e.passphrase {
27441 self.write(", ");
27442 self.generate_expression(passphrase)?;
27443 }
27444 if let Some(aad) = &e.aad {
27445 self.write(", ");
27446 self.generate_expression(aad)?;
27447 }
27448 if let Some(method) = &e.encryption_method {
27449 self.write(", ");
27450 self.generate_expression(method)?;
27451 }
27452 self.write(")");
27453 Ok(())
27454 }
27455
27456 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
27457 self.write_keyword("DECRYPT_RAW");
27459 self.write("(");
27460 self.generate_expression(&e.this)?;
27461 if let Some(key) = &e.key {
27462 self.write(", ");
27463 self.generate_expression(key)?;
27464 }
27465 if let Some(iv) = &e.iv {
27466 self.write(", ");
27467 self.generate_expression(iv)?;
27468 }
27469 if let Some(aad) = &e.aad {
27470 self.write(", ");
27471 self.generate_expression(aad)?;
27472 }
27473 if let Some(method) = &e.encryption_method {
27474 self.write(", ");
27475 self.generate_expression(method)?;
27476 }
27477 self.write(")");
27478 Ok(())
27479 }
27480
27481 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
27482 self.write_keyword("DEFINER");
27484 self.write(" = ");
27485 self.generate_expression(&e.this)?;
27486 Ok(())
27487 }
27488
27489 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
27490 self.write_keyword("DETACH");
27492 if e.exists {
27493 self.write_keyword(" DATABASE IF EXISTS");
27494 }
27495 self.write_space();
27496 self.generate_expression(&e.this)?;
27497 Ok(())
27498 }
27499
27500 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
27501 let property_name = match e.this.as_ref() {
27502 Expression::Identifier(id) => id.name.as_str(),
27503 Expression::Var(v) => v.this.as_str(),
27504 _ => "DICTIONARY",
27505 };
27506 self.write_keyword(property_name);
27507 self.write("(");
27508 self.write(&e.kind);
27509 if let Some(settings) = &e.settings {
27510 self.write("(");
27511 if let Expression::Tuple(t) = settings.as_ref() {
27512 if self.config.pretty && !t.expressions.is_empty() {
27513 self.write_newline();
27514 self.indent_level += 1;
27515 for (i, pair) in t.expressions.iter().enumerate() {
27516 if i > 0 {
27517 self.write(",");
27518 self.write_newline();
27519 }
27520 self.write_indent();
27521 if let Expression::Tuple(pair_tuple) = pair {
27522 if let Some(k) = pair_tuple.expressions.first() {
27523 self.generate_expression(k)?;
27524 }
27525 if let Some(v) = pair_tuple.expressions.get(1) {
27526 self.write(" ");
27527 self.generate_expression(v)?;
27528 }
27529 } else {
27530 self.generate_expression(pair)?;
27531 }
27532 }
27533 self.indent_level -= 1;
27534 self.write_newline();
27535 self.write_indent();
27536 } else {
27537 for (i, pair) in t.expressions.iter().enumerate() {
27538 if i > 0 {
27539 self.write(" ");
27541 }
27542 if let Expression::Tuple(pair_tuple) = pair {
27543 if let Some(k) = pair_tuple.expressions.first() {
27544 self.generate_expression(k)?;
27545 }
27546 if let Some(v) = pair_tuple.expressions.get(1) {
27547 self.write(" ");
27548 self.generate_expression(v)?;
27549 }
27550 } else {
27551 self.generate_expression(pair)?;
27552 }
27553 }
27554 }
27555 } else {
27556 self.generate_expression(settings)?;
27557 }
27558 self.write(")");
27559 } else {
27560 self.write("()");
27562 }
27563 self.write(")");
27564 Ok(())
27565 }
27566
27567 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
27568 let property_name = match e.this.as_ref() {
27569 Expression::Identifier(id) => id.name.as_str(),
27570 Expression::Var(v) => v.this.as_str(),
27571 _ => "RANGE",
27572 };
27573 self.write_keyword(property_name);
27574 self.write("(");
27575 if let Some(min) = &e.min {
27576 self.write_keyword("MIN");
27577 self.write_space();
27578 self.generate_expression(min)?;
27579 }
27580 if let Some(max) = &e.max {
27581 self.write_space();
27582 self.write_keyword("MAX");
27583 self.write_space();
27584 self.generate_expression(max)?;
27585 }
27586 self.write(")");
27587 Ok(())
27588 }
27589
27590 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
27591 if e.local.is_some() {
27593 self.write_keyword("LOCAL ");
27594 }
27595 self.write_keyword("DIRECTORY");
27596 self.write_space();
27597 self.generate_expression(&e.this)?;
27598 if let Some(row_format) = &e.row_format {
27599 self.write_space();
27600 self.generate_expression(row_format)?;
27601 }
27602 Ok(())
27603 }
27604
27605 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
27606 self.write_keyword("DISTKEY");
27608 self.write("(");
27609 self.generate_expression(&e.this)?;
27610 self.write(")");
27611 Ok(())
27612 }
27613
27614 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
27615 self.write_keyword("DISTSTYLE");
27617 self.write_space();
27618 self.generate_expression(&e.this)?;
27619 Ok(())
27620 }
27621
27622 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
27623 self.write_keyword("DISTRIBUTE BY");
27625 self.write_space();
27626 for (i, expr) in e.expressions.iter().enumerate() {
27627 if i > 0 {
27628 self.write(", ");
27629 }
27630 self.generate_expression(expr)?;
27631 }
27632 Ok(())
27633 }
27634
27635 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
27636 self.write_keyword("DISTRIBUTED BY");
27638 self.write_space();
27639 self.write(&e.kind);
27640 if !e.expressions.is_empty() {
27641 self.write(" (");
27642 for (i, expr) in e.expressions.iter().enumerate() {
27643 if i > 0 {
27644 self.write(", ");
27645 }
27646 self.generate_expression(expr)?;
27647 }
27648 self.write(")");
27649 }
27650 if let Some(buckets) = &e.buckets {
27651 self.write_space();
27652 self.write_keyword("BUCKETS");
27653 self.write_space();
27654 self.generate_expression(buckets)?;
27655 }
27656 if let Some(order) = &e.order {
27657 self.write_space();
27658 self.generate_expression(order)?;
27659 }
27660 Ok(())
27661 }
27662
27663 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
27664 self.write_keyword("DOT_PRODUCT");
27666 self.write("(");
27667 self.generate_expression(&e.this)?;
27668 self.write(", ");
27669 self.generate_expression(&e.expression)?;
27670 self.write(")");
27671 Ok(())
27672 }
27673
27674 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
27675 self.write_keyword("DROP");
27677 if e.exists {
27678 self.write_keyword(" IF EXISTS ");
27679 } else {
27680 self.write_space();
27681 }
27682 for (i, expr) in e.expressions.iter().enumerate() {
27683 if i > 0 {
27684 self.write(", ");
27685 }
27686 self.generate_expression(expr)?;
27687 }
27688 Ok(())
27689 }
27690
27691 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
27692 self.write_keyword("DUPLICATE KEY");
27694 self.write(" (");
27695 for (i, expr) in e.expressions.iter().enumerate() {
27696 if i > 0 {
27697 self.write(", ");
27698 }
27699 self.generate_expression(expr)?;
27700 }
27701 self.write(")");
27702 Ok(())
27703 }
27704
27705 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
27706 self.write_keyword("ELT");
27708 self.write("(");
27709 self.generate_expression(&e.this)?;
27710 for expr in &e.expressions {
27711 self.write(", ");
27712 self.generate_expression(expr)?;
27713 }
27714 self.write(")");
27715 Ok(())
27716 }
27717
27718 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
27719 self.write_keyword("ENCODE");
27721 self.write("(");
27722 self.generate_expression(&e.this)?;
27723 if let Some(charset) = &e.charset {
27724 self.write(", ");
27725 self.generate_expression(charset)?;
27726 }
27727 self.write(")");
27728 Ok(())
27729 }
27730
27731 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
27732 if e.key.is_some() {
27734 self.write_keyword("KEY ");
27735 }
27736 self.write_keyword("ENCODE");
27737 self.write_space();
27738 self.generate_expression(&e.this)?;
27739 if !e.properties.is_empty() {
27740 self.write(" (");
27741 for (i, prop) in e.properties.iter().enumerate() {
27742 if i > 0 {
27743 self.write(", ");
27744 }
27745 self.generate_expression(prop)?;
27746 }
27747 self.write(")");
27748 }
27749 Ok(())
27750 }
27751
27752 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
27753 self.write_keyword("ENCRYPT");
27755 self.write("(");
27756 self.generate_expression(&e.this)?;
27757 if let Some(passphrase) = &e.passphrase {
27758 self.write(", ");
27759 self.generate_expression(passphrase)?;
27760 }
27761 if let Some(aad) = &e.aad {
27762 self.write(", ");
27763 self.generate_expression(aad)?;
27764 }
27765 if let Some(method) = &e.encryption_method {
27766 self.write(", ");
27767 self.generate_expression(method)?;
27768 }
27769 self.write(")");
27770 Ok(())
27771 }
27772
27773 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
27774 self.write_keyword("ENCRYPT_RAW");
27776 self.write("(");
27777 self.generate_expression(&e.this)?;
27778 if let Some(key) = &e.key {
27779 self.write(", ");
27780 self.generate_expression(key)?;
27781 }
27782 if let Some(iv) = &e.iv {
27783 self.write(", ");
27784 self.generate_expression(iv)?;
27785 }
27786 if let Some(aad) = &e.aad {
27787 self.write(", ");
27788 self.generate_expression(aad)?;
27789 }
27790 if let Some(method) = &e.encryption_method {
27791 self.write(", ");
27792 self.generate_expression(method)?;
27793 }
27794 self.write(")");
27795 Ok(())
27796 }
27797
27798 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
27799 self.write_keyword("ENGINE");
27801 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
27802 self.write("=");
27803 } else {
27804 self.write(" = ");
27805 }
27806 self.generate_expression(&e.this)?;
27807 Ok(())
27808 }
27809
27810 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
27811 self.write_keyword("ENVIRONMENT");
27813 self.write(" (");
27814 for (i, expr) in e.expressions.iter().enumerate() {
27815 if i > 0 {
27816 self.write(", ");
27817 }
27818 self.generate_expression(expr)?;
27819 }
27820 self.write(")");
27821 Ok(())
27822 }
27823
27824 fn generate_ephemeral_column_constraint(
27825 &mut self,
27826 e: &EphemeralColumnConstraint,
27827 ) -> Result<()> {
27828 self.write_keyword("EPHEMERAL");
27830 if let Some(this) = &e.this {
27831 self.write_space();
27832 self.generate_expression(this)?;
27833 }
27834 Ok(())
27835 }
27836
27837 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
27838 self.write_keyword("EQUAL_NULL");
27840 self.write("(");
27841 self.generate_expression(&e.this)?;
27842 self.write(", ");
27843 self.generate_expression(&e.expression)?;
27844 self.write(")");
27845 Ok(())
27846 }
27847
27848 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
27849 use crate::dialects::DialectType;
27850
27851 match self.config.dialect {
27853 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
27854 self.generate_expression(&e.this)?;
27855 self.write(" <-> ");
27856 self.generate_expression(&e.expression)?;
27857 }
27858 _ => {
27859 self.write_keyword("EUCLIDEAN_DISTANCE");
27861 self.write("(");
27862 self.generate_expression(&e.this)?;
27863 self.write(", ");
27864 self.generate_expression(&e.expression)?;
27865 self.write(")");
27866 }
27867 }
27868 Ok(())
27869 }
27870
27871 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
27872 self.write_keyword("EXECUTE AS");
27874 self.write_space();
27875 self.generate_expression(&e.this)?;
27876 Ok(())
27877 }
27878
27879 fn generate_export(&mut self, e: &Export) -> Result<()> {
27880 self.write_keyword("EXPORT DATA");
27882 if let Some(connection) = &e.connection {
27883 self.write_space();
27884 self.write_keyword("WITH CONNECTION");
27885 self.write_space();
27886 self.generate_expression(connection)?;
27887 }
27888 if !e.options.is_empty() {
27889 self.write_space();
27890 self.generate_options_clause(&e.options)?;
27891 }
27892 self.write_space();
27893 self.write_keyword("AS");
27894 self.write_space();
27895 self.generate_expression(&e.this)?;
27896 Ok(())
27897 }
27898
27899 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
27900 self.write_keyword("EXTERNAL");
27902 if let Some(this) = &e.this {
27903 self.write_space();
27904 self.generate_expression(this)?;
27905 }
27906 Ok(())
27907 }
27908
27909 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
27910 if e.no.is_some() {
27912 self.write_keyword("NO ");
27913 }
27914 self.write_keyword("FALLBACK");
27915 if e.protection.is_some() {
27916 self.write_keyword(" PROTECTION");
27917 }
27918 Ok(())
27919 }
27920
27921 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
27922 self.write_keyword("FARM_FINGERPRINT");
27924 self.write("(");
27925 for (i, expr) in e.expressions.iter().enumerate() {
27926 if i > 0 {
27927 self.write(", ");
27928 }
27929 self.generate_expression(expr)?;
27930 }
27931 self.write(")");
27932 Ok(())
27933 }
27934
27935 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
27936 self.write_keyword("FEATURES_AT_TIME");
27938 self.write("(");
27939 self.generate_expression(&e.this)?;
27940 if let Some(time) = &e.time {
27941 self.write(", ");
27942 self.generate_expression(time)?;
27943 }
27944 if let Some(num_rows) = &e.num_rows {
27945 self.write(", ");
27946 self.generate_expression(num_rows)?;
27947 }
27948 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
27949 self.write(", ");
27950 self.generate_expression(ignore_nulls)?;
27951 }
27952 self.write(")");
27953 Ok(())
27954 }
27955
27956 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
27957 let use_limit = !e.percent
27959 && !e.with_ties
27960 && e.count.is_some()
27961 && matches!(
27962 self.config.dialect,
27963 Some(DialectType::Spark)
27964 | Some(DialectType::Hive)
27965 | Some(DialectType::DuckDB)
27966 | Some(DialectType::SQLite)
27967 | Some(DialectType::MySQL)
27968 | Some(DialectType::BigQuery)
27969 | Some(DialectType::Databricks)
27970 | Some(DialectType::StarRocks)
27971 | Some(DialectType::Doris)
27972 | Some(DialectType::Athena)
27973 | Some(DialectType::ClickHouse)
27974 );
27975
27976 if use_limit {
27977 self.write_keyword("LIMIT");
27978 self.write_space();
27979 self.generate_expression(e.count.as_ref().unwrap())?;
27980 return Ok(());
27981 }
27982
27983 self.write_keyword("FETCH");
27985 if !e.direction.is_empty() {
27986 self.write_space();
27987 self.write_keyword(&e.direction);
27988 }
27989 if let Some(count) = &e.count {
27990 self.write_space();
27991 self.generate_expression(count)?;
27992 }
27993 if e.percent {
27995 self.write_keyword(" PERCENT");
27996 }
27997 if e.rows {
27998 self.write_keyword(" ROWS");
27999 }
28000 if e.with_ties {
28001 self.write_keyword(" WITH TIES");
28002 } else if e.rows {
28003 self.write_keyword(" ONLY");
28004 } else {
28005 self.write_keyword(" ROWS ONLY");
28006 }
28007 Ok(())
28008 }
28009
28010 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
28011 if e.hive_format.is_some() {
28015 self.write_keyword("STORED AS");
28017 self.write_space();
28018 if let Some(this) = &e.this {
28019 if let Expression::Identifier(id) = this.as_ref() {
28021 self.write_keyword(&id.name.to_ascii_uppercase());
28022 } else {
28023 self.generate_expression(this)?;
28024 }
28025 }
28026 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
28027 self.write_keyword("STORED AS");
28029 self.write_space();
28030 if let Some(this) = &e.this {
28031 if let Expression::Identifier(id) = this.as_ref() {
28032 self.write_keyword(&id.name.to_ascii_uppercase());
28033 } else {
28034 self.generate_expression(this)?;
28035 }
28036 }
28037 } else if matches!(
28038 self.config.dialect,
28039 Some(DialectType::Spark) | Some(DialectType::Databricks)
28040 ) {
28041 self.write_keyword("USING");
28043 self.write_space();
28044 if let Some(this) = &e.this {
28045 self.generate_expression(this)?;
28046 }
28047 } else {
28048 self.write_keyword("FILE_FORMAT");
28050 self.write(" = ");
28051 if let Some(this) = &e.this {
28052 self.generate_expression(this)?;
28053 } else if !e.expressions.is_empty() {
28054 self.write("(");
28055 for (i, expr) in e.expressions.iter().enumerate() {
28056 if i > 0 {
28057 self.write(", ");
28058 }
28059 self.generate_expression(expr)?;
28060 }
28061 self.write(")");
28062 }
28063 }
28064 Ok(())
28065 }
28066
28067 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
28068 self.generate_expression(&e.this)?;
28070 self.write_space();
28071 self.write_keyword("FILTER");
28072 self.write("(");
28073 self.write_keyword("WHERE");
28074 self.write_space();
28075 self.generate_expression(&e.expression)?;
28076 self.write(")");
28077 Ok(())
28078 }
28079
28080 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
28081 self.write_keyword("FLOAT64");
28083 self.write("(");
28084 self.generate_expression(&e.this)?;
28085 if let Some(expr) = &e.expression {
28086 self.write(", ");
28087 self.generate_expression(expr)?;
28088 }
28089 self.write(")");
28090 Ok(())
28091 }
28092
28093 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
28094 self.write_keyword("FOR");
28096 self.write_space();
28097 self.generate_expression(&e.this)?;
28098 self.write_space();
28099 self.write_keyword("DO");
28100 self.write_space();
28101 self.generate_expression(&e.expression)?;
28102 Ok(())
28103 }
28104
28105 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
28106 self.write_keyword("FOREIGN KEY");
28108 if !e.expressions.is_empty() {
28109 self.write(" (");
28110 for (i, expr) in e.expressions.iter().enumerate() {
28111 if i > 0 {
28112 self.write(", ");
28113 }
28114 self.generate_expression(expr)?;
28115 }
28116 self.write(")");
28117 }
28118 if let Some(reference) = &e.reference {
28119 self.write_space();
28120 self.generate_expression(reference)?;
28121 }
28122 if let Some(delete) = &e.delete {
28123 self.write_space();
28124 self.write_keyword("ON DELETE");
28125 self.write_space();
28126 self.generate_expression(delete)?;
28127 }
28128 if let Some(update) = &e.update {
28129 self.write_space();
28130 self.write_keyword("ON UPDATE");
28131 self.write_space();
28132 self.generate_expression(update)?;
28133 }
28134 if !e.options.is_empty() {
28135 self.write_space();
28136 for (i, opt) in e.options.iter().enumerate() {
28137 if i > 0 {
28138 self.write_space();
28139 }
28140 self.generate_expression(opt)?;
28141 }
28142 }
28143 Ok(())
28144 }
28145
28146 fn generate_format(&mut self, e: &Format) -> Result<()> {
28147 self.write_keyword("FORMAT");
28149 self.write("(");
28150 self.generate_expression(&e.this)?;
28151 for expr in &e.expressions {
28152 self.write(", ");
28153 self.generate_expression(expr)?;
28154 }
28155 self.write(")");
28156 Ok(())
28157 }
28158
28159 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
28160 self.generate_expression(&e.this)?;
28162 self.write(" (");
28163 self.write_keyword("FORMAT");
28164 self.write(" '");
28165 self.write(&e.format);
28166 self.write("')");
28167 Ok(())
28168 }
28169
28170 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
28171 self.write_keyword("FREESPACE");
28173 self.write("=");
28174 self.generate_expression(&e.this)?;
28175 if e.percent.is_some() {
28176 self.write_keyword(" PERCENT");
28177 }
28178 Ok(())
28179 }
28180
28181 fn generate_from(&mut self, e: &From) -> Result<()> {
28182 self.write_keyword("FROM");
28184 self.write_space();
28185
28186 use crate::dialects::DialectType;
28190 let has_tablesample = e
28191 .expressions
28192 .iter()
28193 .any(|expr| matches!(expr, Expression::TableSample(_)));
28194 let is_cross_join_dialect = matches!(
28195 self.config.dialect,
28196 Some(DialectType::BigQuery)
28197 | Some(DialectType::Hive)
28198 | Some(DialectType::Spark)
28199 | Some(DialectType::Databricks)
28200 | Some(DialectType::SQLite)
28201 | Some(DialectType::ClickHouse)
28202 );
28203 let source_is_same_as_target2 = self.config.source_dialect.is_some()
28204 && self.config.source_dialect == self.config.dialect;
28205 let source_is_cross_join_dialect2 = matches!(
28206 self.config.source_dialect,
28207 Some(DialectType::BigQuery)
28208 | Some(DialectType::Hive)
28209 | Some(DialectType::Spark)
28210 | Some(DialectType::Databricks)
28211 | Some(DialectType::SQLite)
28212 | Some(DialectType::ClickHouse)
28213 );
28214 let use_cross_join = !has_tablesample
28215 && is_cross_join_dialect
28216 && (source_is_same_as_target2
28217 || source_is_cross_join_dialect2
28218 || self.config.source_dialect.is_none());
28219
28220 let wrap_values_in_parens = matches!(self.config.dialect, Some(DialectType::Snowflake));
28222
28223 for (i, expr) in e.expressions.iter().enumerate() {
28224 if i > 0 {
28225 if use_cross_join {
28226 self.write(" CROSS JOIN ");
28227 } else {
28228 self.write(", ");
28229 }
28230 }
28231 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
28232 self.write("(");
28233 self.generate_expression(expr)?;
28234 self.write(")");
28235 } else {
28236 self.generate_expression(expr)?;
28237 }
28238 let leading = Self::extract_table_leading_comments(expr);
28241 for comment in &leading {
28242 self.write_space();
28243 self.write_formatted_comment(comment);
28244 }
28245 }
28246 Ok(())
28247 }
28248
28249 fn extract_table_leading_comments(expr: &Expression) -> Vec<String> {
28251 match expr {
28252 Expression::Table(t) => t.leading_comments.clone(),
28253 Expression::Pivot(p) => {
28254 if let Expression::Table(t) = &p.this {
28255 t.leading_comments.clone()
28256 } else {
28257 Vec::new()
28258 }
28259 }
28260 _ => Vec::new(),
28261 }
28262 }
28263
28264 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
28265 self.write_keyword("FROM_BASE");
28267 self.write("(");
28268 self.generate_expression(&e.this)?;
28269 self.write(", ");
28270 self.generate_expression(&e.expression)?;
28271 self.write(")");
28272 Ok(())
28273 }
28274
28275 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
28276 self.generate_expression(&e.this)?;
28278 if let Some(zone) = &e.zone {
28279 self.write_space();
28280 self.write_keyword("AT TIME ZONE");
28281 self.write_space();
28282 self.generate_expression(zone)?;
28283 self.write_space();
28284 self.write_keyword("AT TIME ZONE");
28285 self.write(" 'UTC'");
28286 }
28287 Ok(())
28288 }
28289
28290 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
28291 self.write_keyword("GAP_FILL");
28293 self.write("(");
28294 self.generate_expression(&e.this)?;
28295 if let Some(ts_column) = &e.ts_column {
28296 self.write(", ");
28297 self.generate_expression(ts_column)?;
28298 }
28299 if let Some(bucket_width) = &e.bucket_width {
28300 self.write(", ");
28301 self.generate_expression(bucket_width)?;
28302 }
28303 if let Some(partitioning_columns) = &e.partitioning_columns {
28304 self.write(", ");
28305 self.generate_expression(partitioning_columns)?;
28306 }
28307 if let Some(value_columns) = &e.value_columns {
28308 self.write(", ");
28309 self.generate_expression(value_columns)?;
28310 }
28311 self.write(")");
28312 Ok(())
28313 }
28314
28315 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
28316 self.write_keyword("GENERATE_DATE_ARRAY");
28318 self.write("(");
28319 let mut first = true;
28320 if let Some(start) = &e.start {
28321 self.generate_expression(start)?;
28322 first = false;
28323 }
28324 if let Some(end) = &e.end {
28325 if !first {
28326 self.write(", ");
28327 }
28328 self.generate_expression(end)?;
28329 first = false;
28330 }
28331 if let Some(step) = &e.step {
28332 if !first {
28333 self.write(", ");
28334 }
28335 self.generate_expression(step)?;
28336 }
28337 self.write(")");
28338 Ok(())
28339 }
28340
28341 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
28342 self.write_keyword("ML.GENERATE_EMBEDDING");
28344 self.write("(");
28345 self.generate_expression(&e.this)?;
28346 self.write(", ");
28347 self.generate_expression(&e.expression)?;
28348 if let Some(params) = &e.params_struct {
28349 self.write(", ");
28350 self.generate_expression(params)?;
28351 }
28352 self.write(")");
28353 Ok(())
28354 }
28355
28356 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
28357 let fn_name = match self.config.dialect {
28359 Some(DialectType::Presto)
28360 | Some(DialectType::Trino)
28361 | Some(DialectType::Athena)
28362 | Some(DialectType::Spark)
28363 | Some(DialectType::Databricks)
28364 | Some(DialectType::Hive) => "SEQUENCE",
28365 _ => "GENERATE_SERIES",
28366 };
28367 self.write_keyword(fn_name);
28368 self.write("(");
28369 let mut first = true;
28370 if let Some(start) = &e.start {
28371 self.generate_expression(start)?;
28372 first = false;
28373 }
28374 if let Some(end) = &e.end {
28375 if !first {
28376 self.write(", ");
28377 }
28378 self.generate_expression(end)?;
28379 first = false;
28380 }
28381 if let Some(step) = &e.step {
28382 if !first {
28383 self.write(", ");
28384 }
28385 if matches!(
28388 self.config.dialect,
28389 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
28390 ) {
28391 if let Some(converted) = self.convert_week_interval_to_day(step) {
28392 self.generate_expression(&converted)?;
28393 } else {
28394 self.generate_expression(step)?;
28395 }
28396 } else {
28397 self.generate_expression(step)?;
28398 }
28399 }
28400 self.write(")");
28401 Ok(())
28402 }
28403
28404 fn convert_week_interval_to_day(&self, expr: &Expression) -> Option<Expression> {
28407 use crate::expressions::*;
28408 if let Expression::Interval(ref iv) = expr {
28409 let (is_week, count_str) = if let Some(IntervalUnitSpec::Simple {
28411 unit: IntervalUnit::Week,
28412 ..
28413 }) = &iv.unit
28414 {
28415 let count = match &iv.this {
28417 Some(Expression::Literal(lit)) => match lit.as_ref() {
28418 Literal::String(s) | Literal::Number(s) => s.clone(),
28419 _ => return None,
28420 },
28421 _ => return None,
28422 };
28423 (true, count)
28424 } else if iv.unit.is_none() {
28425 if let Some(Expression::Literal(lit)) = &iv.this {
28427 if let Literal::String(s) = lit.as_ref() {
28428 let parts: Vec<&str> = s.trim().splitn(2, char::is_whitespace).collect();
28429 if parts.len() == 2 && parts[1].eq_ignore_ascii_case("WEEK") {
28430 (true, parts[0].to_string())
28431 } else {
28432 (false, String::new())
28433 }
28434 } else {
28435 (false, String::new())
28436 }
28437 } else {
28438 (false, String::new())
28439 }
28440 } else {
28441 (false, String::new())
28442 };
28443
28444 if is_week {
28445 let count_expr = Expression::Literal(Box::new(Literal::Number(count_str)));
28447 let day_interval = Expression::Interval(Box::new(Interval {
28448 this: Some(Expression::Literal(Box::new(Literal::String(
28449 "7".to_string(),
28450 )))),
28451 unit: Some(IntervalUnitSpec::Simple {
28452 unit: IntervalUnit::Day,
28453 use_plural: false,
28454 }),
28455 }));
28456 let mul = Expression::Mul(Box::new(BinaryOp {
28457 left: count_expr,
28458 right: day_interval,
28459 left_comments: vec![],
28460 operator_comments: vec![],
28461 trailing_comments: vec![],
28462 inferred_type: None,
28463 }));
28464 return Some(Expression::Paren(Box::new(Paren {
28465 this: mul,
28466 trailing_comments: vec![],
28467 })));
28468 }
28469 }
28470 None
28471 }
28472
28473 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
28474 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
28476 self.write("(");
28477 let mut first = true;
28478 if let Some(start) = &e.start {
28479 self.generate_expression(start)?;
28480 first = false;
28481 }
28482 if let Some(end) = &e.end {
28483 if !first {
28484 self.write(", ");
28485 }
28486 self.generate_expression(end)?;
28487 first = false;
28488 }
28489 if let Some(step) = &e.step {
28490 if !first {
28491 self.write(", ");
28492 }
28493 self.generate_expression(step)?;
28494 }
28495 self.write(")");
28496 Ok(())
28497 }
28498
28499 fn generate_generated_as_identity_column_constraint(
28500 &mut self,
28501 e: &GeneratedAsIdentityColumnConstraint,
28502 ) -> Result<()> {
28503 use crate::dialects::DialectType;
28504
28505 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
28507 self.write_keyword("AUTOINCREMENT");
28508 if let Some(start) = &e.start {
28509 self.write_keyword(" START ");
28510 self.generate_expression(start)?;
28511 }
28512 if let Some(increment) = &e.increment {
28513 self.write_keyword(" INCREMENT ");
28514 self.generate_expression(increment)?;
28515 }
28516 return Ok(());
28517 }
28518
28519 self.write_keyword("GENERATED");
28521 if let Some(this) = &e.this {
28522 if let Expression::Boolean(b) = this.as_ref() {
28524 if b.value {
28525 self.write_keyword(" ALWAYS");
28526 } else {
28527 self.write_keyword(" BY DEFAULT");
28528 if e.on_null.is_some() {
28529 self.write_keyword(" ON NULL");
28530 }
28531 }
28532 } else {
28533 self.write_keyword(" ALWAYS");
28534 }
28535 }
28536 self.write_keyword(" AS IDENTITY");
28537 let has_options = e.start.is_some()
28539 || e.increment.is_some()
28540 || e.minvalue.is_some()
28541 || e.maxvalue.is_some();
28542 if has_options {
28543 self.write(" (");
28544 let mut first = true;
28545 if let Some(start) = &e.start {
28546 self.write_keyword("START WITH ");
28547 self.generate_expression(start)?;
28548 first = false;
28549 }
28550 if let Some(increment) = &e.increment {
28551 if !first {
28552 self.write(" ");
28553 }
28554 self.write_keyword("INCREMENT BY ");
28555 self.generate_expression(increment)?;
28556 first = false;
28557 }
28558 if let Some(minvalue) = &e.minvalue {
28559 if !first {
28560 self.write(" ");
28561 }
28562 self.write_keyword("MINVALUE ");
28563 self.generate_expression(minvalue)?;
28564 first = false;
28565 }
28566 if let Some(maxvalue) = &e.maxvalue {
28567 if !first {
28568 self.write(" ");
28569 }
28570 self.write_keyword("MAXVALUE ");
28571 self.generate_expression(maxvalue)?;
28572 }
28573 self.write(")");
28574 }
28575 Ok(())
28576 }
28577
28578 fn generate_generated_as_row_column_constraint(
28579 &mut self,
28580 e: &GeneratedAsRowColumnConstraint,
28581 ) -> Result<()> {
28582 self.write_keyword("GENERATED ALWAYS AS ROW ");
28584 if e.start.is_some() {
28585 self.write_keyword("START");
28586 } else {
28587 self.write_keyword("END");
28588 }
28589 if e.hidden.is_some() {
28590 self.write_keyword(" HIDDEN");
28591 }
28592 Ok(())
28593 }
28594
28595 fn generate_get(&mut self, e: &Get) -> Result<()> {
28596 self.write_keyword("GET");
28598 self.write_space();
28599 self.generate_expression(&e.this)?;
28600 if let Some(target) = &e.target {
28601 self.write_space();
28602 self.generate_expression(target)?;
28603 }
28604 for prop in &e.properties {
28605 self.write_space();
28606 self.generate_expression(prop)?;
28607 }
28608 Ok(())
28609 }
28610
28611 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
28612 self.generate_expression(&e.this)?;
28614 self.write("[");
28615 self.generate_expression(&e.expression)?;
28616 self.write("]");
28617 Ok(())
28618 }
28619
28620 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
28621 self.write_keyword("GETBIT");
28623 self.write("(");
28624 self.generate_expression(&e.this)?;
28625 self.write(", ");
28626 self.generate_expression(&e.expression)?;
28627 self.write(")");
28628 Ok(())
28629 }
28630
28631 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
28632 if e.is_role {
28634 self.write_keyword("ROLE");
28635 self.write_space();
28636 } else if e.is_group {
28637 self.write_keyword("GROUP");
28638 self.write_space();
28639 } else if e.is_share {
28640 self.write_keyword("SHARE");
28641 self.write_space();
28642 }
28643 self.write(&e.name.name);
28644 Ok(())
28645 }
28646
28647 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
28648 self.generate_expression(&e.this)?;
28650 if !e.expressions.is_empty() {
28651 self.write("(");
28652 for (i, expr) in e.expressions.iter().enumerate() {
28653 if i > 0 {
28654 self.write(", ");
28655 }
28656 self.generate_expression(expr)?;
28657 }
28658 self.write(")");
28659 }
28660 Ok(())
28661 }
28662
28663 fn generate_group(&mut self, e: &Group) -> Result<()> {
28664 self.write_keyword("GROUP BY");
28666 match e.all {
28668 Some(true) => {
28669 self.write_space();
28670 self.write_keyword("ALL");
28671 }
28672 Some(false) => {
28673 self.write_space();
28674 self.write_keyword("DISTINCT");
28675 }
28676 None => {}
28677 }
28678 if !e.expressions.is_empty() {
28679 self.write_space();
28680 for (i, expr) in e.expressions.iter().enumerate() {
28681 if i > 0 {
28682 self.write(", ");
28683 }
28684 self.generate_expression(expr)?;
28685 }
28686 }
28687 if let Some(cube) = &e.cube {
28689 if !e.expressions.is_empty() {
28690 self.write(", ");
28691 } else {
28692 self.write_space();
28693 }
28694 self.generate_expression(cube)?;
28695 }
28696 if let Some(rollup) = &e.rollup {
28697 if !e.expressions.is_empty() || e.cube.is_some() {
28698 self.write(", ");
28699 } else {
28700 self.write_space();
28701 }
28702 self.generate_expression(rollup)?;
28703 }
28704 if let Some(grouping_sets) = &e.grouping_sets {
28705 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
28706 self.write(", ");
28707 } else {
28708 self.write_space();
28709 }
28710 self.generate_expression(grouping_sets)?;
28711 }
28712 if let Some(totals) = &e.totals {
28713 self.write_space();
28714 self.write_keyword("WITH TOTALS");
28715 self.generate_expression(totals)?;
28716 }
28717 Ok(())
28718 }
28719
28720 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
28721 self.write_keyword("GROUP BY");
28723 match e.all {
28725 Some(true) => {
28726 self.write_space();
28727 self.write_keyword("ALL");
28728 }
28729 Some(false) => {
28730 self.write_space();
28731 self.write_keyword("DISTINCT");
28732 }
28733 None => {}
28734 }
28735
28736 let mut trailing_cube = false;
28739 let mut trailing_rollup = false;
28740 let mut regular_expressions: Vec<&Expression> = Vec::new();
28741
28742 for expr in &e.expressions {
28743 match expr {
28744 Expression::Cube(c) if c.expressions.is_empty() => {
28745 trailing_cube = true;
28746 }
28747 Expression::Rollup(r) if r.expressions.is_empty() => {
28748 trailing_rollup = true;
28749 }
28750 _ => {
28751 regular_expressions.push(expr);
28752 }
28753 }
28754 }
28755
28756 if self.config.pretty {
28758 self.write_newline();
28759 self.indent_level += 1;
28760 for (i, expr) in regular_expressions.iter().enumerate() {
28761 if i > 0 {
28762 self.write(",");
28763 self.write_newline();
28764 }
28765 self.write_indent();
28766 self.generate_expression(expr)?;
28767 }
28768 self.indent_level -= 1;
28769 } else {
28770 self.write_space();
28771 for (i, expr) in regular_expressions.iter().enumerate() {
28772 if i > 0 {
28773 self.write(", ");
28774 }
28775 self.generate_expression(expr)?;
28776 }
28777 }
28778
28779 if trailing_cube {
28781 self.write_space();
28782 self.write_keyword("WITH CUBE");
28783 } else if trailing_rollup {
28784 self.write_space();
28785 self.write_keyword("WITH ROLLUP");
28786 }
28787
28788 if e.totals {
28790 self.write_space();
28791 self.write_keyword("WITH TOTALS");
28792 }
28793
28794 Ok(())
28795 }
28796
28797 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
28798 self.write_keyword("GROUPING");
28800 self.write("(");
28801 for (i, expr) in e.expressions.iter().enumerate() {
28802 if i > 0 {
28803 self.write(", ");
28804 }
28805 self.generate_expression(expr)?;
28806 }
28807 self.write(")");
28808 Ok(())
28809 }
28810
28811 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
28812 self.write_keyword("GROUPING_ID");
28814 self.write("(");
28815 for (i, expr) in e.expressions.iter().enumerate() {
28816 if i > 0 {
28817 self.write(", ");
28818 }
28819 self.generate_expression(expr)?;
28820 }
28821 self.write(")");
28822 Ok(())
28823 }
28824
28825 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
28826 self.write_keyword("GROUPING SETS");
28828 self.write(" (");
28829 for (i, expr) in e.expressions.iter().enumerate() {
28830 if i > 0 {
28831 self.write(", ");
28832 }
28833 self.generate_expression(expr)?;
28834 }
28835 self.write(")");
28836 Ok(())
28837 }
28838
28839 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
28840 self.write_keyword("HASH_AGG");
28842 self.write("(");
28843 self.generate_expression(&e.this)?;
28844 for expr in &e.expressions {
28845 self.write(", ");
28846 self.generate_expression(expr)?;
28847 }
28848 self.write(")");
28849 Ok(())
28850 }
28851
28852 fn generate_having(&mut self, e: &Having) -> Result<()> {
28853 self.write_keyword("HAVING");
28855 self.write_space();
28856 self.generate_expression(&e.this)?;
28857 Ok(())
28858 }
28859
28860 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
28861 self.generate_expression(&e.this)?;
28863 self.write_space();
28864 self.write_keyword("HAVING");
28865 self.write_space();
28866 if e.max.is_some() {
28867 self.write_keyword("MAX");
28868 } else {
28869 self.write_keyword("MIN");
28870 }
28871 self.write_space();
28872 self.generate_expression(&e.expression)?;
28873 Ok(())
28874 }
28875
28876 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
28877 use crate::dialects::DialectType;
28878 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
28880 if let Expression::Literal(ref lit) = *e.this {
28882 if let Literal::String(ref s) = lit.as_ref() {
28883 return self.generate_string_literal(s);
28884 }
28885 }
28886 }
28887 if matches!(
28889 self.config.dialect,
28890 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
28891 ) {
28892 self.write("$");
28893 if let Some(tag) = &e.tag {
28894 self.generate_expression(tag)?;
28895 }
28896 self.write("$");
28897 self.generate_expression(&e.this)?;
28898 self.write("$");
28899 if let Some(tag) = &e.tag {
28900 self.generate_expression(tag)?;
28901 }
28902 self.write("$");
28903 return Ok(());
28904 }
28905 self.write("$");
28907 if let Some(tag) = &e.tag {
28908 self.generate_expression(tag)?;
28909 }
28910 self.write("$");
28911 self.generate_expression(&e.this)?;
28912 self.write("$");
28913 if let Some(tag) = &e.tag {
28914 self.generate_expression(tag)?;
28915 }
28916 self.write("$");
28917 Ok(())
28918 }
28919
28920 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
28921 self.write_keyword("HEX_ENCODE");
28923 self.write("(");
28924 self.generate_expression(&e.this)?;
28925 self.write(")");
28926 Ok(())
28927 }
28928
28929 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
28930 match e.this.as_ref() {
28933 Expression::Identifier(id) => self.write(&id.name),
28934 other => self.generate_expression(other)?,
28935 }
28936 self.write(" (");
28937 self.write(&e.kind);
28938 self.write(" => ");
28939 self.generate_expression(&e.expression)?;
28940 self.write(")");
28941 Ok(())
28942 }
28943
28944 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
28945 self.write_keyword("HLL");
28947 self.write("(");
28948 self.generate_expression(&e.this)?;
28949 for expr in &e.expressions {
28950 self.write(", ");
28951 self.generate_expression(expr)?;
28952 }
28953 self.write(")");
28954 Ok(())
28955 }
28956
28957 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
28958 if e.input_.is_some() && e.output.is_some() {
28960 self.write_keyword("IN OUT");
28961 } else if e.input_.is_some() {
28962 self.write_keyword("IN");
28963 } else if e.output.is_some() {
28964 self.write_keyword("OUT");
28965 }
28966 Ok(())
28967 }
28968
28969 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
28970 self.write_keyword("INCLUDE");
28972 self.write_space();
28973 self.generate_expression(&e.this)?;
28974 if let Some(column_def) = &e.column_def {
28975 self.write_space();
28976 self.generate_expression(column_def)?;
28977 }
28978 if let Some(alias) = &e.alias {
28979 self.write_space();
28980 self.write_keyword("AS");
28981 self.write_space();
28982 self.write(alias);
28983 }
28984 Ok(())
28985 }
28986
28987 fn generate_index(&mut self, e: &Index) -> Result<()> {
28988 if e.unique {
28990 self.write_keyword("UNIQUE");
28991 self.write_space();
28992 }
28993 if e.primary.is_some() {
28994 self.write_keyword("PRIMARY");
28995 self.write_space();
28996 }
28997 if e.amp.is_some() {
28998 self.write_keyword("AMP");
28999 self.write_space();
29000 }
29001 if e.table.is_none() {
29002 self.write_keyword("INDEX");
29003 self.write_space();
29004 }
29005 if let Some(name) = &e.this {
29006 self.generate_expression(name)?;
29007 self.write_space();
29008 }
29009 if let Some(table) = &e.table {
29010 self.write_keyword("ON");
29011 self.write_space();
29012 self.generate_expression(table)?;
29013 }
29014 if !e.params.is_empty() {
29015 self.write("(");
29016 for (i, param) in e.params.iter().enumerate() {
29017 if i > 0 {
29018 self.write(", ");
29019 }
29020 self.generate_expression(param)?;
29021 }
29022 self.write(")");
29023 }
29024 Ok(())
29025 }
29026
29027 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
29028 if let Some(kind) = &e.kind {
29030 self.write(kind);
29031 self.write_space();
29032 }
29033 self.write_keyword("INDEX");
29034 if let Some(this) = &e.this {
29035 self.write_space();
29036 self.generate_expression(this)?;
29037 }
29038 if let Some(index_type) = &e.index_type {
29039 self.write_space();
29040 self.write_keyword("USING");
29041 self.write_space();
29042 self.generate_expression(index_type)?;
29043 }
29044 if !e.expressions.is_empty() {
29045 self.write(" (");
29046 for (i, expr) in e.expressions.iter().enumerate() {
29047 if i > 0 {
29048 self.write(", ");
29049 }
29050 self.generate_expression(expr)?;
29051 }
29052 self.write(")");
29053 }
29054 for opt in &e.options {
29055 self.write_space();
29056 self.generate_expression(opt)?;
29057 }
29058 Ok(())
29059 }
29060
29061 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
29062 if let Some(key_block_size) = &e.key_block_size {
29064 self.write_keyword("KEY_BLOCK_SIZE");
29065 self.write(" = ");
29066 self.generate_expression(key_block_size)?;
29067 } else if let Some(using) = &e.using {
29068 self.write_keyword("USING");
29069 self.write_space();
29070 self.generate_expression(using)?;
29071 } else if let Some(parser) = &e.parser {
29072 self.write_keyword("WITH PARSER");
29073 self.write_space();
29074 self.generate_expression(parser)?;
29075 } else if let Some(comment) = &e.comment {
29076 self.write_keyword("COMMENT");
29077 self.write_space();
29078 self.generate_expression(comment)?;
29079 } else if let Some(visible) = &e.visible {
29080 self.generate_expression(visible)?;
29081 } else if let Some(engine_attr) = &e.engine_attr {
29082 self.write_keyword("ENGINE_ATTRIBUTE");
29083 self.write(" = ");
29084 self.generate_expression(engine_attr)?;
29085 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
29086 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
29087 self.write(" = ");
29088 self.generate_expression(secondary_engine_attr)?;
29089 }
29090 Ok(())
29091 }
29092
29093 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
29094 if let Some(using) = &e.using {
29096 self.write_keyword("USING");
29097 self.write_space();
29098 self.generate_expression(using)?;
29099 }
29100 if !e.columns.is_empty() {
29101 self.write("(");
29102 for (i, col) in e.columns.iter().enumerate() {
29103 if i > 0 {
29104 self.write(", ");
29105 }
29106 self.generate_expression(col)?;
29107 }
29108 self.write(")");
29109 }
29110 if let Some(partition_by) = &e.partition_by {
29111 self.write_space();
29112 self.write_keyword("PARTITION BY");
29113 self.write_space();
29114 self.generate_expression(partition_by)?;
29115 }
29116 if let Some(where_) = &e.where_ {
29117 self.write_space();
29118 self.generate_expression(where_)?;
29119 }
29120 if let Some(include) = &e.include {
29121 self.write_space();
29122 self.write_keyword("INCLUDE");
29123 self.write(" (");
29124 self.generate_expression(include)?;
29125 self.write(")");
29126 }
29127 if let Some(with_storage) = &e.with_storage {
29128 self.write_space();
29129 self.write_keyword("WITH");
29130 self.write(" (");
29131 self.generate_expression(with_storage)?;
29132 self.write(")");
29133 }
29134 if let Some(tablespace) = &e.tablespace {
29135 self.write_space();
29136 self.write_keyword("USING INDEX TABLESPACE");
29137 self.write_space();
29138 self.generate_expression(tablespace)?;
29139 }
29140 Ok(())
29141 }
29142
29143 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
29144 if let Expression::Identifier(id) = &*e.this {
29148 self.write_keyword(&id.name);
29149 } else {
29150 self.generate_expression(&e.this)?;
29151 }
29152 self.write_space();
29153 self.write_keyword("INDEX");
29154 if let Some(target) = &e.target {
29155 self.write_space();
29156 self.write_keyword("FOR");
29157 self.write_space();
29158 if let Expression::Identifier(id) = &**target {
29159 self.write_keyword(&id.name);
29160 } else {
29161 self.generate_expression(target)?;
29162 }
29163 }
29164 self.write(" (");
29166 for (i, expr) in e.expressions.iter().enumerate() {
29167 if i > 0 {
29168 self.write(", ");
29169 }
29170 self.generate_expression(expr)?;
29171 }
29172 self.write(")");
29173 Ok(())
29174 }
29175
29176 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
29177 self.write_keyword("INHERITS");
29179 self.write(" (");
29180 for (i, expr) in e.expressions.iter().enumerate() {
29181 if i > 0 {
29182 self.write(", ");
29183 }
29184 self.generate_expression(expr)?;
29185 }
29186 self.write(")");
29187 Ok(())
29188 }
29189
29190 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
29191 self.write_keyword("INPUT");
29193 self.write("(");
29194 self.generate_expression(&e.this)?;
29195 self.write(")");
29196 Ok(())
29197 }
29198
29199 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
29200 if let Some(input_format) = &e.input_format {
29202 self.write_keyword("INPUTFORMAT");
29203 self.write_space();
29204 self.generate_expression(input_format)?;
29205 }
29206 if let Some(output_format) = &e.output_format {
29207 if e.input_format.is_some() {
29208 self.write(" ");
29209 }
29210 self.write_keyword("OUTPUTFORMAT");
29211 self.write_space();
29212 self.generate_expression(output_format)?;
29213 }
29214 Ok(())
29215 }
29216
29217 fn generate_install(&mut self, e: &Install) -> Result<()> {
29218 if e.force.is_some() {
29220 self.write_keyword("FORCE");
29221 self.write_space();
29222 }
29223 self.write_keyword("INSTALL");
29224 self.write_space();
29225 self.generate_expression(&e.this)?;
29226 if let Some(from) = &e.from_ {
29227 self.write_space();
29228 self.write_keyword("FROM");
29229 self.write_space();
29230 self.generate_expression(from)?;
29231 }
29232 Ok(())
29233 }
29234
29235 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
29236 self.write_keyword("INTERVAL");
29238 self.write_space();
29239 self.generate_expression(&e.expression)?;
29241 if let Some(unit) = &e.unit {
29242 self.write_space();
29243 self.write(unit);
29244 }
29245 Ok(())
29246 }
29247
29248 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
29249 self.write(&format!("{:?}", e.this).to_ascii_uppercase());
29251 self.write_space();
29252 self.write_keyword("TO");
29253 self.write_space();
29254 self.write(&format!("{:?}", e.expression).to_ascii_uppercase());
29255 Ok(())
29256 }
29257
29258 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
29259 self.write_keyword("INTO");
29261 if e.temporary {
29262 self.write_keyword(" TEMPORARY");
29263 }
29264 if e.unlogged.is_some() {
29265 self.write_keyword(" UNLOGGED");
29266 }
29267 if let Some(this) = &e.this {
29268 self.write_space();
29269 self.generate_expression(this)?;
29270 }
29271 if !e.expressions.is_empty() {
29272 self.write(" (");
29273 for (i, expr) in e.expressions.iter().enumerate() {
29274 if i > 0 {
29275 self.write(", ");
29276 }
29277 self.generate_expression(expr)?;
29278 }
29279 self.write(")");
29280 }
29281 Ok(())
29282 }
29283
29284 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
29285 self.generate_expression(&e.this)?;
29287 self.write_space();
29288 self.generate_expression(&e.expression)?;
29289 Ok(())
29290 }
29291
29292 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
29293 self.write_keyword("WITH");
29295 if e.no.is_some() {
29296 self.write_keyword(" NO");
29297 }
29298 if e.concurrent.is_some() {
29299 self.write_keyword(" CONCURRENT");
29300 }
29301 self.write_keyword(" ISOLATED LOADING");
29302 if let Some(target) = &e.target {
29303 self.write_space();
29304 self.generate_expression(target)?;
29305 }
29306 Ok(())
29307 }
29308
29309 fn generate_json(&mut self, e: &JSON) -> Result<()> {
29310 self.write_keyword("JSON");
29312 if let Some(this) = &e.this {
29313 self.write_space();
29314 self.generate_expression(this)?;
29315 }
29316 if let Some(with_) = &e.with_ {
29317 if let Expression::Boolean(b) = with_.as_ref() {
29319 if b.value {
29320 self.write_keyword(" WITH");
29321 } else {
29322 self.write_keyword(" WITHOUT");
29323 }
29324 }
29325 }
29326 if e.unique {
29327 self.write_keyword(" UNIQUE KEYS");
29328 }
29329 Ok(())
29330 }
29331
29332 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
29333 self.write_keyword("JSON_ARRAY");
29335 self.write("(");
29336 for (i, expr) in e.expressions.iter().enumerate() {
29337 if i > 0 {
29338 self.write(", ");
29339 }
29340 self.generate_expression(expr)?;
29341 }
29342 if let Some(null_handling) = &e.null_handling {
29343 self.write_space();
29344 self.generate_expression(null_handling)?;
29345 }
29346 if let Some(return_type) = &e.return_type {
29347 self.write_space();
29348 self.write_keyword("RETURNING");
29349 self.write_space();
29350 self.generate_expression(return_type)?;
29351 }
29352 if e.strict.is_some() {
29353 self.write_space();
29354 self.write_keyword("STRICT");
29355 }
29356 self.write(")");
29357 Ok(())
29358 }
29359
29360 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
29361 self.write_keyword("JSON_ARRAYAGG");
29363 self.write("(");
29364 self.generate_expression(&e.this)?;
29365 if let Some(order) = &e.order {
29366 self.write_space();
29367 if let Expression::OrderBy(ob) = order.as_ref() {
29369 self.write_keyword("ORDER BY");
29370 self.write_space();
29371 for (i, ord) in ob.expressions.iter().enumerate() {
29372 if i > 0 {
29373 self.write(", ");
29374 }
29375 self.generate_ordered(ord)?;
29376 }
29377 } else {
29378 self.generate_expression(order)?;
29380 }
29381 }
29382 if let Some(null_handling) = &e.null_handling {
29383 self.write_space();
29384 self.generate_expression(null_handling)?;
29385 }
29386 if let Some(return_type) = &e.return_type {
29387 self.write_space();
29388 self.write_keyword("RETURNING");
29389 self.write_space();
29390 self.generate_expression(return_type)?;
29391 }
29392 if e.strict.is_some() {
29393 self.write_space();
29394 self.write_keyword("STRICT");
29395 }
29396 self.write(")");
29397 Ok(())
29398 }
29399
29400 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
29401 self.write_keyword("JSON_OBJECTAGG");
29403 self.write("(");
29404 for (i, expr) in e.expressions.iter().enumerate() {
29405 if i > 0 {
29406 self.write(", ");
29407 }
29408 self.generate_expression(expr)?;
29409 }
29410 if let Some(null_handling) = &e.null_handling {
29411 self.write_space();
29412 self.generate_expression(null_handling)?;
29413 }
29414 if let Some(unique_keys) = &e.unique_keys {
29415 self.write_space();
29416 if let Expression::Boolean(b) = unique_keys.as_ref() {
29417 if b.value {
29418 self.write_keyword("WITH UNIQUE KEYS");
29419 } else {
29420 self.write_keyword("WITHOUT UNIQUE KEYS");
29421 }
29422 }
29423 }
29424 if let Some(return_type) = &e.return_type {
29425 self.write_space();
29426 self.write_keyword("RETURNING");
29427 self.write_space();
29428 self.generate_expression(return_type)?;
29429 }
29430 self.write(")");
29431 Ok(())
29432 }
29433
29434 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
29435 self.write_keyword("JSON_ARRAY_APPEND");
29437 self.write("(");
29438 self.generate_expression(&e.this)?;
29439 for expr in &e.expressions {
29440 self.write(", ");
29441 self.generate_expression(expr)?;
29442 }
29443 self.write(")");
29444 Ok(())
29445 }
29446
29447 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
29448 self.write_keyword("JSON_ARRAY_CONTAINS");
29450 self.write("(");
29451 self.generate_expression(&e.this)?;
29452 self.write(", ");
29453 self.generate_expression(&e.expression)?;
29454 self.write(")");
29455 Ok(())
29456 }
29457
29458 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
29459 self.write_keyword("JSON_ARRAY_INSERT");
29461 self.write("(");
29462 self.generate_expression(&e.this)?;
29463 for expr in &e.expressions {
29464 self.write(", ");
29465 self.generate_expression(expr)?;
29466 }
29467 self.write(")");
29468 Ok(())
29469 }
29470
29471 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
29472 self.write_keyword("JSONB_EXISTS");
29474 self.write("(");
29475 self.generate_expression(&e.this)?;
29476 if let Some(path) = &e.path {
29477 self.write(", ");
29478 self.generate_expression(path)?;
29479 }
29480 self.write(")");
29481 Ok(())
29482 }
29483
29484 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
29485 self.write_keyword("JSONB_EXTRACT_SCALAR");
29487 self.write("(");
29488 self.generate_expression(&e.this)?;
29489 self.write(", ");
29490 self.generate_expression(&e.expression)?;
29491 self.write(")");
29492 Ok(())
29493 }
29494
29495 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
29496 self.write_keyword("JSONB_OBJECT_AGG");
29498 self.write("(");
29499 self.generate_expression(&e.this)?;
29500 self.write(", ");
29501 self.generate_expression(&e.expression)?;
29502 self.write(")");
29503 Ok(())
29504 }
29505
29506 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
29507 if let Some(nested_schema) = &e.nested_schema {
29509 self.write_keyword("NESTED");
29510 if let Some(path) = &e.path {
29511 self.write_space();
29512 self.write_keyword("PATH");
29513 self.write_space();
29514 self.generate_expression(path)?;
29515 }
29516 self.write_space();
29517 self.generate_expression(nested_schema)?;
29518 } else {
29519 if let Some(this) = &e.this {
29520 self.generate_expression(this)?;
29521 }
29522 if let Some(kind) = &e.kind {
29523 self.write_space();
29524 self.write(kind);
29525 }
29526 if let Some(path) = &e.path {
29527 self.write_space();
29528 self.write_keyword("PATH");
29529 self.write_space();
29530 self.generate_expression(path)?;
29531 }
29532 if e.ordinality.is_some() {
29533 self.write_keyword(" FOR ORDINALITY");
29534 }
29535 }
29536 Ok(())
29537 }
29538
29539 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
29540 self.write_keyword("JSON_EXISTS");
29542 self.write("(");
29543 self.generate_expression(&e.this)?;
29544 if let Some(path) = &e.path {
29545 self.write(", ");
29546 self.generate_expression(path)?;
29547 }
29548 if let Some(passing) = &e.passing {
29549 self.write_space();
29550 self.write_keyword("PASSING");
29551 self.write_space();
29552 self.generate_expression(passing)?;
29553 }
29554 if let Some(on_condition) = &e.on_condition {
29555 self.write_space();
29556 self.generate_expression(on_condition)?;
29557 }
29558 self.write(")");
29559 Ok(())
29560 }
29561
29562 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
29563 self.generate_expression(&e.this)?;
29564 self.write(".:");
29565 if Self::data_type_has_nested_expressions(&e.to) {
29569 let saved = std::mem::take(&mut self.output);
29571 self.generate_data_type(&e.to)?;
29572 let type_sql = std::mem::replace(&mut self.output, saved);
29573 self.write("\"");
29574 self.write(&type_sql);
29575 self.write("\"");
29576 } else {
29577 self.generate_data_type(&e.to)?;
29578 }
29579 Ok(())
29580 }
29581
29582 fn data_type_has_nested_expressions(dt: &DataType) -> bool {
29585 matches!(
29586 dt,
29587 DataType::Array { .. } | DataType::Map { .. } | DataType::Struct { .. }
29588 )
29589 }
29590
29591 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
29592 self.write_keyword("JSON_EXTRACT_ARRAY");
29594 self.write("(");
29595 self.generate_expression(&e.this)?;
29596 if let Some(expr) = &e.expression {
29597 self.write(", ");
29598 self.generate_expression(expr)?;
29599 }
29600 self.write(")");
29601 Ok(())
29602 }
29603
29604 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
29605 if let Some(option) = &e.option {
29607 self.generate_expression(option)?;
29608 self.write_space();
29609 }
29610 self.write_keyword("QUOTES");
29611 if e.scalar.is_some() {
29612 self.write_keyword(" SCALAR_ONLY");
29613 }
29614 Ok(())
29615 }
29616
29617 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
29618 self.write_keyword("JSON_EXTRACT_SCALAR");
29620 self.write("(");
29621 self.generate_expression(&e.this)?;
29622 self.write(", ");
29623 self.generate_expression(&e.expression)?;
29624 self.write(")");
29625 Ok(())
29626 }
29627
29628 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
29629 if e.variant_extract.is_some() {
29633 use crate::dialects::DialectType;
29634 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
29635 self.generate_expression(&e.this)?;
29639 self.write(":");
29640 match e.expression.as_ref() {
29641 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
29642 let Literal::String(s) = lit.as_ref() else {
29643 unreachable!()
29644 };
29645 self.write_databricks_json_path(s);
29646 }
29647 _ => {
29648 self.generate_expression(&e.expression)?;
29650 }
29651 }
29652 } else {
29653 self.write_keyword("GET_PATH");
29655 self.write("(");
29656 self.generate_expression(&e.this)?;
29657 self.write(", ");
29658 self.generate_expression(&e.expression)?;
29659 self.write(")");
29660 }
29661 } else {
29662 self.write_keyword("JSON_EXTRACT");
29663 self.write("(");
29664 self.generate_expression(&e.this)?;
29665 self.write(", ");
29666 self.generate_expression(&e.expression)?;
29667 for expr in &e.expressions {
29668 self.write(", ");
29669 self.generate_expression(expr)?;
29670 }
29671 self.write(")");
29672 }
29673 Ok(())
29674 }
29675
29676 fn write_databricks_json_path(&mut self, path: &str) {
29680 if path.starts_with("[\"") || path.starts_with("['") {
29683 self.write(path);
29684 return;
29685 }
29686 let mut first = true;
29690 for segment in path.split('.') {
29691 if !first {
29692 self.write(".");
29693 }
29694 first = false;
29695 if let Some(bracket_pos) = segment.find('[') {
29697 let key = &segment[..bracket_pos];
29698 let subscript = &segment[bracket_pos..];
29699 if key.is_empty() {
29700 self.write(segment);
29702 } else if Self::is_safe_json_path_key(key) {
29703 self.write(key);
29704 self.write(subscript);
29705 } else {
29706 self.write("[\"");
29707 self.write(key);
29708 self.write("\"]");
29709 self.write(subscript);
29710 }
29711 } else if Self::is_safe_json_path_key(segment) {
29712 self.write(segment);
29713 } else {
29714 self.write("[\"");
29715 self.write(segment);
29716 self.write("\"]");
29717 }
29718 }
29719 }
29720
29721 fn is_safe_json_path_key(key: &str) -> bool {
29724 if key.is_empty() {
29725 return false;
29726 }
29727 let mut chars = key.chars();
29728 let first = chars.next().unwrap();
29729 if first != '_' && !first.is_ascii_alphabetic() {
29730 return false;
29731 }
29732 chars.all(|c| c == '_' || c.is_ascii_alphanumeric())
29733 }
29734
29735 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
29736 if let Some(this) = &e.this {
29739 self.generate_expression(this)?;
29740 self.write_space();
29741 }
29742 self.write_keyword("FORMAT JSON");
29743 Ok(())
29744 }
29745
29746 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
29747 self.generate_expression(&e.this)?;
29749 self.write(": ");
29750 self.generate_expression(&e.expression)?;
29751 Ok(())
29752 }
29753
29754 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
29755 self.write_keyword("JSON_KEYS");
29757 self.write("(");
29758 self.generate_expression(&e.this)?;
29759 if let Some(expr) = &e.expression {
29760 self.write(", ");
29761 self.generate_expression(expr)?;
29762 }
29763 for expr in &e.expressions {
29764 self.write(", ");
29765 self.generate_expression(expr)?;
29766 }
29767 self.write(")");
29768 Ok(())
29769 }
29770
29771 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
29772 self.write_keyword("JSON_KEYS");
29774 self.write("(");
29775 self.generate_expression(&e.this)?;
29776 if let Some(expr) = &e.expression {
29777 self.write(", ");
29778 self.generate_expression(expr)?;
29779 }
29780 self.write(")");
29781 Ok(())
29782 }
29783
29784 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
29785 let mut path_str = String::new();
29788 for expr in &e.expressions {
29789 match expr {
29790 Expression::JSONPathRoot(_) => {
29791 path_str.push('$');
29792 }
29793 Expression::JSONPathKey(k) => {
29794 if let Expression::Literal(lit) = k.this.as_ref() {
29796 if let crate::expressions::Literal::String(s) = lit.as_ref() {
29797 path_str.push('.');
29798 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
29800 if needs_quoting {
29801 path_str.push('"');
29802 path_str.push_str(s);
29803 path_str.push('"');
29804 } else {
29805 path_str.push_str(s);
29806 }
29807 }
29808 }
29809 }
29810 Expression::JSONPathSubscript(s) => {
29811 if let Expression::Literal(lit) = s.this.as_ref() {
29813 if let crate::expressions::Literal::Number(n) = lit.as_ref() {
29814 path_str.push('[');
29815 path_str.push_str(n);
29816 path_str.push(']');
29817 }
29818 }
29819 }
29820 _ => {
29821 let mut temp_gen = Self::with_arc_config(self.config.clone());
29823 temp_gen.generate_expression(expr)?;
29824 path_str.push_str(&temp_gen.output);
29825 }
29826 }
29827 }
29828 self.write("'");
29830 self.write(&path_str);
29831 self.write("'");
29832 Ok(())
29833 }
29834
29835 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
29836 self.write("?(");
29838 self.generate_expression(&e.this)?;
29839 self.write(")");
29840 Ok(())
29841 }
29842
29843 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
29844 self.write(".");
29846 self.generate_expression(&e.this)?;
29847 Ok(())
29848 }
29849
29850 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
29851 self.write("..");
29853 if let Some(this) = &e.this {
29854 self.generate_expression(this)?;
29855 }
29856 Ok(())
29857 }
29858
29859 fn generate_json_path_root(&mut self) -> Result<()> {
29860 self.write("$");
29862 Ok(())
29863 }
29864
29865 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
29866 self.write("(");
29868 self.generate_expression(&e.this)?;
29869 self.write(")");
29870 Ok(())
29871 }
29872
29873 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
29874 self.generate_expression(&e.this)?;
29876 Ok(())
29877 }
29878
29879 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
29880 self.write("[");
29882 if let Some(start) = &e.start {
29883 self.generate_expression(start)?;
29884 }
29885 self.write(":");
29886 if let Some(end) = &e.end {
29887 self.generate_expression(end)?;
29888 }
29889 if let Some(step) = &e.step {
29890 self.write(":");
29891 self.generate_expression(step)?;
29892 }
29893 self.write("]");
29894 Ok(())
29895 }
29896
29897 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
29898 self.write("[");
29900 self.generate_expression(&e.this)?;
29901 self.write("]");
29902 Ok(())
29903 }
29904
29905 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
29906 self.write("[");
29908 for (i, expr) in e.expressions.iter().enumerate() {
29909 if i > 0 {
29910 self.write(", ");
29911 }
29912 self.generate_expression(expr)?;
29913 }
29914 self.write("]");
29915 Ok(())
29916 }
29917
29918 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
29919 self.write_keyword("JSON_REMOVE");
29921 self.write("(");
29922 self.generate_expression(&e.this)?;
29923 for expr in &e.expressions {
29924 self.write(", ");
29925 self.generate_expression(expr)?;
29926 }
29927 self.write(")");
29928 Ok(())
29929 }
29930
29931 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
29932 self.write_keyword("COLUMNS");
29935 self.write("(");
29936
29937 if self.config.pretty && !e.expressions.is_empty() {
29938 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
29940 for expr in &e.expressions {
29941 let mut temp_gen = Generator::with_arc_config(self.config.clone());
29942 temp_gen.generate_expression(expr)?;
29943 expr_strings.push(temp_gen.output);
29944 }
29945
29946 if self.too_wide(&expr_strings) {
29948 self.write_newline();
29950 self.indent_level += 1;
29951 for (i, expr_str) in expr_strings.iter().enumerate() {
29952 if i > 0 {
29953 self.write(",");
29954 self.write_newline();
29955 }
29956 self.write_indent();
29957 self.write(expr_str);
29958 }
29959 self.write_newline();
29960 self.indent_level -= 1;
29961 self.write_indent();
29962 } else {
29963 for (i, expr_str) in expr_strings.iter().enumerate() {
29965 if i > 0 {
29966 self.write(", ");
29967 }
29968 self.write(expr_str);
29969 }
29970 }
29971 } else {
29972 for (i, expr) in e.expressions.iter().enumerate() {
29974 if i > 0 {
29975 self.write(", ");
29976 }
29977 self.generate_expression(expr)?;
29978 }
29979 }
29980 self.write(")");
29981 Ok(())
29982 }
29983
29984 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
29985 self.write_keyword("JSON_SET");
29987 self.write("(");
29988 self.generate_expression(&e.this)?;
29989 for expr in &e.expressions {
29990 self.write(", ");
29991 self.generate_expression(expr)?;
29992 }
29993 self.write(")");
29994 Ok(())
29995 }
29996
29997 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
29998 self.write_keyword("JSON_STRIP_NULLS");
30000 self.write("(");
30001 self.generate_expression(&e.this)?;
30002 if let Some(expr) = &e.expression {
30003 self.write(", ");
30004 self.generate_expression(expr)?;
30005 }
30006 self.write(")");
30007 Ok(())
30008 }
30009
30010 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
30011 self.write_keyword("JSON_TABLE");
30013 self.write("(");
30014 self.generate_expression(&e.this)?;
30015 if let Some(path) = &e.path {
30016 self.write(", ");
30017 self.generate_expression(path)?;
30018 }
30019 if let Some(error_handling) = &e.error_handling {
30020 self.write_space();
30021 self.generate_expression(error_handling)?;
30022 }
30023 if let Some(empty_handling) = &e.empty_handling {
30024 self.write_space();
30025 self.generate_expression(empty_handling)?;
30026 }
30027 if let Some(schema) = &e.schema {
30028 self.write_space();
30029 self.generate_expression(schema)?;
30030 }
30031 self.write(")");
30032 Ok(())
30033 }
30034
30035 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
30036 self.write_keyword("JSON_TYPE");
30038 self.write("(");
30039 self.generate_expression(&e.this)?;
30040 self.write(")");
30041 Ok(())
30042 }
30043
30044 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
30045 self.write_keyword("JSON_VALUE");
30047 self.write("(");
30048 self.generate_expression(&e.this)?;
30049 if let Some(path) = &e.path {
30050 self.write(", ");
30051 self.generate_expression(path)?;
30052 }
30053 if let Some(returning) = &e.returning {
30054 self.write_space();
30055 self.write_keyword("RETURNING");
30056 self.write_space();
30057 self.generate_expression(returning)?;
30058 }
30059 if let Some(on_condition) = &e.on_condition {
30060 self.write_space();
30061 self.generate_expression(on_condition)?;
30062 }
30063 self.write(")");
30064 Ok(())
30065 }
30066
30067 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
30068 self.write_keyword("JSON_VALUE_ARRAY");
30070 self.write("(");
30071 self.generate_expression(&e.this)?;
30072 self.write(")");
30073 Ok(())
30074 }
30075
30076 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
30077 self.write_keyword("JAROWINKLER_SIMILARITY");
30079 self.write("(");
30080 self.generate_expression(&e.this)?;
30081 self.write(", ");
30082 self.generate_expression(&e.expression)?;
30083 self.write(")");
30084 Ok(())
30085 }
30086
30087 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
30088 self.generate_expression(&e.this)?;
30090 self.write("(");
30091 for (i, expr) in e.expressions.iter().enumerate() {
30092 if i > 0 {
30093 self.write(", ");
30094 }
30095 self.generate_expression(expr)?;
30096 }
30097 self.write(")");
30098 Ok(())
30099 }
30100
30101 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
30102 if e.no.is_some() {
30104 self.write_keyword("NO ");
30105 }
30106 if let Some(local) = &e.local {
30107 self.generate_expression(local)?;
30108 self.write_space();
30109 }
30110 if e.dual.is_some() {
30111 self.write_keyword("DUAL ");
30112 }
30113 if e.before.is_some() {
30114 self.write_keyword("BEFORE ");
30115 }
30116 if e.after.is_some() {
30117 self.write_keyword("AFTER ");
30118 }
30119 self.write_keyword("JOURNAL");
30120 Ok(())
30121 }
30122
30123 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
30124 self.write_keyword("LANGUAGE");
30126 self.write_space();
30127 self.generate_expression(&e.this)?;
30128 Ok(())
30129 }
30130
30131 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
30132 if e.view.is_some() {
30134 self.write_keyword("LATERAL VIEW");
30136 if e.outer.is_some() {
30137 self.write_space();
30138 self.write_keyword("OUTER");
30139 }
30140 self.write_space();
30141 self.generate_expression(&e.this)?;
30142 if let Some(alias) = &e.alias {
30143 self.write_space();
30144 self.write(alias);
30145 }
30146 } else {
30147 self.write_keyword("LATERAL");
30149 self.write_space();
30150 self.generate_expression(&e.this)?;
30151 if e.ordinality.is_some() {
30152 self.write_space();
30153 self.write_keyword("WITH ORDINALITY");
30154 }
30155 if let Some(alias) = &e.alias {
30156 self.write_space();
30157 self.write_keyword("AS");
30158 self.write_space();
30159 self.write(alias);
30160 if !e.column_aliases.is_empty() {
30161 self.write("(");
30162 for (i, col) in e.column_aliases.iter().enumerate() {
30163 if i > 0 {
30164 self.write(", ");
30165 }
30166 self.write(col);
30167 }
30168 self.write(")");
30169 }
30170 }
30171 }
30172 Ok(())
30173 }
30174
30175 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
30176 self.write_keyword("LIKE");
30178 self.write_space();
30179 self.generate_expression(&e.this)?;
30180 for expr in &e.expressions {
30181 self.write_space();
30182 self.generate_expression(expr)?;
30183 }
30184 Ok(())
30185 }
30186
30187 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
30188 self.write_keyword("LIMIT");
30189 self.write_space();
30190 self.write_limit_expr(&e.this)?;
30191 if e.percent {
30192 self.write_space();
30193 self.write_keyword("PERCENT");
30194 }
30195 for comment in &e.comments {
30197 self.write(" ");
30198 self.write_formatted_comment(comment);
30199 }
30200 Ok(())
30201 }
30202
30203 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
30204 if e.percent.is_some() {
30206 self.write_keyword(" PERCENT");
30207 }
30208 if e.rows.is_some() {
30209 self.write_keyword(" ROWS");
30210 }
30211 if e.with_ties.is_some() {
30212 self.write_keyword(" WITH TIES");
30213 } else if e.rows.is_some() {
30214 self.write_keyword(" ONLY");
30215 }
30216 Ok(())
30217 }
30218
30219 fn generate_list(&mut self, e: &List) -> Result<()> {
30220 use crate::dialects::DialectType;
30221 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
30222
30223 if e.expressions.len() == 1 {
30225 if let Expression::Select(_) = &e.expressions[0] {
30226 self.write_keyword("LIST");
30227 self.write("(");
30228 self.generate_expression(&e.expressions[0])?;
30229 self.write(")");
30230 return Ok(());
30231 }
30232 }
30233
30234 if is_materialize {
30236 self.write_keyword("LIST");
30237 self.write("[");
30238 for (i, expr) in e.expressions.iter().enumerate() {
30239 if i > 0 {
30240 self.write(", ");
30241 }
30242 self.generate_expression(expr)?;
30243 }
30244 self.write("]");
30245 } else {
30246 self.write_keyword("LIST");
30248 self.write("(");
30249 for (i, expr) in e.expressions.iter().enumerate() {
30250 if i > 0 {
30251 self.write(", ");
30252 }
30253 self.generate_expression(expr)?;
30254 }
30255 self.write(")");
30256 }
30257 Ok(())
30258 }
30259
30260 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
30261 if let Expression::Select(_) = &*e.this {
30263 self.write_keyword("MAP");
30264 self.write("(");
30265 self.generate_expression(&e.this)?;
30266 self.write(")");
30267 return Ok(());
30268 }
30269
30270 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
30271
30272 self.write_keyword("MAP");
30274 if is_duckdb {
30275 self.write(" {");
30276 } else {
30277 self.write("[");
30278 }
30279 if let Expression::Struct(s) = &*e.this {
30280 for (i, (_, expr)) in s.fields.iter().enumerate() {
30281 if i > 0 {
30282 self.write(", ");
30283 }
30284 if let Expression::PropertyEQ(op) = expr {
30285 self.generate_expression(&op.left)?;
30286 if is_duckdb {
30287 self.write(": ");
30288 } else {
30289 self.write(" => ");
30290 }
30291 self.generate_expression(&op.right)?;
30292 } else {
30293 self.generate_expression(expr)?;
30294 }
30295 }
30296 }
30297 if is_duckdb {
30298 self.write("}");
30299 } else {
30300 self.write("]");
30301 }
30302 Ok(())
30303 }
30304
30305 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
30306 self.write_keyword("LOCALTIME");
30308 if let Some(precision) = &e.this {
30309 self.write("(");
30310 self.generate_expression(precision)?;
30311 self.write(")");
30312 }
30313 Ok(())
30314 }
30315
30316 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
30317 self.write_keyword("LOCALTIMESTAMP");
30319 if let Some(precision) = &e.this {
30320 self.write("(");
30321 self.generate_expression(precision)?;
30322 self.write(")");
30323 }
30324 Ok(())
30325 }
30326
30327 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
30328 self.write_keyword("LOCATION");
30330 self.write_space();
30331 self.generate_expression(&e.this)?;
30332 Ok(())
30333 }
30334
30335 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
30336 if e.update.is_some() {
30338 if e.key.is_some() {
30339 self.write_keyword("FOR NO KEY UPDATE");
30340 } else {
30341 self.write_keyword("FOR UPDATE");
30342 }
30343 } else {
30344 if e.key.is_some() {
30345 self.write_keyword("FOR KEY SHARE");
30346 } else {
30347 self.write_keyword("FOR SHARE");
30348 }
30349 }
30350 if !e.expressions.is_empty() {
30351 self.write_keyword(" OF ");
30352 for (i, expr) in e.expressions.iter().enumerate() {
30353 if i > 0 {
30354 self.write(", ");
30355 }
30356 self.generate_expression(expr)?;
30357 }
30358 }
30359 if let Some(wait) = &e.wait {
30364 match wait.as_ref() {
30365 Expression::Boolean(b) => {
30366 if b.value {
30367 self.write_keyword(" NOWAIT");
30368 } else {
30369 self.write_keyword(" SKIP LOCKED");
30370 }
30371 }
30372 _ => {
30373 self.write_keyword(" WAIT ");
30375 self.generate_expression(wait)?;
30376 }
30377 }
30378 }
30379 Ok(())
30380 }
30381
30382 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
30383 self.write_keyword("LOCK");
30385 self.write_space();
30386 self.generate_expression(&e.this)?;
30387 Ok(())
30388 }
30389
30390 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
30391 self.write_keyword("LOCKING");
30393 self.write_space();
30394 self.write(&e.kind);
30395 if let Some(this) = &e.this {
30396 self.write_space();
30397 self.generate_expression(this)?;
30398 }
30399 if let Some(for_or_in) = &e.for_or_in {
30400 self.write_space();
30401 self.generate_expression(for_or_in)?;
30402 }
30403 if let Some(lock_type) = &e.lock_type {
30404 self.write_space();
30405 self.generate_expression(lock_type)?;
30406 }
30407 if e.override_.is_some() {
30408 self.write_keyword(" OVERRIDE");
30409 }
30410 Ok(())
30411 }
30412
30413 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
30414 self.generate_expression(&e.this)?;
30416 self.write_space();
30417 self.generate_expression(&e.expression)?;
30418 Ok(())
30419 }
30420
30421 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
30422 if e.no.is_some() {
30424 self.write_keyword("NO ");
30425 }
30426 self.write_keyword("LOG");
30427 Ok(())
30428 }
30429
30430 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
30431 self.write_keyword("MD5");
30433 self.write("(");
30434 self.generate_expression(&e.this)?;
30435 for expr in &e.expressions {
30436 self.write(", ");
30437 self.generate_expression(expr)?;
30438 }
30439 self.write(")");
30440 Ok(())
30441 }
30442
30443 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
30444 self.write_keyword("ML.FORECAST");
30446 self.write("(");
30447 self.generate_expression(&e.this)?;
30448 if let Some(expression) = &e.expression {
30449 self.write(", ");
30450 self.generate_expression(expression)?;
30451 }
30452 if let Some(params) = &e.params_struct {
30453 self.write(", ");
30454 self.generate_expression(params)?;
30455 }
30456 self.write(")");
30457 Ok(())
30458 }
30459
30460 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
30461 self.write_keyword("ML.TRANSLATE");
30463 self.write("(");
30464 self.generate_expression(&e.this)?;
30465 self.write(", ");
30466 self.generate_expression(&e.expression)?;
30467 if let Some(params) = &e.params_struct {
30468 self.write(", ");
30469 self.generate_expression(params)?;
30470 }
30471 self.write(")");
30472 Ok(())
30473 }
30474
30475 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
30476 self.write_keyword("MAKE_INTERVAL");
30478 self.write("(");
30479 let mut first = true;
30480 if let Some(year) = &e.year {
30481 self.write("years => ");
30482 self.generate_expression(year)?;
30483 first = false;
30484 }
30485 if let Some(month) = &e.month {
30486 if !first {
30487 self.write(", ");
30488 }
30489 self.write("months => ");
30490 self.generate_expression(month)?;
30491 first = false;
30492 }
30493 if let Some(week) = &e.week {
30494 if !first {
30495 self.write(", ");
30496 }
30497 self.write("weeks => ");
30498 self.generate_expression(week)?;
30499 first = false;
30500 }
30501 if let Some(day) = &e.day {
30502 if !first {
30503 self.write(", ");
30504 }
30505 self.write("days => ");
30506 self.generate_expression(day)?;
30507 first = false;
30508 }
30509 if let Some(hour) = &e.hour {
30510 if !first {
30511 self.write(", ");
30512 }
30513 self.write("hours => ");
30514 self.generate_expression(hour)?;
30515 first = false;
30516 }
30517 if let Some(minute) = &e.minute {
30518 if !first {
30519 self.write(", ");
30520 }
30521 self.write("mins => ");
30522 self.generate_expression(minute)?;
30523 first = false;
30524 }
30525 if let Some(second) = &e.second {
30526 if !first {
30527 self.write(", ");
30528 }
30529 self.write("secs => ");
30530 self.generate_expression(second)?;
30531 }
30532 self.write(")");
30533 Ok(())
30534 }
30535
30536 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
30537 self.write_keyword("MANHATTAN_DISTANCE");
30539 self.write("(");
30540 self.generate_expression(&e.this)?;
30541 self.write(", ");
30542 self.generate_expression(&e.expression)?;
30543 self.write(")");
30544 Ok(())
30545 }
30546
30547 fn generate_map(&mut self, e: &Map) -> Result<()> {
30548 self.write_keyword("MAP");
30550 self.write("(");
30551 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
30552 if i > 0 {
30553 self.write(", ");
30554 }
30555 self.generate_expression(key)?;
30556 self.write(", ");
30557 self.generate_expression(value)?;
30558 }
30559 self.write(")");
30560 Ok(())
30561 }
30562
30563 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
30564 self.write_keyword("MAP_CAT");
30566 self.write("(");
30567 self.generate_expression(&e.this)?;
30568 self.write(", ");
30569 self.generate_expression(&e.expression)?;
30570 self.write(")");
30571 Ok(())
30572 }
30573
30574 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
30575 self.write_keyword("MAP_DELETE");
30577 self.write("(");
30578 self.generate_expression(&e.this)?;
30579 for expr in &e.expressions {
30580 self.write(", ");
30581 self.generate_expression(expr)?;
30582 }
30583 self.write(")");
30584 Ok(())
30585 }
30586
30587 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
30588 self.write_keyword("MAP_INSERT");
30590 self.write("(");
30591 self.generate_expression(&e.this)?;
30592 if let Some(key) = &e.key {
30593 self.write(", ");
30594 self.generate_expression(key)?;
30595 }
30596 if let Some(value) = &e.value {
30597 self.write(", ");
30598 self.generate_expression(value)?;
30599 }
30600 if let Some(update_flag) = &e.update_flag {
30601 self.write(", ");
30602 self.generate_expression(update_flag)?;
30603 }
30604 self.write(")");
30605 Ok(())
30606 }
30607
30608 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
30609 self.write_keyword("MAP_PICK");
30611 self.write("(");
30612 self.generate_expression(&e.this)?;
30613 for expr in &e.expressions {
30614 self.write(", ");
30615 self.generate_expression(expr)?;
30616 }
30617 self.write(")");
30618 Ok(())
30619 }
30620
30621 fn generate_masking_policy_column_constraint(
30622 &mut self,
30623 e: &MaskingPolicyColumnConstraint,
30624 ) -> Result<()> {
30625 self.write_keyword("MASKING POLICY");
30627 self.write_space();
30628 self.generate_expression(&e.this)?;
30629 if !e.expressions.is_empty() {
30630 self.write_keyword(" USING");
30631 self.write(" (");
30632 for (i, expr) in e.expressions.iter().enumerate() {
30633 if i > 0 {
30634 self.write(", ");
30635 }
30636 self.generate_expression(expr)?;
30637 }
30638 self.write(")");
30639 }
30640 Ok(())
30641 }
30642
30643 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
30644 if matches!(
30645 self.config.dialect,
30646 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
30647 ) {
30648 if e.expressions.len() > 1 {
30649 self.write("(");
30650 }
30651 for (i, expr) in e.expressions.iter().enumerate() {
30652 if i > 0 {
30653 self.write_keyword(" OR ");
30654 }
30655 self.generate_expression(expr)?;
30656 self.write_space();
30657 self.write("@@");
30658 self.write_space();
30659 self.generate_expression(&e.this)?;
30660 }
30661 if e.expressions.len() > 1 {
30662 self.write(")");
30663 }
30664 return Ok(());
30665 }
30666
30667 self.write_keyword("MATCH");
30669 self.write("(");
30670 for (i, expr) in e.expressions.iter().enumerate() {
30671 if i > 0 {
30672 self.write(", ");
30673 }
30674 self.generate_expression(expr)?;
30675 }
30676 self.write(")");
30677 self.write_keyword(" AGAINST");
30678 self.write("(");
30679 self.generate_expression(&e.this)?;
30680 if let Some(modifier) = &e.modifier {
30681 self.write_space();
30682 self.generate_expression(modifier)?;
30683 }
30684 self.write(")");
30685 Ok(())
30686 }
30687
30688 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
30689 if let Some(window_frame) = &e.window_frame {
30691 self.write(&format!("{:?}", window_frame).to_ascii_uppercase());
30692 self.write_space();
30693 }
30694 self.generate_expression(&e.this)?;
30695 Ok(())
30696 }
30697
30698 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
30699 self.write_keyword("MATERIALIZED");
30701 if let Some(this) = &e.this {
30702 self.write_space();
30703 self.generate_expression(this)?;
30704 }
30705 Ok(())
30706 }
30707
30708 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
30709 if let Some(with_) = &e.with_ {
30712 self.generate_expression(with_)?;
30713 self.write_space();
30714 }
30715 self.write_keyword("MERGE INTO");
30716 self.write_space();
30717 self.generate_expression(&e.this)?;
30718
30719 if self.config.pretty {
30721 self.write_newline();
30722 self.write_indent();
30723 } else {
30724 self.write_space();
30725 }
30726 self.write_keyword("USING");
30727 self.write_space();
30728 self.generate_expression(&e.using)?;
30729
30730 if let Some(on) = &e.on {
30732 if self.config.pretty {
30733 self.write_newline();
30734 self.write_indent();
30735 } else {
30736 self.write_space();
30737 }
30738 self.write_keyword("ON");
30739 self.write_space();
30740 self.generate_expression(on)?;
30741 }
30742 if let Some(using_cond) = &e.using_cond {
30744 self.write_space();
30745 self.write_keyword("USING");
30746 self.write_space();
30747 self.write("(");
30748 if let Expression::Tuple(tuple) = using_cond.as_ref() {
30750 for (i, col) in tuple.expressions.iter().enumerate() {
30751 if i > 0 {
30752 self.write(", ");
30753 }
30754 self.generate_expression(col)?;
30755 }
30756 } else {
30757 self.generate_expression(using_cond)?;
30758 }
30759 self.write(")");
30760 }
30761 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
30763 if matches!(
30764 self.config.dialect,
30765 Some(crate::DialectType::PostgreSQL)
30766 | Some(crate::DialectType::Redshift)
30767 | Some(crate::DialectType::Trino)
30768 | Some(crate::DialectType::Presto)
30769 | Some(crate::DialectType::Athena)
30770 ) {
30771 let mut names = Vec::new();
30772 match e.this.as_ref() {
30773 Expression::Alias(a) => {
30774 if let Expression::Table(t) = &a.this {
30776 names.push(t.name.name.clone());
30777 } else if let Expression::Identifier(id) = &a.this {
30778 names.push(id.name.clone());
30779 }
30780 names.push(a.alias.name.clone());
30781 }
30782 Expression::Table(t) => {
30783 names.push(t.name.name.clone());
30784 }
30785 Expression::Identifier(id) => {
30786 names.push(id.name.clone());
30787 }
30788 _ => {}
30789 }
30790 self.merge_strip_qualifiers = names;
30791 }
30792
30793 if let Some(whens) = &e.whens {
30795 if self.config.pretty {
30796 self.write_newline();
30797 self.write_indent();
30798 } else {
30799 self.write_space();
30800 }
30801 self.generate_expression(whens)?;
30802 }
30803
30804 self.merge_strip_qualifiers = saved_merge_strip;
30806
30807 if let Some(returning) = &e.returning {
30809 if self.config.pretty {
30810 self.write_newline();
30811 self.write_indent();
30812 } else {
30813 self.write_space();
30814 }
30815 self.generate_expression(returning)?;
30816 }
30817 Ok(())
30818 }
30819
30820 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
30821 if e.no.is_some() {
30823 self.write_keyword("NO MERGEBLOCKRATIO");
30824 } else if e.default.is_some() {
30825 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
30826 } else {
30827 self.write_keyword("MERGEBLOCKRATIO");
30828 self.write("=");
30829 if let Some(this) = &e.this {
30830 self.generate_expression(this)?;
30831 }
30832 if e.percent.is_some() {
30833 self.write_keyword(" PERCENT");
30834 }
30835 }
30836 Ok(())
30837 }
30838
30839 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
30840 self.write_keyword("TTL");
30842 let pretty_clickhouse = self.config.pretty
30843 && matches!(
30844 self.config.dialect,
30845 Some(crate::dialects::DialectType::ClickHouse)
30846 );
30847
30848 if pretty_clickhouse {
30849 self.write_newline();
30850 self.indent_level += 1;
30851 for (i, expr) in e.expressions.iter().enumerate() {
30852 if i > 0 {
30853 self.write(",");
30854 self.write_newline();
30855 }
30856 self.write_indent();
30857 self.generate_expression(expr)?;
30858 }
30859 self.indent_level -= 1;
30860 } else {
30861 self.write_space();
30862 for (i, expr) in e.expressions.iter().enumerate() {
30863 if i > 0 {
30864 self.write(", ");
30865 }
30866 self.generate_expression(expr)?;
30867 }
30868 }
30869
30870 if let Some(where_) = &e.where_ {
30871 if pretty_clickhouse {
30872 self.write_newline();
30873 if let Expression::Where(w) = where_.as_ref() {
30874 self.write_indent();
30875 self.write_keyword("WHERE");
30876 self.write_newline();
30877 self.indent_level += 1;
30878 self.write_indent();
30879 self.generate_expression(&w.this)?;
30880 self.indent_level -= 1;
30881 } else {
30882 self.write_indent();
30883 self.generate_expression(where_)?;
30884 }
30885 } else {
30886 self.write_space();
30887 self.generate_expression(where_)?;
30888 }
30889 }
30890 if let Some(group) = &e.group {
30891 if pretty_clickhouse {
30892 self.write_newline();
30893 if let Expression::Group(g) = group.as_ref() {
30894 self.write_indent();
30895 self.write_keyword("GROUP BY");
30896 self.write_newline();
30897 self.indent_level += 1;
30898 for (i, expr) in g.expressions.iter().enumerate() {
30899 if i > 0 {
30900 self.write(",");
30901 self.write_newline();
30902 }
30903 self.write_indent();
30904 self.generate_expression(expr)?;
30905 }
30906 self.indent_level -= 1;
30907 } else {
30908 self.write_indent();
30909 self.generate_expression(group)?;
30910 }
30911 } else {
30912 self.write_space();
30913 self.generate_expression(group)?;
30914 }
30915 }
30916 if let Some(aggregates) = &e.aggregates {
30917 if pretty_clickhouse {
30918 self.write_newline();
30919 self.write_indent();
30920 self.write_keyword("SET");
30921 self.write_newline();
30922 self.indent_level += 1;
30923 if let Expression::Tuple(t) = aggregates.as_ref() {
30924 for (i, agg) in t.expressions.iter().enumerate() {
30925 if i > 0 {
30926 self.write(",");
30927 self.write_newline();
30928 }
30929 self.write_indent();
30930 self.generate_expression(agg)?;
30931 }
30932 } else {
30933 self.write_indent();
30934 self.generate_expression(aggregates)?;
30935 }
30936 self.indent_level -= 1;
30937 } else {
30938 self.write_space();
30939 self.write_keyword("SET");
30940 self.write_space();
30941 self.generate_expression(aggregates)?;
30942 }
30943 }
30944 Ok(())
30945 }
30946
30947 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
30948 self.generate_expression(&e.this)?;
30950 if e.delete.is_some() {
30951 self.write_keyword(" DELETE");
30952 }
30953 if let Some(recompress) = &e.recompress {
30954 self.write_keyword(" RECOMPRESS ");
30955 self.generate_expression(recompress)?;
30956 }
30957 if let Some(to_disk) = &e.to_disk {
30958 self.write_keyword(" TO DISK ");
30959 self.generate_expression(to_disk)?;
30960 }
30961 if let Some(to_volume) = &e.to_volume {
30962 self.write_keyword(" TO VOLUME ");
30963 self.generate_expression(to_volume)?;
30964 }
30965 Ok(())
30966 }
30967
30968 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
30969 self.write_keyword("MINHASH");
30971 self.write("(");
30972 self.generate_expression(&e.this)?;
30973 for expr in &e.expressions {
30974 self.write(", ");
30975 self.generate_expression(expr)?;
30976 }
30977 self.write(")");
30978 Ok(())
30979 }
30980
30981 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
30982 self.generate_expression(&e.this)?;
30984 self.write("!");
30985 self.generate_expression(&e.expression)?;
30986 Ok(())
30987 }
30988
30989 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
30990 self.write_keyword("MONTHNAME");
30992 self.write("(");
30993 self.generate_expression(&e.this)?;
30994 self.write(")");
30995 Ok(())
30996 }
30997
30998 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
30999 for comment in &e.leading_comments {
31001 self.write_formatted_comment(comment);
31002 if self.config.pretty {
31003 self.write_newline();
31004 self.write_indent();
31005 } else {
31006 self.write_space();
31007 }
31008 }
31009 self.write_keyword("INSERT");
31011 self.write_space();
31012 self.write(&e.kind);
31013 if self.config.pretty {
31014 self.indent_level += 1;
31015 for expr in &e.expressions {
31016 self.write_newline();
31017 self.write_indent();
31018 self.generate_expression(expr)?;
31019 }
31020 self.indent_level -= 1;
31021 } else {
31022 for expr in &e.expressions {
31023 self.write_space();
31024 self.generate_expression(expr)?;
31025 }
31026 }
31027 if let Some(source) = &e.source {
31028 if self.config.pretty {
31029 self.write_newline();
31030 self.write_indent();
31031 } else {
31032 self.write_space();
31033 }
31034 self.generate_expression(source)?;
31035 }
31036 Ok(())
31037 }
31038
31039 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
31040 self.write_keyword("NEXT VALUE FOR");
31042 self.write_space();
31043 self.generate_expression(&e.this)?;
31044 if let Some(order) = &e.order {
31045 self.write_space();
31046 self.write_keyword("OVER");
31047 self.write(" (");
31048 self.generate_expression(order)?;
31049 self.write(")");
31050 }
31051 Ok(())
31052 }
31053
31054 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
31055 self.write_keyword("NORMAL");
31057 self.write("(");
31058 self.generate_expression(&e.this)?;
31059 if let Some(stddev) = &e.stddev {
31060 self.write(", ");
31061 self.generate_expression(stddev)?;
31062 }
31063 if let Some(gen) = &e.gen {
31064 self.write(", ");
31065 self.generate_expression(gen)?;
31066 }
31067 self.write(")");
31068 Ok(())
31069 }
31070
31071 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
31072 if e.is_casefold.is_some() {
31074 self.write_keyword("NORMALIZE_AND_CASEFOLD");
31075 } else {
31076 self.write_keyword("NORMALIZE");
31077 }
31078 self.write("(");
31079 self.generate_expression(&e.this)?;
31080 if let Some(form) = &e.form {
31081 self.write(", ");
31082 self.generate_expression(form)?;
31083 }
31084 self.write(")");
31085 Ok(())
31086 }
31087
31088 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
31089 if e.allow_null.is_none() {
31091 self.write_keyword("NOT ");
31092 }
31093 self.write_keyword("NULL");
31094 Ok(())
31095 }
31096
31097 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
31098 self.write_keyword("NULLIF");
31100 self.write("(");
31101 self.generate_expression(&e.this)?;
31102 self.write(", ");
31103 self.generate_expression(&e.expression)?;
31104 self.write(")");
31105 Ok(())
31106 }
31107
31108 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
31109 self.write_keyword("FORMAT");
31111 self.write("(");
31112 self.generate_expression(&e.this)?;
31113 self.write(", '");
31114 self.write(&e.format);
31115 self.write("'");
31116 if let Some(culture) = &e.culture {
31117 self.write(", ");
31118 self.generate_expression(culture)?;
31119 }
31120 self.write(")");
31121 Ok(())
31122 }
31123
31124 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
31125 self.write_keyword("OBJECT_AGG");
31127 self.write("(");
31128 self.generate_expression(&e.this)?;
31129 self.write(", ");
31130 self.generate_expression(&e.expression)?;
31131 self.write(")");
31132 Ok(())
31133 }
31134
31135 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
31136 self.generate_expression(&e.this)?;
31138 Ok(())
31139 }
31140
31141 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
31142 self.write_keyword("OBJECT_INSERT");
31144 self.write("(");
31145 self.generate_expression(&e.this)?;
31146 if let Some(key) = &e.key {
31147 self.write(", ");
31148 self.generate_expression(key)?;
31149 }
31150 if let Some(value) = &e.value {
31151 self.write(", ");
31152 self.generate_expression(value)?;
31153 }
31154 if let Some(update_flag) = &e.update_flag {
31155 self.write(", ");
31156 self.generate_expression(update_flag)?;
31157 }
31158 self.write(")");
31159 Ok(())
31160 }
31161
31162 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
31163 self.write_keyword("OFFSET");
31165 self.write_space();
31166 self.generate_expression(&e.this)?;
31167 if e.rows == Some(true)
31169 && matches!(
31170 self.config.dialect,
31171 Some(crate::dialects::DialectType::TSQL)
31172 | Some(crate::dialects::DialectType::Oracle)
31173 )
31174 {
31175 self.write_space();
31176 self.write_keyword("ROWS");
31177 }
31178 Ok(())
31179 }
31180
31181 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
31182 self.write_keyword("QUALIFY");
31184 self.write_space();
31185 self.generate_expression(&e.this)?;
31186 Ok(())
31187 }
31188
31189 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
31190 self.write_keyword("ON CLUSTER");
31192 self.write_space();
31193 self.generate_expression(&e.this)?;
31194 Ok(())
31195 }
31196
31197 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
31198 self.write_keyword("ON COMMIT");
31200 if e.delete.is_some() {
31201 self.write_keyword(" DELETE ROWS");
31202 } else {
31203 self.write_keyword(" PRESERVE ROWS");
31204 }
31205 Ok(())
31206 }
31207
31208 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
31209 if let Some(empty) = &e.empty {
31211 self.generate_expression(empty)?;
31212 self.write_keyword(" ON EMPTY");
31213 }
31214 if let Some(error) = &e.error {
31215 if e.empty.is_some() {
31216 self.write_space();
31217 }
31218 self.generate_expression(error)?;
31219 self.write_keyword(" ON ERROR");
31220 }
31221 if let Some(null) = &e.null {
31222 if e.empty.is_some() || e.error.is_some() {
31223 self.write_space();
31224 }
31225 self.generate_expression(null)?;
31226 self.write_keyword(" ON NULL");
31227 }
31228 Ok(())
31229 }
31230
31231 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
31232 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
31234 return Ok(());
31235 }
31236 if e.duplicate.is_some() {
31238 self.write_keyword("ON DUPLICATE KEY UPDATE");
31240 for (i, expr) in e.expressions.iter().enumerate() {
31241 if i > 0 {
31242 self.write(",");
31243 }
31244 self.write_space();
31245 self.generate_expression(expr)?;
31246 }
31247 return Ok(());
31248 } else {
31249 self.write_keyword("ON CONFLICT");
31250 }
31251 if let Some(constraint) = &e.constraint {
31252 self.write_keyword(" ON CONSTRAINT ");
31253 self.generate_expression(constraint)?;
31254 }
31255 if let Some(conflict_keys) = &e.conflict_keys {
31256 if let Expression::Tuple(t) = conflict_keys.as_ref() {
31258 self.write("(");
31259 for (i, expr) in t.expressions.iter().enumerate() {
31260 if i > 0 {
31261 self.write(", ");
31262 }
31263 self.generate_expression(expr)?;
31264 }
31265 self.write(")");
31266 } else {
31267 self.write("(");
31268 self.generate_expression(conflict_keys)?;
31269 self.write(")");
31270 }
31271 }
31272 if let Some(index_predicate) = &e.index_predicate {
31273 self.write_keyword(" WHERE ");
31274 self.generate_expression(index_predicate)?;
31275 }
31276 if let Some(action) = &e.action {
31277 if let Expression::Identifier(id) = action.as_ref() {
31279 if id.name.eq_ignore_ascii_case("NOTHING") {
31280 self.write_keyword(" DO NOTHING");
31281 } else {
31282 self.write_keyword(" DO ");
31283 self.generate_expression(action)?;
31284 }
31285 } else if let Expression::Tuple(t) = action.as_ref() {
31286 self.write_keyword(" DO UPDATE SET ");
31288 for (i, expr) in t.expressions.iter().enumerate() {
31289 if i > 0 {
31290 self.write(", ");
31291 }
31292 self.generate_expression(expr)?;
31293 }
31294 } else {
31295 self.write_keyword(" DO ");
31296 self.generate_expression(action)?;
31297 }
31298 }
31299 if let Some(where_) = &e.where_ {
31301 self.write_keyword(" WHERE ");
31302 self.generate_expression(where_)?;
31303 }
31304 Ok(())
31305 }
31306
31307 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
31308 self.write_keyword("ON");
31310 self.write_space();
31311 self.generate_expression(&e.this)?;
31312 Ok(())
31313 }
31314
31315 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
31316 self.generate_expression(&e.this)?;
31318 self.write_space();
31319 self.generate_expression(&e.expression)?;
31320 Ok(())
31321 }
31322
31323 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
31324 self.write_keyword("OPENJSON");
31326 self.write("(");
31327 self.generate_expression(&e.this)?;
31328 if let Some(path) = &e.path {
31329 self.write(", ");
31330 self.generate_expression(path)?;
31331 }
31332 self.write(")");
31333 if !e.expressions.is_empty() {
31334 self.write_keyword(" WITH");
31335 if self.config.pretty {
31336 self.write(" (\n");
31337 self.indent_level += 2;
31338 for (i, expr) in e.expressions.iter().enumerate() {
31339 if i > 0 {
31340 self.write(",\n");
31341 }
31342 self.write_indent();
31343 self.generate_expression(expr)?;
31344 }
31345 self.write("\n");
31346 self.indent_level -= 2;
31347 self.write(")");
31348 } else {
31349 self.write(" (");
31350 for (i, expr) in e.expressions.iter().enumerate() {
31351 if i > 0 {
31352 self.write(", ");
31353 }
31354 self.generate_expression(expr)?;
31355 }
31356 self.write(")");
31357 }
31358 }
31359 Ok(())
31360 }
31361
31362 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
31363 self.generate_expression(&e.this)?;
31365 self.write_space();
31366 if let Some(ref dt) = e.data_type {
31368 self.generate_data_type(dt)?;
31369 } else if !e.kind.is_empty() {
31370 self.write(&e.kind);
31371 }
31372 if let Some(path) = &e.path {
31373 self.write_space();
31374 self.generate_expression(path)?;
31375 }
31376 if e.as_json.is_some() {
31377 self.write_keyword(" AS JSON");
31378 }
31379 Ok(())
31380 }
31381
31382 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
31383 self.generate_expression(&e.this)?;
31385 self.write_space();
31386 if let Some(op) = &e.operator {
31387 self.write_keyword("OPERATOR");
31388 self.write("(");
31389 self.generate_expression(op)?;
31390 self.write(")");
31391 }
31392 for comment in &e.comments {
31394 self.write_space();
31395 self.write_formatted_comment(comment);
31396 }
31397 self.write_space();
31398 self.generate_expression(&e.expression)?;
31399 Ok(())
31400 }
31401
31402 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
31403 self.write_keyword("ORDER BY");
31405 let pretty_clickhouse_single_paren = self.config.pretty
31406 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
31407 && e.expressions.len() == 1
31408 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
31409 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
31410 && e.expressions.len() == 1
31411 && matches!(e.expressions[0].this, Expression::Tuple(_))
31412 && !e.expressions[0].desc
31413 && e.expressions[0].nulls_first.is_none();
31414
31415 if pretty_clickhouse_single_paren {
31416 self.write_space();
31417 if let Expression::Paren(p) = &e.expressions[0].this {
31418 self.write("(");
31419 self.write_newline();
31420 self.indent_level += 1;
31421 self.write_indent();
31422 self.generate_expression(&p.this)?;
31423 self.indent_level -= 1;
31424 self.write_newline();
31425 self.write(")");
31426 }
31427 return Ok(());
31428 }
31429
31430 if clickhouse_single_tuple {
31431 self.write_space();
31432 if let Expression::Tuple(t) = &e.expressions[0].this {
31433 self.write("(");
31434 for (i, expr) in t.expressions.iter().enumerate() {
31435 if i > 0 {
31436 self.write(", ");
31437 }
31438 self.generate_expression(expr)?;
31439 }
31440 self.write(")");
31441 }
31442 return Ok(());
31443 }
31444
31445 self.write_space();
31446 for (i, ordered) in e.expressions.iter().enumerate() {
31447 if i > 0 {
31448 self.write(", ");
31449 }
31450 self.generate_expression(&ordered.this)?;
31451 if ordered.desc {
31452 self.write_space();
31453 self.write_keyword("DESC");
31454 } else if ordered.explicit_asc {
31455 self.write_space();
31456 self.write_keyword("ASC");
31457 }
31458 if let Some(nulls_first) = ordered.nulls_first {
31459 let skip_nulls_last =
31461 !nulls_first && matches!(self.config.dialect, Some(DialectType::Dremio));
31462 if !skip_nulls_last {
31463 self.write_space();
31464 self.write_keyword("NULLS");
31465 self.write_space();
31466 if nulls_first {
31467 self.write_keyword("FIRST");
31468 } else {
31469 self.write_keyword("LAST");
31470 }
31471 }
31472 }
31473 }
31474 Ok(())
31475 }
31476
31477 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
31478 self.write_keyword("OUTPUT");
31480 self.write("(");
31481 if self.config.pretty {
31482 self.indent_level += 1;
31483 self.write_newline();
31484 self.write_indent();
31485 self.generate_expression(&e.this)?;
31486 self.indent_level -= 1;
31487 self.write_newline();
31488 } else {
31489 self.generate_expression(&e.this)?;
31490 }
31491 self.write(")");
31492 Ok(())
31493 }
31494
31495 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
31496 self.write_keyword("TRUNCATE");
31498 if let Some(this) = &e.this {
31499 self.write_space();
31500 self.generate_expression(this)?;
31501 }
31502 if e.with_count.is_some() {
31503 self.write_keyword(" WITH COUNT");
31504 } else {
31505 self.write_keyword(" WITHOUT COUNT");
31506 }
31507 Ok(())
31508 }
31509
31510 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
31511 self.generate_expression(&e.this)?;
31513 self.write("(");
31514 for (i, expr) in e.expressions.iter().enumerate() {
31515 if i > 0 {
31516 self.write(", ");
31517 }
31518 self.generate_expression(expr)?;
31519 }
31520 self.write(")(");
31521 for (i, param) in e.params.iter().enumerate() {
31522 if i > 0 {
31523 self.write(", ");
31524 }
31525 self.generate_expression(param)?;
31526 }
31527 self.write(")");
31528 Ok(())
31529 }
31530
31531 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
31532 self.write_keyword("PARSE_DATETIME");
31534 self.write("(");
31535 if let Some(format) = &e.format {
31536 self.write("'");
31537 self.write(format);
31538 self.write("', ");
31539 }
31540 self.generate_expression(&e.this)?;
31541 if let Some(zone) = &e.zone {
31542 self.write(", ");
31543 self.generate_expression(zone)?;
31544 }
31545 self.write(")");
31546 Ok(())
31547 }
31548
31549 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
31550 self.write_keyword("PARSE_IP");
31552 self.write("(");
31553 self.generate_expression(&e.this)?;
31554 if let Some(type_) = &e.type_ {
31555 self.write(", ");
31556 self.generate_expression(type_)?;
31557 }
31558 if let Some(permissive) = &e.permissive {
31559 self.write(", ");
31560 self.generate_expression(permissive)?;
31561 }
31562 self.write(")");
31563 Ok(())
31564 }
31565
31566 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
31567 self.write_keyword("PARSE_JSON");
31569 self.write("(");
31570 self.generate_expression(&e.this)?;
31571 if let Some(expression) = &e.expression {
31572 self.write(", ");
31573 self.generate_expression(expression)?;
31574 }
31575 self.write(")");
31576 Ok(())
31577 }
31578
31579 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
31580 self.write_keyword("PARSE_TIME");
31582 self.write("(");
31583 self.write(&format!("'{}'", e.format));
31584 self.write(", ");
31585 self.generate_expression(&e.this)?;
31586 self.write(")");
31587 Ok(())
31588 }
31589
31590 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
31591 self.write_keyword("PARSE_URL");
31593 self.write("(");
31594 self.generate_expression(&e.this)?;
31595 if let Some(part) = &e.part_to_extract {
31596 self.write(", ");
31597 self.generate_expression(part)?;
31598 }
31599 if let Some(key) = &e.key {
31600 self.write(", ");
31601 self.generate_expression(key)?;
31602 }
31603 if let Some(permissive) = &e.permissive {
31604 self.write(", ");
31605 self.generate_expression(permissive)?;
31606 }
31607 self.write(")");
31608 Ok(())
31609 }
31610
31611 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
31612 if e.subpartition {
31614 self.write_keyword("SUBPARTITION");
31615 } else {
31616 self.write_keyword("PARTITION");
31617 }
31618 self.write("(");
31619 for (i, expr) in e.expressions.iter().enumerate() {
31620 if i > 0 {
31621 self.write(", ");
31622 }
31623 self.generate_expression(expr)?;
31624 }
31625 self.write(")");
31626 Ok(())
31627 }
31628
31629 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
31630 if let Some(this) = &e.this {
31632 if let Some(expression) = &e.expression {
31633 self.write_keyword("WITH");
31635 self.write(" (");
31636 self.write_keyword("MODULUS");
31637 self.write_space();
31638 self.generate_expression(this)?;
31639 self.write(", ");
31640 self.write_keyword("REMAINDER");
31641 self.write_space();
31642 self.generate_expression(expression)?;
31643 self.write(")");
31644 } else {
31645 self.write_keyword("IN");
31647 self.write(" (");
31648 self.generate_partition_bound_values(this)?;
31649 self.write(")");
31650 }
31651 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
31652 self.write_keyword("FROM");
31654 self.write(" (");
31655 self.generate_partition_bound_values(from)?;
31656 self.write(") ");
31657 self.write_keyword("TO");
31658 self.write(" (");
31659 self.generate_partition_bound_values(to)?;
31660 self.write(")");
31661 }
31662 Ok(())
31663 }
31664
31665 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
31668 if let Expression::Tuple(t) = expr {
31669 for (i, e) in t.expressions.iter().enumerate() {
31670 if i > 0 {
31671 self.write(", ");
31672 }
31673 self.generate_expression(e)?;
31674 }
31675 Ok(())
31676 } else {
31677 self.generate_expression(expr)
31678 }
31679 }
31680
31681 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
31682 self.write_keyword("PARTITION BY LIST");
31684 if let Some(partition_exprs) = &e.partition_expressions {
31685 self.write(" (");
31686 self.generate_doris_partition_expressions(partition_exprs)?;
31688 self.write(")");
31689 }
31690 if let Some(create_exprs) = &e.create_expressions {
31691 self.write(" (");
31692 self.generate_doris_partition_definitions(create_exprs)?;
31694 self.write(")");
31695 }
31696 Ok(())
31697 }
31698
31699 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
31700 self.write_keyword("PARTITION BY RANGE");
31702 if let Some(partition_exprs) = &e.partition_expressions {
31703 self.write(" (");
31704 self.generate_doris_partition_expressions(partition_exprs)?;
31706 self.write(")");
31707 }
31708 if let Some(create_exprs) = &e.create_expressions {
31709 self.write(" (");
31710 self.generate_doris_partition_definitions(create_exprs)?;
31712 self.write(")");
31713 }
31714 Ok(())
31715 }
31716
31717 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
31719 if let Expression::Tuple(t) = expr {
31720 for (i, e) in t.expressions.iter().enumerate() {
31721 if i > 0 {
31722 self.write(", ");
31723 }
31724 self.generate_expression(e)?;
31725 }
31726 } else {
31727 self.generate_expression(expr)?;
31728 }
31729 Ok(())
31730 }
31731
31732 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
31734 match expr {
31735 Expression::Tuple(t) => {
31736 for (i, part) in t.expressions.iter().enumerate() {
31738 if i > 0 {
31739 self.write(", ");
31740 }
31741 if let Expression::Partition(p) = part {
31743 for (j, inner) in p.expressions.iter().enumerate() {
31744 if j > 0 {
31745 self.write(", ");
31746 }
31747 self.generate_expression(inner)?;
31748 }
31749 } else {
31750 self.generate_expression(part)?;
31751 }
31752 }
31753 }
31754 Expression::PartitionByRangePropertyDynamic(_) => {
31755 self.generate_expression(expr)?;
31757 }
31758 _ => {
31759 self.generate_expression(expr)?;
31760 }
31761 }
31762 Ok(())
31763 }
31764
31765 fn generate_partition_by_range_property_dynamic(
31766 &mut self,
31767 e: &PartitionByRangePropertyDynamic,
31768 ) -> Result<()> {
31769 if e.use_start_end {
31770 if let Some(start) = &e.start {
31772 self.write_keyword("START");
31773 self.write(" (");
31774 self.generate_expression(start)?;
31775 self.write(")");
31776 }
31777 if let Some(end) = &e.end {
31778 self.write_space();
31779 self.write_keyword("END");
31780 self.write(" (");
31781 self.generate_expression(end)?;
31782 self.write(")");
31783 }
31784 if let Some(every) = &e.every {
31785 self.write_space();
31786 self.write_keyword("EVERY");
31787 self.write(" (");
31788 self.generate_doris_interval(every)?;
31790 self.write(")");
31791 }
31792 } else {
31793 if let Some(start) = &e.start {
31795 self.write_keyword("FROM");
31796 self.write(" (");
31797 self.generate_expression(start)?;
31798 self.write(")");
31799 }
31800 if let Some(end) = &e.end {
31801 self.write_space();
31802 self.write_keyword("TO");
31803 self.write(" (");
31804 self.generate_expression(end)?;
31805 self.write(")");
31806 }
31807 if let Some(every) = &e.every {
31808 self.write_space();
31809 self.generate_doris_interval(every)?;
31811 }
31812 }
31813 Ok(())
31814 }
31815
31816 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
31818 if let Expression::Interval(interval) = expr {
31819 self.write_keyword("INTERVAL");
31820 if let Some(ref value) = interval.this {
31821 self.write_space();
31822 match value {
31826 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()) => {
31827 if let Literal::String(s) = lit.as_ref() {
31828 self.write(s);
31829 }
31830 }
31831 _ => {
31832 self.generate_expression(value)?;
31833 }
31834 }
31835 }
31836 if let Some(ref unit_spec) = interval.unit {
31837 self.write_space();
31838 self.write_interval_unit_spec(unit_spec)?;
31839 }
31840 Ok(())
31841 } else {
31842 self.generate_expression(expr)
31843 }
31844 }
31845
31846 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
31847 self.write_keyword("TRUNCATE");
31849 self.write("(");
31850 self.generate_expression(&e.expression)?;
31851 self.write(", ");
31852 self.generate_expression(&e.this)?;
31853 self.write(")");
31854 Ok(())
31855 }
31856
31857 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
31858 self.write_keyword("PARTITION");
31860 self.write_space();
31861 self.generate_expression(&e.this)?;
31862 self.write_space();
31863 self.write_keyword("VALUES IN");
31864 self.write(" (");
31865 for (i, expr) in e.expressions.iter().enumerate() {
31866 if i > 0 {
31867 self.write(", ");
31868 }
31869 self.generate_expression(expr)?;
31870 }
31871 self.write(")");
31872 Ok(())
31873 }
31874
31875 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
31876 if e.expressions.is_empty() && e.expression.is_some() {
31879 self.generate_expression(&e.this)?;
31881 self.write_space();
31882 self.write_keyword("TO");
31883 self.write_space();
31884 self.generate_expression(e.expression.as_ref().unwrap())?;
31885 return Ok(());
31886 }
31887
31888 self.write_keyword("PARTITION");
31890 self.write_space();
31891 self.generate_expression(&e.this)?;
31892 self.write_space();
31893
31894 if e.expressions.len() == 1 {
31896 self.write_keyword("VALUES LESS THAN");
31898 self.write(" (");
31899 self.generate_expression(&e.expressions[0])?;
31900 self.write(")");
31901 } else if !e.expressions.is_empty() {
31902 self.write_keyword("VALUES");
31904 self.write(" [");
31905 for (i, expr) in e.expressions.iter().enumerate() {
31906 if i > 0 {
31907 self.write(", ");
31908 }
31909 if let Expression::Tuple(t) = expr {
31911 self.write("(");
31912 for (j, inner) in t.expressions.iter().enumerate() {
31913 if j > 0 {
31914 self.write(", ");
31915 }
31916 self.generate_expression(inner)?;
31917 }
31918 self.write(")");
31919 } else {
31920 self.write("(");
31921 self.generate_expression(expr)?;
31922 self.write(")");
31923 }
31924 }
31925 self.write(")");
31926 }
31927 Ok(())
31928 }
31929
31930 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
31931 self.write_keyword("BUCKET");
31933 self.write("(");
31934 self.generate_expression(&e.this)?;
31935 self.write(", ");
31936 self.generate_expression(&e.expression)?;
31937 self.write(")");
31938 Ok(())
31939 }
31940
31941 fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> {
31942 self.write_keyword("PARTITION BY");
31944 self.write_space();
31945 for (i, expr) in e.expressions.iter().enumerate() {
31946 if i > 0 {
31947 self.write(", ");
31948 }
31949 self.generate_expression(expr)?;
31950 }
31951 Ok(())
31952 }
31953
31954 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
31955 if matches!(
31957 self.config.dialect,
31958 Some(crate::dialects::DialectType::Teradata)
31959 | Some(crate::dialects::DialectType::ClickHouse)
31960 ) {
31961 self.write_keyword("PARTITION BY");
31962 } else {
31963 self.write_keyword("PARTITIONED BY");
31964 }
31965 self.write_space();
31966 if self.config.pretty {
31968 if let Expression::Tuple(ref tuple) = *e.this {
31969 self.write("(");
31970 self.write_newline();
31971 self.indent_level += 1;
31972 for (i, expr) in tuple.expressions.iter().enumerate() {
31973 if i > 0 {
31974 self.write(",");
31975 self.write_newline();
31976 }
31977 self.write_indent();
31978 self.generate_expression(expr)?;
31979 }
31980 self.indent_level -= 1;
31981 self.write_newline();
31982 self.write(")");
31983 } else {
31984 self.generate_expression(&e.this)?;
31985 }
31986 } else {
31987 self.generate_expression(&e.this)?;
31988 }
31989 Ok(())
31990 }
31991
31992 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
31993 self.write_keyword("PARTITION OF");
31995 self.write_space();
31996 self.generate_expression(&e.this)?;
31997 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
31999 self.write_space();
32000 self.write_keyword("FOR VALUES");
32001 self.write_space();
32002 self.generate_expression(&e.expression)?;
32003 } else {
32004 self.write_space();
32005 self.write_keyword("DEFAULT");
32006 }
32007 Ok(())
32008 }
32009
32010 fn generate_period_for_system_time_constraint(
32011 &mut self,
32012 e: &PeriodForSystemTimeConstraint,
32013 ) -> Result<()> {
32014 self.write_keyword("PERIOD FOR SYSTEM_TIME");
32016 self.write(" (");
32017 self.generate_expression(&e.this)?;
32018 self.write(", ");
32019 self.generate_expression(&e.expression)?;
32020 self.write(")");
32021 Ok(())
32022 }
32023
32024 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
32025 self.generate_expression(&e.this)?;
32028 self.write_space();
32029 self.write_keyword("AS");
32030 self.write_space();
32031 if self.config.unpivot_aliases_are_identifiers {
32033 match &e.alias {
32034 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
32035 let Literal::String(s) = lit.as_ref() else {
32036 unreachable!()
32037 };
32038 self.generate_identifier(&Identifier::new(s.clone()))?;
32040 }
32041 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
32042 let Literal::Number(n) = lit.as_ref() else {
32043 unreachable!()
32044 };
32045 let mut id = Identifier::new(n.clone());
32047 id.quoted = true;
32048 self.generate_identifier(&id)?;
32049 }
32050 other => {
32051 self.generate_expression(other)?;
32052 }
32053 }
32054 } else {
32055 self.generate_expression(&e.alias)?;
32056 }
32057 Ok(())
32058 }
32059
32060 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
32061 self.write_keyword("ANY");
32063 if let Some(this) = &e.this {
32064 self.write_space();
32065 self.generate_expression(this)?;
32066 }
32067 Ok(())
32068 }
32069
32070 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
32071 self.write_keyword("ML.PREDICT");
32073 self.write("(");
32074 self.write_keyword("MODEL");
32075 self.write_space();
32076 self.generate_expression(&e.this)?;
32077 self.write(", ");
32078 self.generate_expression(&e.expression)?;
32079 if let Some(params) = &e.params_struct {
32080 self.write(", ");
32081 self.generate_expression(params)?;
32082 }
32083 self.write(")");
32084 Ok(())
32085 }
32086
32087 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
32088 self.write_keyword("PREVIOUS_DAY");
32090 self.write("(");
32091 self.generate_expression(&e.this)?;
32092 self.write(", ");
32093 self.generate_expression(&e.expression)?;
32094 self.write(")");
32095 Ok(())
32096 }
32097
32098 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
32099 self.write_keyword("PRIMARY KEY");
32101 if let Some(name) = &e.this {
32102 self.write_space();
32103 self.generate_expression(name)?;
32104 }
32105 if !e.expressions.is_empty() {
32106 self.write(" (");
32107 for (i, expr) in e.expressions.iter().enumerate() {
32108 if i > 0 {
32109 self.write(", ");
32110 }
32111 self.generate_expression(expr)?;
32112 }
32113 self.write(")");
32114 }
32115 if let Some(include) = &e.include {
32116 self.write_space();
32117 self.generate_expression(include)?;
32118 }
32119 if !e.options.is_empty() {
32120 self.write_space();
32121 for (i, opt) in e.options.iter().enumerate() {
32122 if i > 0 {
32123 self.write_space();
32124 }
32125 self.generate_expression(opt)?;
32126 }
32127 }
32128 Ok(())
32129 }
32130
32131 fn generate_primary_key_column_constraint(
32132 &mut self,
32133 _e: &PrimaryKeyColumnConstraint,
32134 ) -> Result<()> {
32135 self.write_keyword("PRIMARY KEY");
32137 Ok(())
32138 }
32139
32140 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
32141 self.write_keyword("PATH");
32143 self.write_space();
32144 self.generate_expression(&e.this)?;
32145 Ok(())
32146 }
32147
32148 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
32149 self.write_keyword("PROJECTION");
32151 self.write_space();
32152 self.generate_expression(&e.this)?;
32153 self.write(" (");
32154 self.generate_expression(&e.expression)?;
32155 self.write(")");
32156 Ok(())
32157 }
32158
32159 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
32160 for (i, prop) in e.expressions.iter().enumerate() {
32162 if i > 0 {
32163 self.write(", ");
32164 }
32165 self.generate_expression(prop)?;
32166 }
32167 Ok(())
32168 }
32169
32170 fn generate_property(&mut self, e: &Property) -> Result<()> {
32171 self.generate_expression(&e.this)?;
32173 if let Some(value) = &e.value {
32174 self.write("=");
32175 self.generate_expression(value)?;
32176 }
32177 Ok(())
32178 }
32179
32180 fn generate_options_property(&mut self, e: &OptionsProperty) -> Result<()> {
32181 self.write_keyword("OPTIONS");
32182 if e.entries.is_empty() {
32183 self.write(" ()");
32184 return Ok(());
32185 }
32186
32187 if self.config.pretty {
32188 self.write(" (");
32189 self.write_newline();
32190 self.indent_level += 1;
32191 for (i, entry) in e.entries.iter().enumerate() {
32192 if i > 0 {
32193 self.write(",");
32194 self.write_newline();
32195 }
32196 self.write_indent();
32197 self.generate_identifier(&entry.key)?;
32198 self.write("=");
32199 self.generate_expression(&entry.value)?;
32200 }
32201 self.indent_level -= 1;
32202 self.write_newline();
32203 self.write(")");
32204 } else {
32205 self.write(" (");
32206 for (i, entry) in e.entries.iter().enumerate() {
32207 if i > 0 {
32208 self.write(", ");
32209 }
32210 self.generate_identifier(&entry.key)?;
32211 self.write("=");
32212 self.generate_expression(&entry.value)?;
32213 }
32214 self.write(")");
32215 }
32216 Ok(())
32217 }
32218
32219 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
32221 self.write_keyword("OPTIONS");
32222 self.write(" (");
32223 for (i, opt) in options.iter().enumerate() {
32224 if i > 0 {
32225 self.write(", ");
32226 }
32227 self.generate_option_expression(opt)?;
32228 }
32229 self.write(")");
32230 Ok(())
32231 }
32232
32233 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
32235 self.write_keyword("PROPERTIES");
32236 self.write(" (");
32237 for (i, prop) in properties.iter().enumerate() {
32238 if i > 0 {
32239 self.write(", ");
32240 }
32241 self.generate_option_expression(prop)?;
32242 }
32243 self.write(")");
32244 Ok(())
32245 }
32246
32247 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
32249 self.write_keyword("ENVIRONMENT");
32250 self.write(" (");
32251 for (i, env_item) in environment.iter().enumerate() {
32252 if i > 0 {
32253 self.write(", ");
32254 }
32255 self.generate_environment_expression(env_item)?;
32256 }
32257 self.write(")");
32258 Ok(())
32259 }
32260
32261 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
32263 match expr {
32264 Expression::Eq(eq) => {
32265 self.generate_expression(&eq.left)?;
32267 self.write(" = ");
32268 self.generate_expression(&eq.right)?;
32269 Ok(())
32270 }
32271 _ => self.generate_expression(expr),
32272 }
32273 }
32274
32275 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
32277 self.write_keyword("TBLPROPERTIES");
32278 if self.config.pretty {
32279 self.write(" (");
32280 self.write_newline();
32281 self.indent_level += 1;
32282 for (i, opt) in options.iter().enumerate() {
32283 if i > 0 {
32284 self.write(",");
32285 self.write_newline();
32286 }
32287 self.write_indent();
32288 self.generate_option_expression(opt)?;
32289 }
32290 self.indent_level -= 1;
32291 self.write_newline();
32292 self.write(")");
32293 } else {
32294 self.write(" (");
32295 for (i, opt) in options.iter().enumerate() {
32296 if i > 0 {
32297 self.write(", ");
32298 }
32299 self.generate_option_expression(opt)?;
32300 }
32301 self.write(")");
32302 }
32303 Ok(())
32304 }
32305
32306 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
32308 match expr {
32309 Expression::Eq(eq) => {
32310 self.generate_expression(&eq.left)?;
32312 self.write("=");
32313 self.generate_expression(&eq.right)?;
32314 Ok(())
32315 }
32316 _ => self.generate_expression(expr),
32317 }
32318 }
32319
32320 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
32321 self.generate_expression(&e.this)?;
32323 Ok(())
32324 }
32325
32326 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
32327 self.write_keyword("PUT");
32329 self.write_space();
32330
32331 if e.source_quoted {
32333 self.write("'");
32334 self.write(&e.source);
32335 self.write("'");
32336 } else {
32337 self.write(&e.source);
32338 }
32339
32340 self.write_space();
32341
32342 if let Expression::Literal(lit) = &e.target {
32344 if let Literal::String(s) = lit.as_ref() {
32345 self.write(s);
32346 }
32347 } else {
32348 self.generate_expression(&e.target)?;
32349 }
32350
32351 for param in &e.params {
32353 self.write_space();
32354 self.write(¶m.name);
32355 if let Some(ref value) = param.value {
32356 self.write("=");
32357 self.generate_expression(value)?;
32358 }
32359 }
32360
32361 Ok(())
32362 }
32363
32364 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
32365 self.write_keyword("QUANTILE");
32367 self.write("(");
32368 self.generate_expression(&e.this)?;
32369 if let Some(quantile) = &e.quantile {
32370 self.write(", ");
32371 self.generate_expression(quantile)?;
32372 }
32373 self.write(")");
32374 Ok(())
32375 }
32376
32377 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
32378 if matches!(
32380 self.config.dialect,
32381 Some(crate::dialects::DialectType::Teradata)
32382 ) {
32383 self.write_keyword("SET");
32384 self.write_space();
32385 }
32386 self.write_keyword("QUERY_BAND");
32387 self.write(" = ");
32388 self.generate_expression(&e.this)?;
32389 if e.update.is_some() {
32390 self.write_space();
32391 self.write_keyword("UPDATE");
32392 }
32393 if let Some(scope) = &e.scope {
32394 self.write_space();
32395 self.write_keyword("FOR");
32396 self.write_space();
32397 self.generate_expression(scope)?;
32398 }
32399 Ok(())
32400 }
32401
32402 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
32403 self.generate_expression(&e.this)?;
32405 if let Some(expression) = &e.expression {
32406 self.write(" = ");
32407 self.generate_expression(expression)?;
32408 }
32409 Ok(())
32410 }
32411
32412 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
32413 self.write_keyword("TRANSFORM");
32415 self.write("(");
32416 for (i, expr) in e.expressions.iter().enumerate() {
32417 if i > 0 {
32418 self.write(", ");
32419 }
32420 self.generate_expression(expr)?;
32421 }
32422 self.write(")");
32423 if let Some(row_format_before) = &e.row_format_before {
32424 self.write_space();
32425 self.generate_expression(row_format_before)?;
32426 }
32427 if let Some(record_writer) = &e.record_writer {
32428 self.write_space();
32429 self.write_keyword("RECORDWRITER");
32430 self.write_space();
32431 self.generate_expression(record_writer)?;
32432 }
32433 if let Some(command_script) = &e.command_script {
32434 self.write_space();
32435 self.write_keyword("USING");
32436 self.write_space();
32437 self.generate_expression(command_script)?;
32438 }
32439 if let Some(schema) = &e.schema {
32440 self.write_space();
32441 self.write_keyword("AS");
32442 self.write_space();
32443 self.generate_expression(schema)?;
32444 }
32445 if let Some(row_format_after) = &e.row_format_after {
32446 self.write_space();
32447 self.generate_expression(row_format_after)?;
32448 }
32449 if let Some(record_reader) = &e.record_reader {
32450 self.write_space();
32451 self.write_keyword("RECORDREADER");
32452 self.write_space();
32453 self.generate_expression(record_reader)?;
32454 }
32455 Ok(())
32456 }
32457
32458 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
32459 self.write_keyword("RANDN");
32461 self.write("(");
32462 if let Some(this) = &e.this {
32463 self.generate_expression(this)?;
32464 }
32465 self.write(")");
32466 Ok(())
32467 }
32468
32469 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
32470 self.write_keyword("RANDSTR");
32472 self.write("(");
32473 self.generate_expression(&e.this)?;
32474 if let Some(generator) = &e.generator {
32475 self.write(", ");
32476 self.generate_expression(generator)?;
32477 }
32478 self.write(")");
32479 Ok(())
32480 }
32481
32482 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
32483 self.write_keyword("RANGE_BUCKET");
32485 self.write("(");
32486 self.generate_expression(&e.this)?;
32487 self.write(", ");
32488 self.generate_expression(&e.expression)?;
32489 self.write(")");
32490 Ok(())
32491 }
32492
32493 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
32494 self.write_keyword("RANGE_N");
32496 self.write("(");
32497 self.generate_expression(&e.this)?;
32498 self.write_space();
32499 self.write_keyword("BETWEEN");
32500 self.write_space();
32501 for (i, expr) in e.expressions.iter().enumerate() {
32502 if i > 0 {
32503 self.write(", ");
32504 }
32505 self.generate_expression(expr)?;
32506 }
32507 if let Some(each) = &e.each {
32508 self.write_space();
32509 self.write_keyword("EACH");
32510 self.write_space();
32511 self.generate_expression(each)?;
32512 }
32513 self.write(")");
32514 Ok(())
32515 }
32516
32517 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
32518 self.write_keyword("READ_CSV");
32520 self.write("(");
32521 self.generate_expression(&e.this)?;
32522 for expr in &e.expressions {
32523 self.write(", ");
32524 self.generate_expression(expr)?;
32525 }
32526 self.write(")");
32527 Ok(())
32528 }
32529
32530 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
32531 self.write_keyword("READ_PARQUET");
32533 self.write("(");
32534 for (i, expr) in e.expressions.iter().enumerate() {
32535 if i > 0 {
32536 self.write(", ");
32537 }
32538 self.generate_expression(expr)?;
32539 }
32540 self.write(")");
32541 Ok(())
32542 }
32543
32544 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
32545 if e.kind == "CYCLE" {
32548 self.write_keyword("CYCLE");
32549 } else {
32550 self.write_keyword("SEARCH");
32551 self.write_space();
32552 self.write(&e.kind);
32553 self.write_space();
32554 self.write_keyword("FIRST BY");
32555 }
32556 self.write_space();
32557 self.generate_expression(&e.this)?;
32558 self.write_space();
32559 self.write_keyword("SET");
32560 self.write_space();
32561 self.generate_expression(&e.expression)?;
32562 if let Some(using) = &e.using {
32563 self.write_space();
32564 self.write_keyword("USING");
32565 self.write_space();
32566 self.generate_expression(using)?;
32567 }
32568 Ok(())
32569 }
32570
32571 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
32572 self.write_keyword("REDUCE");
32574 self.write("(");
32575 self.generate_expression(&e.this)?;
32576 if let Some(initial) = &e.initial {
32577 self.write(", ");
32578 self.generate_expression(initial)?;
32579 }
32580 if let Some(merge) = &e.merge {
32581 self.write(", ");
32582 self.generate_expression(merge)?;
32583 }
32584 if let Some(finish) = &e.finish {
32585 self.write(", ");
32586 self.generate_expression(finish)?;
32587 }
32588 self.write(")");
32589 Ok(())
32590 }
32591
32592 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
32593 self.write_keyword("REFERENCES");
32595 self.write_space();
32596 self.generate_expression(&e.this)?;
32597 if !e.expressions.is_empty() {
32598 self.write(" (");
32599 for (i, expr) in e.expressions.iter().enumerate() {
32600 if i > 0 {
32601 self.write(", ");
32602 }
32603 self.generate_expression(expr)?;
32604 }
32605 self.write(")");
32606 }
32607 for opt in &e.options {
32608 self.write_space();
32609 self.generate_expression(opt)?;
32610 }
32611 Ok(())
32612 }
32613
32614 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
32615 self.write_keyword("REFRESH");
32617 if !e.kind.is_empty() {
32618 self.write_space();
32619 self.write_keyword(&e.kind);
32620 }
32621 self.write_space();
32622 self.generate_expression(&e.this)?;
32623 Ok(())
32624 }
32625
32626 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
32627 self.write_keyword("REFRESH");
32629 self.write_space();
32630 self.write_keyword(&e.method);
32631
32632 if let Some(ref kind) = e.kind {
32633 self.write_space();
32634 self.write_keyword("ON");
32635 self.write_space();
32636 self.write_keyword(kind);
32637
32638 if let Some(ref every) = e.every {
32640 self.write_space();
32641 self.write_keyword("EVERY");
32642 self.write_space();
32643 self.generate_expression(every)?;
32644 if let Some(ref unit) = e.unit {
32645 self.write_space();
32646 self.write_keyword(unit);
32647 }
32648 }
32649
32650 if let Some(ref starts) = e.starts {
32652 self.write_space();
32653 self.write_keyword("STARTS");
32654 self.write_space();
32655 self.generate_expression(starts)?;
32656 }
32657 }
32658 Ok(())
32659 }
32660
32661 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
32662 self.write_keyword("REGEXP_COUNT");
32664 self.write("(");
32665 self.generate_expression(&e.this)?;
32666 self.write(", ");
32667 self.generate_expression(&e.expression)?;
32668 if let Some(position) = &e.position {
32669 self.write(", ");
32670 self.generate_expression(position)?;
32671 }
32672 if let Some(parameters) = &e.parameters {
32673 self.write(", ");
32674 self.generate_expression(parameters)?;
32675 }
32676 self.write(")");
32677 Ok(())
32678 }
32679
32680 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
32681 self.write_keyword("REGEXP_EXTRACT_ALL");
32683 self.write("(");
32684 self.generate_expression(&e.this)?;
32685 self.write(", ");
32686 self.generate_expression(&e.expression)?;
32687 if let Some(group) = &e.group {
32688 self.write(", ");
32689 self.generate_expression(group)?;
32690 }
32691 self.write(")");
32692 Ok(())
32693 }
32694
32695 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
32696 self.write_keyword("REGEXP_FULL_MATCH");
32698 self.write("(");
32699 self.generate_expression(&e.this)?;
32700 self.write(", ");
32701 self.generate_expression(&e.expression)?;
32702 self.write(")");
32703 Ok(())
32704 }
32705
32706 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
32707 use crate::dialects::DialectType;
32708 if matches!(
32710 self.config.dialect,
32711 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
32712 ) && e.flag.is_none()
32713 {
32714 self.generate_expression(&e.this)?;
32715 self.write(" ~* ");
32716 self.generate_expression(&e.expression)?;
32717 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
32718 self.write_keyword("REGEXP_LIKE");
32720 self.write("(");
32721 self.generate_expression(&e.this)?;
32722 self.write(", ");
32723 self.generate_expression(&e.expression)?;
32724 self.write(", ");
32725 if let Some(flag) = &e.flag {
32726 self.generate_expression(flag)?;
32727 } else {
32728 self.write("'i'");
32729 }
32730 self.write(")");
32731 } else {
32732 self.generate_expression(&e.this)?;
32734 self.write_space();
32735 self.write_keyword("REGEXP_ILIKE");
32736 self.write_space();
32737 self.generate_expression(&e.expression)?;
32738 if let Some(flag) = &e.flag {
32739 self.write(", ");
32740 self.generate_expression(flag)?;
32741 }
32742 }
32743 Ok(())
32744 }
32745
32746 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
32747 self.write_keyword("REGEXP_INSTR");
32749 self.write("(");
32750 self.generate_expression(&e.this)?;
32751 self.write(", ");
32752 self.generate_expression(&e.expression)?;
32753 if let Some(position) = &e.position {
32754 self.write(", ");
32755 self.generate_expression(position)?;
32756 }
32757 if let Some(occurrence) = &e.occurrence {
32758 self.write(", ");
32759 self.generate_expression(occurrence)?;
32760 }
32761 if let Some(option) = &e.option {
32762 self.write(", ");
32763 self.generate_expression(option)?;
32764 }
32765 if let Some(parameters) = &e.parameters {
32766 self.write(", ");
32767 self.generate_expression(parameters)?;
32768 }
32769 if let Some(group) = &e.group {
32770 self.write(", ");
32771 self.generate_expression(group)?;
32772 }
32773 self.write(")");
32774 Ok(())
32775 }
32776
32777 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
32778 self.write_keyword("REGEXP_SPLIT");
32780 self.write("(");
32781 self.generate_expression(&e.this)?;
32782 self.write(", ");
32783 self.generate_expression(&e.expression)?;
32784 if let Some(limit) = &e.limit {
32785 self.write(", ");
32786 self.generate_expression(limit)?;
32787 }
32788 self.write(")");
32789 Ok(())
32790 }
32791
32792 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
32793 self.write_keyword("REGR_AVGX");
32795 self.write("(");
32796 self.generate_expression(&e.this)?;
32797 self.write(", ");
32798 self.generate_expression(&e.expression)?;
32799 self.write(")");
32800 Ok(())
32801 }
32802
32803 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
32804 self.write_keyword("REGR_AVGY");
32806 self.write("(");
32807 self.generate_expression(&e.this)?;
32808 self.write(", ");
32809 self.generate_expression(&e.expression)?;
32810 self.write(")");
32811 Ok(())
32812 }
32813
32814 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
32815 self.write_keyword("REGR_COUNT");
32817 self.write("(");
32818 self.generate_expression(&e.this)?;
32819 self.write(", ");
32820 self.generate_expression(&e.expression)?;
32821 self.write(")");
32822 Ok(())
32823 }
32824
32825 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
32826 self.write_keyword("REGR_INTERCEPT");
32828 self.write("(");
32829 self.generate_expression(&e.this)?;
32830 self.write(", ");
32831 self.generate_expression(&e.expression)?;
32832 self.write(")");
32833 Ok(())
32834 }
32835
32836 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
32837 self.write_keyword("REGR_R2");
32839 self.write("(");
32840 self.generate_expression(&e.this)?;
32841 self.write(", ");
32842 self.generate_expression(&e.expression)?;
32843 self.write(")");
32844 Ok(())
32845 }
32846
32847 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
32848 self.write_keyword("REGR_SLOPE");
32850 self.write("(");
32851 self.generate_expression(&e.this)?;
32852 self.write(", ");
32853 self.generate_expression(&e.expression)?;
32854 self.write(")");
32855 Ok(())
32856 }
32857
32858 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
32859 self.write_keyword("REGR_SXX");
32861 self.write("(");
32862 self.generate_expression(&e.this)?;
32863 self.write(", ");
32864 self.generate_expression(&e.expression)?;
32865 self.write(")");
32866 Ok(())
32867 }
32868
32869 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
32870 self.write_keyword("REGR_SXY");
32872 self.write("(");
32873 self.generate_expression(&e.this)?;
32874 self.write(", ");
32875 self.generate_expression(&e.expression)?;
32876 self.write(")");
32877 Ok(())
32878 }
32879
32880 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
32881 self.write_keyword("REGR_SYY");
32883 self.write("(");
32884 self.generate_expression(&e.this)?;
32885 self.write(", ");
32886 self.generate_expression(&e.expression)?;
32887 self.write(")");
32888 Ok(())
32889 }
32890
32891 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
32892 self.write_keyword("REGR_VALX");
32894 self.write("(");
32895 self.generate_expression(&e.this)?;
32896 self.write(", ");
32897 self.generate_expression(&e.expression)?;
32898 self.write(")");
32899 Ok(())
32900 }
32901
32902 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
32903 self.write_keyword("REGR_VALY");
32905 self.write("(");
32906 self.generate_expression(&e.this)?;
32907 self.write(", ");
32908 self.generate_expression(&e.expression)?;
32909 self.write(")");
32910 Ok(())
32911 }
32912
32913 fn generate_remote_with_connection_model_property(
32914 &mut self,
32915 e: &RemoteWithConnectionModelProperty,
32916 ) -> Result<()> {
32917 self.write_keyword("REMOTE WITH CONNECTION");
32919 self.write_space();
32920 self.generate_expression(&e.this)?;
32921 Ok(())
32922 }
32923
32924 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
32925 self.write_keyword("RENAME COLUMN");
32927 if e.exists {
32928 self.write_space();
32929 self.write_keyword("IF EXISTS");
32930 }
32931 self.write_space();
32932 self.generate_expression(&e.this)?;
32933 if let Some(to) = &e.to {
32934 self.write_space();
32935 self.write_keyword("TO");
32936 self.write_space();
32937 self.generate_expression(to)?;
32938 }
32939 Ok(())
32940 }
32941
32942 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
32943 self.write_keyword("REPLACE PARTITION");
32945 self.write_space();
32946 self.generate_expression(&e.expression)?;
32947 if let Some(source) = &e.source {
32948 self.write_space();
32949 self.write_keyword("FROM");
32950 self.write_space();
32951 self.generate_expression(source)?;
32952 }
32953 Ok(())
32954 }
32955
32956 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
32957 let keyword = match self.config.dialect {
32960 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
32961 _ => "RETURNING",
32962 };
32963 self.write_keyword(keyword);
32964 self.write_space();
32965 for (i, expr) in e.expressions.iter().enumerate() {
32966 if i > 0 {
32967 self.write(", ");
32968 }
32969 self.generate_expression(expr)?;
32970 }
32971 if let Some(into) = &e.into {
32972 self.write_space();
32973 self.write_keyword("INTO");
32974 self.write_space();
32975 self.generate_expression(into)?;
32976 }
32977 Ok(())
32978 }
32979
32980 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
32981 self.write_space();
32983 self.write_keyword("OUTPUT");
32984 self.write_space();
32985 for (i, expr) in output.columns.iter().enumerate() {
32986 if i > 0 {
32987 self.write(", ");
32988 }
32989 self.generate_expression(expr)?;
32990 }
32991 if let Some(into_table) = &output.into_table {
32992 self.write_space();
32993 self.write_keyword("INTO");
32994 self.write_space();
32995 self.generate_expression(into_table)?;
32996 }
32997 Ok(())
32998 }
32999
33000 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
33001 self.write_keyword("RETURNS");
33003 if e.is_table.is_some() {
33004 self.write_space();
33005 self.write_keyword("TABLE");
33006 }
33007 if let Some(table) = &e.table {
33008 self.write_space();
33009 self.generate_expression(table)?;
33010 } else if let Some(this) = &e.this {
33011 self.write_space();
33012 self.generate_expression(this)?;
33013 }
33014 if e.null.is_some() {
33015 self.write_space();
33016 self.write_keyword("NULL ON NULL INPUT");
33017 }
33018 Ok(())
33019 }
33020
33021 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
33022 self.write_keyword("ROLLBACK");
33024
33025 if e.this.is_none()
33027 && matches!(
33028 self.config.dialect,
33029 Some(DialectType::TSQL) | Some(DialectType::Fabric)
33030 )
33031 {
33032 self.write_space();
33033 self.write_keyword("TRANSACTION");
33034 }
33035
33036 if let Some(this) = &e.this {
33038 let is_transaction_marker = matches!(
33040 this.as_ref(),
33041 Expression::Identifier(id) if id.name == "TRANSACTION"
33042 );
33043
33044 self.write_space();
33045 self.write_keyword("TRANSACTION");
33046
33047 if !is_transaction_marker {
33049 self.write_space();
33050 self.generate_expression(this)?;
33051 }
33052 }
33053
33054 if let Some(savepoint) = &e.savepoint {
33056 self.write_space();
33057 self.write_keyword("TO");
33058 self.write_space();
33059 self.generate_expression(savepoint)?;
33060 }
33061 Ok(())
33062 }
33063
33064 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
33065 if e.expressions.is_empty() {
33067 self.write_keyword("WITH ROLLUP");
33068 } else {
33069 self.write_keyword("ROLLUP");
33070 self.write("(");
33071 for (i, expr) in e.expressions.iter().enumerate() {
33072 if i > 0 {
33073 self.write(", ");
33074 }
33075 self.generate_expression(expr)?;
33076 }
33077 self.write(")");
33078 }
33079 Ok(())
33080 }
33081
33082 fn generate_row_format_delimited_property(
33083 &mut self,
33084 e: &RowFormatDelimitedProperty,
33085 ) -> Result<()> {
33086 self.write_keyword("ROW FORMAT DELIMITED");
33088 if let Some(fields) = &e.fields {
33089 self.write_space();
33090 self.write_keyword("FIELDS TERMINATED BY");
33091 self.write_space();
33092 self.generate_expression(fields)?;
33093 }
33094 if let Some(escaped) = &e.escaped {
33095 self.write_space();
33096 self.write_keyword("ESCAPED BY");
33097 self.write_space();
33098 self.generate_expression(escaped)?;
33099 }
33100 if let Some(items) = &e.collection_items {
33101 self.write_space();
33102 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
33103 self.write_space();
33104 self.generate_expression(items)?;
33105 }
33106 if let Some(keys) = &e.map_keys {
33107 self.write_space();
33108 self.write_keyword("MAP KEYS TERMINATED BY");
33109 self.write_space();
33110 self.generate_expression(keys)?;
33111 }
33112 if let Some(lines) = &e.lines {
33113 self.write_space();
33114 self.write_keyword("LINES TERMINATED BY");
33115 self.write_space();
33116 self.generate_expression(lines)?;
33117 }
33118 if let Some(null) = &e.null {
33119 self.write_space();
33120 self.write_keyword("NULL DEFINED AS");
33121 self.write_space();
33122 self.generate_expression(null)?;
33123 }
33124 if let Some(serde) = &e.serde {
33125 self.write_space();
33126 self.generate_expression(serde)?;
33127 }
33128 Ok(())
33129 }
33130
33131 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
33132 self.write_keyword("ROW FORMAT");
33134 self.write_space();
33135 self.generate_expression(&e.this)?;
33136 Ok(())
33137 }
33138
33139 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
33140 self.write_keyword("ROW FORMAT SERDE");
33142 self.write_space();
33143 self.generate_expression(&e.this)?;
33144 if let Some(props) = &e.serde_properties {
33145 self.write_space();
33146 self.generate_expression(props)?;
33148 }
33149 Ok(())
33150 }
33151
33152 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
33153 self.write_keyword("SHA2");
33155 self.write("(");
33156 self.generate_expression(&e.this)?;
33157 if let Some(length) = e.length {
33158 self.write(", ");
33159 self.write(&length.to_string());
33160 }
33161 self.write(")");
33162 Ok(())
33163 }
33164
33165 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
33166 self.write_keyword("SHA2_DIGEST");
33168 self.write("(");
33169 self.generate_expression(&e.this)?;
33170 if let Some(length) = e.length {
33171 self.write(", ");
33172 self.write(&length.to_string());
33173 }
33174 self.write(")");
33175 Ok(())
33176 }
33177
33178 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
33179 let name = if matches!(
33180 self.config.dialect,
33181 Some(crate::dialects::DialectType::Spark)
33182 | Some(crate::dialects::DialectType::Databricks)
33183 ) {
33184 "TRY_ADD"
33185 } else {
33186 "SAFE_ADD"
33187 };
33188 self.write_keyword(name);
33189 self.write("(");
33190 self.generate_expression(&e.this)?;
33191 self.write(", ");
33192 self.generate_expression(&e.expression)?;
33193 self.write(")");
33194 Ok(())
33195 }
33196
33197 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
33198 self.write_keyword("SAFE_DIVIDE");
33200 self.write("(");
33201 self.generate_expression(&e.this)?;
33202 self.write(", ");
33203 self.generate_expression(&e.expression)?;
33204 self.write(")");
33205 Ok(())
33206 }
33207
33208 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
33209 let name = if matches!(
33210 self.config.dialect,
33211 Some(crate::dialects::DialectType::Spark)
33212 | Some(crate::dialects::DialectType::Databricks)
33213 ) {
33214 "TRY_MULTIPLY"
33215 } else {
33216 "SAFE_MULTIPLY"
33217 };
33218 self.write_keyword(name);
33219 self.write("(");
33220 self.generate_expression(&e.this)?;
33221 self.write(", ");
33222 self.generate_expression(&e.expression)?;
33223 self.write(")");
33224 Ok(())
33225 }
33226
33227 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
33228 let name = if matches!(
33229 self.config.dialect,
33230 Some(crate::dialects::DialectType::Spark)
33231 | Some(crate::dialects::DialectType::Databricks)
33232 ) {
33233 "TRY_SUBTRACT"
33234 } else {
33235 "SAFE_SUBTRACT"
33236 };
33237 self.write_keyword(name);
33238 self.write("(");
33239 self.generate_expression(&e.this)?;
33240 self.write(", ");
33241 self.generate_expression(&e.expression)?;
33242 self.write(")");
33243 Ok(())
33244 }
33245
33246 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
33249 if matches!(sample.method, SampleMethod::Bucket) {
33251 self.write(" (");
33252 self.write_keyword("BUCKET");
33253 self.write_space();
33254 if let Some(ref num) = sample.bucket_numerator {
33255 self.generate_expression(num)?;
33256 }
33257 self.write_space();
33258 self.write_keyword("OUT OF");
33259 self.write_space();
33260 if let Some(ref denom) = sample.bucket_denominator {
33261 self.generate_expression(denom)?;
33262 }
33263 if let Some(ref field) = sample.bucket_field {
33264 self.write_space();
33265 self.write_keyword("ON");
33266 self.write_space();
33267 self.generate_expression(field)?;
33268 }
33269 self.write(")");
33270 return Ok(());
33271 }
33272
33273 let is_snowflake = matches!(
33275 self.config.dialect,
33276 Some(crate::dialects::DialectType::Snowflake)
33277 );
33278 let is_postgres = matches!(
33279 self.config.dialect,
33280 Some(crate::dialects::DialectType::PostgreSQL)
33281 | Some(crate::dialects::DialectType::Redshift)
33282 );
33283 let is_databricks = matches!(
33285 self.config.dialect,
33286 Some(crate::dialects::DialectType::Databricks)
33287 );
33288 let is_spark = matches!(
33289 self.config.dialect,
33290 Some(crate::dialects::DialectType::Spark)
33291 );
33292 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
33293 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
33295 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
33296 self.write_space();
33297 if !sample.explicit_method && (is_snowflake || force_method) {
33298 self.write_keyword("BERNOULLI");
33300 } else {
33301 match sample.method {
33302 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
33303 SampleMethod::System => self.write_keyword("SYSTEM"),
33304 SampleMethod::Block => self.write_keyword("BLOCK"),
33305 SampleMethod::Row => self.write_keyword("ROW"),
33306 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
33307 SampleMethod::Percent => self.write_keyword("SYSTEM"),
33308 SampleMethod::Bucket => {} }
33310 }
33311 }
33312
33313 let emit_size_no_parens = !self.config.tablesample_requires_parens;
33315 if emit_size_no_parens {
33316 self.write_space();
33317 match &sample.size {
33318 Expression::Tuple(tuple) => {
33319 for (i, expr) in tuple.expressions.iter().enumerate() {
33320 if i > 0 {
33321 self.write(", ");
33322 }
33323 self.generate_expression(expr)?;
33324 }
33325 }
33326 expr => self.generate_expression(expr)?,
33327 }
33328 } else {
33329 self.write(" (");
33330 self.generate_expression(&sample.size)?;
33331 }
33332
33333 let is_rows_method = matches!(
33335 sample.method,
33336 SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket
33337 );
33338 let is_percent = matches!(
33339 sample.method,
33340 SampleMethod::Percent
33341 | SampleMethod::System
33342 | SampleMethod::Bernoulli
33343 | SampleMethod::Block
33344 );
33345
33346 let is_presto = matches!(
33350 self.config.dialect,
33351 Some(crate::dialects::DialectType::Presto)
33352 | Some(crate::dialects::DialectType::Trino)
33353 | Some(crate::dialects::DialectType::Athena)
33354 );
33355 let should_output_unit = if is_databricks || is_spark {
33356 is_percent || is_rows_method || sample.unit_after_size
33358 } else if is_snowflake || is_postgres || is_presto {
33359 sample.unit_after_size
33360 } else {
33361 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
33362 };
33363
33364 if should_output_unit {
33365 self.write_space();
33366 if sample.is_percent {
33367 self.write_keyword("PERCENT");
33368 } else if is_rows_method && !sample.unit_after_size {
33369 self.write_keyword("ROWS");
33370 } else if sample.unit_after_size {
33371 match sample.method {
33372 SampleMethod::Percent
33373 | SampleMethod::System
33374 | SampleMethod::Bernoulli
33375 | SampleMethod::Block => {
33376 self.write_keyword("PERCENT");
33377 }
33378 SampleMethod::Row | SampleMethod::Reservoir => {
33379 self.write_keyword("ROWS");
33380 }
33381 _ => self.write_keyword("ROWS"),
33382 }
33383 } else {
33384 self.write_keyword("PERCENT");
33385 }
33386 }
33387
33388 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33389 if let Some(ref offset) = sample.offset {
33390 self.write_space();
33391 self.write_keyword("OFFSET");
33392 self.write_space();
33393 self.generate_expression(offset)?;
33394 }
33395 }
33396 if !emit_size_no_parens {
33397 self.write(")");
33398 }
33399
33400 Ok(())
33401 }
33402
33403 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
33404 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33406 self.write_keyword("SAMPLE BY");
33407 } else {
33408 self.write_keyword("SAMPLE");
33409 }
33410 self.write_space();
33411 self.generate_expression(&e.this)?;
33412 Ok(())
33413 }
33414
33415 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
33416 if let Some(this) = &e.this {
33418 self.generate_expression(this)?;
33419 }
33420 if !e.expressions.is_empty() {
33421 if e.this.is_some() {
33423 self.write_space();
33424 }
33425 self.write("(");
33426 for (i, expr) in e.expressions.iter().enumerate() {
33427 if i > 0 {
33428 self.write(", ");
33429 }
33430 self.generate_expression(expr)?;
33431 }
33432 self.write(")");
33433 }
33434 Ok(())
33435 }
33436
33437 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
33438 self.write_keyword("COMMENT");
33440 self.write_space();
33441 self.generate_expression(&e.this)?;
33442 Ok(())
33443 }
33444
33445 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
33446 if let Some(this) = &e.this {
33448 self.generate_expression(this)?;
33449 self.write("::");
33450 }
33451 self.generate_expression(&e.expression)?;
33452 Ok(())
33453 }
33454
33455 fn generate_search(&mut self, e: &Search) -> Result<()> {
33456 self.write_keyword("SEARCH");
33458 self.write("(");
33459 self.generate_expression(&e.this)?;
33460 self.write(", ");
33461 self.generate_expression(&e.expression)?;
33462 if let Some(json_scope) = &e.json_scope {
33463 self.write(", ");
33464 self.generate_expression(json_scope)?;
33465 }
33466 if let Some(analyzer) = &e.analyzer {
33467 self.write(", ");
33468 self.generate_expression(analyzer)?;
33469 }
33470 if let Some(analyzer_options) = &e.analyzer_options {
33471 self.write(", ");
33472 self.generate_expression(analyzer_options)?;
33473 }
33474 if let Some(search_mode) = &e.search_mode {
33475 self.write(", ");
33476 self.generate_expression(search_mode)?;
33477 }
33478 self.write(")");
33479 Ok(())
33480 }
33481
33482 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
33483 self.write_keyword("SEARCH_IP");
33485 self.write("(");
33486 self.generate_expression(&e.this)?;
33487 self.write(", ");
33488 self.generate_expression(&e.expression)?;
33489 self.write(")");
33490 Ok(())
33491 }
33492
33493 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
33494 self.write_keyword("SECURITY");
33496 self.write_space();
33497 self.generate_expression(&e.this)?;
33498 Ok(())
33499 }
33500
33501 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
33502 self.write("SEMANTIC_VIEW(");
33504
33505 if self.config.pretty {
33506 self.write_newline();
33508 self.indent_level += 1;
33509 self.write_indent();
33510 self.generate_expression(&e.this)?;
33511
33512 if let Some(metrics) = &e.metrics {
33513 self.write_newline();
33514 self.write_indent();
33515 self.write_keyword("METRICS");
33516 self.write_space();
33517 self.generate_semantic_view_tuple(metrics)?;
33518 }
33519 if let Some(dimensions) = &e.dimensions {
33520 self.write_newline();
33521 self.write_indent();
33522 self.write_keyword("DIMENSIONS");
33523 self.write_space();
33524 self.generate_semantic_view_tuple(dimensions)?;
33525 }
33526 if let Some(facts) = &e.facts {
33527 self.write_newline();
33528 self.write_indent();
33529 self.write_keyword("FACTS");
33530 self.write_space();
33531 self.generate_semantic_view_tuple(facts)?;
33532 }
33533 if let Some(where_) = &e.where_ {
33534 self.write_newline();
33535 self.write_indent();
33536 self.write_keyword("WHERE");
33537 self.write_space();
33538 self.generate_expression(where_)?;
33539 }
33540 self.write_newline();
33541 self.indent_level -= 1;
33542 self.write_indent();
33543 } else {
33544 self.generate_expression(&e.this)?;
33546 if let Some(metrics) = &e.metrics {
33547 self.write_space();
33548 self.write_keyword("METRICS");
33549 self.write_space();
33550 self.generate_semantic_view_tuple(metrics)?;
33551 }
33552 if let Some(dimensions) = &e.dimensions {
33553 self.write_space();
33554 self.write_keyword("DIMENSIONS");
33555 self.write_space();
33556 self.generate_semantic_view_tuple(dimensions)?;
33557 }
33558 if let Some(facts) = &e.facts {
33559 self.write_space();
33560 self.write_keyword("FACTS");
33561 self.write_space();
33562 self.generate_semantic_view_tuple(facts)?;
33563 }
33564 if let Some(where_) = &e.where_ {
33565 self.write_space();
33566 self.write_keyword("WHERE");
33567 self.write_space();
33568 self.generate_expression(where_)?;
33569 }
33570 }
33571 self.write(")");
33572 Ok(())
33573 }
33574
33575 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
33577 if let Expression::Tuple(t) = expr {
33578 for (i, e) in t.expressions.iter().enumerate() {
33579 if i > 0 {
33580 self.write(", ");
33581 }
33582 self.generate_expression(e)?;
33583 }
33584 } else {
33585 self.generate_expression(expr)?;
33586 }
33587 Ok(())
33588 }
33589
33590 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
33591 if let Some(start) = &e.start {
33593 self.write_keyword("START WITH");
33594 self.write_space();
33595 self.generate_expression(start)?;
33596 }
33597 if let Some(increment) = &e.increment {
33598 self.write_space();
33599 self.write_keyword("INCREMENT BY");
33600 self.write_space();
33601 self.generate_expression(increment)?;
33602 }
33603 if let Some(minvalue) = &e.minvalue {
33604 self.write_space();
33605 self.write_keyword("MINVALUE");
33606 self.write_space();
33607 self.generate_expression(minvalue)?;
33608 }
33609 if let Some(maxvalue) = &e.maxvalue {
33610 self.write_space();
33611 self.write_keyword("MAXVALUE");
33612 self.write_space();
33613 self.generate_expression(maxvalue)?;
33614 }
33615 if let Some(cache) = &e.cache {
33616 self.write_space();
33617 self.write_keyword("CACHE");
33618 self.write_space();
33619 self.generate_expression(cache)?;
33620 }
33621 if let Some(owned) = &e.owned {
33622 self.write_space();
33623 self.write_keyword("OWNED BY");
33624 self.write_space();
33625 self.generate_expression(owned)?;
33626 }
33627 for opt in &e.options {
33628 self.write_space();
33629 self.generate_expression(opt)?;
33630 }
33631 Ok(())
33632 }
33633
33634 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
33635 if e.with_.is_some() {
33637 self.write_keyword("WITH");
33638 self.write_space();
33639 }
33640 self.write_keyword("SERDEPROPERTIES");
33641 self.write(" (");
33642 for (i, expr) in e.expressions.iter().enumerate() {
33643 if i > 0 {
33644 self.write(", ");
33645 }
33646 match expr {
33648 Expression::Eq(eq) => {
33649 self.generate_expression(&eq.left)?;
33650 self.write("=");
33651 self.generate_expression(&eq.right)?;
33652 }
33653 _ => self.generate_expression(expr)?,
33654 }
33655 }
33656 self.write(")");
33657 Ok(())
33658 }
33659
33660 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
33661 self.write("@@");
33663 if let Some(kind) = &e.kind {
33664 self.write(kind);
33665 self.write(".");
33666 }
33667 self.generate_expression(&e.this)?;
33668 Ok(())
33669 }
33670
33671 fn generate_set(&mut self, e: &Set) -> Result<()> {
33672 if e.unset.is_some() {
33674 self.write_keyword("UNSET");
33675 } else {
33676 self.write_keyword("SET");
33677 }
33678 if e.tag.is_some() {
33679 self.write_space();
33680 self.write_keyword("TAG");
33681 }
33682 if !e.expressions.is_empty() {
33683 self.write_space();
33684 for (i, expr) in e.expressions.iter().enumerate() {
33685 if i > 0 {
33686 self.write(", ");
33687 }
33688 self.generate_expression(expr)?;
33689 }
33690 }
33691 Ok(())
33692 }
33693
33694 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
33695 self.write_keyword("SET");
33697 self.write_space();
33698 self.generate_expression(&e.this)?;
33699 Ok(())
33700 }
33701
33702 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
33703 if let Some(kind) = &e.kind {
33705 self.write_keyword(kind);
33706 self.write_space();
33707 }
33708 self.generate_expression(&e.name)?;
33709 self.write(" = ");
33710 self.generate_expression(&e.value)?;
33711 Ok(())
33712 }
33713
33714 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
33715 if let Some(with_) = &e.with_ {
33717 self.generate_expression(with_)?;
33718 self.write_space();
33719 }
33720 self.generate_expression(&e.this)?;
33721 self.write_space();
33722 if let Some(kind) = &e.kind {
33724 self.write_keyword(kind);
33725 }
33726 if e.distinct {
33727 self.write_space();
33728 self.write_keyword("DISTINCT");
33729 } else {
33730 self.write_space();
33731 self.write_keyword("ALL");
33732 }
33733 if e.by_name.is_some() {
33734 self.write_space();
33735 self.write_keyword("BY NAME");
33736 }
33737 self.write_space();
33738 self.generate_expression(&e.expression)?;
33739 Ok(())
33740 }
33741
33742 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
33743 if e.multi.is_some() {
33745 self.write_keyword("MULTISET");
33746 } else {
33747 self.write_keyword("SET");
33748 }
33749 Ok(())
33750 }
33751
33752 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
33753 self.write_keyword("SETTINGS");
33755 if self.config.pretty && e.expressions.len() > 1 {
33756 self.indent_level += 1;
33758 for (i, expr) in e.expressions.iter().enumerate() {
33759 if i > 0 {
33760 self.write(",");
33761 }
33762 self.write_newline();
33763 self.write_indent();
33764 self.generate_expression(expr)?;
33765 }
33766 self.indent_level -= 1;
33767 } else {
33768 self.write_space();
33769 for (i, expr) in e.expressions.iter().enumerate() {
33770 if i > 0 {
33771 self.write(", ");
33772 }
33773 self.generate_expression(expr)?;
33774 }
33775 }
33776 Ok(())
33777 }
33778
33779 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
33780 self.write_keyword("SHARING");
33782 if let Some(this) = &e.this {
33783 self.write(" = ");
33784 self.generate_expression(this)?;
33785 }
33786 Ok(())
33787 }
33788
33789 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
33790 if let Some(begin) = &e.this {
33792 self.generate_expression(begin)?;
33793 }
33794 self.write(":");
33795 if let Some(end) = &e.expression {
33796 self.generate_expression(end)?;
33797 }
33798 if let Some(step) = &e.step {
33799 self.write(":");
33800 self.generate_expression(step)?;
33801 }
33802 Ok(())
33803 }
33804
33805 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
33806 self.write_keyword("SORT_ARRAY");
33808 self.write("(");
33809 self.generate_expression(&e.this)?;
33810 if let Some(asc) = &e.asc {
33811 self.write(", ");
33812 self.generate_expression(asc)?;
33813 }
33814 self.write(")");
33815 Ok(())
33816 }
33817
33818 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
33819 self.write_keyword("SORT BY");
33821 self.write_space();
33822 for (i, expr) in e.expressions.iter().enumerate() {
33823 if i > 0 {
33824 self.write(", ");
33825 }
33826 self.generate_ordered(expr)?;
33827 }
33828 Ok(())
33829 }
33830
33831 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
33832 if e.compound.is_some() {
33834 self.write_keyword("COMPOUND");
33835 self.write_space();
33836 }
33837 self.write_keyword("SORTKEY");
33838 self.write("(");
33839 if let Expression::Tuple(t) = e.this.as_ref() {
33841 for (i, expr) in t.expressions.iter().enumerate() {
33842 if i > 0 {
33843 self.write(", ");
33844 }
33845 self.generate_expression(expr)?;
33846 }
33847 } else {
33848 self.generate_expression(&e.this)?;
33849 }
33850 self.write(")");
33851 Ok(())
33852 }
33853
33854 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
33855 self.write_keyword("SPLIT_PART");
33857 self.write("(");
33858 self.generate_expression(&e.this)?;
33859 if let Some(delimiter) = &e.delimiter {
33860 self.write(", ");
33861 self.generate_expression(delimiter)?;
33862 }
33863 if let Some(part_index) = &e.part_index {
33864 self.write(", ");
33865 self.generate_expression(part_index)?;
33866 }
33867 self.write(")");
33868 Ok(())
33869 }
33870
33871 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
33872 self.generate_expression(&e.this)?;
33874 Ok(())
33875 }
33876
33877 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
33878 self.write_keyword("SQL SECURITY");
33880 self.write_space();
33881 self.generate_expression(&e.this)?;
33882 Ok(())
33883 }
33884
33885 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
33886 self.write_keyword("ST_DISTANCE");
33888 self.write("(");
33889 self.generate_expression(&e.this)?;
33890 self.write(", ");
33891 self.generate_expression(&e.expression)?;
33892 if let Some(use_spheroid) = &e.use_spheroid {
33893 self.write(", ");
33894 self.generate_expression(use_spheroid)?;
33895 }
33896 self.write(")");
33897 Ok(())
33898 }
33899
33900 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
33901 self.write_keyword("ST_POINT");
33903 self.write("(");
33904 self.generate_expression(&e.this)?;
33905 self.write(", ");
33906 self.generate_expression(&e.expression)?;
33907 self.write(")");
33908 Ok(())
33909 }
33910
33911 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
33912 self.generate_expression(&e.this)?;
33914 Ok(())
33915 }
33916
33917 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
33918 self.write_keyword("STANDARD_HASH");
33920 self.write("(");
33921 self.generate_expression(&e.this)?;
33922 if let Some(expression) = &e.expression {
33923 self.write(", ");
33924 self.generate_expression(expression)?;
33925 }
33926 self.write(")");
33927 Ok(())
33928 }
33929
33930 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
33931 self.write_keyword("STORED BY");
33933 self.write_space();
33934 self.generate_expression(&e.this)?;
33935 Ok(())
33936 }
33937
33938 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
33939 use crate::dialects::DialectType;
33942 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
33943 self.write_keyword("CHARINDEX");
33945 self.write("(");
33946 if let Some(substr) = &e.substr {
33947 self.generate_expression(substr)?;
33948 self.write(", ");
33949 }
33950 self.generate_expression(&e.this)?;
33951 if let Some(position) = &e.position {
33952 self.write(", ");
33953 self.generate_expression(position)?;
33954 }
33955 self.write(")");
33956 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
33957 self.write_keyword("POSITION");
33958 self.write("(");
33959 self.generate_expression(&e.this)?;
33960 if let Some(substr) = &e.substr {
33961 self.write(", ");
33962 self.generate_expression(substr)?;
33963 }
33964 if let Some(position) = &e.position {
33965 self.write(", ");
33966 self.generate_expression(position)?;
33967 }
33968 if let Some(occurrence) = &e.occurrence {
33969 self.write(", ");
33970 self.generate_expression(occurrence)?;
33971 }
33972 self.write(")");
33973 } else if matches!(
33974 self.config.dialect,
33975 Some(DialectType::SQLite)
33976 | Some(DialectType::Oracle)
33977 | Some(DialectType::BigQuery)
33978 | Some(DialectType::Teradata)
33979 ) {
33980 self.write_keyword("INSTR");
33981 self.write("(");
33982 self.generate_expression(&e.this)?;
33983 if let Some(substr) = &e.substr {
33984 self.write(", ");
33985 self.generate_expression(substr)?;
33986 }
33987 if let Some(position) = &e.position {
33988 self.write(", ");
33989 self.generate_expression(position)?;
33990 } else if e.occurrence.is_some() {
33991 self.write(", 1");
33994 }
33995 if let Some(occurrence) = &e.occurrence {
33996 self.write(", ");
33997 self.generate_expression(occurrence)?;
33998 }
33999 self.write(")");
34000 } else if matches!(
34001 self.config.dialect,
34002 Some(DialectType::MySQL)
34003 | Some(DialectType::SingleStore)
34004 | Some(DialectType::Doris)
34005 | Some(DialectType::StarRocks)
34006 | Some(DialectType::Hive)
34007 | Some(DialectType::Spark)
34008 | Some(DialectType::Databricks)
34009 ) {
34010 self.write_keyword("LOCATE");
34012 self.write("(");
34013 if let Some(substr) = &e.substr {
34014 self.generate_expression(substr)?;
34015 self.write(", ");
34016 }
34017 self.generate_expression(&e.this)?;
34018 if let Some(position) = &e.position {
34019 self.write(", ");
34020 self.generate_expression(position)?;
34021 }
34022 self.write(")");
34023 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
34024 self.write_keyword("CHARINDEX");
34026 self.write("(");
34027 if let Some(substr) = &e.substr {
34028 self.generate_expression(substr)?;
34029 self.write(", ");
34030 }
34031 self.generate_expression(&e.this)?;
34032 if let Some(position) = &e.position {
34033 self.write(", ");
34034 self.generate_expression(position)?;
34035 }
34036 self.write(")");
34037 } else if matches!(
34038 self.config.dialect,
34039 Some(DialectType::PostgreSQL)
34040 | Some(DialectType::Materialize)
34041 | Some(DialectType::RisingWave)
34042 | Some(DialectType::Redshift)
34043 ) {
34044 self.write_keyword("POSITION");
34046 self.write("(");
34047 if let Some(substr) = &e.substr {
34048 self.generate_expression(substr)?;
34049 self.write(" IN ");
34050 }
34051 self.generate_expression(&e.this)?;
34052 self.write(")");
34053 } else {
34054 self.write_keyword("STRPOS");
34055 self.write("(");
34056 self.generate_expression(&e.this)?;
34057 if let Some(substr) = &e.substr {
34058 self.write(", ");
34059 self.generate_expression(substr)?;
34060 }
34061 if let Some(position) = &e.position {
34062 self.write(", ");
34063 self.generate_expression(position)?;
34064 }
34065 if let Some(occurrence) = &e.occurrence {
34066 self.write(", ");
34067 self.generate_expression(occurrence)?;
34068 }
34069 self.write(")");
34070 }
34071 Ok(())
34072 }
34073
34074 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
34075 match self.config.dialect {
34076 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
34077 self.write_keyword("TO_DATE");
34079 self.write("(");
34080 self.generate_expression(&e.this)?;
34081 if let Some(format) = &e.format {
34082 self.write(", '");
34083 self.write(&Self::strftime_to_java_format(format));
34084 self.write("'");
34085 }
34086 self.write(")");
34087 }
34088 Some(DialectType::DuckDB) => {
34089 self.write_keyword("CAST");
34091 self.write("(");
34092 self.write_keyword("STRPTIME");
34093 self.write("(");
34094 self.generate_expression(&e.this)?;
34095 if let Some(format) = &e.format {
34096 self.write(", '");
34097 self.write(format);
34098 self.write("'");
34099 }
34100 self.write(")");
34101 self.write_keyword(" AS ");
34102 self.write_keyword("DATE");
34103 self.write(")");
34104 }
34105 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
34106 self.write_keyword("TO_DATE");
34108 self.write("(");
34109 self.generate_expression(&e.this)?;
34110 if let Some(format) = &e.format {
34111 self.write(", '");
34112 self.write(&Self::strftime_to_postgres_format(format));
34113 self.write("'");
34114 }
34115 self.write(")");
34116 }
34117 Some(DialectType::BigQuery) => {
34118 self.write_keyword("PARSE_DATE");
34120 self.write("(");
34121 if let Some(format) = &e.format {
34122 self.write("'");
34123 self.write(format);
34124 self.write("'");
34125 self.write(", ");
34126 }
34127 self.generate_expression(&e.this)?;
34128 self.write(")");
34129 }
34130 Some(DialectType::Teradata) => {
34131 self.write_keyword("CAST");
34133 self.write("(");
34134 self.generate_expression(&e.this)?;
34135 self.write_keyword(" AS ");
34136 self.write_keyword("DATE");
34137 if let Some(format) = &e.format {
34138 self.write_keyword(" FORMAT ");
34139 self.write("'");
34140 self.write(&Self::strftime_to_teradata_format(format));
34141 self.write("'");
34142 }
34143 self.write(")");
34144 }
34145 _ => {
34146 self.write_keyword("STR_TO_DATE");
34148 self.write("(");
34149 self.generate_expression(&e.this)?;
34150 if let Some(format) = &e.format {
34151 self.write(", '");
34152 self.write(format);
34153 self.write("'");
34154 }
34155 self.write(")");
34156 }
34157 }
34158 Ok(())
34159 }
34160
34161 fn strftime_to_teradata_format(fmt: &str) -> String {
34163 let mut result = String::with_capacity(fmt.len() * 2);
34164 let bytes = fmt.as_bytes();
34165 let len = bytes.len();
34166 let mut i = 0;
34167 while i < len {
34168 if bytes[i] == b'%' && i + 1 < len {
34169 let replacement = match bytes[i + 1] {
34170 b'Y' => "YYYY",
34171 b'y' => "YY",
34172 b'm' => "MM",
34173 b'B' => "MMMM",
34174 b'b' => "MMM",
34175 b'd' => "DD",
34176 b'j' => "DDD",
34177 b'H' => "HH",
34178 b'M' => "MI",
34179 b'S' => "SS",
34180 b'f' => "SSSSSS",
34181 b'A' => "EEEE",
34182 b'a' => "EEE",
34183 _ => {
34184 result.push('%');
34185 i += 1;
34186 continue;
34187 }
34188 };
34189 result.push_str(replacement);
34190 i += 2;
34191 } else {
34192 result.push(bytes[i] as char);
34193 i += 1;
34194 }
34195 }
34196 result
34197 }
34198
34199 pub fn strftime_to_java_format_static(fmt: &str) -> String {
34202 Self::strftime_to_java_format(fmt)
34203 }
34204
34205 fn strftime_to_java_format(fmt: &str) -> String {
34207 let mut result = String::with_capacity(fmt.len() * 2);
34208 let bytes = fmt.as_bytes();
34209 let len = bytes.len();
34210 let mut i = 0;
34211 while i < len {
34212 if bytes[i] == b'%' && i + 1 < len {
34213 if bytes[i + 1] == b'-' && i + 2 < len {
34215 let replacement = match bytes[i + 2] {
34216 b'd' => "d",
34217 b'm' => "M",
34218 b'H' => "H",
34219 b'M' => "m",
34220 b'S' => "s",
34221 _ => {
34222 result.push('%');
34223 i += 1;
34224 continue;
34225 }
34226 };
34227 result.push_str(replacement);
34228 i += 3;
34229 } else {
34230 let replacement = match bytes[i + 1] {
34231 b'Y' => "yyyy",
34232 b'y' => "yy",
34233 b'm' => "MM",
34234 b'B' => "MMMM",
34235 b'b' => "MMM",
34236 b'd' => "dd",
34237 b'j' => "DDD",
34238 b'H' => "HH",
34239 b'M' => "mm",
34240 b'S' => "ss",
34241 b'f' => "SSSSSS",
34242 b'A' => "EEEE",
34243 b'a' => "EEE",
34244 _ => {
34245 result.push('%');
34246 i += 1;
34247 continue;
34248 }
34249 };
34250 result.push_str(replacement);
34251 i += 2;
34252 }
34253 } else {
34254 result.push(bytes[i] as char);
34255 i += 1;
34256 }
34257 }
34258 result
34259 }
34260
34261 fn strftime_to_tsql_format(fmt: &str) -> String {
34264 let mut result = String::with_capacity(fmt.len() * 2);
34265 let bytes = fmt.as_bytes();
34266 let len = bytes.len();
34267 let mut i = 0;
34268 while i < len {
34269 if bytes[i] == b'%' && i + 1 < len {
34270 if bytes[i + 1] == b'-' && i + 2 < len {
34272 let replacement = match bytes[i + 2] {
34273 b'd' => "d",
34274 b'm' => "M",
34275 b'H' => "H",
34276 b'M' => "m",
34277 b'S' => "s",
34278 _ => {
34279 result.push('%');
34280 i += 1;
34281 continue;
34282 }
34283 };
34284 result.push_str(replacement);
34285 i += 3;
34286 } else {
34287 let replacement = match bytes[i + 1] {
34288 b'Y' => "yyyy",
34289 b'y' => "yy",
34290 b'm' => "MM",
34291 b'B' => "MMMM",
34292 b'b' => "MMM",
34293 b'd' => "dd",
34294 b'j' => "DDD",
34295 b'H' => "HH",
34296 b'M' => "mm",
34297 b'S' => "ss",
34298 b'f' => "ffffff",
34299 b'A' => "dddd",
34300 b'a' => "ddd",
34301 _ => {
34302 result.push('%');
34303 i += 1;
34304 continue;
34305 }
34306 };
34307 result.push_str(replacement);
34308 i += 2;
34309 }
34310 } else {
34311 result.push(bytes[i] as char);
34312 i += 1;
34313 }
34314 }
34315 result
34316 }
34317
34318 fn decompose_json_path(path: &str) -> Vec<String> {
34321 let mut parts = Vec::new();
34322 let path = if path.starts_with("$.") {
34324 &path[2..]
34325 } else if path.starts_with('$') {
34326 &path[1..]
34327 } else {
34328 path
34329 };
34330 if path.is_empty() {
34331 return parts;
34332 }
34333 let mut current = String::new();
34334 let chars: Vec<char> = path.chars().collect();
34335 let mut i = 0;
34336 while i < chars.len() {
34337 match chars[i] {
34338 '.' => {
34339 if !current.is_empty() {
34340 parts.push(current.clone());
34341 current.clear();
34342 }
34343 i += 1;
34344 }
34345 '[' => {
34346 if !current.is_empty() {
34347 parts.push(current.clone());
34348 current.clear();
34349 }
34350 i += 1;
34351 let mut bracket_content = String::new();
34353 while i < chars.len() && chars[i] != ']' {
34354 if chars[i] == '"' || chars[i] == '\'' {
34356 let quote = chars[i];
34357 i += 1;
34358 while i < chars.len() && chars[i] != quote {
34359 bracket_content.push(chars[i]);
34360 i += 1;
34361 }
34362 if i < chars.len() {
34363 i += 1;
34364 } } else {
34366 bracket_content.push(chars[i]);
34367 i += 1;
34368 }
34369 }
34370 if i < chars.len() {
34371 i += 1;
34372 } if bracket_content != "*" {
34375 parts.push(bracket_content);
34376 }
34377 }
34378 _ => {
34379 current.push(chars[i]);
34380 i += 1;
34381 }
34382 }
34383 }
34384 if !current.is_empty() {
34385 parts.push(current);
34386 }
34387 parts
34388 }
34389
34390 fn strftime_to_postgres_format(fmt: &str) -> String {
34392 let mut result = String::with_capacity(fmt.len() * 2);
34393 let bytes = fmt.as_bytes();
34394 let len = bytes.len();
34395 let mut i = 0;
34396 while i < len {
34397 if bytes[i] == b'%' && i + 1 < len {
34398 if bytes[i + 1] == b'-' && i + 2 < len {
34400 let replacement = match bytes[i + 2] {
34401 b'd' => "FMDD",
34402 b'm' => "FMMM",
34403 b'H' => "FMHH24",
34404 b'M' => "FMMI",
34405 b'S' => "FMSS",
34406 _ => {
34407 result.push('%');
34408 i += 1;
34409 continue;
34410 }
34411 };
34412 result.push_str(replacement);
34413 i += 3;
34414 } else {
34415 let replacement = match bytes[i + 1] {
34416 b'Y' => "YYYY",
34417 b'y' => "YY",
34418 b'm' => "MM",
34419 b'B' => "Month",
34420 b'b' => "Mon",
34421 b'd' => "DD",
34422 b'j' => "DDD",
34423 b'H' => "HH24",
34424 b'M' => "MI",
34425 b'S' => "SS",
34426 b'f' => "US",
34427 b'A' => "Day",
34428 b'a' => "Dy",
34429 _ => {
34430 result.push('%');
34431 i += 1;
34432 continue;
34433 }
34434 };
34435 result.push_str(replacement);
34436 i += 2;
34437 }
34438 } else {
34439 result.push(bytes[i] as char);
34440 i += 1;
34441 }
34442 }
34443 result
34444 }
34445
34446 fn strftime_to_snowflake_format(fmt: &str) -> String {
34448 let mut result = String::with_capacity(fmt.len() * 2);
34449 let bytes = fmt.as_bytes();
34450 let len = bytes.len();
34451 let mut i = 0;
34452 while i < len {
34453 if bytes[i] == b'%' && i + 1 < len {
34454 if bytes[i + 1] == b'-' && i + 2 < len {
34456 let replacement = match bytes[i + 2] {
34457 b'd' => "dd",
34458 b'm' => "mm",
34459 _ => {
34460 result.push('%');
34461 i += 1;
34462 continue;
34463 }
34464 };
34465 result.push_str(replacement);
34466 i += 3;
34467 } else {
34468 let replacement = match bytes[i + 1] {
34469 b'Y' => "yyyy",
34470 b'y' => "yy",
34471 b'm' => "mm",
34472 b'd' => "DD",
34473 b'H' => "hh24",
34474 b'M' => "mi",
34475 b'S' => "ss",
34476 b'f' => "ff",
34477 _ => {
34478 result.push('%');
34479 i += 1;
34480 continue;
34481 }
34482 };
34483 result.push_str(replacement);
34484 i += 2;
34485 }
34486 } else {
34487 result.push(bytes[i] as char);
34488 i += 1;
34489 }
34490 }
34491 result
34492 }
34493
34494 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
34495 self.write_keyword("STR_TO_MAP");
34497 self.write("(");
34498 self.generate_expression(&e.this)?;
34499 let needs_defaults = matches!(
34501 self.config.dialect,
34502 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
34503 );
34504 if let Some(pair_delim) = &e.pair_delim {
34505 self.write(", ");
34506 self.generate_expression(pair_delim)?;
34507 } else if needs_defaults {
34508 self.write(", ','");
34509 }
34510 if let Some(key_value_delim) = &e.key_value_delim {
34511 self.write(", ");
34512 self.generate_expression(key_value_delim)?;
34513 } else if needs_defaults {
34514 self.write(", ':'");
34515 }
34516 self.write(")");
34517 Ok(())
34518 }
34519
34520 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
34521 let is_strftime = e.format.contains('%');
34523 let to_strftime = |f: &str| -> String {
34525 if is_strftime {
34526 f.to_string()
34527 } else {
34528 Self::snowflake_format_to_strftime(f)
34529 }
34530 };
34531 let to_java = |f: &str| -> String {
34533 if is_strftime {
34534 Self::strftime_to_java_format(f)
34535 } else {
34536 Self::snowflake_format_to_spark(f)
34537 }
34538 };
34539 let to_pg = |f: &str| -> String {
34541 if is_strftime {
34542 Self::strftime_to_postgres_format(f)
34543 } else {
34544 Self::convert_strptime_to_postgres_format(f)
34545 }
34546 };
34547
34548 match self.config.dialect {
34549 Some(DialectType::Exasol) => {
34550 self.write_keyword("TO_DATE");
34551 self.write("(");
34552 self.generate_expression(&e.this)?;
34553 self.write(", '");
34554 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
34555 self.write("'");
34556 self.write(")");
34557 }
34558 Some(DialectType::BigQuery) => {
34559 let fmt = to_strftime(&e.format);
34561 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
34563 self.write_keyword("PARSE_TIMESTAMP");
34564 self.write("('");
34565 self.write(&fmt);
34566 self.write("', ");
34567 self.generate_expression(&e.this)?;
34568 self.write(")");
34569 }
34570 Some(DialectType::Hive) => {
34571 let java_fmt = to_java(&e.format);
34574 if java_fmt == "yyyy-MM-dd HH:mm:ss"
34575 || java_fmt == "yyyy-MM-dd"
34576 || e.format == "yyyy-MM-dd HH:mm:ss"
34577 || e.format == "yyyy-MM-dd"
34578 {
34579 self.write_keyword("CAST");
34580 self.write("(");
34581 self.generate_expression(&e.this)?;
34582 self.write(" ");
34583 self.write_keyword("AS TIMESTAMP");
34584 self.write(")");
34585 } else {
34586 self.write_keyword("CAST");
34588 self.write("(");
34589 self.write_keyword("FROM_UNIXTIME");
34590 self.write("(");
34591 self.write_keyword("UNIX_TIMESTAMP");
34592 self.write("(");
34593 self.generate_expression(&e.this)?;
34594 self.write(", '");
34595 self.write(&java_fmt);
34596 self.write("')");
34597 self.write(") ");
34598 self.write_keyword("AS TIMESTAMP");
34599 self.write(")");
34600 }
34601 }
34602 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34603 let java_fmt = to_java(&e.format);
34605 self.write_keyword("TO_TIMESTAMP");
34606 self.write("(");
34607 self.generate_expression(&e.this)?;
34608 self.write(", '");
34609 self.write(&java_fmt);
34610 self.write("')");
34611 }
34612 Some(DialectType::MySQL) => {
34613 let mut fmt = to_strftime(&e.format);
34615 fmt = fmt.replace("%-d", "%e");
34617 fmt = fmt.replace("%-m", "%c");
34618 fmt = fmt.replace("%H:%M:%S", "%T");
34619 self.write_keyword("STR_TO_DATE");
34620 self.write("(");
34621 self.generate_expression(&e.this)?;
34622 self.write(", '");
34623 self.write(&fmt);
34624 self.write("')");
34625 }
34626 Some(DialectType::Drill) => {
34627 let java_fmt = to_java(&e.format);
34629 let java_fmt = java_fmt.replace('T', "''T''");
34631 self.write_keyword("TO_TIMESTAMP");
34632 self.write("(");
34633 self.generate_expression(&e.this)?;
34634 self.write(", '");
34635 self.write(&java_fmt);
34636 self.write("')");
34637 }
34638 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
34639 let mut fmt = to_strftime(&e.format);
34641 fmt = fmt.replace("%-d", "%e");
34643 fmt = fmt.replace("%-m", "%c");
34644 fmt = fmt.replace("%H:%M:%S", "%T");
34645 self.write_keyword("DATE_PARSE");
34646 self.write("(");
34647 self.generate_expression(&e.this)?;
34648 self.write(", '");
34649 self.write(&fmt);
34650 self.write("')");
34651 }
34652 Some(DialectType::DuckDB) => {
34653 let fmt = to_strftime(&e.format);
34655 self.write_keyword("STRPTIME");
34656 self.write("(");
34657 self.generate_expression(&e.this)?;
34658 self.write(", '");
34659 self.write(&fmt);
34660 self.write("')");
34661 }
34662 Some(DialectType::PostgreSQL)
34663 | Some(DialectType::Redshift)
34664 | Some(DialectType::Materialize) => {
34665 let pg_fmt = to_pg(&e.format);
34667 self.write_keyword("TO_TIMESTAMP");
34668 self.write("(");
34669 self.generate_expression(&e.this)?;
34670 self.write(", '");
34671 self.write(&pg_fmt);
34672 self.write("')");
34673 }
34674 Some(DialectType::Oracle) => {
34675 let pg_fmt = to_pg(&e.format);
34677 self.write_keyword("TO_TIMESTAMP");
34678 self.write("(");
34679 self.generate_expression(&e.this)?;
34680 self.write(", '");
34681 self.write(&pg_fmt);
34682 self.write("')");
34683 }
34684 Some(DialectType::Snowflake) => {
34685 self.write_keyword("TO_TIMESTAMP");
34687 self.write("(");
34688 self.generate_expression(&e.this)?;
34689 self.write(", '");
34690 self.write(&e.format);
34691 self.write("')");
34692 }
34693 _ => {
34694 self.write_keyword("STR_TO_TIME");
34696 self.write("(");
34697 self.generate_expression(&e.this)?;
34698 self.write(", '");
34699 self.write(&e.format);
34700 self.write("'");
34701 self.write(")");
34702 }
34703 }
34704 Ok(())
34705 }
34706
34707 fn snowflake_format_to_strftime(format: &str) -> String {
34709 let mut result = String::new();
34710 let chars: Vec<char> = format.chars().collect();
34711 let mut i = 0;
34712 while i < chars.len() {
34713 let remaining = &format[i..];
34714 if remaining.starts_with("yyyy") {
34715 result.push_str("%Y");
34716 i += 4;
34717 } else if remaining.starts_with("yy") {
34718 result.push_str("%y");
34719 i += 2;
34720 } else if remaining.starts_with("mmmm") {
34721 result.push_str("%B"); i += 4;
34723 } else if remaining.starts_with("mon") {
34724 result.push_str("%b"); i += 3;
34726 } else if remaining.starts_with("mm") {
34727 result.push_str("%m");
34728 i += 2;
34729 } else if remaining.starts_with("DD") {
34730 result.push_str("%d");
34731 i += 2;
34732 } else if remaining.starts_with("dy") {
34733 result.push_str("%a"); i += 2;
34735 } else if remaining.starts_with("hh24") {
34736 result.push_str("%H");
34737 i += 4;
34738 } else if remaining.starts_with("hh12") {
34739 result.push_str("%I");
34740 i += 4;
34741 } else if remaining.starts_with("hh") {
34742 result.push_str("%H");
34743 i += 2;
34744 } else if remaining.starts_with("mi") {
34745 result.push_str("%M");
34746 i += 2;
34747 } else if remaining.starts_with("ss") {
34748 result.push_str("%S");
34749 i += 2;
34750 } else if remaining.starts_with("ff") {
34751 result.push_str("%f");
34753 i += 2;
34754 while i < chars.len() && chars[i].is_ascii_digit() {
34756 i += 1;
34757 }
34758 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
34759 result.push_str("%p");
34760 i += 2;
34761 } else if remaining.starts_with("tz") {
34762 result.push_str("%Z");
34763 i += 2;
34764 } else {
34765 result.push(chars[i]);
34766 i += 1;
34767 }
34768 }
34769 result
34770 }
34771
34772 fn snowflake_format_to_spark(format: &str) -> String {
34774 let mut result = String::new();
34775 let chars: Vec<char> = format.chars().collect();
34776 let mut i = 0;
34777 while i < chars.len() {
34778 let remaining = &format[i..];
34779 if remaining.starts_with("yyyy") {
34780 result.push_str("yyyy");
34781 i += 4;
34782 } else if remaining.starts_with("yy") {
34783 result.push_str("yy");
34784 i += 2;
34785 } else if remaining.starts_with("mmmm") {
34786 result.push_str("MMMM"); i += 4;
34788 } else if remaining.starts_with("mon") {
34789 result.push_str("MMM"); i += 3;
34791 } else if remaining.starts_with("mm") {
34792 result.push_str("MM");
34793 i += 2;
34794 } else if remaining.starts_with("DD") {
34795 result.push_str("dd");
34796 i += 2;
34797 } else if remaining.starts_with("dy") {
34798 result.push_str("EEE"); i += 2;
34800 } else if remaining.starts_with("hh24") {
34801 result.push_str("HH");
34802 i += 4;
34803 } else if remaining.starts_with("hh12") {
34804 result.push_str("hh");
34805 i += 4;
34806 } else if remaining.starts_with("hh") {
34807 result.push_str("HH");
34808 i += 2;
34809 } else if remaining.starts_with("mi") {
34810 result.push_str("mm");
34811 i += 2;
34812 } else if remaining.starts_with("ss") {
34813 result.push_str("ss");
34814 i += 2;
34815 } else if remaining.starts_with("ff") {
34816 result.push_str("SSS"); i += 2;
34818 while i < chars.len() && chars[i].is_ascii_digit() {
34820 i += 1;
34821 }
34822 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
34823 result.push_str("a");
34824 i += 2;
34825 } else if remaining.starts_with("tz") {
34826 result.push_str("z");
34827 i += 2;
34828 } else {
34829 result.push(chars[i]);
34830 i += 1;
34831 }
34832 }
34833 result
34834 }
34835
34836 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
34837 match self.config.dialect {
34838 Some(DialectType::DuckDB) => {
34839 self.write_keyword("EPOCH");
34841 self.write("(");
34842 self.write_keyword("STRPTIME");
34843 self.write("(");
34844 if let Some(this) = &e.this {
34845 self.generate_expression(this)?;
34846 }
34847 if let Some(format) = &e.format {
34848 self.write(", '");
34849 self.write(format);
34850 self.write("'");
34851 }
34852 self.write("))");
34853 }
34854 Some(DialectType::Hive) => {
34855 self.write_keyword("UNIX_TIMESTAMP");
34857 self.write("(");
34858 if let Some(this) = &e.this {
34859 self.generate_expression(this)?;
34860 }
34861 if let Some(format) = &e.format {
34862 let java_fmt = Self::strftime_to_java_format(format);
34863 if java_fmt != "yyyy-MM-dd HH:mm:ss" {
34864 self.write(", '");
34865 self.write(&java_fmt);
34866 self.write("'");
34867 }
34868 }
34869 self.write(")");
34870 }
34871 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
34872 self.write_keyword("UNIX_TIMESTAMP");
34874 self.write("(");
34875 if let Some(this) = &e.this {
34876 self.generate_expression(this)?;
34877 }
34878 if let Some(format) = &e.format {
34879 self.write(", '");
34880 self.write(format);
34881 self.write("'");
34882 }
34883 self.write(")");
34884 }
34885 Some(DialectType::Presto) | Some(DialectType::Trino) => {
34886 let c_fmt = e.format.as_deref().unwrap_or("%Y-%m-%d %T");
34889 let java_fmt = Self::strftime_to_java_format(c_fmt);
34890 self.write_keyword("TO_UNIXTIME");
34891 self.write("(");
34892 self.write_keyword("COALESCE");
34893 self.write("(");
34894 self.write_keyword("TRY");
34895 self.write("(");
34896 self.write_keyword("DATE_PARSE");
34897 self.write("(");
34898 self.write_keyword("CAST");
34899 self.write("(");
34900 if let Some(this) = &e.this {
34901 self.generate_expression(this)?;
34902 }
34903 self.write(" ");
34904 self.write_keyword("AS VARCHAR");
34905 self.write("), '");
34906 self.write(c_fmt);
34907 self.write("')), ");
34908 self.write_keyword("PARSE_DATETIME");
34909 self.write("(");
34910 self.write_keyword("DATE_FORMAT");
34911 self.write("(");
34912 self.write_keyword("CAST");
34913 self.write("(");
34914 if let Some(this) = &e.this {
34915 self.generate_expression(this)?;
34916 }
34917 self.write(" ");
34918 self.write_keyword("AS TIMESTAMP");
34919 self.write("), '");
34920 self.write(c_fmt);
34921 self.write("'), '");
34922 self.write(&java_fmt);
34923 self.write("')))");
34924 }
34925 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
34926 self.write_keyword("UNIX_TIMESTAMP");
34928 self.write("(");
34929 if let Some(this) = &e.this {
34930 self.generate_expression(this)?;
34931 }
34932 if let Some(format) = &e.format {
34933 let java_fmt = Self::strftime_to_java_format(format);
34934 self.write(", '");
34935 self.write(&java_fmt);
34936 self.write("'");
34937 }
34938 self.write(")");
34939 }
34940 _ => {
34941 self.write_keyword("STR_TO_UNIX");
34943 self.write("(");
34944 if let Some(this) = &e.this {
34945 self.generate_expression(this)?;
34946 }
34947 if let Some(format) = &e.format {
34948 self.write(", '");
34949 self.write(format);
34950 self.write("'");
34951 }
34952 self.write(")");
34953 }
34954 }
34955 Ok(())
34956 }
34957
34958 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
34959 self.write_keyword("STRING_TO_ARRAY");
34961 self.write("(");
34962 self.generate_expression(&e.this)?;
34963 if let Some(expression) = &e.expression {
34964 self.write(", ");
34965 self.generate_expression(expression)?;
34966 }
34967 if let Some(null_val) = &e.null {
34968 self.write(", ");
34969 self.generate_expression(null_val)?;
34970 }
34971 self.write(")");
34972 Ok(())
34973 }
34974
34975 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
34976 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
34977 self.write_keyword("OBJECT_CONSTRUCT");
34979 self.write("(");
34980 for (i, (name, expr)) in e.fields.iter().enumerate() {
34981 if i > 0 {
34982 self.write(", ");
34983 }
34984 if let Some(name) = name {
34985 self.write("'");
34986 self.write(name);
34987 self.write("'");
34988 self.write(", ");
34989 } else {
34990 self.write("'_");
34991 self.write(&i.to_string());
34992 self.write("'");
34993 self.write(", ");
34994 }
34995 self.generate_expression(expr)?;
34996 }
34997 self.write(")");
34998 } else if self.config.struct_curly_brace_notation {
34999 self.write("{");
35001 for (i, (name, expr)) in e.fields.iter().enumerate() {
35002 if i > 0 {
35003 self.write(", ");
35004 }
35005 if let Some(name) = name {
35006 self.write("'");
35008 self.write(name);
35009 self.write("'");
35010 self.write(": ");
35011 } else {
35012 self.write("'_");
35014 self.write(&i.to_string());
35015 self.write("'");
35016 self.write(": ");
35017 }
35018 self.generate_expression(expr)?;
35019 }
35020 self.write("}");
35021 } else {
35022 let value_as_name = matches!(
35026 self.config.dialect,
35027 Some(DialectType::BigQuery)
35028 | Some(DialectType::Spark)
35029 | Some(DialectType::Databricks)
35030 | Some(DialectType::Hive)
35031 );
35032 self.write_keyword("STRUCT");
35033 self.write("(");
35034 for (i, (name, expr)) in e.fields.iter().enumerate() {
35035 if i > 0 {
35036 self.write(", ");
35037 }
35038 if let Some(name) = name {
35039 if value_as_name {
35040 self.generate_expression(expr)?;
35042 self.write_space();
35043 self.write_keyword("AS");
35044 self.write_space();
35045 let needs_quoting = name.contains(' ') || name.contains('-');
35047 if needs_quoting {
35048 if matches!(
35049 self.config.dialect,
35050 Some(DialectType::Spark)
35051 | Some(DialectType::Databricks)
35052 | Some(DialectType::Hive)
35053 ) {
35054 self.write("`");
35055 self.write(name);
35056 self.write("`");
35057 } else {
35058 self.write(name);
35059 }
35060 } else {
35061 self.write(name);
35062 }
35063 } else {
35064 self.write(name);
35066 self.write_space();
35067 self.write_keyword("AS");
35068 self.write_space();
35069 self.generate_expression(expr)?;
35070 }
35071 } else {
35072 self.generate_expression(expr)?;
35073 }
35074 }
35075 self.write(")");
35076 }
35077 Ok(())
35078 }
35079
35080 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
35081 self.write_keyword("STUFF");
35083 self.write("(");
35084 self.generate_expression(&e.this)?;
35085 if let Some(start) = &e.start {
35086 self.write(", ");
35087 self.generate_expression(start)?;
35088 }
35089 if let Some(length) = e.length {
35090 self.write(", ");
35091 self.write(&length.to_string());
35092 }
35093 self.write(", ");
35094 self.generate_expression(&e.expression)?;
35095 self.write(")");
35096 Ok(())
35097 }
35098
35099 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
35100 self.write_keyword("SUBSTRING_INDEX");
35102 self.write("(");
35103 self.generate_expression(&e.this)?;
35104 if let Some(delimiter) = &e.delimiter {
35105 self.write(", ");
35106 self.generate_expression(delimiter)?;
35107 }
35108 if let Some(count) = &e.count {
35109 self.write(", ");
35110 self.generate_expression(count)?;
35111 }
35112 self.write(")");
35113 Ok(())
35114 }
35115
35116 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
35117 self.write_keyword("SUMMARIZE");
35119 if e.table.is_some() {
35120 self.write_space();
35121 self.write_keyword("TABLE");
35122 }
35123 self.write_space();
35124 self.generate_expression(&e.this)?;
35125 Ok(())
35126 }
35127
35128 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
35129 self.write_keyword("SYSTIMESTAMP");
35131 Ok(())
35132 }
35133
35134 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
35135 if let Some(this) = &e.this {
35137 self.generate_expression(this)?;
35138 }
35139 if !e.columns.is_empty() {
35140 self.write("(");
35141 for (i, col) in e.columns.iter().enumerate() {
35142 if i > 0 {
35143 self.write(", ");
35144 }
35145 self.generate_expression(col)?;
35146 }
35147 self.write(")");
35148 }
35149 Ok(())
35150 }
35151
35152 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
35153 self.write_keyword("TABLE");
35155 self.write("(");
35156 self.generate_expression(&e.this)?;
35157 self.write(")");
35158 if let Some(alias) = &e.alias {
35159 self.write_space();
35160 self.write_keyword("AS");
35161 self.write_space();
35162 self.write(alias);
35163 }
35164 Ok(())
35165 }
35166
35167 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
35168 self.write_keyword("ROWS FROM");
35170 self.write(" (");
35171 for (i, expr) in e.expressions.iter().enumerate() {
35172 if i > 0 {
35173 self.write(", ");
35174 }
35175 match expr {
35179 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
35180 self.generate_expression(&tuple.expressions[0])?;
35182 self.write_space();
35183 self.write_keyword("AS");
35184 self.write_space();
35185 self.generate_expression(&tuple.expressions[1])?;
35186 }
35187 _ => {
35188 self.generate_expression(expr)?;
35189 }
35190 }
35191 }
35192 self.write(")");
35193 if e.ordinality {
35194 self.write_space();
35195 self.write_keyword("WITH ORDINALITY");
35196 }
35197 if let Some(alias) = &e.alias {
35198 self.write_space();
35199 self.write_keyword("AS");
35200 self.write_space();
35201 self.generate_expression(alias)?;
35202 }
35203 Ok(())
35204 }
35205
35206 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
35207 use crate::dialects::DialectType;
35208
35209 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
35211 if self.config.alias_post_tablesample {
35213 if let Expression::Subquery(ref s) = **this {
35215 if let Some(ref alias) = s.alias {
35216 let mut subquery_no_alias = (**s).clone();
35218 subquery_no_alias.alias = None;
35219 subquery_no_alias.column_aliases = Vec::new();
35220 self.generate_expression(&Expression::Subquery(Box::new(
35221 subquery_no_alias,
35222 )))?;
35223 self.write_space();
35224 self.write_keyword("TABLESAMPLE");
35225 self.generate_sample_body(sample)?;
35226 if let Some(ref seed) = sample.seed {
35227 self.write_space();
35228 let use_seed = sample.use_seed_keyword
35229 && !matches!(
35230 self.config.dialect,
35231 Some(crate::dialects::DialectType::Databricks)
35232 | Some(crate::dialects::DialectType::Spark)
35233 );
35234 if use_seed {
35235 self.write_keyword("SEED");
35236 } else {
35237 self.write_keyword("REPEATABLE");
35238 }
35239 self.write(" (");
35240 self.generate_expression(seed)?;
35241 self.write(")");
35242 }
35243 self.write_space();
35244 self.write_keyword("AS");
35245 self.write_space();
35246 self.generate_identifier(alias)?;
35247 return Ok(());
35248 }
35249 } else if let Expression::Alias(ref a) = **this {
35250 self.generate_expression(&a.this)?;
35252 self.write_space();
35253 self.write_keyword("TABLESAMPLE");
35254 self.generate_sample_body(sample)?;
35255 if let Some(ref seed) = sample.seed {
35256 self.write_space();
35257 let use_seed = sample.use_seed_keyword
35258 && !matches!(
35259 self.config.dialect,
35260 Some(crate::dialects::DialectType::Databricks)
35261 | Some(crate::dialects::DialectType::Spark)
35262 );
35263 if use_seed {
35264 self.write_keyword("SEED");
35265 } else {
35266 self.write_keyword("REPEATABLE");
35267 }
35268 self.write(" (");
35269 self.generate_expression(seed)?;
35270 self.write(")");
35271 }
35272 self.write_space();
35274 self.write_keyword("AS");
35275 self.write_space();
35276 self.generate_identifier(&a.alias)?;
35277 return Ok(());
35278 }
35279 }
35280 self.generate_expression(this)?;
35282 self.write_space();
35283 self.write_keyword("TABLESAMPLE");
35284 self.generate_sample_body(sample)?;
35285 if let Some(ref seed) = sample.seed {
35287 self.write_space();
35288 let use_seed = sample.use_seed_keyword
35290 && !matches!(
35291 self.config.dialect,
35292 Some(crate::dialects::DialectType::Databricks)
35293 | Some(crate::dialects::DialectType::Spark)
35294 );
35295 if use_seed {
35296 self.write_keyword("SEED");
35297 } else {
35298 self.write_keyword("REPEATABLE");
35299 }
35300 self.write(" (");
35301 self.generate_expression(seed)?;
35302 self.write(")");
35303 }
35304 return Ok(());
35305 }
35306
35307 self.write_keyword("TABLESAMPLE");
35309 if let Some(method) = &e.method {
35310 self.write_space();
35311 self.write_keyword(method);
35312 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
35313 self.write_space();
35315 self.write_keyword("BERNOULLI");
35316 }
35317 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
35318 self.write_space();
35319 self.write_keyword("BUCKET");
35320 self.write_space();
35321 self.generate_expression(numerator)?;
35322 self.write_space();
35323 self.write_keyword("OUT OF");
35324 self.write_space();
35325 self.generate_expression(denominator)?;
35326 if let Some(field) = &e.bucket_field {
35327 self.write_space();
35328 self.write_keyword("ON");
35329 self.write_space();
35330 self.generate_expression(field)?;
35331 }
35332 } else if !e.expressions.is_empty() {
35333 self.write(" (");
35334 for (i, expr) in e.expressions.iter().enumerate() {
35335 if i > 0 {
35336 self.write(", ");
35337 }
35338 self.generate_expression(expr)?;
35339 }
35340 self.write(")");
35341 } else if let Some(percent) = &e.percent {
35342 self.write(" (");
35343 self.generate_expression(percent)?;
35344 self.write_space();
35345 self.write_keyword("PERCENT");
35346 self.write(")");
35347 }
35348 Ok(())
35349 }
35350
35351 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
35352 if let Some(prefix) = &e.prefix {
35354 self.generate_expression(prefix)?;
35355 }
35356 if let Some(this) = &e.this {
35357 self.generate_expression(this)?;
35358 }
35359 if let Some(postfix) = &e.postfix {
35360 self.generate_expression(postfix)?;
35361 }
35362 Ok(())
35363 }
35364
35365 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
35366 self.write_keyword("TAG");
35368 self.write(" (");
35369 for (i, expr) in e.expressions.iter().enumerate() {
35370 if i > 0 {
35371 self.write(", ");
35372 }
35373 self.generate_expression(expr)?;
35374 }
35375 self.write(")");
35376 Ok(())
35377 }
35378
35379 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
35380 if let Some(this) = &e.this {
35382 self.generate_expression(this)?;
35383 self.write_space();
35384 }
35385 self.write_keyword("TEMPORARY");
35386 Ok(())
35387 }
35388
35389 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
35392 self.write_keyword("TIME");
35394 self.write("(");
35395 self.generate_expression(&e.this)?;
35396 self.write(")");
35397 Ok(())
35398 }
35399
35400 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
35401 self.write_keyword("TIME_ADD");
35403 self.write("(");
35404 self.generate_expression(&e.this)?;
35405 self.write(", ");
35406 self.generate_expression(&e.expression)?;
35407 if let Some(unit) = &e.unit {
35408 self.write(", ");
35409 self.write_keyword(unit);
35410 }
35411 self.write(")");
35412 Ok(())
35413 }
35414
35415 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
35416 self.write_keyword("TIME_DIFF");
35418 self.write("(");
35419 self.generate_expression(&e.this)?;
35420 self.write(", ");
35421 self.generate_expression(&e.expression)?;
35422 if let Some(unit) = &e.unit {
35423 self.write(", ");
35424 self.write_keyword(unit);
35425 }
35426 self.write(")");
35427 Ok(())
35428 }
35429
35430 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
35431 self.write_keyword("TIME_FROM_PARTS");
35433 self.write("(");
35434 let mut first = true;
35435 if let Some(hour) = &e.hour {
35436 self.generate_expression(hour)?;
35437 first = false;
35438 }
35439 if let Some(minute) = &e.min {
35440 if !first {
35441 self.write(", ");
35442 }
35443 self.generate_expression(minute)?;
35444 first = false;
35445 }
35446 if let Some(second) = &e.sec {
35447 if !first {
35448 self.write(", ");
35449 }
35450 self.generate_expression(second)?;
35451 first = false;
35452 }
35453 if let Some(ns) = &e.nano {
35454 if !first {
35455 self.write(", ");
35456 }
35457 self.generate_expression(ns)?;
35458 }
35459 self.write(")");
35460 Ok(())
35461 }
35462
35463 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
35464 self.write_keyword("TIME_SLICE");
35466 self.write("(");
35467 self.generate_expression(&e.this)?;
35468 self.write(", ");
35469 self.generate_expression(&e.expression)?;
35470 self.write(", ");
35471 self.write_keyword(&e.unit);
35472 self.write(")");
35473 Ok(())
35474 }
35475
35476 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
35477 self.write_keyword("TIME_STR_TO_TIME");
35479 self.write("(");
35480 self.generate_expression(&e.this)?;
35481 self.write(")");
35482 Ok(())
35483 }
35484
35485 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
35486 self.write_keyword("TIME_SUB");
35488 self.write("(");
35489 self.generate_expression(&e.this)?;
35490 self.write(", ");
35491 self.generate_expression(&e.expression)?;
35492 if let Some(unit) = &e.unit {
35493 self.write(", ");
35494 self.write_keyword(unit);
35495 }
35496 self.write(")");
35497 Ok(())
35498 }
35499
35500 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
35501 match self.config.dialect {
35502 Some(DialectType::Exasol) => {
35503 self.write_keyword("TO_CHAR");
35505 self.write("(");
35506 self.generate_expression(&e.this)?;
35507 self.write(", '");
35508 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
35509 self.write("'");
35510 self.write(")");
35511 }
35512 Some(DialectType::PostgreSQL)
35513 | Some(DialectType::Redshift)
35514 | Some(DialectType::Materialize) => {
35515 self.write_keyword("TO_CHAR");
35517 self.write("(");
35518 self.generate_expression(&e.this)?;
35519 self.write(", '");
35520 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
35521 self.write("'");
35522 self.write(")");
35523 }
35524 Some(DialectType::Oracle) => {
35525 self.write_keyword("TO_CHAR");
35527 self.write("(");
35528 self.generate_expression(&e.this)?;
35529 self.write(", '");
35530 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
35531 self.write("'");
35532 self.write(")");
35533 }
35534 Some(DialectType::Drill) => {
35535 self.write_keyword("TO_CHAR");
35537 self.write("(");
35538 self.generate_expression(&e.this)?;
35539 self.write(", '");
35540 self.write(&Self::strftime_to_java_format(&e.format));
35541 self.write("'");
35542 self.write(")");
35543 }
35544 Some(DialectType::TSQL) | Some(DialectType::Fabric) => {
35545 self.write_keyword("FORMAT");
35547 self.write("(");
35548 self.generate_expression(&e.this)?;
35549 self.write(", '");
35550 self.write(&Self::strftime_to_tsql_format(&e.format));
35551 self.write("'");
35552 self.write(")");
35553 }
35554 Some(DialectType::DuckDB) => {
35555 self.write_keyword("STRFTIME");
35557 self.write("(");
35558 self.generate_expression(&e.this)?;
35559 self.write(", '");
35560 self.write(&e.format);
35561 self.write("'");
35562 self.write(")");
35563 }
35564 Some(DialectType::BigQuery) => {
35565 let fmt = e.format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
35568 self.write_keyword("FORMAT_DATE");
35569 self.write("('");
35570 self.write(&fmt);
35571 self.write("', ");
35572 self.generate_expression(&e.this)?;
35573 self.write(")");
35574 }
35575 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) => {
35576 self.write_keyword("DATE_FORMAT");
35578 self.write("(");
35579 self.generate_expression(&e.this)?;
35580 self.write(", '");
35581 self.write(&Self::strftime_to_java_format(&e.format));
35582 self.write("'");
35583 self.write(")");
35584 }
35585 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
35586 self.write_keyword("DATE_FORMAT");
35588 self.write("(");
35589 self.generate_expression(&e.this)?;
35590 self.write(", '");
35591 self.write(&e.format);
35592 self.write("'");
35593 self.write(")");
35594 }
35595 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
35596 self.write_keyword("DATE_FORMAT");
35598 self.write("(");
35599 self.generate_expression(&e.this)?;
35600 self.write(", '");
35601 self.write(&e.format);
35602 self.write("'");
35603 self.write(")");
35604 }
35605 _ => {
35606 self.write_keyword("TIME_TO_STR");
35608 self.write("(");
35609 self.generate_expression(&e.this)?;
35610 self.write(", '");
35611 self.write(&e.format);
35612 self.write("'");
35613 self.write(")");
35614 }
35615 }
35616 Ok(())
35617 }
35618
35619 fn generate_time_to_unix(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
35620 match self.config.dialect {
35621 Some(DialectType::DuckDB) => {
35622 self.write_keyword("EPOCH");
35624 self.write("(");
35625 self.generate_expression(&e.this)?;
35626 self.write(")");
35627 }
35628 Some(DialectType::Hive)
35629 | Some(DialectType::Spark)
35630 | Some(DialectType::Databricks)
35631 | Some(DialectType::Doris)
35632 | Some(DialectType::StarRocks)
35633 | Some(DialectType::Drill) => {
35634 self.write_keyword("UNIX_TIMESTAMP");
35636 self.write("(");
35637 self.generate_expression(&e.this)?;
35638 self.write(")");
35639 }
35640 Some(DialectType::Presto) | Some(DialectType::Trino) => {
35641 self.write_keyword("TO_UNIXTIME");
35643 self.write("(");
35644 self.generate_expression(&e.this)?;
35645 self.write(")");
35646 }
35647 _ => {
35648 self.write_keyword("TIME_TO_UNIX");
35650 self.write("(");
35651 self.generate_expression(&e.this)?;
35652 self.write(")");
35653 }
35654 }
35655 Ok(())
35656 }
35657
35658 fn generate_time_str_to_date(&mut self, e: &crate::expressions::UnaryFunc) -> Result<()> {
35659 match self.config.dialect {
35660 Some(DialectType::Hive) => {
35661 self.write_keyword("TO_DATE");
35663 self.write("(");
35664 self.generate_expression(&e.this)?;
35665 self.write(")");
35666 }
35667 _ => {
35668 self.write_keyword("TIME_STR_TO_DATE");
35670 self.write("(");
35671 self.generate_expression(&e.this)?;
35672 self.write(")");
35673 }
35674 }
35675 Ok(())
35676 }
35677
35678 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
35679 self.write_keyword("TIME_TRUNC");
35681 self.write("(");
35682 self.generate_expression(&e.this)?;
35683 self.write(", ");
35684 self.write_keyword(&e.unit);
35685 self.write(")");
35686 Ok(())
35687 }
35688
35689 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
35690 if let Some(unit) = &e.unit {
35692 self.write_keyword(unit);
35693 }
35694 Ok(())
35695 }
35696
35697 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
35701 use crate::dialects::DialectType;
35702 use crate::expressions::Literal;
35703
35704 match self.config.dialect {
35705 Some(DialectType::Exasol) => {
35707 self.write_keyword("TO_TIMESTAMP");
35708 self.write("(");
35709 if let Some(this) = &e.this {
35711 match this.as_ref() {
35712 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
35713 let Literal::String(s) = lit.as_ref() else {
35714 unreachable!()
35715 };
35716 self.write("'");
35717 self.write(s);
35718 self.write("'");
35719 }
35720 _ => {
35721 self.generate_expression(this)?;
35722 }
35723 }
35724 }
35725 self.write(")");
35726 }
35727 _ => {
35729 self.write_keyword("TIMESTAMP");
35730 self.write("(");
35731 if let Some(this) = &e.this {
35732 self.generate_expression(this)?;
35733 }
35734 if let Some(zone) = &e.zone {
35735 self.write(", ");
35736 self.generate_expression(zone)?;
35737 }
35738 self.write(")");
35739 }
35740 }
35741 Ok(())
35742 }
35743
35744 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
35745 self.write_keyword("TIMESTAMP_ADD");
35747 self.write("(");
35748 self.generate_expression(&e.this)?;
35749 self.write(", ");
35750 self.generate_expression(&e.expression)?;
35751 if let Some(unit) = &e.unit {
35752 self.write(", ");
35753 self.write_keyword(unit);
35754 }
35755 self.write(")");
35756 Ok(())
35757 }
35758
35759 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
35760 self.write_keyword("TIMESTAMP_DIFF");
35762 self.write("(");
35763 self.generate_expression(&e.this)?;
35764 self.write(", ");
35765 self.generate_expression(&e.expression)?;
35766 if let Some(unit) = &e.unit {
35767 self.write(", ");
35768 self.write_keyword(unit);
35769 }
35770 self.write(")");
35771 Ok(())
35772 }
35773
35774 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
35775 self.write_keyword("TIMESTAMP_FROM_PARTS");
35777 self.write("(");
35778 if let Some(this) = &e.this {
35779 self.generate_expression(this)?;
35780 }
35781 if let Some(expression) = &e.expression {
35782 self.write(", ");
35783 self.generate_expression(expression)?;
35784 }
35785 if let Some(zone) = &e.zone {
35786 self.write(", ");
35787 self.generate_expression(zone)?;
35788 }
35789 if let Some(milli) = &e.milli {
35790 self.write(", ");
35791 self.generate_expression(milli)?;
35792 }
35793 self.write(")");
35794 Ok(())
35795 }
35796
35797 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
35798 self.write_keyword("TIMESTAMP_SUB");
35800 self.write("(");
35801 self.generate_expression(&e.this)?;
35802 self.write(", ");
35803 self.write_keyword("INTERVAL");
35804 self.write_space();
35805 self.generate_expression(&e.expression)?;
35806 if let Some(unit) = &e.unit {
35807 self.write_space();
35808 self.write_keyword(unit);
35809 }
35810 self.write(")");
35811 Ok(())
35812 }
35813
35814 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
35815 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
35817 self.write("(");
35818 if let Some(zone) = &e.zone {
35819 self.generate_expression(zone)?;
35820 }
35821 self.write(")");
35822 Ok(())
35823 }
35824
35825 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
35826 self.write_keyword("TO_BINARY");
35828 self.write("(");
35829 self.generate_expression(&e.this)?;
35830 if let Some(format) = &e.format {
35831 self.write(", '");
35832 self.write(format);
35833 self.write("'");
35834 }
35835 self.write(")");
35836 Ok(())
35837 }
35838
35839 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
35840 self.write_keyword("TO_BOOLEAN");
35842 self.write("(");
35843 self.generate_expression(&e.this)?;
35844 self.write(")");
35845 Ok(())
35846 }
35847
35848 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
35849 self.write_keyword("TO_CHAR");
35851 self.write("(");
35852 self.generate_expression(&e.this)?;
35853 if let Some(format) = &e.format {
35854 self.write(", '");
35855 self.write(format);
35856 self.write("'");
35857 }
35858 if let Some(nlsparam) = &e.nlsparam {
35859 self.write(", ");
35860 self.generate_expression(nlsparam)?;
35861 }
35862 self.write(")");
35863 Ok(())
35864 }
35865
35866 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
35867 self.write_keyword("TO_DECFLOAT");
35869 self.write("(");
35870 self.generate_expression(&e.this)?;
35871 if let Some(format) = &e.format {
35872 self.write(", '");
35873 self.write(format);
35874 self.write("'");
35875 }
35876 self.write(")");
35877 Ok(())
35878 }
35879
35880 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
35881 self.write_keyword("TO_DOUBLE");
35883 self.write("(");
35884 self.generate_expression(&e.this)?;
35885 if let Some(format) = &e.format {
35886 self.write(", '");
35887 self.write(format);
35888 self.write("'");
35889 }
35890 self.write(")");
35891 Ok(())
35892 }
35893
35894 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
35895 self.write_keyword("TO_FILE");
35897 self.write("(");
35898 self.generate_expression(&e.this)?;
35899 if let Some(path) = &e.path {
35900 self.write(", ");
35901 self.generate_expression(path)?;
35902 }
35903 self.write(")");
35904 Ok(())
35905 }
35906
35907 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
35908 let is_safe = e.safe.is_some();
35911 if is_safe {
35912 self.write_keyword("TRY_TO_NUMBER");
35913 } else {
35914 self.write_keyword("TO_NUMBER");
35915 }
35916 self.write("(");
35917 self.generate_expression(&e.this)?;
35918 if let Some(format) = &e.format {
35919 self.write(", ");
35920 self.generate_expression(format)?;
35921 }
35922 if let Some(nlsparam) = &e.nlsparam {
35923 self.write(", ");
35924 self.generate_expression(nlsparam)?;
35925 }
35926 if let Some(precision) = &e.precision {
35927 self.write(", ");
35928 self.generate_expression(precision)?;
35929 }
35930 if let Some(scale) = &e.scale {
35931 self.write(", ");
35932 self.generate_expression(scale)?;
35933 }
35934 self.write(")");
35935 Ok(())
35936 }
35937
35938 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
35939 self.write_keyword("TO_TABLE");
35941 self.write_space();
35942 self.generate_expression(&e.this)?;
35943 Ok(())
35944 }
35945
35946 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
35947 let mark_text = e.mark.as_ref().map(|m| match m.as_ref() {
35949 Expression::Identifier(id) => id.name.clone(),
35950 Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
35951 let Literal::String(s) = lit.as_ref() else {
35952 unreachable!()
35953 };
35954 s.clone()
35955 }
35956 _ => String::new(),
35957 });
35958
35959 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
35960 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
35961 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
35962 matches!(m.as_ref(), Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)))
35963 });
35964
35965 let use_start_transaction = matches!(
35967 self.config.dialect,
35968 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
35969 );
35970 let strip_transaction = matches!(
35972 self.config.dialect,
35973 Some(DialectType::Snowflake)
35974 | Some(DialectType::PostgreSQL)
35975 | Some(DialectType::Redshift)
35976 | Some(DialectType::MySQL)
35977 | Some(DialectType::Hive)
35978 | Some(DialectType::Spark)
35979 | Some(DialectType::Databricks)
35980 | Some(DialectType::DuckDB)
35981 | Some(DialectType::Oracle)
35982 | Some(DialectType::Doris)
35983 | Some(DialectType::StarRocks)
35984 | Some(DialectType::Materialize)
35985 | Some(DialectType::ClickHouse)
35986 );
35987
35988 if is_start || use_start_transaction {
35989 self.write_keyword("START TRANSACTION");
35991 if let Some(modes) = &e.modes {
35992 self.write_space();
35993 self.generate_expression(modes)?;
35994 }
35995 } else {
35996 self.write_keyword("BEGIN");
35998
35999 let is_kind = e.this.as_ref().map_or(false, |t| {
36001 if let Expression::Identifier(id) = t.as_ref() {
36002 id.name.eq_ignore_ascii_case("DEFERRED")
36003 || id.name.eq_ignore_ascii_case("IMMEDIATE")
36004 || id.name.eq_ignore_ascii_case("EXCLUSIVE")
36005 } else {
36006 false
36007 }
36008 });
36009
36010 if is_kind {
36012 if let Some(this) = &e.this {
36013 self.write_space();
36014 if let Expression::Identifier(id) = this.as_ref() {
36015 self.write_keyword(&id.name);
36016 }
36017 }
36018 }
36019
36020 if (has_transaction_keyword || has_with_mark) && !strip_transaction {
36022 self.write_space();
36023 self.write_keyword("TRANSACTION");
36024 }
36025
36026 if !is_kind {
36028 if let Some(this) = &e.this {
36029 self.write_space();
36030 self.generate_expression(this)?;
36031 }
36032 }
36033
36034 if has_with_mark {
36036 self.write_space();
36037 self.write_keyword("WITH MARK");
36038 if let Some(Expression::Literal(lit)) = e.mark.as_deref() {
36039 if let Literal::String(desc) = lit.as_ref() {
36040 if !desc.is_empty() {
36041 self.write_space();
36042 self.write(&format!("'{}'", desc));
36043 }
36044 }
36045 }
36046 }
36047
36048 if let Some(modes) = &e.modes {
36050 self.write_space();
36051 self.generate_expression(modes)?;
36052 }
36053 }
36054 Ok(())
36055 }
36056
36057 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
36058 self.write_keyword("TRANSFORM");
36060 self.write("(");
36061 self.generate_expression(&e.this)?;
36062 self.write(", ");
36063 self.generate_expression(&e.expression)?;
36064 self.write(")");
36065 Ok(())
36066 }
36067
36068 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
36069 self.write_keyword("TRANSFORM");
36071 self.write("(");
36072 if self.config.pretty && !e.expressions.is_empty() {
36073 self.indent_level += 1;
36074 for (i, expr) in e.expressions.iter().enumerate() {
36075 if i > 0 {
36076 self.write(",");
36077 }
36078 self.write_newline();
36079 self.write_indent();
36080 self.generate_expression(expr)?;
36081 }
36082 self.indent_level -= 1;
36083 self.write_newline();
36084 self.write(")");
36085 } else {
36086 for (i, expr) in e.expressions.iter().enumerate() {
36087 if i > 0 {
36088 self.write(", ");
36089 }
36090 self.generate_expression(expr)?;
36091 }
36092 self.write(")");
36093 }
36094 Ok(())
36095 }
36096
36097 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
36098 use crate::dialects::DialectType;
36099 if let Some(this) = &e.this {
36101 self.generate_expression(this)?;
36102 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36103 self.write_space();
36104 }
36105 }
36106 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
36107 self.write_keyword("TRANSIENT");
36108 }
36109 Ok(())
36110 }
36111
36112 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
36113 self.write_keyword("TRANSLATE");
36115 self.write("(");
36116 self.generate_expression(&e.this)?;
36117 if let Some(from) = &e.from_ {
36118 self.write(", ");
36119 self.generate_expression(from)?;
36120 }
36121 if let Some(to) = &e.to {
36122 self.write(", ");
36123 self.generate_expression(to)?;
36124 }
36125 self.write(")");
36126 Ok(())
36127 }
36128
36129 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
36130 self.write_keyword("TRANSLATE");
36132 self.write("(");
36133 self.generate_expression(&e.this)?;
36134 self.write_space();
36135 self.write_keyword("USING");
36136 self.write_space();
36137 self.generate_expression(&e.expression)?;
36138 if e.with_error.is_some() {
36139 self.write_space();
36140 self.write_keyword("WITH ERROR");
36141 }
36142 self.write(")");
36143 Ok(())
36144 }
36145
36146 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
36147 self.write_keyword("TRUNCATE TABLE");
36149 self.write_space();
36150 for (i, expr) in e.expressions.iter().enumerate() {
36151 if i > 0 {
36152 self.write(", ");
36153 }
36154 self.generate_expression(expr)?;
36155 }
36156 Ok(())
36157 }
36158
36159 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
36160 self.write_keyword("TRY_BASE64_DECODE_BINARY");
36162 self.write("(");
36163 self.generate_expression(&e.this)?;
36164 if let Some(alphabet) = &e.alphabet {
36165 self.write(", ");
36166 self.generate_expression(alphabet)?;
36167 }
36168 self.write(")");
36169 Ok(())
36170 }
36171
36172 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
36173 self.write_keyword("TRY_BASE64_DECODE_STRING");
36175 self.write("(");
36176 self.generate_expression(&e.this)?;
36177 if let Some(alphabet) = &e.alphabet {
36178 self.write(", ");
36179 self.generate_expression(alphabet)?;
36180 }
36181 self.write(")");
36182 Ok(())
36183 }
36184
36185 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
36186 self.write_keyword("TRY_TO_DECFLOAT");
36188 self.write("(");
36189 self.generate_expression(&e.this)?;
36190 if let Some(format) = &e.format {
36191 self.write(", '");
36192 self.write(format);
36193 self.write("'");
36194 }
36195 self.write(")");
36196 Ok(())
36197 }
36198
36199 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
36200 self.write_keyword("TS_OR_DS_ADD");
36202 self.write("(");
36203 self.generate_expression(&e.this)?;
36204 self.write(", ");
36205 self.generate_expression(&e.expression)?;
36206 if let Some(unit) = &e.unit {
36207 self.write(", ");
36208 self.write_keyword(unit);
36209 }
36210 if let Some(return_type) = &e.return_type {
36211 self.write(", ");
36212 self.generate_expression(return_type)?;
36213 }
36214 self.write(")");
36215 Ok(())
36216 }
36217
36218 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
36219 self.write_keyword("TS_OR_DS_DIFF");
36221 self.write("(");
36222 self.generate_expression(&e.this)?;
36223 self.write(", ");
36224 self.generate_expression(&e.expression)?;
36225 if let Some(unit) = &e.unit {
36226 self.write(", ");
36227 self.write_keyword(unit);
36228 }
36229 self.write(")");
36230 Ok(())
36231 }
36232
36233 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
36234 let default_time_format = "%Y-%m-%d %H:%M:%S";
36235 let default_date_format = "%Y-%m-%d";
36236 let has_non_default_format = e.format.as_ref().map_or(false, |f| {
36237 f != default_time_format && f != default_date_format
36238 });
36239
36240 if has_non_default_format {
36241 let fmt = e.format.as_ref().unwrap();
36243 match self.config.dialect {
36244 Some(DialectType::MySQL) | Some(DialectType::StarRocks) => {
36245 let str_to_time = crate::expressions::StrToTime {
36248 this: Box::new((*e.this).clone()),
36249 format: fmt.clone(),
36250 zone: None,
36251 safe: None,
36252 target_type: None,
36253 };
36254 self.generate_str_to_time(&str_to_time)?;
36255 }
36256 Some(DialectType::Hive)
36257 | Some(DialectType::Spark)
36258 | Some(DialectType::Databricks) => {
36259 self.write_keyword("TO_DATE");
36261 self.write("(");
36262 self.generate_expression(&e.this)?;
36263 self.write(", '");
36264 self.write(&Self::strftime_to_java_format(fmt));
36265 self.write("')");
36266 }
36267 Some(DialectType::Snowflake) => {
36268 self.write_keyword("TO_DATE");
36270 self.write("(");
36271 self.generate_expression(&e.this)?;
36272 self.write(", '");
36273 self.write(&Self::strftime_to_snowflake_format(fmt));
36274 self.write("')");
36275 }
36276 Some(DialectType::Doris) => {
36277 self.write_keyword("TO_DATE");
36279 self.write("(");
36280 self.generate_expression(&e.this)?;
36281 self.write(")");
36282 }
36283 _ => {
36284 self.write_keyword("CAST");
36286 self.write("(");
36287 let str_to_time = crate::expressions::StrToTime {
36288 this: Box::new((*e.this).clone()),
36289 format: fmt.clone(),
36290 zone: None,
36291 safe: None,
36292 target_type: None,
36293 };
36294 self.generate_str_to_time(&str_to_time)?;
36295 self.write_keyword(" AS ");
36296 self.write_keyword("DATE");
36297 self.write(")");
36298 }
36299 }
36300 } else {
36301 match self.config.dialect {
36303 Some(DialectType::MySQL)
36304 | Some(DialectType::SQLite)
36305 | Some(DialectType::StarRocks) => {
36306 self.write_keyword("DATE");
36308 self.write("(");
36309 self.generate_expression(&e.this)?;
36310 self.write(")");
36311 }
36312 Some(DialectType::Hive)
36313 | Some(DialectType::Spark)
36314 | Some(DialectType::Databricks)
36315 | Some(DialectType::Snowflake)
36316 | Some(DialectType::Doris) => {
36317 self.write_keyword("TO_DATE");
36319 self.write("(");
36320 self.generate_expression(&e.this)?;
36321 self.write(")");
36322 }
36323 Some(DialectType::Presto)
36324 | Some(DialectType::Trino)
36325 | Some(DialectType::Athena) => {
36326 self.write_keyword("CAST");
36328 self.write("(");
36329 self.write_keyword("CAST");
36330 self.write("(");
36331 self.generate_expression(&e.this)?;
36332 self.write_keyword(" AS ");
36333 self.write_keyword("TIMESTAMP");
36334 self.write(")");
36335 self.write_keyword(" AS ");
36336 self.write_keyword("DATE");
36337 self.write(")");
36338 }
36339 Some(DialectType::ClickHouse) => {
36340 self.write_keyword("CAST");
36342 self.write("(");
36343 self.generate_expression(&e.this)?;
36344 self.write_keyword(" AS ");
36345 self.write("Nullable(DATE)");
36346 self.write(")");
36347 }
36348 _ => {
36349 self.write_keyword("CAST");
36351 self.write("(");
36352 self.generate_expression(&e.this)?;
36353 self.write_keyword(" AS ");
36354 self.write_keyword("DATE");
36355 self.write(")");
36356 }
36357 }
36358 }
36359 Ok(())
36360 }
36361
36362 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
36363 self.write_keyword("TS_OR_DS_TO_TIME");
36365 self.write("(");
36366 self.generate_expression(&e.this)?;
36367 if let Some(format) = &e.format {
36368 self.write(", '");
36369 self.write(format);
36370 self.write("'");
36371 }
36372 self.write(")");
36373 Ok(())
36374 }
36375
36376 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
36377 self.write_keyword("UNHEX");
36379 self.write("(");
36380 self.generate_expression(&e.this)?;
36381 if let Some(expression) = &e.expression {
36382 self.write(", ");
36383 self.generate_expression(expression)?;
36384 }
36385 self.write(")");
36386 Ok(())
36387 }
36388
36389 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
36390 self.write("U&");
36392 self.generate_expression(&e.this)?;
36393 if let Some(escape) = &e.escape {
36394 self.write_space();
36395 self.write_keyword("UESCAPE");
36396 self.write_space();
36397 self.generate_expression(escape)?;
36398 }
36399 Ok(())
36400 }
36401
36402 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
36403 self.write_keyword("UNIFORM");
36405 self.write("(");
36406 self.generate_expression(&e.this)?;
36407 self.write(", ");
36408 self.generate_expression(&e.expression)?;
36409 if let Some(gen) = &e.gen {
36410 self.write(", ");
36411 self.generate_expression(gen)?;
36412 }
36413 if let Some(seed) = &e.seed {
36414 self.write(", ");
36415 self.generate_expression(seed)?;
36416 }
36417 self.write(")");
36418 Ok(())
36419 }
36420
36421 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
36422 self.write_keyword("UNIQUE");
36424 if e.nulls.is_some() {
36426 self.write(" NULLS NOT DISTINCT");
36427 }
36428 if let Some(this) = &e.this {
36429 self.write_space();
36430 self.generate_expression(this)?;
36431 }
36432 if let Some(index_type) = &e.index_type {
36433 self.write(" USING ");
36434 self.generate_expression(index_type)?;
36435 }
36436 if let Some(on_conflict) = &e.on_conflict {
36437 self.write_space();
36438 self.generate_expression(on_conflict)?;
36439 }
36440 for opt in &e.options {
36441 self.write_space();
36442 self.generate_expression(opt)?;
36443 }
36444 Ok(())
36445 }
36446
36447 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
36448 self.write_keyword("UNIQUE KEY");
36450 self.write(" (");
36451 for (i, expr) in e.expressions.iter().enumerate() {
36452 if i > 0 {
36453 self.write(", ");
36454 }
36455 self.generate_expression(expr)?;
36456 }
36457 self.write(")");
36458 Ok(())
36459 }
36460
36461 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
36462 self.write_keyword("ROLLUP");
36464 self.write(" (");
36465 for (i, index) in e.expressions.iter().enumerate() {
36466 if i > 0 {
36467 self.write(", ");
36468 }
36469 self.generate_identifier(&index.name)?;
36470 self.write("(");
36471 for (j, col) in index.expressions.iter().enumerate() {
36472 if j > 0 {
36473 self.write(", ");
36474 }
36475 self.generate_identifier(col)?;
36476 }
36477 self.write(")");
36478 }
36479 self.write(")");
36480 Ok(())
36481 }
36482
36483 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
36484 match self.config.dialect {
36485 Some(DialectType::DuckDB) => {
36486 self.write_keyword("STRFTIME");
36488 self.write("(");
36489 self.write_keyword("TO_TIMESTAMP");
36490 self.write("(");
36491 self.generate_expression(&e.this)?;
36492 self.write("), '");
36493 if let Some(format) = &e.format {
36494 self.write(format);
36495 }
36496 self.write("')");
36497 }
36498 Some(DialectType::Hive) => {
36499 self.write_keyword("FROM_UNIXTIME");
36501 self.write("(");
36502 self.generate_expression(&e.this)?;
36503 if let Some(format) = &e.format {
36504 if format != "yyyy-MM-dd HH:mm:ss" {
36505 self.write(", '");
36506 self.write(format);
36507 self.write("'");
36508 }
36509 }
36510 self.write(")");
36511 }
36512 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36513 self.write_keyword("DATE_FORMAT");
36515 self.write("(");
36516 self.write_keyword("FROM_UNIXTIME");
36517 self.write("(");
36518 self.generate_expression(&e.this)?;
36519 self.write("), '");
36520 if let Some(format) = &e.format {
36521 self.write(format);
36522 }
36523 self.write("')");
36524 }
36525 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
36526 self.write_keyword("FROM_UNIXTIME");
36528 self.write("(");
36529 self.generate_expression(&e.this)?;
36530 if let Some(format) = &e.format {
36531 self.write(", '");
36532 self.write(format);
36533 self.write("'");
36534 }
36535 self.write(")");
36536 }
36537 _ => {
36538 self.write_keyword("UNIX_TO_STR");
36540 self.write("(");
36541 self.generate_expression(&e.this)?;
36542 if let Some(format) = &e.format {
36543 self.write(", '");
36544 self.write(format);
36545 self.write("'");
36546 }
36547 self.write(")");
36548 }
36549 }
36550 Ok(())
36551 }
36552
36553 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
36554 use crate::dialects::DialectType;
36555 let scale = e.scale.unwrap_or(0); match self.config.dialect {
36558 Some(DialectType::Snowflake) => {
36559 self.write_keyword("TO_TIMESTAMP");
36561 self.write("(");
36562 self.generate_expression(&e.this)?;
36563 if let Some(s) = e.scale {
36564 if s > 0 {
36565 self.write(", ");
36566 self.write(&s.to_string());
36567 }
36568 }
36569 self.write(")");
36570 }
36571 Some(DialectType::BigQuery) => {
36572 match scale {
36575 0 => {
36576 self.write_keyword("TIMESTAMP_SECONDS");
36577 self.write("(");
36578 self.generate_expression(&e.this)?;
36579 self.write(")");
36580 }
36581 3 => {
36582 self.write_keyword("TIMESTAMP_MILLIS");
36583 self.write("(");
36584 self.generate_expression(&e.this)?;
36585 self.write(")");
36586 }
36587 6 => {
36588 self.write_keyword("TIMESTAMP_MICROS");
36589 self.write("(");
36590 self.generate_expression(&e.this)?;
36591 self.write(")");
36592 }
36593 _ => {
36594 self.write_keyword("TIMESTAMP_SECONDS");
36596 self.write("(CAST(");
36597 self.generate_expression(&e.this)?;
36598 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
36599 }
36600 }
36601 }
36602 Some(DialectType::Spark) => {
36603 match scale {
36608 0 => {
36609 self.write_keyword("CAST");
36610 self.write("(");
36611 self.write_keyword("FROM_UNIXTIME");
36612 self.write("(");
36613 self.generate_expression(&e.this)?;
36614 self.write(") ");
36615 self.write_keyword("AS TIMESTAMP");
36616 self.write(")");
36617 }
36618 3 => {
36619 self.write_keyword("TIMESTAMP_MILLIS");
36620 self.write("(");
36621 self.generate_expression(&e.this)?;
36622 self.write(")");
36623 }
36624 6 => {
36625 self.write_keyword("TIMESTAMP_MICROS");
36626 self.write("(");
36627 self.generate_expression(&e.this)?;
36628 self.write(")");
36629 }
36630 _ => {
36631 self.write_keyword("TIMESTAMP_SECONDS");
36632 self.write("(");
36633 self.generate_expression(&e.this)?;
36634 self.write(&format!(" / POWER(10, {}))", scale));
36635 }
36636 }
36637 }
36638 Some(DialectType::Databricks) => {
36639 match scale {
36643 0 => {
36644 self.write_keyword("CAST");
36645 self.write("(");
36646 self.write_keyword("FROM_UNIXTIME");
36647 self.write("(");
36648 self.generate_expression(&e.this)?;
36649 self.write(") ");
36650 self.write_keyword("AS TIMESTAMP");
36651 self.write(")");
36652 }
36653 3 => {
36654 self.write_keyword("TIMESTAMP_MILLIS");
36655 self.write("(");
36656 self.generate_expression(&e.this)?;
36657 self.write(")");
36658 }
36659 6 => {
36660 self.write_keyword("TIMESTAMP_MICROS");
36661 self.write("(");
36662 self.generate_expression(&e.this)?;
36663 self.write(")");
36664 }
36665 _ => {
36666 self.write_keyword("TIMESTAMP_SECONDS");
36667 self.write("(");
36668 self.generate_expression(&e.this)?;
36669 self.write(&format!(" / POWER(10, {}))", scale));
36670 }
36671 }
36672 }
36673 Some(DialectType::Hive) => {
36674 if scale == 0 {
36676 self.write_keyword("FROM_UNIXTIME");
36677 self.write("(");
36678 self.generate_expression(&e.this)?;
36679 self.write(")");
36680 } else {
36681 self.write_keyword("FROM_UNIXTIME");
36682 self.write("(");
36683 self.generate_expression(&e.this)?;
36684 self.write(&format!(" / POWER(10, {})", scale));
36685 self.write(")");
36686 }
36687 }
36688 Some(DialectType::Presto) | Some(DialectType::Trino) => {
36689 if scale == 0 {
36692 self.write_keyword("FROM_UNIXTIME");
36693 self.write("(");
36694 self.generate_expression(&e.this)?;
36695 self.write(")");
36696 } else {
36697 self.write_keyword("FROM_UNIXTIME");
36698 self.write("(CAST(");
36699 self.generate_expression(&e.this)?;
36700 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
36701 }
36702 }
36703 Some(DialectType::DuckDB) => {
36704 match scale {
36708 0 => {
36709 self.write_keyword("TO_TIMESTAMP");
36710 self.write("(");
36711 self.generate_expression(&e.this)?;
36712 self.write(")");
36713 }
36714 3 => {
36715 self.write_keyword("EPOCH_MS");
36716 self.write("(");
36717 self.generate_expression(&e.this)?;
36718 self.write(")");
36719 }
36720 6 => {
36721 self.write_keyword("MAKE_TIMESTAMP");
36722 self.write("(");
36723 self.generate_expression(&e.this)?;
36724 self.write(")");
36725 }
36726 _ => {
36727 self.write_keyword("TO_TIMESTAMP");
36728 self.write("(");
36729 self.generate_expression(&e.this)?;
36730 self.write(&format!(" / POWER(10, {}))", scale));
36731 self.write_keyword(" AT TIME ZONE");
36732 self.write(" 'UTC'");
36733 }
36734 }
36735 }
36736 Some(DialectType::Doris) | Some(DialectType::StarRocks) => {
36737 self.write_keyword("FROM_UNIXTIME");
36739 self.write("(");
36740 self.generate_expression(&e.this)?;
36741 self.write(")");
36742 }
36743 Some(DialectType::Oracle) => {
36744 self.write("TO_DATE('1970-01-01', 'YYYY-MM-DD') + (");
36746 self.generate_expression(&e.this)?;
36747 self.write(" / 86400)");
36748 }
36749 Some(DialectType::Redshift) => {
36750 self.write("(TIMESTAMP 'epoch' + ");
36753 if scale == 0 {
36754 self.generate_expression(&e.this)?;
36755 } else {
36756 self.write("(");
36757 self.generate_expression(&e.this)?;
36758 self.write(&format!(" / POWER(10, {}))", scale));
36759 }
36760 self.write(" * INTERVAL '1 SECOND')");
36761 }
36762 Some(DialectType::Exasol) => {
36763 self.write_keyword("FROM_POSIX_TIME");
36765 self.write("(");
36766 self.generate_expression(&e.this)?;
36767 self.write(")");
36768 }
36769 _ => {
36770 self.write_keyword("TO_TIMESTAMP");
36772 self.write("(");
36773 self.generate_expression(&e.this)?;
36774 if let Some(s) = e.scale {
36775 self.write(", ");
36776 self.write(&s.to_string());
36777 }
36778 self.write(")");
36779 }
36780 }
36781 Ok(())
36782 }
36783
36784 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
36785 if !matches!(&*e.this, Expression::Null(_)) {
36787 self.write_keyword("NAME");
36788 self.write_space();
36789 self.generate_expression(&e.this)?;
36790 }
36791 if !e.expressions.is_empty() {
36792 self.write_space();
36793 self.write_keyword("VALUE");
36794 self.write_space();
36795 for (i, expr) in e.expressions.iter().enumerate() {
36796 if i > 0 {
36797 self.write(", ");
36798 }
36799 self.generate_expression(expr)?;
36800 }
36801 }
36802 Ok(())
36803 }
36804
36805 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
36806 if e.wrapped.is_some() {
36808 self.write("(");
36809 }
36810 self.generate_expression(&e.this)?;
36811 if e.wrapped.is_some() {
36812 self.write(")");
36813 }
36814 self.write("(");
36815 for (i, expr) in e.expressions.iter().enumerate() {
36816 if i > 0 {
36817 self.write(", ");
36818 }
36819 self.generate_expression(expr)?;
36820 }
36821 self.write(")");
36822 Ok(())
36823 }
36824
36825 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
36826 self.write_keyword("USING TEMPLATE");
36828 self.write_space();
36829 self.generate_expression(&e.this)?;
36830 Ok(())
36831 }
36832
36833 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
36834 self.write_keyword("UTC_TIME");
36836 Ok(())
36837 }
36838
36839 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
36840 if matches!(
36841 self.config.dialect,
36842 Some(crate::dialects::DialectType::ClickHouse)
36843 ) {
36844 self.write_keyword("CURRENT_TIMESTAMP");
36845 self.write("('UTC')");
36846 } else {
36847 self.write_keyword("UTC_TIMESTAMP");
36848 }
36849 Ok(())
36850 }
36851
36852 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
36853 use crate::dialects::DialectType;
36854 let func_name = match self.config.dialect {
36856 Some(DialectType::Snowflake) => "UUID_STRING",
36857 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
36858 Some(DialectType::BigQuery) => "GENERATE_UUID",
36859 _ => {
36860 if let Some(name) = &e.name {
36861 name.as_str()
36862 } else {
36863 "UUID"
36864 }
36865 }
36866 };
36867 self.write_keyword(func_name);
36868 self.write("(");
36869 if let Some(this) = &e.this {
36870 self.generate_expression(this)?;
36871 }
36872 self.write(")");
36873 Ok(())
36874 }
36875
36876 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
36877 self.write_keyword("MAP");
36879 self.write("(");
36880 let mut first = true;
36881 for (k, v) in e.keys.iter().zip(e.values.iter()) {
36882 if !first {
36883 self.write(", ");
36884 }
36885 self.generate_expression(k)?;
36886 self.write(", ");
36887 self.generate_expression(v)?;
36888 first = false;
36889 }
36890 self.write(")");
36891 Ok(())
36892 }
36893
36894 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
36895 self.write_keyword("VECTOR_SEARCH");
36897 self.write("(");
36898 self.generate_expression(&e.this)?;
36899 if let Some(col) = &e.column_to_search {
36900 self.write(", ");
36901 self.generate_expression(col)?;
36902 }
36903 if let Some(query_table) = &e.query_table {
36904 self.write(", ");
36905 self.generate_expression(query_table)?;
36906 }
36907 if let Some(query_col) = &e.query_column_to_search {
36908 self.write(", ");
36909 self.generate_expression(query_col)?;
36910 }
36911 if let Some(top_k) = &e.top_k {
36912 self.write(", ");
36913 self.generate_expression(top_k)?;
36914 }
36915 if let Some(dist_type) = &e.distance_type {
36916 self.write(", ");
36917 self.generate_expression(dist_type)?;
36918 }
36919 self.write(")");
36920 Ok(())
36921 }
36922
36923 fn generate_version(&mut self, e: &Version) -> Result<()> {
36924 use crate::dialects::DialectType;
36930 let skip_for = matches!(
36931 self.config.dialect,
36932 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
36933 );
36934 if !skip_for {
36935 self.write_keyword("FOR");
36936 self.write_space();
36937 }
36938 match e.this.as_ref() {
36940 Expression::Identifier(ident) => {
36941 self.write_keyword(&ident.name);
36942 }
36943 _ => {
36944 self.generate_expression(&e.this)?;
36945 }
36946 }
36947 self.write_space();
36948 self.write_keyword(&e.kind);
36949 if let Some(expression) = &e.expression {
36950 self.write_space();
36951 self.generate_expression(expression)?;
36952 }
36953 Ok(())
36954 }
36955
36956 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
36957 self.generate_expression(&e.this)?;
36959 Ok(())
36960 }
36961
36962 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
36963 if e.this.is_some() {
36965 self.write_keyword("NOT VOLATILE");
36966 } else {
36967 self.write_keyword("VOLATILE");
36968 }
36969 Ok(())
36970 }
36971
36972 fn generate_watermark_column_constraint(
36973 &mut self,
36974 e: &WatermarkColumnConstraint,
36975 ) -> Result<()> {
36976 self.write_keyword("WATERMARK FOR");
36978 self.write_space();
36979 self.generate_expression(&e.this)?;
36980 self.write_space();
36981 self.write_keyword("AS");
36982 self.write_space();
36983 self.generate_expression(&e.expression)?;
36984 Ok(())
36985 }
36986
36987 fn generate_week(&mut self, e: &Week) -> Result<()> {
36988 self.write_keyword("WEEK");
36990 self.write("(");
36991 self.generate_expression(&e.this)?;
36992 if let Some(mode) = &e.mode {
36993 self.write(", ");
36994 self.generate_expression(mode)?;
36995 }
36996 self.write(")");
36997 Ok(())
36998 }
36999
37000 fn generate_when(&mut self, e: &When) -> Result<()> {
37001 self.write_keyword("WHEN");
37005 self.write_space();
37006
37007 if let Some(matched) = &e.matched {
37009 match matched.as_ref() {
37011 Expression::Boolean(b) if b.value => {
37012 self.write_keyword("MATCHED");
37013 }
37014 _ => {
37015 self.write_keyword("NOT MATCHED");
37016 }
37017 }
37018 } else {
37019 self.write_keyword("NOT MATCHED");
37020 }
37021
37022 if self.config.matched_by_source {
37027 if let Some(source) = &e.source {
37028 if let Expression::Boolean(b) = source.as_ref() {
37029 if b.value {
37030 self.write_space();
37032 self.write_keyword("BY SOURCE");
37033 }
37034 } else {
37036 self.write_space();
37038 self.write_keyword("BY SOURCE");
37039 }
37040 }
37041 }
37042
37043 if let Some(condition) = &e.condition {
37045 self.write_space();
37046 self.write_keyword("AND");
37047 self.write_space();
37048 self.generate_expression(condition)?;
37049 }
37050
37051 self.write_space();
37052 self.write_keyword("THEN");
37053 self.write_space();
37054
37055 self.generate_merge_action(&e.then)?;
37058
37059 Ok(())
37060 }
37061
37062 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
37063 match action {
37064 Expression::Tuple(tuple) => {
37065 let elements = &tuple.expressions;
37066 if elements.is_empty() {
37067 return self.generate_expression(action);
37068 }
37069 match &elements[0] {
37071 Expression::Var(v) if v.this == "INSERT" => {
37072 self.write_keyword("INSERT");
37073 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37075 self.write(" *");
37076 } else {
37077 let mut values_idx = 1;
37078 if elements.len() > 1 {
37080 if let Expression::Tuple(cols) = &elements[1] {
37081 if elements.len() > 2 {
37083 self.write(" (");
37085 for (i, col) in cols.expressions.iter().enumerate() {
37086 if i > 0 {
37087 self.write(", ");
37088 }
37089 if !self.merge_strip_qualifiers.is_empty() {
37091 let stripped = self.strip_merge_qualifier(col);
37092 self.generate_expression(&stripped)?;
37093 } else {
37094 self.generate_expression(col)?;
37095 }
37096 }
37097 self.write(")");
37098 values_idx = 2;
37099 } else {
37100 values_idx = 1;
37102 }
37103 }
37104 }
37105 if values_idx < elements.len() {
37107 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
37109 if !is_row {
37110 self.write_space();
37111 self.write_keyword("VALUES");
37112 }
37113 self.write(" ");
37114 if let Expression::Tuple(vals) = &elements[values_idx] {
37115 self.write("(");
37116 for (i, val) in vals.expressions.iter().enumerate() {
37117 if i > 0 {
37118 self.write(", ");
37119 }
37120 self.generate_expression(val)?;
37121 }
37122 self.write(")");
37123 } else {
37124 self.generate_expression(&elements[values_idx])?;
37125 }
37126 }
37127 } }
37129 Expression::Var(v) if v.this == "UPDATE" => {
37130 self.write_keyword("UPDATE");
37131 if elements.len() > 1 && matches!(&elements[1], Expression::Star(_)) {
37133 self.write(" *");
37134 } else if elements.len() > 1 {
37135 self.write_space();
37136 self.write_keyword("SET");
37137 if self.config.pretty {
37139 self.write_newline();
37140 self.indent_level += 1;
37141 self.write_indent();
37142 } else {
37143 self.write_space();
37144 }
37145 if let Expression::Tuple(assignments) = &elements[1] {
37146 for (i, assignment) in assignments.expressions.iter().enumerate() {
37147 if i > 0 {
37148 if self.config.pretty {
37149 self.write(",");
37150 self.write_newline();
37151 self.write_indent();
37152 } else {
37153 self.write(", ");
37154 }
37155 }
37156 if !self.merge_strip_qualifiers.is_empty() {
37158 self.generate_merge_set_assignment(assignment)?;
37159 } else {
37160 self.generate_expression(assignment)?;
37161 }
37162 }
37163 } else {
37164 self.generate_expression(&elements[1])?;
37165 }
37166 if self.config.pretty {
37167 self.indent_level -= 1;
37168 }
37169 }
37170 }
37171 _ => {
37172 self.generate_expression(action)?;
37174 }
37175 }
37176 }
37177 Expression::Var(v)
37178 if v.this == "INSERT"
37179 || v.this == "UPDATE"
37180 || v.this == "DELETE"
37181 || v.this == "DO NOTHING" =>
37182 {
37183 self.write_keyword(&v.this);
37184 }
37185 _ => {
37186 self.generate_expression(action)?;
37187 }
37188 }
37189 Ok(())
37190 }
37191
37192 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
37194 match assignment {
37195 Expression::Eq(eq) => {
37196 let stripped_left = self.strip_merge_qualifier(&eq.left);
37198 self.generate_expression(&stripped_left)?;
37199 self.write(" = ");
37200 self.generate_expression(&eq.right)?;
37201 Ok(())
37202 }
37203 other => self.generate_expression(other),
37204 }
37205 }
37206
37207 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
37209 match expr {
37210 Expression::Column(col) => {
37211 if let Some(ref table_ident) = col.table {
37212 if self
37213 .merge_strip_qualifiers
37214 .iter()
37215 .any(|n| n.eq_ignore_ascii_case(&table_ident.name))
37216 {
37217 let mut col = col.clone();
37219 col.table = None;
37220 return Expression::Column(col);
37221 }
37222 }
37223 expr.clone()
37224 }
37225 Expression::Dot(dot) => {
37226 if let Expression::Identifier(id) = &dot.this {
37228 if self
37229 .merge_strip_qualifiers
37230 .iter()
37231 .any(|n| n.eq_ignore_ascii_case(&id.name))
37232 {
37233 return Expression::Identifier(dot.field.clone());
37234 }
37235 }
37236 expr.clone()
37237 }
37238 _ => expr.clone(),
37239 }
37240 }
37241
37242 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
37243 for (i, expr) in e.expressions.iter().enumerate() {
37245 if i > 0 {
37246 if self.config.pretty {
37248 self.write_newline();
37249 self.write_indent();
37250 } else {
37251 self.write_space();
37252 }
37253 }
37254 self.generate_expression(expr)?;
37255 }
37256 Ok(())
37257 }
37258
37259 fn generate_where(&mut self, e: &Where) -> Result<()> {
37260 self.write_keyword("WHERE");
37262 self.write_space();
37263 self.generate_expression(&e.this)?;
37264 Ok(())
37265 }
37266
37267 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
37268 self.write_keyword("WIDTH_BUCKET");
37270 self.write("(");
37271 self.generate_expression(&e.this)?;
37272 if let Some(min_value) = &e.min_value {
37273 self.write(", ");
37274 self.generate_expression(min_value)?;
37275 }
37276 if let Some(max_value) = &e.max_value {
37277 self.write(", ");
37278 self.generate_expression(max_value)?;
37279 }
37280 if let Some(num_buckets) = &e.num_buckets {
37281 self.write(", ");
37282 self.generate_expression(num_buckets)?;
37283 }
37284 self.write(")");
37285 Ok(())
37286 }
37287
37288 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
37289 self.generate_window_spec(e)
37291 }
37292
37293 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
37294 let mut has_content = false;
37296
37297 if !e.partition_by.is_empty() {
37299 self.write_keyword("PARTITION BY");
37300 self.write_space();
37301 for (i, expr) in e.partition_by.iter().enumerate() {
37302 if i > 0 {
37303 self.write(", ");
37304 }
37305 self.generate_expression(expr)?;
37306 }
37307 has_content = true;
37308 }
37309
37310 if !e.order_by.is_empty() {
37312 if has_content {
37313 self.write_space();
37314 }
37315 self.write_keyword("ORDER BY");
37316 self.write_space();
37317 for (i, ordered) in e.order_by.iter().enumerate() {
37318 if i > 0 {
37319 self.write(", ");
37320 }
37321 self.generate_expression(&ordered.this)?;
37322 if ordered.desc {
37323 self.write_space();
37324 self.write_keyword("DESC");
37325 } else if ordered.explicit_asc {
37326 self.write_space();
37327 self.write_keyword("ASC");
37328 }
37329 if let Some(nulls_first) = ordered.nulls_first {
37330 self.write_space();
37331 self.write_keyword("NULLS");
37332 self.write_space();
37333 if nulls_first {
37334 self.write_keyword("FIRST");
37335 } else {
37336 self.write_keyword("LAST");
37337 }
37338 }
37339 }
37340 has_content = true;
37341 }
37342
37343 if let Some(frame) = &e.frame {
37345 if has_content {
37346 self.write_space();
37347 }
37348 self.generate_window_frame(frame)?;
37349 }
37350
37351 Ok(())
37352 }
37353
37354 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
37355 self.write_keyword("WITH");
37357 self.write_space();
37358 if e.no.is_some() {
37359 self.write_keyword("NO");
37360 self.write_space();
37361 }
37362 self.write_keyword("DATA");
37363
37364 if let Some(statistics) = &e.statistics {
37366 self.write_space();
37367 self.write_keyword("AND");
37368 self.write_space();
37369 match statistics.as_ref() {
37371 Expression::Boolean(b) if !b.value => {
37372 self.write_keyword("NO");
37373 self.write_space();
37374 }
37375 _ => {}
37376 }
37377 self.write_keyword("STATISTICS");
37378 }
37379 Ok(())
37380 }
37381
37382 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
37383 self.write_keyword("WITH FILL");
37385
37386 if let Some(from_) = &e.from_ {
37387 self.write_space();
37388 self.write_keyword("FROM");
37389 self.write_space();
37390 self.generate_expression(from_)?;
37391 }
37392
37393 if let Some(to) = &e.to {
37394 self.write_space();
37395 self.write_keyword("TO");
37396 self.write_space();
37397 self.generate_expression(to)?;
37398 }
37399
37400 if let Some(step) = &e.step {
37401 self.write_space();
37402 self.write_keyword("STEP");
37403 self.write_space();
37404 self.generate_expression(step)?;
37405 }
37406
37407 if let Some(staleness) = &e.staleness {
37408 self.write_space();
37409 self.write_keyword("STALENESS");
37410 self.write_space();
37411 self.generate_expression(staleness)?;
37412 }
37413
37414 if let Some(interpolate) = &e.interpolate {
37415 self.write_space();
37416 self.write_keyword("INTERPOLATE");
37417 self.write(" (");
37418 self.generate_interpolate_item(interpolate)?;
37420 self.write(")");
37421 }
37422
37423 Ok(())
37424 }
37425
37426 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
37428 match expr {
37429 Expression::Alias(alias) => {
37430 self.generate_identifier(&alias.alias)?;
37432 self.write_space();
37433 self.write_keyword("AS");
37434 self.write_space();
37435 self.generate_expression(&alias.this)?;
37436 }
37437 Expression::Tuple(tuple) => {
37438 for (i, item) in tuple.expressions.iter().enumerate() {
37439 if i > 0 {
37440 self.write(", ");
37441 }
37442 self.generate_interpolate_item(item)?;
37443 }
37444 }
37445 other => {
37446 self.generate_expression(other)?;
37447 }
37448 }
37449 Ok(())
37450 }
37451
37452 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
37453 self.write_keyword("WITH JOURNAL TABLE");
37455 self.write("=");
37456 self.generate_expression(&e.this)?;
37457 Ok(())
37458 }
37459
37460 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
37461 self.generate_expression(&e.this)?;
37463 self.write_space();
37464 self.write_keyword("WITH");
37465 self.write_space();
37466 self.write_keyword(&e.op);
37467 Ok(())
37468 }
37469
37470 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
37471 self.write_keyword("WITH");
37473 self.write_space();
37474 for (i, expr) in e.expressions.iter().enumerate() {
37475 if i > 0 {
37476 self.write(", ");
37477 }
37478 self.generate_expression(expr)?;
37479 }
37480 Ok(())
37481 }
37482
37483 fn generate_with_schema_binding_property(
37484 &mut self,
37485 e: &WithSchemaBindingProperty,
37486 ) -> Result<()> {
37487 self.write_keyword("WITH");
37489 self.write_space();
37490 self.generate_expression(&e.this)?;
37491 Ok(())
37492 }
37493
37494 fn generate_with_system_versioning_property(
37495 &mut self,
37496 e: &WithSystemVersioningProperty,
37497 ) -> Result<()> {
37498 let mut parts = Vec::new();
37504
37505 if let Some(this) = &e.this {
37506 let mut s = String::from("HISTORY_TABLE=");
37508 let mut gen = Generator::new();
37509 gen.generate_expression(this)?;
37510 s.push_str(&gen.output);
37511 parts.push(s);
37512 }
37513
37514 if let Some(data_consistency) = &e.data_consistency {
37515 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
37516 let mut gen = Generator::new();
37517 gen.generate_expression(data_consistency)?;
37518 s.push_str(&gen.output);
37519 parts.push(s);
37520 }
37521
37522 if let Some(retention_period) = &e.retention_period {
37523 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
37524 let mut gen = Generator::new();
37525 gen.generate_expression(retention_period)?;
37526 s.push_str(&gen.output);
37527 parts.push(s);
37528 }
37529
37530 self.write_keyword("SYSTEM_VERSIONING");
37531 self.write("=");
37532
37533 if !parts.is_empty() {
37534 self.write_keyword("ON");
37535 self.write("(");
37536 self.write(&parts.join(", "));
37537 self.write(")");
37538 } else if e.on.is_some() {
37539 self.write_keyword("ON");
37540 } else {
37541 self.write_keyword("OFF");
37542 }
37543
37544 if e.with_.is_some() {
37546 let inner = self.output.clone();
37547 self.output.clear();
37548 self.write("WITH(");
37549 self.write(&inner);
37550 self.write(")");
37551 }
37552
37553 Ok(())
37554 }
37555
37556 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
37557 self.write_keyword("WITH");
37559 self.write(" (");
37560 for (i, expr) in e.expressions.iter().enumerate() {
37561 if i > 0 {
37562 self.write(", ");
37563 }
37564 self.generate_expression(expr)?;
37565 }
37566 self.write(")");
37567 Ok(())
37568 }
37569
37570 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
37571 self.write_keyword("XMLELEMENT");
37574 self.write("(");
37575
37576 if e.evalname.is_some() {
37577 self.write_keyword("EVALNAME");
37578 } else {
37579 self.write_keyword("NAME");
37580 }
37581 self.write_space();
37582 self.generate_expression(&e.this)?;
37583
37584 for expr in &e.expressions {
37585 self.write(", ");
37586 self.generate_expression(expr)?;
37587 }
37588 self.write(")");
37589 Ok(())
37590 }
37591
37592 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
37593 self.write_keyword("XMLGET");
37595 self.write("(");
37596 self.generate_expression(&e.this)?;
37597 self.write(", ");
37598 self.generate_expression(&e.expression)?;
37599 if let Some(instance) = &e.instance {
37600 self.write(", ");
37601 self.generate_expression(instance)?;
37602 }
37603 self.write(")");
37604 Ok(())
37605 }
37606
37607 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
37608 self.generate_expression(&e.this)?;
37610 if let Some(expression) = &e.expression {
37611 self.write("(");
37612 self.generate_expression(expression)?;
37613 self.write(")");
37614 }
37615 Ok(())
37616 }
37617
37618 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
37619 self.write_keyword("XMLTABLE");
37621 self.write("(");
37622
37623 if self.config.pretty {
37624 self.indent_level += 1;
37625 self.write_newline();
37626 self.write_indent();
37627 self.generate_expression(&e.this)?;
37628
37629 if let Some(passing) = &e.passing {
37630 self.write_newline();
37631 self.write_indent();
37632 self.write_keyword("PASSING");
37633 if let Expression::Tuple(tuple) = passing.as_ref() {
37634 for expr in &tuple.expressions {
37635 self.write_newline();
37636 self.indent_level += 1;
37637 self.write_indent();
37638 self.generate_expression(expr)?;
37639 self.indent_level -= 1;
37640 }
37641 } else {
37642 self.write_newline();
37643 self.indent_level += 1;
37644 self.write_indent();
37645 self.generate_expression(passing)?;
37646 self.indent_level -= 1;
37647 }
37648 }
37649
37650 if e.by_ref.is_some() {
37651 self.write_newline();
37652 self.write_indent();
37653 self.write_keyword("RETURNING SEQUENCE BY REF");
37654 }
37655
37656 if !e.columns.is_empty() {
37657 self.write_newline();
37658 self.write_indent();
37659 self.write_keyword("COLUMNS");
37660 for (i, col) in e.columns.iter().enumerate() {
37661 self.write_newline();
37662 self.indent_level += 1;
37663 self.write_indent();
37664 self.generate_expression(col)?;
37665 self.indent_level -= 1;
37666 if i < e.columns.len() - 1 {
37667 self.write(",");
37668 }
37669 }
37670 }
37671
37672 self.indent_level -= 1;
37673 self.write_newline();
37674 self.write_indent();
37675 self.write(")");
37676 return Ok(());
37677 }
37678
37679 if let Some(namespaces) = &e.namespaces {
37681 self.write_keyword("XMLNAMESPACES");
37682 self.write("(");
37683 if let Expression::Tuple(tuple) = namespaces.as_ref() {
37685 for (i, expr) in tuple.expressions.iter().enumerate() {
37686 if i > 0 {
37687 self.write(", ");
37688 }
37689 if !matches!(expr, Expression::Alias(_)) {
37692 self.write_keyword("DEFAULT");
37693 self.write_space();
37694 }
37695 self.generate_expression(expr)?;
37696 }
37697 } else {
37698 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
37700 self.write_keyword("DEFAULT");
37701 self.write_space();
37702 }
37703 self.generate_expression(namespaces)?;
37704 }
37705 self.write("), ");
37706 }
37707
37708 self.generate_expression(&e.this)?;
37710
37711 if let Some(passing) = &e.passing {
37713 self.write_space();
37714 self.write_keyword("PASSING");
37715 self.write_space();
37716 if let Expression::Tuple(tuple) = passing.as_ref() {
37718 for (i, expr) in tuple.expressions.iter().enumerate() {
37719 if i > 0 {
37720 self.write(", ");
37721 }
37722 self.generate_expression(expr)?;
37723 }
37724 } else {
37725 self.generate_expression(passing)?;
37726 }
37727 }
37728
37729 if e.by_ref.is_some() {
37731 self.write_space();
37732 self.write_keyword("RETURNING SEQUENCE BY REF");
37733 }
37734
37735 if !e.columns.is_empty() {
37737 self.write_space();
37738 self.write_keyword("COLUMNS");
37739 self.write_space();
37740 for (i, col) in e.columns.iter().enumerate() {
37741 if i > 0 {
37742 self.write(", ");
37743 }
37744 self.generate_expression(col)?;
37745 }
37746 }
37747
37748 self.write(")");
37749 Ok(())
37750 }
37751
37752 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
37753 if let Some(this) = &e.this {
37756 self.generate_expression(this)?;
37757 if let Some(expression) = &e.expression {
37758 self.write_space();
37759 self.write_keyword("XOR");
37760 self.write_space();
37761 self.generate_expression(expression)?;
37762 }
37763 }
37764
37765 for (i, expr) in e.expressions.iter().enumerate() {
37767 if i > 0 || e.this.is_some() {
37768 self.write_space();
37769 self.write_keyword("XOR");
37770 self.write_space();
37771 }
37772 self.generate_expression(expr)?;
37773 }
37774 Ok(())
37775 }
37776
37777 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
37778 self.write_keyword("ZIPF");
37780 self.write("(");
37781 self.generate_expression(&e.this)?;
37782 if let Some(elementcount) = &e.elementcount {
37783 self.write(", ");
37784 self.generate_expression(elementcount)?;
37785 }
37786 if let Some(gen) = &e.gen {
37787 self.write(", ");
37788 self.generate_expression(gen)?;
37789 }
37790 self.write(")");
37791 Ok(())
37792 }
37793}
37794
37795impl Default for Generator {
37796 fn default() -> Self {
37797 Self::new()
37798 }
37799}
37800
37801#[cfg(test)]
37802mod tests {
37803 use super::*;
37804 use crate::parser::Parser;
37805
37806 fn roundtrip(sql: &str) -> String {
37807 let ast = Parser::parse_sql(sql).unwrap();
37808 Generator::sql(&ast[0]).unwrap()
37809 }
37810
37811 #[test]
37812 fn test_simple_select() {
37813 let result = roundtrip("SELECT 1");
37814 assert_eq!(result, "SELECT 1");
37815 }
37816
37817 #[test]
37818 fn test_select_from() {
37819 let result = roundtrip("SELECT a, b FROM t");
37820 assert_eq!(result, "SELECT a, b FROM t");
37821 }
37822
37823 #[test]
37824 fn test_select_where() {
37825 let result = roundtrip("SELECT * FROM t WHERE x = 1");
37826 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
37827 }
37828
37829 #[test]
37830 fn test_select_join() {
37831 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
37832 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
37833 }
37834
37835 #[test]
37836 fn test_insert() {
37837 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
37838 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
37839 }
37840
37841 #[test]
37842 fn test_pretty_print() {
37843 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
37844 let result = Generator::pretty_sql(&ast[0]).unwrap();
37845 assert!(result.contains('\n'));
37846 }
37847
37848 #[test]
37849 fn test_window_function() {
37850 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
37851 assert_eq!(
37852 result,
37853 "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)"
37854 );
37855 }
37856
37857 #[test]
37858 fn test_window_function_with_frame() {
37859 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
37860 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
37861 }
37862
37863 #[test]
37864 fn test_aggregate_with_filter() {
37865 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
37866 assert_eq!(
37867 result,
37868 "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders"
37869 );
37870 }
37871
37872 #[test]
37873 fn test_subscript() {
37874 let result = roundtrip("SELECT arr[0]");
37875 assert_eq!(result, "SELECT arr[0]");
37876 }
37877
37878 #[test]
37880 fn test_create_table() {
37881 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
37882 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
37883 }
37884
37885 #[test]
37886 fn test_create_table_with_constraints() {
37887 let result = roundtrip(
37888 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)",
37889 );
37890 assert_eq!(
37891 result,
37892 "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)"
37893 );
37894 }
37895
37896 #[test]
37897 fn test_create_table_if_not_exists() {
37898 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
37899 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
37900 }
37901
37902 #[test]
37903 fn test_drop_table() {
37904 let result = roundtrip("DROP TABLE users");
37905 assert_eq!(result, "DROP TABLE users");
37906 }
37907
37908 #[test]
37909 fn test_drop_table_if_exists_cascade() {
37910 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
37911 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
37912 }
37913
37914 #[test]
37915 fn test_alter_table_add_column() {
37916 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
37917 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
37918 }
37919
37920 #[test]
37921 fn test_alter_table_drop_column() {
37922 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
37923 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
37924 }
37925
37926 #[test]
37927 fn test_create_index() {
37928 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
37929 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
37930 }
37931
37932 #[test]
37933 fn test_create_unique_index() {
37934 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
37935 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
37936 }
37937
37938 #[test]
37939 fn test_drop_index() {
37940 let result = roundtrip("DROP INDEX idx_name");
37941 assert_eq!(result, "DROP INDEX idx_name");
37942 }
37943
37944 #[test]
37945 fn test_create_view() {
37946 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
37947 assert_eq!(
37948 result,
37949 "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1"
37950 );
37951 }
37952
37953 #[test]
37954 fn test_drop_view() {
37955 let result = roundtrip("DROP VIEW active_users");
37956 assert_eq!(result, "DROP VIEW active_users");
37957 }
37958
37959 #[test]
37960 fn test_truncate() {
37961 let result = roundtrip("TRUNCATE TABLE users");
37962 assert_eq!(result, "TRUNCATE TABLE users");
37963 }
37964
37965 #[test]
37966 fn test_string_literal_escaping_default() {
37967 let result = roundtrip("SELECT 'hello'");
37969 assert_eq!(result, "SELECT 'hello'");
37970
37971 let result = roundtrip("SELECT 'it''s a test'");
37973 assert_eq!(result, "SELECT 'it''s a test'");
37974 }
37975
37976 #[test]
37977 fn test_not_in_style_prefix_default_generic() {
37978 let result = roundtrip("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')");
37979 assert_eq!(
37980 result,
37981 "SELECT id FROM users WHERE NOT status IN ('deleted', 'banned')"
37982 );
37983 }
37984
37985 #[test]
37986 fn test_not_in_style_infix_generic_override() {
37987 let ast =
37988 Parser::parse_sql("SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')")
37989 .unwrap();
37990 let config = GeneratorConfig {
37991 not_in_style: NotInStyle::Infix,
37992 ..Default::default()
37993 };
37994 let mut gen = Generator::with_config(config);
37995 let result = gen.generate(&ast[0]).unwrap();
37996 assert_eq!(
37997 result,
37998 "SELECT id FROM users WHERE status NOT IN ('deleted', 'banned')"
37999 );
38000 }
38001
38002 #[test]
38003 fn test_string_literal_escaping_mysql() {
38004 use crate::dialects::DialectType;
38005
38006 let config = GeneratorConfig {
38007 dialect: Some(DialectType::MySQL),
38008 ..Default::default()
38009 };
38010
38011 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38012 let mut gen = Generator::with_config(config.clone());
38013 let result = gen.generate(&ast[0]).unwrap();
38014 assert_eq!(result, "SELECT 'hello'");
38015
38016 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38018 let mut gen = Generator::with_config(config.clone());
38019 let result = gen.generate(&ast[0]).unwrap();
38020 assert_eq!(result, "SELECT 'it''s'");
38021 }
38022
38023 #[test]
38024 fn test_string_literal_escaping_postgres() {
38025 use crate::dialects::DialectType;
38026
38027 let config = GeneratorConfig {
38028 dialect: Some(DialectType::PostgreSQL),
38029 ..Default::default()
38030 };
38031
38032 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38033 let mut gen = Generator::with_config(config.clone());
38034 let result = gen.generate(&ast[0]).unwrap();
38035 assert_eq!(result, "SELECT 'hello'");
38036
38037 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38039 let mut gen = Generator::with_config(config.clone());
38040 let result = gen.generate(&ast[0]).unwrap();
38041 assert_eq!(result, "SELECT 'it''s'");
38042 }
38043
38044 #[test]
38045 fn test_string_literal_escaping_bigquery() {
38046 use crate::dialects::DialectType;
38047
38048 let config = GeneratorConfig {
38049 dialect: Some(DialectType::BigQuery),
38050 ..Default::default()
38051 };
38052
38053 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
38054 let mut gen = Generator::with_config(config.clone());
38055 let result = gen.generate(&ast[0]).unwrap();
38056 assert_eq!(result, "SELECT 'hello'");
38057
38058 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
38060 let mut gen = Generator::with_config(config.clone());
38061 let result = gen.generate(&ast[0]).unwrap();
38062 assert_eq!(result, "SELECT 'it\\'s'");
38063 }
38064
38065 #[test]
38066 fn test_generate_deep_and_chain_without_stack_growth() {
38067 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38068 Expression::column("c0"),
38069 Expression::number(0),
38070 )));
38071
38072 for i in 1..2500 {
38073 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38074 Expression::column(format!("c{i}")),
38075 Expression::number(i as i64),
38076 )));
38077 expr = Expression::And(Box::new(BinaryOp::new(expr, predicate)));
38078 }
38079
38080 let sql = Generator::sql(&expr).expect("deep AND chain should generate");
38081 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38082 }
38083
38084 #[test]
38085 fn test_generate_deep_or_chain_without_stack_growth() {
38086 let mut expr = Expression::Eq(Box::new(BinaryOp::new(
38087 Expression::column("c0"),
38088 Expression::number(0),
38089 )));
38090
38091 for i in 1..2500 {
38092 let predicate = Expression::Eq(Box::new(BinaryOp::new(
38093 Expression::column(format!("c{i}")),
38094 Expression::number(i as i64),
38095 )));
38096 expr = Expression::Or(Box::new(BinaryOp::new(expr, predicate)));
38097 }
38098
38099 let sql = Generator::sql(&expr).expect("deep OR chain should generate");
38100 assert!(sql.contains("c2499 = 2499"), "{}", sql);
38101 }
38102}